Massive refactor to accommodate RISC-V targets

- Refactored entire codebase (excluding the Insight component) to accommodate multiple target architectures (no longer specific to AVR)
- Deleted 'generate SVD' GDB monitor command - I will eventually move this functionality to the Bloom website
- Added unit size property to address spaces
- Many other changes which I couldn't be bothered to describe here
This commit is contained in:
Nav
2024-07-23 21:14:22 +01:00
parent 2986934485
commit 6cdbfbe950
331 changed files with 8815 additions and 8565 deletions

View File

@@ -1,27 +0,0 @@
#pragma once
#include <cstdint>
#include <vector>
#include <set>
#include <optional>
namespace Targets::RiscV::DebugModule
{
using RegisterAddress = std::uint8_t;
using RegisterValue = std::uint32_t;
using HartIndex = std::uint32_t;
enum class DmiOperation: std::uint8_t
{
IGNORE = 0x00,
READ = 0x01,
WRITE = 0x02,
};
enum class DmiOperationStatus: std::uint8_t
{
SUCCESS = 0x00,
FAILED = 0x02,
BUSY = 0x03,
};
}

View File

@@ -1,38 +0,0 @@
#pragma once
#include <cstdint>
#include <cassert>
#include "src/Targets/RiscV/DebugModule/DebugModule.hpp"
namespace Targets::RiscV::DebugModule::Registers
{
struct AbstractCommandRegister
{
enum CommandType: std::uint8_t
{
REGISTER_ACCESS = 0x00,
QUICK_ACCESS = 0x01,
MEMORY_ACCESS = 0x02,
};
std::uint32_t control = 0;
CommandType commandType = CommandType::REGISTER_ACCESS;
AbstractCommandRegister() = default;
constexpr explicit AbstractCommandRegister(RegisterValue registerValue)
: control(static_cast<std::uint32_t>(registerValue & 0x00FFFFFF))
, commandType(static_cast<CommandType>((registerValue >> 24) & 0xFF))
{}
[[nodiscard]] constexpr RegisterValue value() const {
assert(this->control <= 0x00FFFFFF);
return RegisterValue{0}
| static_cast<RegisterValue>(this->control & 0x00FFFFFF)
| static_cast<RegisterValue>(this->commandType) << 24
;
}
};
}

View File

@@ -1,53 +0,0 @@
#pragma once
#include <cstdint>
#include "src/Targets/RiscV/DebugModule/DebugModule.hpp"
namespace Targets::RiscV::DebugModule::Registers
{
struct AbstractControlStatusRegister
{
enum CommandError: std::uint8_t
{
NONE = 0x00,
BUSY = 0x01,
NOT_SUPPORTED = 0x02,
EXCEPTION = 0x03,
HALT_RESUME = 0x04,
BUS = 0x05,
OTHER = 0x07,
};
std::uint8_t dataCount:4 = 0;
CommandError commandError:3 = CommandError::NONE;
bool relaxedPrivilege:1 = false;
bool busy:1 = false;
std::uint8_t programBufferSize:5 = 0;
AbstractControlStatusRegister() = default;
constexpr explicit AbstractControlStatusRegister(RegisterValue registerValue)
: dataCount(static_cast<std::uint8_t>(registerValue & 0x0F))
, commandError(static_cast<CommandError>((registerValue >> 8) & 0x07))
, relaxedPrivilege(static_cast<bool>(registerValue & (0x01 << 11)))
, busy(static_cast<bool>(registerValue & (0x01 << 12)))
, programBufferSize(static_cast<std::uint8_t>((registerValue >> 24) & 0x1F))
{}
[[nodiscard]] constexpr RegisterValue value() const {
return RegisterValue{0}
| static_cast<RegisterValue>(this->dataCount)
| static_cast<RegisterValue>(this->commandError) << 8
| static_cast<RegisterValue>(this->relaxedPrivilege) << 11
| static_cast<RegisterValue>(this->busy) << 12
| static_cast<RegisterValue>(this->programBufferSize) << 24
;
}
constexpr void clearCommandError() {
// Setting all of the bits will clear the field
this->commandError = CommandError::OTHER;
}
};
}

View File

