New WchRiscV target class
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
#include <algorithm>
|
||||
|
||||
#include "src/Targets/Microchip/AVR8/TargetDescriptionFile.hpp"
|
||||
#include "src/Targets/RiscV/TargetDescriptionFile.hpp"
|
||||
#include "src/Targets/RiscV/Wch/TargetDescriptionFile.hpp"
|
||||
|
||||
#include "Responses/Error.hpp"
|
||||
|
||||
@@ -393,9 +393,15 @@ namespace TargetController
|
||||
}
|
||||
|
||||
if (briefDescriptor.family == TargetFamily::RISC_V) {
|
||||
return std::make_unique<RiscV::RiscV>(
|
||||
/*
|
||||
* Given that WCH targets are the only RISC-V targets we support ATM, we can just assume that
|
||||
* construction of a WchRiscV object is necessary.
|
||||
*
|
||||
* TODO: Review later
|
||||
*/
|
||||
return std::make_unique<RiscV::Wch::WchRiscV>(
|
||||
this->environmentConfig.targetConfig,
|
||||
RiscV::TargetDescriptionFile{
|
||||
RiscV::Wch::TargetDescriptionFile{
|
||||
PathService::targetDescriptionFilesDirPath() + "/" + briefDescriptor.relativeTdfPath
|
||||
}
|
||||
);
|
||||
|
||||
@@ -24,4 +24,6 @@ target_sources(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/RiscV/RiscV.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/RiscV/RiscVTargetConfig.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/RiscV/TargetDescriptionFile.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/RiscV/Wch/WchRiscV.cpp
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/RiscV/Wch/TargetDescriptionFile.cpp
|
||||
)
|
||||
|
||||
@@ -16,10 +16,10 @@ namespace Targets::RiscV
|
||||
{
|
||||
RiscV::RiscV(
|
||||
const TargetConfig& targetConfig,
|
||||
TargetDescriptionFile&& targetDescriptionFile
|
||||
const TargetDescriptionFile& targetDescriptionFile
|
||||
)
|
||||
: targetConfig(RiscVTargetConfig{targetConfig})
|
||||
, targetDescriptionFile(std::move(targetDescriptionFile))
|
||||
, targetDescriptionFile(targetDescriptionFile)
|
||||
, cpuRegisterAddressSpaceDescriptor(RiscV::generateCpuRegisterAddressSpaceDescriptor())
|
||||
, csrMemorySegmentDescriptor(this->cpuRegisterAddressSpaceDescriptor.getMemorySegmentDescriptor("cs_registers"))
|
||||
, gprMemorySegmentDescriptor(this->cpuRegisterAddressSpaceDescriptor.getMemorySegmentDescriptor("gp_registers"))
|
||||
@@ -58,15 +58,6 @@ namespace Targets::RiscV
|
||||
|
||||
void RiscV::activate() {
|
||||
this->riscVDebugInterface->activate();
|
||||
|
||||
const auto deviceId = this->riscVIdInterface->getDeviceId();
|
||||
const auto tdfDeviceId = this->targetDescriptionFile.getTargetId();
|
||||
if (deviceId != tdfDeviceId) {
|
||||
throw Exceptions::InvalidConfig{
|
||||
"RISC-V target ID mismatch - expected " + tdfDeviceId + " but got " + deviceId +
|
||||
". Please check target configuration."
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
void RiscV::deactivate() {
|
||||
@@ -82,39 +73,7 @@ namespace Targets::RiscV
|
||||
}
|
||||
|
||||
void RiscV::postActivate() {
|
||||
Logger::info("WCH target ID: " + this->riscVIdInterface->getDeviceId());
|
||||
}
|
||||
|
||||
TargetDescriptor RiscV::targetDescriptor() {
|
||||
auto descriptor = TargetDescriptor{
|
||||
this->targetDescriptionFile.getName(),
|
||||
this->targetDescriptionFile.getFamily(),
|
||||
this->targetDescriptionFile.getTargetId(),
|
||||
this->targetDescriptionFile.getVendorName(),
|
||||
this->targetDescriptionFile.targetAddressSpaceDescriptorsByKey(),
|
||||
this->targetDescriptionFile.targetPeripheralDescriptorsByKey(),
|
||||
this->targetDescriptionFile.targetPadDescriptorsByKey(),
|
||||
this->targetDescriptionFile.targetPinoutDescriptorsByKey(),
|
||||
this->targetDescriptionFile.targetVariantDescriptorsByKey(),
|
||||
BreakpointResources{
|
||||
this->riscVDebugInterface->getHardwareBreakpointCount(),
|
||||
std::nullopt,
|
||||
static_cast<std::uint16_t>(this->targetConfig.reserveSteppingBreakpoint ? 1 : 0)
|
||||
}
|
||||
};
|
||||
|
||||
// Copy the RISC-V CPU register address space and peripheral descriptor
|
||||
descriptor.addressSpaceDescriptorsByKey.emplace(
|
||||
this->cpuRegisterAddressSpaceDescriptor.key,
|
||||
this->cpuRegisterAddressSpaceDescriptor.clone()
|
||||
);
|
||||
|
||||
descriptor.peripheralDescriptorsByKey.emplace(
|
||||
this->cpuPeripheralDescriptor.key,
|
||||
this->cpuPeripheralDescriptor.clone()
|
||||
);
|
||||
|
||||
return descriptor;
|
||||
// Nothing to do here, for now.
|
||||
}
|
||||
|
||||
void RiscV::run(std::optional<TargetMemoryAddress> toAddress) {
|
||||
|
||||
@@ -19,7 +19,7 @@ namespace Targets::RiscV
|
||||
class RiscV: public Target
|
||||
{
|
||||
public:
|
||||
RiscV(const TargetConfig& targetConfig, TargetDescriptionFile&& targetDescriptionFile);
|
||||
RiscV(const TargetConfig& targetConfig, const TargetDescriptionFile& targetDescriptionFile);
|
||||
|
||||
/*
|
||||
* The functions below implement the Target interface for RISC-V targets.
|
||||
@@ -36,8 +36,6 @@ namespace Targets::RiscV
|
||||
|
||||
void postActivate() override;
|
||||
|
||||
TargetDescriptor targetDescriptor() override;
|
||||
|
||||
void run(std::optional<TargetMemoryAddress> toAddress = std::nullopt) override;
|
||||
void stop() override;
|
||||
void step() override;
|
||||
|
||||
@@ -6,10 +6,6 @@ namespace Targets::RiscV
|
||||
: Targets::TargetDescription::TargetDescriptionFile(xmlFilePath)
|
||||
{}
|
||||
|
||||
std::string TargetDescriptionFile::getTargetId() const {
|
||||
return this->getProperty("vendor", "target_id").value;
|
||||
}
|
||||
|
||||
TargetAddressSpaceDescriptor TargetDescriptionFile::getSystemAddressSpaceDescriptor() const {
|
||||
return this->targetAddressSpaceDescriptorFromAddressSpace(this->getAddressSpace("system"));
|
||||
}
|
||||
|
||||
@@ -14,13 +14,6 @@ namespace Targets::RiscV
|
||||
public:
|
||||
explicit TargetDescriptionFile(const std::string& xmlFilePath);
|
||||
|
||||
/**
|
||||
* Returns the RISC-V target ID from the TDF.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
[[nodiscard]] std::string getTargetId() const;
|
||||
|
||||
[[nodiscard]] TargetAddressSpaceDescriptor getSystemAddressSpaceDescriptor() const;
|
||||
};
|
||||
}
|
||||
|
||||
21
src/Targets/RiscV/Wch/TargetDescriptionFile.cpp
Normal file
21
src/Targets/RiscV/Wch/TargetDescriptionFile.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "TargetDescriptionFile.hpp"
|
||||
|
||||
namespace Targets::RiscV::Wch
|
||||
{
|
||||
TargetDescriptionFile::TargetDescriptionFile(const std::string& xmlFilePath)
|
||||
: Targets::RiscV::TargetDescriptionFile(xmlFilePath)
|
||||
{}
|
||||
|
||||
std::map<
|
||||
std::string,
|
||||
const Targets::TargetDescription::Variant*
|
||||
> TargetDescriptionFile::getVariantsByWchVariantId() {
|
||||
auto output = std::map<std::string, const Targets::TargetDescription::Variant*>{};
|
||||
|
||||
for (const auto& [variantKey, variant] : this->variantsByKey) {
|
||||
output.emplace(variant.getProperty("vendor", "variant_id").value, &variant);
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
}
|
||||
17
src/Targets/RiscV/Wch/TargetDescriptionFile.hpp
Normal file
17
src/Targets/RiscV/Wch/TargetDescriptionFile.hpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "src/Targets/RiscV/TargetDescriptionFile.hpp"
|
||||
#include "src/Targets/TargetDescription/Variant.hpp"
|
||||
|
||||
namespace Targets::RiscV::Wch
|
||||
{
|
||||
class TargetDescriptionFile: public Targets::RiscV::TargetDescriptionFile
|
||||
{
|
||||
public:
|
||||
explicit TargetDescriptionFile(const std::string& xmlFilePath);
|
||||
|
||||
std::map<std::string, const Targets::TargetDescription::Variant*> getVariantsByWchVariantId();
|
||||
};
|
||||
}
|
||||
84
src/Targets/RiscV/Wch/WchRiscV.cpp
Normal file
84
src/Targets/RiscV/Wch/WchRiscV.cpp
Normal file
@@ -0,0 +1,84 @@
|
||||
#include "WchRiscV.hpp"
|
||||
|
||||
#include <utility>
|
||||
#include <cassert>
|
||||
|
||||
#include "src/Logger/Logger.hpp"
|
||||
#include "src/Exceptions/InvalidConfig.hpp"
|
||||
|
||||
namespace Targets::RiscV::Wch
|
||||
{
|
||||
WchRiscV::WchRiscV(
|
||||
const TargetConfig& targetConfig,
|
||||
TargetDescriptionFile&& targetDescriptionFile
|
||||
)
|
||||
: RiscV(targetConfig, targetDescriptionFile)
|
||||
, targetDescriptionFile(std::move(targetDescriptionFile))
|
||||
{}
|
||||
|
||||
void WchRiscV::activate() {
|
||||
RiscV::activate();
|
||||
|
||||
/*
|
||||
* WCH target IDs are specific to the variant. Each variant in the TDF should have a property group that holds
|
||||
* the variant ID.
|
||||
*/
|
||||
const auto variantsById = this->targetDescriptionFile.getVariantsByWchVariantId();
|
||||
const auto deviceId = this->riscVIdInterface->getDeviceId();
|
||||
|
||||
const auto variantIt = variantsById.find(deviceId);
|
||||
if (variantIt == variantsById.end()) {
|
||||
throw Exceptions::InvalidConfig{
|
||||
"Unknown WCH variant ID \"" + deviceId + "\". Please check your configuration."
|
||||
};
|
||||
}
|
||||
|
||||
this->variant = *(variantIt->second);
|
||||
}
|
||||
|
||||
void WchRiscV::postActivate() {
|
||||
assert(this->variant.has_value());
|
||||
|
||||
const auto& variant = this->variant->get();
|
||||
Logger::info("WCH variant ID: " + variant.getProperty("vendor", "variant_id").value);
|
||||
Logger::info("WCH variant name: " + variant.name);
|
||||
|
||||
RiscV::postActivate();
|
||||
}
|
||||
|
||||
TargetDescriptor WchRiscV::targetDescriptor() {
|
||||
auto descriptor = TargetDescriptor{
|
||||
this->targetDescriptionFile.getName(),
|
||||
this->targetDescriptionFile.getFamily(),
|
||||
this->variant->get().getProperty("vendor", "variant_id").value,
|
||||
this->targetDescriptionFile.getVendorName(),
|
||||
this->targetDescriptionFile.targetAddressSpaceDescriptorsByKey(),
|
||||
this->targetDescriptionFile.targetPeripheralDescriptorsByKey(),
|
||||
this->targetDescriptionFile.targetPadDescriptorsByKey(),
|
||||
this->targetDescriptionFile.targetPinoutDescriptorsByKey(),
|
||||
this->targetDescriptionFile.targetVariantDescriptorsByKey(),
|
||||
BreakpointResources{
|
||||
this->riscVDebugInterface->getHardwareBreakpointCount(),
|
||||
std::nullopt,
|
||||
static_cast<std::uint16_t>(this->targetConfig.reserveSteppingBreakpoint ? 1 : 0)
|
||||
}
|
||||
};
|
||||
|
||||
// Copy the RISC-V CPU register address space and peripheral descriptor
|
||||
descriptor.addressSpaceDescriptorsByKey.emplace(
|
||||
this->cpuRegisterAddressSpaceDescriptor.key,
|
||||
this->cpuRegisterAddressSpaceDescriptor.clone()
|
||||
);
|
||||
|
||||
descriptor.peripheralDescriptorsByKey.emplace(
|
||||
this->cpuPeripheralDescriptor.key,
|
||||
this->cpuPeripheralDescriptor.clone()
|
||||
);
|
||||
|
||||
auto& sysAddressSpaceDescriptor = descriptor.getAddressSpaceDescriptor("system");
|
||||
sysAddressSpaceDescriptor.getMemorySegmentDescriptor("internal_program_memory").inspectionEnabled = true;
|
||||
sysAddressSpaceDescriptor.getMemorySegmentDescriptor("internal_ram").inspectionEnabled = true;
|
||||
|
||||
return descriptor;
|
||||
}
|
||||
}
|
||||
26
src/Targets/RiscV/Wch/WchRiscV.hpp
Normal file
26
src/Targets/RiscV/Wch/WchRiscV.hpp
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <optional>
|
||||
#include <functional>
|
||||
|
||||
#include "src/Targets/RiscV/RiscV.hpp"
|
||||
|
||||
#include "TargetDescriptionFile.hpp"
|
||||
|
||||
namespace Targets::RiscV::Wch
|
||||
{
|
||||
class WchRiscV: public ::Targets::RiscV::RiscV
|
||||
{
|
||||
public:
|
||||
WchRiscV(const TargetConfig& targetConfig, TargetDescriptionFile&& targetDescriptionFile);
|
||||
|
||||
void activate() override;
|
||||
void postActivate() override;
|
||||
TargetDescriptor targetDescriptor() override;
|
||||
|
||||
protected:
|
||||
TargetDescriptionFile targetDescriptionFile;
|
||||
std::optional<std::reference_wrapper<const TargetDescription::Variant>> variant = std::nullopt;
|
||||
};
|
||||
}
|
||||
@@ -2,4 +2,4 @@
|
||||
|
||||
#include "src/Targets/Target.hpp"
|
||||
#include "src/Targets/Microchip/AVR8/Avr8.hpp"
|
||||
#include "src/Targets/RiscV/RiscV.hpp"
|
||||
#include "src/Targets/RiscV/Wch/WchRiscV.hpp"
|
||||
|
||||
Reference in New Issue
Block a user