Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ if(NOT TARGET dbt-rise-core)
FetchContent_Declare(
dbt_rise_core_git
GIT_REPOSITORY "https://github.com/Minres/DBT-RISE-Core.git"
GIT_TAG 5d1ab03db17819fc113d3c4182cf0cee666085f2
GIT_TAG e17e1b58
GIT_SHALLOW OFF
UPDATE_DISCONNECTED NOT ${UPDATE_EXTERNAL_PROJECT} # When enabled, this option causes the update step to be skipped.
)
Expand Down Expand Up @@ -176,7 +176,7 @@ install(TARGETS ${PROJECT_NAME} COMPONENT ${PROJECT_NAME}
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME} # headers for mac (note the different component -> different package)
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # headers
)
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/incl/iss COMPONENT ${PROJECT_NAME}
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/src/iss COMPONENT ${PROJECT_NAME}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} # target directory
FILES_MATCHING # install only matched files
PATTERN "*.h" # select header files
Expand Down
3 changes: 2 additions & 1 deletion gen_input/templates/asmjit/CORENAME.cpp.gtl
Original file line number Diff line number Diff line change
Expand Up @@ -346,7 +346,8 @@ private:
}
};

template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); }
template <typename ARCH> vm_impl<ARCH>::vm_impl()
: vm_base<ARCH>(std::make_unique<ARCH>()) {}

template <typename ARCH>
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
Expand Down
3 changes: 2 additions & 1 deletion gen_input/templates/llvm/CORENAME.cpp.gtl
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,8 @@ template <typename CODE_WORD> void debug_fn(CODE_WORD instr) {
instr = 2 * x;
}

template <typename ARCH> vm_impl<ARCH>::vm_impl() { this(new ARCH()); }
template <typename ARCH> vm_impl<ARCH>::vm_impl()
: vm_base<ARCH>(std::make_unique<ARCH>()) {}

template <typename ARCH>
vm_impl<ARCH>::vm_impl(ARCH &core, unsigned core_id, unsigned cluster_id)
Expand Down
2 changes: 1 addition & 1 deletion softvector
74 changes: 47 additions & 27 deletions src/iss/debugger/riscv_target_adapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,6 @@ char const* const get_csr_name(unsigned);
constexpr auto vec_offset = 128U;
constexpr auto csr_offset = 256U;

using namespace iss::arch;
using namespace iss::debugger;