@@ -1,71 +0,0 @@
#pragma once
#include <cstdint>
#include <cassert>
#include "src/Targets/RiscV/DebugModule/DebugModule.hpp"
namespace Targets::RiscV::DebugModule::Registers
{
struct ControlRegister
{
enum HartSelectionMode: std::uint8_t
{
SINGLE = 0x00,
MULTI = 0x01,
};
bool debugModuleActive:1 = false;
bool ndmReset:1 = false;
bool clearResetHaltRequest:1 = false;
bool setResetHaltRequest:1 = false;
bool clearKeepAlive:1 = false;
bool setKeepAlive:1 = false;
HartIndex selectedHartIndex = 0;
HartSelectionMode hartSelectionMode:1 = HartSelectionMode::SINGLE;
bool acknowledgeUnavailableHarts:1 = false;
bool acknowledgeHaveReset:1 = false;
bool hartReset:1 = false;
bool resumeRequest:1 = false;
bool haltRequest:1 = false;
ControlRegister() = default;
constexpr explicit ControlRegister(RegisterValue registerValue)
: debugModuleActive(static_cast<bool>(registerValue & 0x01))
, ndmReset(static_cast<bool>(registerValue & (0x01 << 1)))
, clearResetHaltRequest(static_cast<bool>(registerValue & (0x01 << 2)))
, setResetHaltRequest(static_cast<bool>(registerValue & (0x01 << 3)))
, clearKeepAlive(static_cast<bool>(registerValue & (0x01 << 4)))
, setKeepAlive(static_cast<bool>(registerValue & (0x01 << 5)))
, selectedHartIndex((((registerValue >> 6) & 0x3FF) << 10) | ((registerValue >> 16) & 0x3FF))
, hartSelectionMode(static_cast<HartSelectionMode>(registerValue & (0x01 << 26)))
, acknowledgeUnavailableHarts(static_cast<bool>(registerValue & (0x01 << 27)))
, acknowledgeHaveReset(static_cast<bool>(registerValue & (0x01 << 28)))
, hartReset(static_cast<bool>(registerValue & (0x01 << 29)))
, resumeRequest(static_cast<bool>(registerValue & (0x01 << 30)))
, haltRequest(static_cast<bool>(registerValue & static_cast<std::uint32_t>(0x01 << 31)))
{}
[[nodiscard]] constexpr RegisterValue value() const {
assert(this->selectedHartIndex <= 0xFFFFF);
return RegisterValue{0}
| static_cast<RegisterValue>(this->debugModuleActive)
| static_cast<RegisterValue>(this->ndmReset) << 1
| static_cast<RegisterValue>(this->clearResetHaltRequest) << 2
| static_cast<RegisterValue>(this->setResetHaltRequest) << 3
| static_cast<RegisterValue>(this->clearKeepAlive) << 4
| static_cast<RegisterValue>(this->setKeepAlive) << 5
| static_cast<RegisterValue>((this->selectedHartIndex & 0xFFFFF) >> 10) << 6
| static_cast<RegisterValue>(this->selectedHartIndex & 0x3FF) << 16
| static_cast<RegisterValue>(this->hartSelectionMode) << 26
| static_cast<RegisterValue>(this->acknowledgeUnavailableHarts) << 27
| static_cast<RegisterValue>(this->acknowledgeHaveReset) << 28
| static_cast<RegisterValue>(this->hartReset) << 29
| static_cast<RegisterValue>(this->resumeRequest) << 30
| static_cast<RegisterValue>(this->haltRequest) << 31
;
}
};
}

View File

