New WchRiscV target class

This commit is contained in:
Nav
2024-10-12 23:16:16 +01:00
parent 5c896bb2ca
commit 52171734d8
11 changed files with 164 additions and 62 deletions

View File

@@ -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
}
);

View File

@@ -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
)

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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"));
}

View File

@@ -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;
};
}

View 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;
}
}

View 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();
};
}

View 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;
}
}

View 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;
};
}

View File

@@ -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"