template <typename ARCH> class riscv_target_adapter : public target_adapter_base {
public:
riscv_target_adapter(server_if* srv, iss::arch_if* core)
Expand Down Expand Up @@ -117,7 +114,7 @@ template <typename ARCH> class riscv_target_adapter : public target_adapter_base

status crc_query(uint64_t addr, size_t len, uint32_t& val) override;

status raw_query(std::string in_buf, std::string& out_buf) override;
status raw_query(const std::string& in_buf, std::string& out_buf) override;

status threadinfo_query(int first, std::string& out_buf) override;

Expand Down Expand Up @@ -198,7 +195,7 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::read_registers(std::
for(size_t i = 0; i < 33; ++i) {
if(i < arch::traits<ARCH>::RFS || i == arch::traits<ARCH>::PC) {
auto reg_no = i < 32 ? start_reg + i : arch::traits<ARCH>::PC;
unsigned offset = traits<ARCH>::reg_byte_offsets[reg_no];
unsigned offset = iss::arch::traits<ARCH>::reg_byte_offsets[reg_no];
for(size_t j = 0; j < arch::traits<ARCH>::XLEN / 8; ++j) {
data.push_back(*(reg_base + offset + j));
avail.push_back(0xff);
Expand All @@ -220,11 +217,13 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::write_registers(cons
auto iter_end = data.data() + data.size();
for(size_t i = 0; i < 33 && iter < iter_end; ++i) {
auto reg_width = arch::traits<ARCH>::XLEN / 8;
if(iter_end - iter < static_cast<decltype(iter_end - iter)>(reg_width))
return Err;
if(i < arch::traits<ARCH>::RFS) {
auto offset = traits<ARCH>::reg_byte_offsets[start_reg + i];
auto offset = iss::arch::traits<ARCH>::reg_byte_offsets[start_reg + i];
std::copy(iter, iter + reg_width, reg_base + offset);
} else if(i == 32) {
auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC];
auto offset = iss::arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC];
std::copy(iter, iter + reg_width, reg_base + offset);
}
iter += reg_width;
Expand All @@ -234,54 +233,73 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::write_registers(cons

template <typename ARCH>
status riscv_target_adapter<ARCH>::read_single_register(unsigned int reg_no, std::vector<uint8_t>& data, std::vector<uint8_t>& avail) {
data.clear();
avail.clear();
if(reg_no < vec_offset) {
// auto reg_size = arch::traits<ARCH>::reg_bit_width(static_cast<typename
// arch::traits<ARCH>::reg_e>(reg_no))/8;
if(reg_no >= iss::arch::traits<ARCH>::reg_bit_widths.size() || reg_no >= iss::arch::traits<ARCH>::reg_byte_offsets.size())
return Err;
auto* reg_base = core->get_regs_base_ptr();
auto reg_width = arch::traits<ARCH>::reg_bit_widths[reg_no] / 8;
if(reg_width == 0)
return Err;
data.resize(reg_width);
avail.resize(reg_width);
auto offset = traits<ARCH>::reg_byte_offsets[reg_no];
auto offset = iss::arch::traits<ARCH>::reg_byte_offsets[reg_no];
std::copy(reg_base + offset, reg_base + offset + reg_width, data.begin());
std::fill(avail.begin(), avail.end(), 0xff);
} else if(reg_no < csr_offset) {
// TODO: implement vector register reading
return Err;
} else {
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_READ, traits<ARCH>::CSR, reg_no - csr_offset);
data.resize(sizeof(typename traits<ARCH>::reg_t));
avail.resize(sizeof(typename traits<ARCH>::reg_t));
std::fill(avail.begin(), avail.end(), 0xff);
core->read(a, data.size(), data.data());
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_READ, iss::arch::traits<ARCH>::CSR, reg_no - csr_offset);
data.resize(sizeof(typename iss::arch::traits<ARCH>::reg_t));
avail.resize(sizeof(typename iss::arch::traits<ARCH>::reg_t));
auto res = core->read(a, data.size(), data.data());
if(res != Ok) {
std::fill(avail.begin(), avail.end(), 0);
return res;
}
std::fill(avail.begin(), avail.end(), 0xff);
}
return data.size() > 0 ? Ok : Err;
}

template <typename ARCH> status riscv_target_adapter<ARCH>::write_single_register(unsigned int reg_no, const std::vector<uint8_t>& data) {
if(reg_no < vec_offset) {
if(reg_no >= iss::arch::traits<ARCH>::reg_bit_widths.size() || reg_no >= iss::arch::traits<ARCH>::reg_byte_offsets.size())
return Err;
auto* reg_base = core->get_regs_base_ptr();
auto reg_width = arch::traits<ARCH>::reg_bit_widths[static_cast<typename arch::traits<ARCH>::reg_e>(reg_no)] / 8;
auto offset = traits<ARCH>::reg_byte_offsets[reg_no];
if(data.size() < reg_width)
return Err;
auto offset = iss::arch::traits<ARCH>::reg_byte_offsets[reg_no];
std::copy(data.begin(), data.begin() + reg_width, reg_base + offset);
} else if(reg_no < csr_offset) {
// TODO: implement vector register writing
return Err;
} else {
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_WRITE, traits<ARCH>::CSR, reg_no - csr_offset);
core->write(a, data.size(), data.data());
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_WRITE, iss::arch::traits<ARCH>::CSR, reg_no - csr_offset);
auto res = core->write(a, data.size(), data.data());
if(res != Ok)
return res;
}
return Ok;
}

template <typename ARCH> status riscv_target_adapter<ARCH>::read_mem(uint64_t addr, std::vector<uint8_t>& data) {
if(!srv)
return Err;
auto a = map_addr({iss::address_type::VIRTUAL, iss::access_type::DEBUG_READ, 0, addr});
auto f = [&]() -> status { return core->read(a, data.size(), data.data()); };
return srv->execute_syncronized(f);
return srv->execute_synchronized(f);
}

template <typename ARCH> status riscv_target_adapter<ARCH>::write_mem(uint64_t addr, const std::vector<uint8_t>& data) {
if(!srv)
return Err;
auto a = map_addr({iss::address_type::VIRTUAL, iss::access_type::DEBUG_WRITE, 0, addr});
auto f = [&]() -> status { return core->write(a, data.size(), data.data()); };
return srv->execute_syncronized(f);
return srv->execute_synchronized(f);
}

template <typename ARCH>
Expand All @@ -298,7 +316,9 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::offsets_query(uint64

template <typename ARCH> status riscv_target_adapter<ARCH>::crc_query(uint64_t addr, size_t len, uint32_t& val) { return NotSupported; }

template <typename ARCH> status riscv_target_adapter<ARCH>::raw_query(std::string in_buf, std::string& out_buf) { return NotSupported; }
template <typename ARCH> status riscv_target_adapter<ARCH>::raw_query(const std::string& in_buf, std::string& out_buf) {
return NotSupported;
}

template <typename ARCH> status riscv_target_adapter<ARCH>::threadinfo_query(int first, std::string& out_buf) {
if(first) {
Expand Down Expand Up @@ -365,9 +385,9 @@ status riscv_target_adapter<ARCH>::resume_from_addr(bool step, int sig, uint64_t
std::function<void(unsigned)> stop_callback) {
auto* reg_base = core->get_regs_base_ptr();
auto reg_width = arch::traits<ARCH>::reg_bit_widths[arch::traits<ARCH>::PC] / 8;
auto offset = traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC];
auto offset = iss::arch::traits<ARCH>::reg_byte_offsets[arch::traits<ARCH>::PC];
const uint8_t* iter = reinterpret_cast<const uint8_t*>(&addr);
std::copy(iter, iter + reg_width, reg_base);
std::copy(iter, iter + reg_width, reg_base + offset);
return resume_from_current(step, sig, thread, stop_callback);
}

Expand Down Expand Up @@ -415,8 +435,8 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std
oss << " </feature>\n";
}
std::vector<uint8_t> data;
data.resize(sizeof(typename traits<ARCH>::reg_t));
typed_addr_t<iss::address_type::PHYSICAL> vlen_addr(iss::access_type::DEBUG_READ, traits<ARCH>::CSR, 0xC22);
data.resize(sizeof(typename iss::arch::traits<ARCH>::reg_t));
typed_addr_t<iss::address_type::PHYSICAL> vlen_addr(iss::access_type::DEBUG_READ, iss::arch::traits<ARCH>::CSR, 0xC22);
auto res = core->read(vlen_addr, data.size(), data.data());
if(res == iss::Ok) {
auto bitsize = data[0] * 8L;
Expand All @@ -438,9 +458,9 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::target_xml_query(std
}
oss << " <feature name=\"org.gnu.gdb.riscv.csr\">\n";
std::vector<uint8_t> avail;
avail.resize(sizeof(typename traits<ARCH>::reg_t));
avail.resize(sizeof(typename iss::arch::traits<ARCH>::reg_t));
for(auto i = 0U; i < 4096; ++i) {
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_READ, traits<ARCH>::CSR, i);
typed_addr_t<iss::address_type::PHYSICAL> a(iss::access_type::DEBUG_READ, iss::arch::traits<ARCH>::CSR, i);
std::fill(avail.begin(), avail.end(), 0xff);
auto res = core->read(a, data.size(), data.data());
if(res == iss::Ok) {
Expand Down
65 changes: 43 additions & 22 deletions src/iss/semihosting/semihosting.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,9 @@
******************************************************************************/

#include "semihosting.h"
#include <algorithm>
#include <array>
#include <cerrno>
#include <chrono>
#include <cstdint>
#include <iss/vm_types.h>
Expand All @@ -42,16 +45,16 @@

const char* SYS_OPEN_MODES_STRS[] = {"r", "rb", "r+", "r+b", "w", "wb", "w+", "w+b", "a", "ab", "a+", "a+b"};

template <typename T> T sh_read_field(iss::arch_if* arch_if_ptr, T addr, int len = 4) {
uint8_t bytes[4];
auto res = arch_if_ptr->read({iss::address_type::LOGICAL, iss::access_type::DEBUG_READ, 0, addr}, 4, &bytes[0]);
// auto res = arch_if_ptr->read(iss::address_type::PHYSICAL, iss::access_type::DEBUG_READ, 0, *parameter, 1, &character);

if(res != iss::Ok) {
template <typename T> T sh_read_field(iss::arch_if* arch_if_ptr, T addr, size_t len = sizeof(T)) {
std::array<uint8_t, sizeof(T)> bytes{};
len = std::min(len, sizeof(T));
auto res = arch_if_ptr->read({iss::address_type::LOGICAL, iss::access_type::DEBUG_READ, 0, addr}, len, bytes.data());
if(res != iss::Ok)
return 0; // TODO THROW ERROR
} else
return static_cast<T>(bytes[0]) | (static_cast<T>(bytes[1]) << 8) | (static_cast<T>(bytes[2]) << 16) |
(static_cast<T>(bytes[3]) << 24);
T value{0};
for(size_t i = 0; i < len; ++i)
value |= static_cast<T>(bytes[i]) << (8 * i);
return value;
}

template <typename T> std::string sh_read_string(iss::arch_if* arch_if_ptr, T addr, T str_len) {
Expand All @@ -67,6 +70,16 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
static std::map<T, FILE*> openFiles;
static T file_count = 3;
static T semihostingErrno;
auto get_open_file = [call_number, this](T file_handle, FILE*& file) -> bool {
auto it = openFiles.find(file_handle);
if(it == openFiles.end() || it->second == nullptr) {
semihostingErrno = EBADF;
*call_number = static_cast<T>(-1);
return false;
}
file = it->second;
return true;
};

switch(static_cast<semihosting_syscalls>(*call_number)) {
case semihosting_syscalls::SYS_CLOCK: {
Expand All @@ -78,11 +91,13 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
}
case semihosting_syscalls::SYS_CLOSE: {
T file_handle = *parameter;
if(openFiles.size() <= file_handle && file_handle < 0) {
auto it = openFiles.find(file_handle);
if(it == openFiles.end() || it->second == nullptr) {
semihostingErrno = EBADF;
*call_number = static_cast<T>(-1);
return;
}
auto file = openFiles[file_handle];
auto file = it->second;
openFiles.erase(file_handle);
if(!(file == stdin || file == stdout || file == stderr)) {
int i = fclose(file);
Expand Down Expand Up @@ -112,7 +127,9 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
}
case semihosting_syscalls::SYS_FLEN: {
T file_handle = *parameter;
auto file = openFiles[file_handle];
FILE* file = nullptr;
if(!get_open_file(file_handle, file))
return;

size_t currentPos = ftell(file);
if(currentPos < 0)
Expand Down Expand Up @@ -151,7 +168,7 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
// TODO LOG INFO

if(mode >= 12) {
// TODO throw ERROR
*call_number = static_cast<T>(-1);
return;
}

Expand All @@ -166,7 +183,7 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
} else {
file = fopen(path_str.c_str(), SYS_OPEN_MODES_STRS[mode]);
if(file == nullptr) {
// TODO throw error
*call_number = static_cast<T>(-1);
return;
}
}
Expand All @@ -179,8 +196,9 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
T file_handle = sh_read_field<T>(arch_if_ptr, (*parameter) + 4);
T addr = sh_read_field<T>(arch_if_ptr, *parameter);
T count = sh_read_field<T>(arch_if_ptr, (*parameter) + 8);

auto file = openFiles[file_handle];
FILE* file = nullptr;
if(!get_open_file(file_handle, file))
return;

std::vector<uint8_t> buffer(count);
size_t num_read = 0;
Expand All @@ -199,7 +217,7 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
}
buffer.resize(num_read);
for(int i = 0; i < num_read; i++) {
auto res = arch_if_ptr->write({iss::address_type::LOGICAL, iss::access_type::DEBUG_READ, 0, addr + i}, 1, &buffer[i]);
auto res = arch_if_ptr->write({iss::address_type::LOGICAL, iss::access_type::DEBUG_WRITE, 0, addr + i}, 1, &buffer[i]);
if(res != iss::Ok)
return;
}
Expand Down Expand Up @@ -238,7 +256,9 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
case semihosting_syscalls::SYS_SEEK: {
T file_handle = sh_read_field<T>(arch_if_ptr, *parameter);
T pos = sh_read_field<T>(arch_if_ptr, (*parameter) + 1);
auto file = openFiles[file_handle];
FILE* file = nullptr;
if(!get_open_file(file_handle, file))
return;

int retval = fseek(file, pos, SEEK_SET);
if(retval < 0)
Expand Down Expand Up @@ -275,9 +295,9 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
ss << "tmp/file-" << std::setfill('0') << std::setw(3) << identifier;
std::string filename = ss.str();

for(int i = 0; i < buffer_len; i++) {
for(int i = 0; i < buffer_len && i < static_cast<int>(filename.size()); i++) {
uint8_t character = filename[i];
auto res = arch_if_ptr->write({iss::address_type::LOGICAL, iss::access_type::DEBUG_READ, 0, (*parameter) + i}, 1, &character);
auto res = arch_if_ptr->write({iss::address_type::LOGICAL, iss::access_type::DEBUG_WRITE, 0, (*parameter) + i}, 1, &character);
if(res != iss::Ok)
return;
}
Expand All @@ -287,8 +307,9 @@ template <typename T> void semihosting_callback<T>::operator()(iss::arch_if* arc
T file_handle = sh_read_field<T>(arch_if_ptr, (*parameter) + 4);
T addr = sh_read_field<T>(arch_if_ptr, *parameter);
T count = sh_read_field<T>(arch_if_ptr, (*parameter) + 8);

auto file = openFiles[file_handle];
FILE* file = nullptr;
if(!get_open_file(file_handle, file))
return;
std::string str = sh_read_string<T>(arch_if_ptr, addr, count);
fwrite(&str[0], 1, count, file);
break;
Expand Down
4 changes: 2 additions & 2 deletions src/sysc/register_cores.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,12 +134,12 @@ using namespace sysc;
volatile std::array<bool, 4> riscv_init = {
iss_factory::instance().register_creator("rv32imac_m:llvm",
[](unsigned gdb_port, sysc::riscv::core_complex_if* cc) -> iss_factory::base_t {
auto* cpu = new core2sc_adapter<arch::riscv_hart_m_p<arch::rv32imc>>(cc);
auto* cpu = new core2sc_adapter<arch::riscv_hart_m_p<arch::rv32imac>>(cc);
return {sysc::core_ptr{cpu}, vm_ptr{create(static_cast<arch::rv32imac*>(cpu), gdb_port)}};
}),
iss_factory::instance().register_creator("rv32imac_mu:llvm",
[](unsigned gdb_port, sysc::riscv::core_complex_if* cc) -> iss_factory::base_t {
auto* cpu = new core2sc_adapter<arch::riscv_hart_mu_p<arch::rv32imc>>(cc);
auto* cpu = new core2sc_adapter<arch::riscv_hart_mu_p<arch::rv32imac>>(cc);
return {sysc::core_ptr{cpu}, vm_ptr{create(static_cast<arch::rv32imac*>(cpu), gdb_port)}};
}),
iss_factory::instance().register_creator("tgc5c_m:llvm",
Expand Down
Loading