@@ -1,55 +0,0 @@
#pragma once
#include <cstdint>
#include "src/Targets/RiscV/RiscVGeneric.hpp"
namespace Targets::RiscV::DebugModule::Registers
{
struct MemoryAccessControlField
{
enum class MemorySize: std::uint8_t
{
SIZE_8 = 0x00,
SIZE_16 = 0x01,
SIZE_32 = 0x02,
SIZE_64 = 0x03,
SIZE_128 = 0x04,
};
bool write:1 = false;
bool postIncrement:1 = false;
MemorySize size:3 = MemorySize::SIZE_32;
bool virtualAddress:1 = false;
MemoryAccessControlField() = default;
MemoryAccessControlField(
bool write,
bool postIncrement,
MemorySize size,
bool virtualAddress
)
: write(write)
, postIncrement(postIncrement)
, size(size)
, virtualAddress(virtualAddress)
{}
constexpr explicit MemoryAccessControlField(std::uint32_t controlValue)
: write(static_cast<bool>(controlValue & (0x01 << 16)))
, postIncrement(static_cast<bool>(controlValue & (0x01 << 19)))
, size(static_cast<MemorySize>((controlValue >> 20) & 0x07))
, virtualAddress(static_cast<bool>(controlValue & (0x01 << 23)))
{}
[[nodiscard]] constexpr std::uint32_t value() const {
return std::uint32_t{0}
| static_cast<std::uint32_t>(this->write) << 16
| static_cast<std::uint32_t>(this->postIncrement) << 19
| static_cast<std::uint32_t>(this->size) << 20
| static_cast<std::uint32_t>(this->virtualAddress) << 23
;
}
};
}

View File

@@ -1,61 +0,0 @@
#pragma once
#include <cstdint>
#include "src/Targets/RiscV/RiscVGeneric.hpp"
namespace Targets::RiscV::DebugModule::Registers
{
struct RegisterAccessControlField
{
enum class RegisterSize: std::uint8_t
{
SIZE_32 = 0x02,
SIZE_64 = 0x03,
SIZE_128 = 0x04,
};
RegisterNumber registerNumber;
bool write:1 = false;
bool transfer:1 = false;
bool postExecute:1 = false;
bool postIncrement:1 = false;
RegisterSize size:3 = RegisterSize::SIZE_32;
RegisterAccessControlField(
RegisterNumber registerNumber,
bool write,
bool transfer,
bool postExecute,
bool postIncrement,
RegisterSize size
)
: registerNumber(registerNumber)
, write(write)
, transfer(transfer)
, postExecute(postExecute)
, postIncrement(postIncrement)
, size(size)
{}
constexpr explicit RegisterAccessControlField(std::uint32_t controlValue)
: registerNumber(static_cast<RegisterNumber>(controlValue & 0xFFFF))
, write(static_cast<bool>(controlValue & (0x01 << 16)))
, transfer(static_cast<bool>(controlValue & (0x01 << 17)))
, postExecute(static_cast<bool>(controlValue & (0x01 << 18)))
, postIncrement(static_cast<bool>(controlValue & (0x01 << 19)))
, size(static_cast<RegisterSize>((controlValue >> 20) & 0x07))
{}
[[nodiscard]] constexpr std::uint32_t value() const {
return std::uint32_t{0}
| static_cast<std::uint32_t>(this->registerNumber)
| static_cast<std::uint32_t>(this->write) << 16
| static_cast<std::uint32_t>(this->transfer) << 17
| static_cast<std::uint32_t>(this->postExecute) << 18
| static_cast<std::uint32_t>(this->postIncrement) << 19
| static_cast<std::uint32_t>(this->size) << 20
;
}
};
}

View File

@@ -1,23 +0,0 @@
#pragma once
#include <cstdint>
#include "src/Targets/RiscV/DebugModule/DebugModule.hpp"
namespace Targets::RiscV::DebugModule::Registers
{
enum class RegisterAddress: ::Targets::RiscV::DebugModule::RegisterAddress
{
ABSTRACT_DATA_0 = 0x04,
ABSTRACT_DATA_1 = 0x05,
ABSTRACT_DATA_2 = 0x06,
ABSTRACT_DATA_3 = 0x07,
ABSTRACT_DATA_4 = 0x08,
ABSTRACT_DATA_5 = 0x09,
ABSTRACT_DATA_6 = 0x0a,
CONTROL_REGISTER = 0x10,
STATUS_REGISTER = 0x11,
ABSTRACT_CONTROL_STATUS_REGISTER = 0x16,
ABSTRACT_COMMAND_REGISTER = 0x17,
};
}

View File

