Implemented RiscV::readMemory()
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
#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)))
|
||||
{}
|
||||
|
||||
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
|
||||
;
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -9,6 +9,12 @@ 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,
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
#include <thread>
|
||||
#include <chrono>
|
||||
#include <limits>
|
||||
#include <cmath>
|
||||
|
||||
#include "Registers/RegisterNumbers.hpp"
|
||||
#include "DebugModule/Registers/RegisterAddresses.hpp"
|
||||
#include "DebugModule/Registers/RegisterAccessControlField.hpp"
|
||||
#include "DebugModule/Registers/MemoryAccessControlField.hpp"
|
||||
|
||||
#include "src/Exceptions/Exception.hpp"
|
||||
#include "src/TargetController/Exceptions/TargetOperationFailure.hpp"
|
||||
@@ -260,7 +262,65 @@ namespace Targets::RiscV
|
||||
TargetMemorySize bytes,
|
||||
const std::set<Targets::TargetMemoryAddressRange>& excludedAddressRanges
|
||||
) {
|
||||
return {};
|
||||
// TODO: excluded addresses
|
||||
|
||||
const auto pageSize = 4;
|
||||
if ((startAddress % pageSize) != 0 || (bytes % pageSize) != 0) {
|
||||
// Alignment required
|
||||
const auto alignedStartAddress = static_cast<TargetMemoryAddress>(
|
||||
std::floor(static_cast<float>(startAddress) / static_cast<float>(pageSize)) * pageSize
|
||||
);
|
||||
|
||||
const auto alignedBytes = static_cast<TargetMemorySize>(
|
||||
std::ceil(
|
||||
static_cast<float>(bytes + (startAddress - alignedStartAddress))
|
||||
/ static_cast<float>(pageSize)
|
||||
) * pageSize
|
||||
);
|
||||
|
||||
auto memoryBuffer = this->readMemory(
|
||||
memoryType,
|
||||
alignedStartAddress,
|
||||
alignedBytes,
|
||||
excludedAddressRanges
|
||||
);
|
||||
|
||||
const auto offset = memoryBuffer.begin() + (startAddress - alignedStartAddress);
|
||||
|
||||
auto output = TargetMemoryBuffer();
|
||||
output.reserve(bytes);
|
||||
std::move(offset, offset + bytes, std::back_inserter(output));
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
using DebugModule::Registers::MemoryAccessControlField;
|
||||
|
||||
auto output = TargetMemoryBuffer();
|
||||
output.reserve(bytes);
|
||||
|
||||
for (auto address = startAddress; address <= (startAddress + bytes - 1); address += 4) {
|
||||
auto command = AbstractCommandRegister();
|
||||
command.commandType = AbstractCommandRegister::CommandType::MEMORY_ACCESS;
|
||||
command.control = MemoryAccessControlField(
|
||||
false,
|
||||
false,
|
||||
MemoryAccessControlField::MemorySize::SIZE_32,
|
||||
false
|
||||
).value();
|
||||
|
||||
this->riscVDebugInterface->writeDebugModuleRegister(RegisterAddress::ABSTRACT_DATA_1, address);
|
||||
|
||||
this->executeAbstractCommand(command);
|
||||
|
||||
const auto data = this->riscVDebugInterface->readDebugModuleRegister(RegisterAddress::ABSTRACT_DATA_0);
|
||||
output.emplace_back(static_cast<unsigned char>(data >> 24));
|
||||
output.emplace_back(static_cast<unsigned char>(data >> 16));
|
||||
output.emplace_back(static_cast<unsigned char>(data >> 8));
|
||||
output.emplace_back(static_cast<unsigned char>(data));
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
|
||||
void RiscV::writeMemory(
|
||||
|
||||
Reference in New Issue
Block a user