@@ -1,80 +0,0 @@
#pragma once
#include <cstdint>
#include "src/Targets/RiscV/DebugModule/DebugModule.hpp"
namespace Targets::RiscV::DebugModule::Registers
{
struct StatusRegister
{
std::uint8_t version:4 = 0;
bool validConfigStructurePointer:1 = false;
bool supportsResetHalt:1 = false;
bool authBusy:1 = false;
bool authenticated:1 = false;
bool anyHalted:1 = false;
bool allHalted:1 = false;
bool anyRunning:1 = false;
bool allRunning:1 = false;
bool anyUnavailable:1 = false;
bool allUnavailable:1 = false;
bool anyNonExistent:1 = false;
bool allNonExistent:1 = false;
bool anyResumeAcknowledge:1 = false;
bool allResumeAcknowledge:1 = false;
bool anyHaveReset:1 = false;
bool allHaveReset:1 = false;
bool implicitBreak:1 = false;
bool stickyUnavailableBits:1 = false;
bool ndmResetPending:1 = false;
constexpr explicit StatusRegister(RegisterValue registerValue)
: version(static_cast<std::uint8_t>(registerValue & 0x0F))
, validConfigStructurePointer(static_cast<bool>(registerValue & (0x01 << 4)))
, supportsResetHalt(static_cast<bool>(registerValue & (0x01 << 5)))
, authBusy(static_cast<bool>(registerValue & (0x01 << 6)))
, authenticated(static_cast<bool>(registerValue & (0x01 << 7)))
, anyHalted(static_cast<bool>(registerValue & (0x01 << 8)))
, allHalted(static_cast<bool>(registerValue & (0x01 << 9)))
, anyRunning(static_cast<bool>(registerValue & (0x01 << 10)))
, allRunning(static_cast<bool>(registerValue & (0x01 << 11)))
, anyUnavailable(static_cast<bool>(registerValue & (0x01 << 12)))
, allUnavailable(static_cast<bool>(registerValue & (0x01 << 13)))
, anyNonExistent(static_cast<bool>(registerValue & (0x01 << 14)))
, allNonExistent(static_cast<bool>(registerValue & (0x01 << 15)))
, anyResumeAcknowledge(static_cast<bool>(registerValue & (0x01 << 16)))
, allResumeAcknowledge(static_cast<bool>(registerValue & (0x01 << 17)))
, anyHaveReset(static_cast<bool>(registerValue & (0x01 << 18)))
, allHaveReset(static_cast<bool>(registerValue & (0x01 << 19)))
, implicitBreak(static_cast<bool>(registerValue & (0x01 << 22)))
, stickyUnavailableBits(static_cast<bool>(registerValue & (0x01 << 23)))
, ndmResetPending(static_cast<bool>(registerValue & (0x01 << 24)))
{}
[[nodiscard]] constexpr RegisterValue value() const {
return RegisterValue{0}
| static_cast<RegisterValue>(this->version)
| static_cast<RegisterValue>(this->validConfigStructurePointer) << 4
| static_cast<RegisterValue>(this->supportsResetHalt) << 5
| static_cast<RegisterValue>(this->authBusy) << 6
| static_cast<RegisterValue>(this->authenticated) << 7
| static_cast<RegisterValue>(this->anyHalted) << 8
| static_cast<RegisterValue>(this->allHalted) << 9
| static_cast<RegisterValue>(this->anyRunning) << 10
| static_cast<RegisterValue>(this->allRunning) << 11
| static_cast<RegisterValue>(this->anyUnavailable) << 12
| static_cast<RegisterValue>(this->allUnavailable) << 13
| static_cast<RegisterValue>(this->anyNonExistent) << 14
| static_cast<RegisterValue>(this->allNonExistent) << 15
| static_cast<RegisterValue>(this->anyResumeAcknowledge) << 16
| static_cast<RegisterValue>(this->allResumeAcknowledge) << 17
| static_cast<RegisterValue>(this->anyHaveReset) << 18
| static_cast<RegisterValue>(this->allHaveReset) << 19
| static_cast<RegisterValue>(this->implicitBreak) << 22
| static_cast<RegisterValue>(this->stickyUnavailableBits) << 23
| static_cast<RegisterValue>(this->ndmResetPending) << 24
;
}
};
}

View File

@@ -1,74 +0,0 @@
#pragma once
#include <cstdint>
#include "src/Targets/RiscV/RiscVGeneric.hpp"
namespace Targets::RiscV::Registers
{
struct DebugControlStatusRegister
{
enum class DebugModeCause: std::uint8_t
{
BREAK = 0x01,
TRIGGER = 0x02,
HALT_REQUEST = 0x03,
STEP = 0x04,
RESET_HALT_REQUEST = 0x05,
GROUP = 0x06,
};
PrivilegeMode privilegeMode:2;
bool step:1 = false;
bool nmiPending:1 = false;
bool mprvEnabled:1 = false;
DebugModeCause debugModeCause:3;
bool stopTime:1 = false;
bool stopCount:1 = false;
bool stepInterruptsEnabled:1 = false;
bool breakUMode:1 = false;
bool breakSMode:1 = false;
bool breakMMode:1 = false;
bool breakVUMode:1 = false;
bool breakVSMode:1 = false;
std::uint8_t debugVersion:4 = 0;
DebugControlStatusRegister() = default;
constexpr explicit DebugControlStatusRegister(RegisterValue registerValue)
: privilegeMode(static_cast<PrivilegeMode>(registerValue & 0x03))
, step(static_cast<bool>(registerValue & (0x01 << 2)))
, nmiPending(static_cast<bool>(registerValue & (0x01 << 3)))
, mprvEnabled(static_cast<bool>(registerValue & (0x01 << 4)))
, debugModeCause(static_cast<DebugModeCause>((registerValue >> 6) & 0x07))
, stopTime(static_cast<bool>(registerValue & (0x01 << 9)))
, stopCount(static_cast<bool>(registerValue & (0x01 << 10)))
, stepInterruptsEnabled(static_cast<bool>(registerValue & (0x01 << 11)))
, breakUMode(static_cast<bool>(registerValue & (0x01 << 12)))
, breakSMode(static_cast<bool>(registerValue & (0x01 << 13)))
, breakMMode(static_cast<bool>(registerValue & (0x01 << 15)))
, breakVUMode(static_cast<bool>(registerValue & (0x01 << 16)))
, breakVSMode(static_cast<bool>(registerValue & (0x01 << 17)))
, debugVersion(static_cast<std::uint8_t>(registerValue >> 28) & 0x0F)
{}
constexpr RegisterValue value() const {
return RegisterValue{0}
| static_cast<RegisterValue>(this->privilegeMode)
| static_cast<RegisterValue>(this->step) << 2
| static_cast<RegisterValue>(this->nmiPending) << 3
| static_cast<RegisterValue>(this->mprvEnabled) << 4
| static_cast<RegisterValue>(this->debugModeCause) << 6
| static_cast<RegisterValue>(this->stopTime) << 9
| static_cast<RegisterValue>(this->stopCount) << 10
| static_cast<RegisterValue>(this->stepInterruptsEnabled) << 11
| static_cast<RegisterValue>(this->breakUMode) << 12
| static_cast<RegisterValue>(this->breakSMode) << 13
| static_cast<RegisterValue>(this->breakMMode) << 15
| static_cast<RegisterValue>(this->breakVUMode) << 16
| static_cast<RegisterValue>(this->breakVSMode) << 17
| static_cast<RegisterValue>(this->debugVersion) << 28
;
}
};
}

View File

@@ -1,23 +0,0 @@
#pragma once
#include <cstdint>
#include "src/Targets/RiscV/RiscVGeneric.hpp"
namespace Targets::RiscV::Registers
{
enum class RegisterNumberBase: ::Targets::RiscV::RegisterNumber
{
CSR = 0x0000,
GPR = 0x1000,
FPR = 0x1020,
OTHER = 0xc000,
};
enum class RegisterNumber: ::Targets::RiscV::RegisterNumber
{
DEBUG_CONTROL_STATUS_REGISTER = 0x07b0,
DEBUG_PROGRAM_COUNTER_REGISTER = 0x07b1,
STACK_POINTER_X2 = 0x1002,
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -7,32 +7,19 @@
#include "src/Targets/Target.hpp"
#include "src/DebugToolDrivers/DebugTool.hpp"
#include "TargetDescription/TargetDescriptionFile.hpp"
#include "RiscVTargetConfig.hpp"
#include "TargetDescriptionFile.hpp"
#include "src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVDebugInterface.hpp"
#include "src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVProgramInterface.hpp"
#include "src/Targets/RiscV/RiscVGeneric.hpp"
#include "src/Targets/RiscV/Registers/RegisterNumbers.hpp"
#include "src/Targets/RiscV/Registers/DebugControlStatusRegister.hpp"
#include "src/Targets/RiscV/DebugModule/DebugModule.hpp"
#include "src/Targets/RiscV/DebugModule/Registers/ControlRegister.hpp"
#include "src/Targets/RiscV/DebugModule/Registers/StatusRegister.hpp"
#include "src/Targets/RiscV/DebugModule/Registers/AbstractControlStatusRegister.hpp"
#include "src/Targets/RiscV/DebugModule/Registers/AbstractCommandRegister.hpp"
#include "RiscVRegisterDescriptor.hpp"
#include "src/DebugToolDrivers/TargetInterfaces/RiscV/RiscVIdentificationInterface.hpp"
namespace Targets::RiscV
{
class RiscV: public Target
{
public:
explicit RiscV(
const TargetConfig& targetConfig,
TargetDescription::TargetDescriptionFile&& targetDescriptionFile
);
RiscV(const TargetConfig& targetConfig, TargetDescriptionFile&& targetDescriptionFile);
/*
* The functions below implement the Target interface for RISC-V targets.
@@ -41,20 +28,13 @@ namespace Targets::RiscV
* each function.
*/
/**
* All RISC-V compatible debug tools must provide a valid RiscVDebugInterface.
*
* @param debugTool
* @return
*/
bool supportsDebugTool(DebugTool* debugTool) override;
void setDebugTool(DebugTool* debugTool) override;
void activate() override;
void deactivate() override;
TargetDescriptor getDescriptor() override;
TargetDescriptor targetDescriptor() override;
void run(std::optional<TargetMemoryAddress> toAddress = std::nullopt) override;
void stop() override;
@@ -68,34 +48,45 @@ namespace Targets::RiscV
void removeHardwareBreakpoint(TargetMemoryAddress address) override;
void clearAllBreakpoints() override;
TargetRegisters readRegisters(const TargetRegisterDescriptorIds& descriptorIds) override;
void writeRegisters(const TargetRegisters& registers) override;
TargetRegisterDescriptorAndValuePairs readRegisters(const TargetRegisterDescriptors& descriptors) override;
void writeRegisters(const TargetRegisterDescriptorAndValuePairs& registers) override;
TargetMemoryBuffer readMemory(
TargetMemoryType memoryType,
const TargetAddressSpaceDescriptor& addressSpaceDescriptor,
const TargetMemorySegmentDescriptor& memorySegmentDescriptor,
TargetMemoryAddress startAddress,
TargetMemorySize bytes,
const std::set<TargetMemoryAddressRange>& excludedAddressRanges = {}
) override;
void writeMemory(
TargetMemoryType memoryType,
const TargetAddressSpaceDescriptor& addressSpaceDescriptor,
const TargetMemorySegmentDescriptor& memorySegmentDescriptor,
TargetMemoryAddress startAddress,
const TargetMemoryBuffer& buffer
) override;
void eraseMemory(TargetMemoryType memoryType) override;
bool isProgramMemory(
const TargetAddressSpaceDescriptor& addressSpaceDescriptor,
const TargetMemorySegmentDescriptor& memorySegmentDescriptor,
TargetMemoryAddress startAddress,
TargetMemorySize size
) override;
void eraseMemory(
const TargetAddressSpaceDescriptor& addressSpaceDescriptor,
const TargetMemorySegmentDescriptor& memorySegmentDescriptor
) override;
TargetState getState() override;
TargetExecutionState getExecutionState() override;
TargetMemoryAddress getProgramCounter() override;
void setProgramCounter(TargetMemoryAddress programCounter) override;
TargetStackPointer getStackPointer() override;
void setStackPointer(TargetStackPointer stackPointer) override;
std::map<int, TargetPinState> getPinStates(int variantId) override;
void setPinState(
const TargetPinDescriptor& pinDescriptor,
const TargetPinState& state
TargetGpioPinDescriptorAndStatePairs getGpioPinStates(
const TargetPinoutDescriptor& pinoutDescriptor
) override;
void setGpioPinState(const TargetPinDescriptor& pinDescriptor, const TargetGpioPinState& state) override;
void enableProgrammingMode() override;
@@ -104,43 +95,53 @@ namespace Targets::RiscV
bool programmingModeEnabled() override;
protected:
TargetDescription::TargetDescriptionFile targetDescriptionFile;
std::map<TargetRegisterDescriptorId, RiscVRegisterDescriptor> registerDescriptorsById;
RiscVRegisterDescriptor stackPointerRegisterDescriptor;
RiscVTargetConfig targetConfig;
TargetDescriptionFile targetDescriptionFile;
DebugToolDrivers::TargetInterfaces::RiscV::RiscVDebugInterface* riscVDebugInterface = nullptr;
DebugToolDrivers::TargetInterfaces::RiscV::RiscVProgramInterface* riscVProgramInterface = nullptr;
DebugToolDrivers::TargetInterfaces::RiscV::RiscVIdentificationInterface* riscVIdInterface = nullptr;
std::set<DebugModule::HartIndex> hartIndices;
DebugModule::HartIndex selectedHartIndex = 0;
/*
* On RISC-V targets, CPU registers are typically only accessible via the debug module (we can't access them
* via the system address space). So we use abstract commands to access these registers. This means we have to
* address these registers via their register numbers, as defined in the RISC-V debug spec.
*
* We effectively treat register numbers as a separate address space, with an addressable unit size of 4 bytes.
* The `cpuRegisterAddressSpaceDescriptor` member holds the descriptor for this address space.
*
* TODO: review this. This address space is specific to the RISC-V debug spec, but some debug tools may
* implement their own debug translator in firmware, and then provide a higher-level API to access the
* same registers. In that case, this address space may not be relevant. This may need to be moved.
* ATM all RISC-V debug tools supported by Bloom provide a DTM interface, so we use our own debug
* translator driver and this address space is, in fact, relevant. I will deal with this when it
* becomes a problem.
*/
TargetAddressSpaceDescriptor cpuRegisterAddressSpaceDescriptor;
const TargetMemorySegmentDescriptor& csrMemorySegmentDescriptor;
const TargetMemorySegmentDescriptor& gprMemorySegmentDescriptor;
void loadRegisterDescriptors();
TargetPeripheralDescriptor cpuPeripheralDescriptor;
const TargetRegisterGroupDescriptor& csrGroupDescriptor;
const TargetRegisterGroupDescriptor& gprGroupDescriptor;
const TargetRegisterDescriptor& pcRegisterDescriptor;
const TargetRegisterDescriptor& spRegisterDescriptor;
std::set<DebugModule::HartIndex> discoverHartIndices();
/*
* The "system" address space is the main address space on RISC-V targets.
*/
TargetAddressSpaceDescriptor sysAddressSpaceDescriptor;
DebugModule::Registers::ControlRegister readDebugModuleControlRegister();
DebugModule::Registers::StatusRegister readDebugModuleStatusRegister();
DebugModule::Registers::AbstractControlStatusRegister readDebugModuleAbstractControlStatusRegister();
const TargetMemorySegmentDescriptor& resolveRegisterMemorySegmentDescriptor(
const TargetRegisterDescriptor& regDescriptor,
const TargetAddressSpaceDescriptor& addressSpaceDescriptor
);
Registers::DebugControlStatusRegister readDebugControlStatusRegister();
void enableDebugModule();
void disableDebugModule();
RegisterValue readRegister(RegisterNumber number);
RegisterValue readRegister(Registers::RegisterNumber number);
void writeRegister(RegisterNumber number, RegisterValue value);
void writeRegister(Registers::RegisterNumber number, RegisterValue value);
void writeDebugModuleControlRegister(const DebugModule::Registers::ControlRegister& controlRegister);
void writeDebugControlStatusRegister(const Registers::DebugControlStatusRegister& controlRegister);
void executeAbstractCommand(const DebugModule::Registers::AbstractCommandRegister& abstractCommandRegister);
TargetMemoryAddress alignMemoryAddress(TargetMemoryAddress address, TargetMemoryAddress alignTo);
TargetMemorySize alignMemorySize(TargetMemorySize size, TargetMemorySize alignTo);
static TargetAddressSpaceDescriptor generateCpuRegisterAddressSpaceDescriptor();
static TargetPeripheralDescriptor generateCpuPeripheralDescriptor(
const TargetAddressSpaceDescriptor& addressSpaceDescriptor,
const TargetMemorySegmentDescriptor& csrMemorySegmentDescriptor,
const TargetMemorySegmentDescriptor& gprMemorySegmentDescriptor
);
};
}

View File

@@ -1,16 +0,0 @@
#pragma once
#include <cstdint>
namespace Targets::RiscV
{
using RegisterValue = std::uint32_t;
using RegisterNumber = std::uint16_t;
enum class PrivilegeMode: std::uint8_t
{
U_MODE = 0x00,
S_MODE = 0x01,
M_MODE = 0x03,
};
}

View File

@@ -1,38 +0,0 @@
#pragma once
#include <cstdint>
#include "src/Targets/TargetRegisterDescriptor.hpp"
#include "RiscVGeneric.hpp"
namespace Targets::RiscV
{
struct RiscVRegisterDescriptor: public ::Targets::TargetRegisterDescriptor
{
RegisterNumber number;
RiscVRegisterDescriptor(
TargetRegisterType type,
RegisterNumber number,
TargetMemorySize size,
TargetMemoryType memoryType,
std::optional<std::string> name,
std::optional<std::string> groupName,
std::optional<std::string> description,
TargetRegisterAccess access
)
: ::Targets::TargetRegisterDescriptor(
type,
std::nullopt,
size,
memoryType,
name,
groupName,
description,
access
)
, number(number)
{}
};
}

View File

@@ -0,0 +1,8 @@
#include "RiscVTargetConfig.hpp"
namespace Targets::RiscV
{
RiscVTargetConfig::RiscVTargetConfig(const TargetConfig& targetConfig)
: TargetConfig(targetConfig)
{}
}

View File

@@ -0,0 +1,15 @@
#pragma once
#include "src/ProjectConfig.hpp"
namespace Targets::RiscV
{
/**
* Extending the generic TargetConfig struct to accommodate RISC-V target configuration parameters.
*/
struct RiscVTargetConfig: public TargetConfig
{
public:
explicit RiscVTargetConfig(const TargetConfig& targetConfig);
};
}

View File

@@ -1,18 +0,0 @@
#include "TargetDescriptionFile.hpp"
#include <QString>
namespace Targets::RiscV::TargetDescription
{
TargetDescriptionFile::TargetDescriptionFile(const std::string& xmlFilePath)
: Targets::TargetDescription::TargetDescriptionFile(xmlFilePath)
{}
std::string TargetDescriptionFile::getTargetId() const {
return this->deviceAttribute("id");
}
std::string TargetDescriptionFile::getVendorName() const {
return this->deviceAttribute("vendor");
}
}

View File

@@ -0,0 +1,16 @@
#include "TargetDescriptionFile.hpp"
namespace Targets::RiscV
{
TargetDescriptionFile::TargetDescriptionFile(const std::string& xmlFilePath)
: 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

@@ -2,9 +2,7 @@
#include "src/Targets/TargetDescription/TargetDescriptionFile.hpp"
#include "src/Targets/RiscV/RiscVGeneric.hpp"
namespace Targets::RiscV::TargetDescription
namespace Targets::RiscV
{
/**
* Represents an RISC-V TDF.
@@ -23,11 +21,6 @@ namespace Targets::RiscV::TargetDescription
*/
[[nodiscard]] std::string getTargetId() const;
/**
* Returns the RISC-V vendor name from the TDF.
*
* @return
*/
[[nodiscard]] std::string getVendorName() const;
[[nodiscard]] TargetAddressSpaceDescriptor getSystemAddressSpaceDescriptor() const;
};
}

View File

@@ -1,11 +0,0 @@
#pragma once
#include <cstdint>
#include "src/Targets/TargetMemory.hpp"
namespace Targets::RiscV
{
struct TargetParameters
{};
}