From d8184abbccd2481d49988799df2ff1b63cf77041 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Tue, 26 Sep 2017 17:10:10 +0200 Subject: [PATCH] Refactored file dependencies to decouple components --- dbt-core | 2 +- riscv.sc/incl/sysc/SiFive/gen/gpio_regs.h | 24 +- riscv.sc/incl/sysc/SiFive/gen/plic_regs.h | 9 +- riscv.sc/incl/sysc/SiFive/gen/spi_regs.h | 23 +- riscv.sc/incl/sysc/SiFive/gen/uart_regs.h | 11 +- riscv.sc/src/CMakeLists.txt | 2 +- riscv.sc/src/sysc/core_complex.cpp | 6 +- riscv.sc/src/sysc/gpio.cpp | 9 +- riscv.sc/src/sysc/platform.cpp | 11 +- riscv.sc/src/sysc/plic.cpp | 6 +- riscv.sc/src/sysc/spi.cpp | 6 +- riscv.sc/src/sysc/uart.cpp | 6 +- riscv/incl/iss/arch/riscv_hart_msu_vp.h | 24 +- riscv/incl/iss/arch/rv32imac.h | 28 +- riscv/incl/iss/arch/rv64ia.h | 28 +- .../incl/iss/debugger/riscv_target_adapter.h | 317 +++++++++++++++++ riscv/src/CMakeLists.txt | 4 +- riscv/src/internal/vm_riscv.in.cpp | 334 ++---------------- riscv/src/internal/vm_rv32imac.cpp | 333 ++--------------- riscv/src/internal/vm_rv64ia.cpp | 327 ++--------------- sc-components | 2 +- 21 files changed, 515 insertions(+), 997 deletions(-) create mode 100644 riscv/incl/iss/debugger/riscv_target_adapter.h diff --git a/dbt-core b/dbt-core index c338c68..aefc568 160000 --- a/dbt-core +++ b/dbt-core @@ -1 +1 @@ -Subproject commit c338c6879fe968b2bde07b536731b855fccebf10 +Subproject commit aefc5681f12cdbbaa5f48d4a043697002b996eec diff --git a/riscv.sc/incl/sysc/SiFive/gen/gpio_regs.h b/riscv.sc/incl/sysc/SiFive/gen/gpio_regs.h index b036908..f91a056 100644 --- a/riscv.sc/incl/sysc/SiFive/gen/gpio_regs.h +++ b/riscv.sc/incl/sysc/SiFive/gen/gpio_regs.h @@ -110,12 +110,24 @@ public: ////////////////////////////////////////////////////////////////////////////// inline sysc::gpio_regs::gpio_regs(sc_core::sc_module_name nm) - : sc_core::sc_module(nm), NAMED(value, r_value, 0, *this), NAMED(input_en, r_input_en, 0, *this), - NAMED(output_en, r_output_en, 0, *this), NAMED(port, r_port, 0, *this), NAMED(pue, r_pue, 0, *this), - NAMED(ds, r_ds, 0, *this), NAMED(rise_ie, r_rise_ie, 0, *this), NAMED(rise_ip, r_rise_ip, 0, *this), - NAMED(fall_ie, r_fall_ie, 0, *this), NAMED(fall_ip, r_fall_ip, 0, *this), NAMED(high_ie, r_high_ie, 0, *this), - NAMED(high_ip, r_high_ip, 0, *this), NAMED(low_ie, r_low_ie, 0, *this), NAMED(low_ip, r_low_ip, 0, *this), - NAMED(iof_en, r_iof_en, 0, *this), NAMED(iof_sel, r_iof_sel, 0, *this), NAMED(out_xor, r_out_xor, 0, *this) {} +: sc_core::sc_module(nm) +, NAMED(value, r_value, 0, *this) +, NAMED(input_en, r_input_en, 0, *this) +, NAMED(output_en, r_output_en, 0, *this) +, NAMED(port, r_port, 0, *this) +, NAMED(pue, r_pue, 0, *this) +, NAMED(ds, r_ds, 0, *this) +, NAMED(rise_ie, r_rise_ie, 0, *this) +, NAMED(rise_ip, r_rise_ip, 0, *this) +, NAMED(fall_ie, r_fall_ie, 0, *this) +, NAMED(fall_ip, r_fall_ip, 0, *this) +, NAMED(high_ie, r_high_ie, 0, *this) +, NAMED(high_ip, r_high_ip, 0, *this) +, NAMED(low_ie, r_low_ie, 0, *this) +, NAMED(low_ip, r_low_ip, 0, *this) +, NAMED(iof_en, r_iof_en, 0, *this) +, NAMED(iof_sel, r_iof_sel, 0, *this) +, NAMED(out_xor, r_out_xor, 0, *this) {} template inline void sysc::gpio_regs::registerResources(sysc::tlm_target &target) { target.addResource(value, 0x0UL); diff --git a/riscv.sc/incl/sysc/SiFive/gen/plic_regs.h b/riscv.sc/incl/sysc/SiFive/gen/plic_regs.h index c61d503..875a855 100644 --- a/riscv.sc/incl/sysc/SiFive/gen/plic_regs.h +++ b/riscv.sc/incl/sysc/SiFive/gen/plic_regs.h @@ -79,9 +79,12 @@ public: ////////////////////////////////////////////////////////////////////////////// inline sysc::plic_regs::plic_regs(sc_core::sc_module_name nm) - : sc_core::sc_module(nm), NAMED(priority, r_priority, 0, *this), NAMED(pending, r_pending, 0, *this), - NAMED(enabled, r_enabled, 0, *this), NAMED(threshold, r_threshold, 0, *this), - NAMED(claim_complete, r_claim_complete, 0, *this) {} +: sc_core::sc_module(nm) +, NAMED(priority, r_priority, 0, *this) +, NAMED(pending, r_pending, 0, *this) +, NAMED(enabled, r_enabled, 0, *this) +, NAMED(threshold, r_threshold, 0, *this) +, NAMED(claim_complete, r_claim_complete, 0, *this) {} template inline void sysc::plic_regs::registerResources(sysc::tlm_target &target) { target.addResource(priority, 0x4UL); diff --git a/riscv.sc/incl/sysc/SiFive/gen/spi_regs.h b/riscv.sc/incl/sysc/SiFive/gen/spi_regs.h index 945fe78..03e5b13 100644 --- a/riscv.sc/incl/sysc/SiFive/gen/spi_regs.h +++ b/riscv.sc/incl/sysc/SiFive/gen/spi_regs.h @@ -152,12 +152,23 @@ public: ////////////////////////////////////////////////////////////////////////////// inline sysc::spi_regs::spi_regs(sc_core::sc_module_name nm) - : sc_core::sc_module(nm), NAMED(sckdiv, r_sckdiv, 0, *this), NAMED(sckmode, r_sckmode, 0, *this), - NAMED(csid, r_csid, 0, *this), NAMED(csdef, r_csdef, 0, *this), NAMED(csmode, r_csmode, 0, *this), - NAMED(delay0, r_delay0, 0, *this), NAMED(delay1, r_delay1, 0, *this), NAMED(fmt, r_fmt, 0, *this), - NAMED(txdata, r_txdata, 0, *this), NAMED(rxdata, r_rxdata, 0, *this), NAMED(txmark, r_txmark, 0, *this), - NAMED(rxmark, r_rxmark, 0, *this), NAMED(fctrl, r_fctrl, 0, *this), NAMED(ffmt, r_ffmt, 0, *this), - NAMED(ie, r_ie, 0, *this), NAMED(ip, r_ip, 0, *this) {} +: sc_core::sc_module(nm) +, NAMED(sckdiv, r_sckdiv, 0, *this) +, NAMED(sckmode, r_sckmode, 0, *this) +, NAMED(csid, r_csid, 0, *this) +, NAMED(csdef, r_csdef, 0, *this) +, NAMED(csmode, r_csmode, 0, *this) +, NAMED(delay0, r_delay0, 0, *this) +, NAMED(delay1, r_delay1, 0, *this) +, NAMED(fmt, r_fmt, 0, *this) +, NAMED(txdata, r_txdata, 0, *this) +, NAMED(rxdata, r_rxdata, 0, *this) +, NAMED(txmark, r_txmark, 0, *this) +, NAMED(rxmark, r_rxmark, 0, *this) +, NAMED(fctrl, r_fctrl, 0, *this) +, NAMED(ffmt, r_ffmt, 0, *this) +, NAMED(ie, r_ie, 0, *this) +, NAMED(ip, r_ip, 0, *this) {} template inline void sysc::spi_regs::registerResources(sysc::tlm_target &target) { target.addResource(sckdiv, 0x0UL); diff --git a/riscv.sc/incl/sysc/SiFive/gen/uart_regs.h b/riscv.sc/incl/sysc/SiFive/gen/uart_regs.h index 9726e1e..4f4b166 100644 --- a/riscv.sc/incl/sysc/SiFive/gen/uart_regs.h +++ b/riscv.sc/incl/sysc/SiFive/gen/uart_regs.h @@ -103,9 +103,14 @@ public: ////////////////////////////////////////////////////////////////////////////// inline sysc::uart_regs::uart_regs(sc_core::sc_module_name nm) - : sc_core::sc_module(nm), NAMED(txdata, r_txdata, 0, *this), NAMED(rxdata, r_rxdata, 0, *this), - NAMED(txctrl, r_txctrl, 0, *this), NAMED(rxctrl, r_rxctrl, 0, *this), NAMED(ie, r_ie, 0, *this), - NAMED(ip, r_ip, 0, *this), NAMED(div, r_div, 0, *this) {} +: sc_core::sc_module(nm) +, NAMED(txdata, r_txdata, 0, *this) +, NAMED(rxdata, r_rxdata, 0, *this) +, NAMED(txctrl, r_txctrl, 0, *this) +, NAMED(rxctrl, r_rxctrl, 0, *this) +, NAMED(ie, r_ie, 0, *this) +, NAMED(ip, r_ip, 0, *this) +, NAMED(div, r_div, 0, *this) {} template inline void sysc::uart_regs::registerResources(sysc::tlm_target &target) { target.addResource(txdata, 0x0UL); diff --git a/riscv.sc/src/CMakeLists.txt b/riscv.sc/src/CMakeLists.txt index beb930c..ee4461b 100644 --- a/riscv.sc/src/CMakeLists.txt +++ b/riscv.sc/src/CMakeLists.txt @@ -34,10 +34,10 @@ add_executable(${APPLICATION_NAME} ${APP_SOURCES}) # Links the target exe against the libraries target_link_libraries(${APPLICATION_NAME} ${LIBRARY_NAME}) +target_link_libraries(${APPLICATION_NAME} risc-v) target_link_libraries(${APPLICATION_NAME} dbt-core) target_link_libraries(${APPLICATION_NAME} sc-components) target_link_libraries(${APPLICATION_NAME} external) -target_link_libraries(${APPLICATION_NAME} risc-v) target_link_libraries(${APPLICATION_NAME} ${llvm_libs}) target_link_libraries(${APPLICATION_NAME} ${SystemC_LIBRARIES} ) if(SCV_FOUND) diff --git a/riscv.sc/src/sysc/core_complex.cpp b/riscv.sc/src/sysc/core_complex.cpp index e01bbdb..757e08b 100644 --- a/riscv.sc/src/sysc/core_complex.cpp +++ b/riscv.sc/src/sysc/core_complex.cpp @@ -39,10 +39,12 @@ namespace sysc { namespace SiFive { -core_complex::core_complex(sc_core::sc_module_name name) : sc_core::sc_module(name), NAMED(initiator), NAMED(rst_i) { +core_complex::core_complex(sc_core::sc_module_name name) +: sc_core::sc_module(name) +, NAMED(initiator) +, NAMED(rst_i) { // TODO Auto-generated constructor stub } - } /* namespace SiFive */ } /* namespace sysc */ diff --git a/riscv.sc/src/sysc/gpio.cpp b/riscv.sc/src/sysc/gpio.cpp index 52509f1..eb625bb 100644 --- a/riscv.sc/src/sysc/gpio.cpp +++ b/riscv.sc/src/sysc/gpio.cpp @@ -21,7 +21,11 @@ namespace sysc { gpio::gpio(sc_core::sc_module_name nm) - : sc_core::sc_module(nm), tlm_target<>(clk), NAMED(clk_i), NAMED(rst_i), NAMEDD(gpio_regs, regs) { +: sc_core::sc_module(nm) +, tlm_target<>(clk) +, NAMED(clk_i) +, NAMED(rst_i) +, NAMEDD(gpio_regs, regs) { regs->registerResources(*this); SC_METHOD(clock_cb); sensitive << clk_i; @@ -31,8 +35,7 @@ gpio::gpio(sc_core::sc_module_name nm) void gpio::clock_cb() {} -gpio::~gpio() { -} +gpio::~gpio() {} void gpio::reset_cb() { if (rst_i.read()) diff --git a/riscv.sc/src/sysc/platform.cpp b/riscv.sc/src/sysc/platform.cpp index 26d6875..e3a308c 100644 --- a/riscv.sc/src/sysc/platform.cpp +++ b/riscv.sc/src/sysc/platform.cpp @@ -25,8 +25,15 @@ namespace sysc { platform::platform(sc_core::sc_module_name nm) - : sc_core::sc_module(nm), NAMED(i_master), NAMED(i_router, 4, 1), NAMED(i_uart), NAMED(i_spi), NAMED(i_gpio), - NAMED(i_plic), NAMED(s_clk), NAMED(s_rst) { +: sc_core::sc_module(nm) +, NAMED(i_master) +, NAMED(i_router, 4, 1) +, NAMED(i_uart) +, NAMED(i_spi) +, NAMED(i_gpio) +, NAMED(i_plic) +, NAMED(s_clk) +, NAMED(s_rst) { i_master.initiator(i_router.target[0]); size_t i = 0; for (const auto &e : e300_plat_map) { diff --git a/riscv.sc/src/sysc/plic.cpp b/riscv.sc/src/sysc/plic.cpp index 9b0153a..fe1a006 100644 --- a/riscv.sc/src/sysc/plic.cpp +++ b/riscv.sc/src/sysc/plic.cpp @@ -21,7 +21,11 @@ namespace sysc { plic::plic(sc_core::sc_module_name nm) - : sc_core::sc_module(nm), tlm_target<>(clk), NAMED(clk_i), NAMED(rst_i), NAMEDD(plic_regs, regs) { +: sc_core::sc_module(nm) +, tlm_target<>(clk) +, NAMED(clk_i) +, NAMED(rst_i) +, NAMEDD(plic_regs, regs) { regs->registerResources(*this); SC_METHOD(clock_cb); sensitive << clk_i; diff --git a/riscv.sc/src/sysc/spi.cpp b/riscv.sc/src/sysc/spi.cpp index 134cc48..1ddd1a6 100644 --- a/riscv.sc/src/sysc/spi.cpp +++ b/riscv.sc/src/sysc/spi.cpp @@ -21,7 +21,11 @@ namespace sysc { spi::spi(sc_core::sc_module_name nm) - : sc_core::sc_module(nm), tlm_target<>(clk), NAMED(clk_i), NAMED(rst_i), NAMEDD(spi_regs, regs) { +: sc_core::sc_module(nm) +, tlm_target<>(clk) +, NAMED(clk_i) +, NAMED(rst_i) +, NAMEDD(spi_regs, regs) { regs->registerResources(*this); SC_METHOD(clock_cb); sensitive << clk_i; diff --git a/riscv.sc/src/sysc/uart.cpp b/riscv.sc/src/sysc/uart.cpp index b68a712..7888c90 100644 --- a/riscv.sc/src/sysc/uart.cpp +++ b/riscv.sc/src/sysc/uart.cpp @@ -21,7 +21,11 @@ namespace sysc { uart::uart(sc_core::sc_module_name nm) - : sc_core::sc_module(nm), tlm_target<>(clk), NAMED(clk_i), NAMED(rst_i), NAMEDD(uart_regs, regs) { +: sc_core::sc_module(nm) +, tlm_target<>(clk) +, NAMED(clk_i) +, NAMED(rst_i) +, NAMEDD(uart_regs, regs) { regs->registerResources(*this); SC_METHOD(clock_cb); sensitive << clk_i; diff --git a/riscv/incl/iss/arch/riscv_hart_msu_vp.h b/riscv/incl/iss/arch/riscv_hart_msu_vp.h index bad36d8..8c201d4 100644 --- a/riscv/incl/iss/arch/riscv_hart_msu_vp.h +++ b/riscv/incl/iss/arch/riscv_hart_msu_vp.h @@ -224,19 +224,24 @@ struct vm_info { }; struct trap_load_access_fault : public trap_access { - trap_load_access_fault(uint64_t badaddr) : trap_access(5 << 16, badaddr) {} + trap_load_access_fault(uint64_t badaddr) + : trap_access(5 << 16, badaddr) {} }; struct illegal_instruction_fault : public trap_access { - illegal_instruction_fault(uint64_t badaddr) : trap_access(2 << 16, badaddr) {} + illegal_instruction_fault(uint64_t badaddr) + : trap_access(2 << 16, badaddr) {} }; struct trap_instruction_page_fault : public trap_access { - trap_instruction_page_fault(uint64_t badaddr) : trap_access(12 << 16, badaddr) {} + trap_instruction_page_fault(uint64_t badaddr) + : trap_access(12 << 16, badaddr) {} }; struct trap_load_page_fault : public trap_access { - trap_load_page_fault(uint64_t badaddr) : trap_access(13 << 16, badaddr) {} + trap_load_page_fault(uint64_t badaddr) + : trap_access(13 << 16, badaddr) {} }; struct trap_store_page_fault : public trap_access { - trap_store_page_fault(uint64_t badaddr) : trap_access(15 << 16, badaddr) {} + trap_store_page_fault(uint64_t badaddr) + : trap_access(15 << 16, badaddr) {} }; } @@ -277,7 +282,7 @@ using mstatus32_t = union { uint32_t SD : 1, _WPRI4 : 11, MXR : 1, SUM : 1, _WPRI3 : 1, XS : 2, FS : 2, _WPRI2 : 8, UPIE : 1, _WPRI0 : 3, UIE : 1; } u; -} ; +}; using mstatus64_t = union { uint64_t val; @@ -324,7 +329,7 @@ using mstatus64_t = union { UXL : 2, // value of XLEN for U-mode _WPRI3 : 12, MXR : 1, SUM : 1, _WPRI2 : 1, XS : 2, FS : 2, _WPRI1 : 8, UPIE : 1, _WPRI0 : 3, UIE : 1; } u; -} ; +}; template inline vm_info decode_vm_info(uint32_t state, uint64_t sptbr); @@ -483,7 +488,10 @@ private: void check_interrupt(); }; -template riscv_hart_msu_vp::riscv_hart_msu_vp() : mstatus_r(csr[mstatus]), satp_r(csr[satp]) { +template +riscv_hart_msu_vp::riscv_hart_msu_vp() +: mstatus_r(csr[mstatus]) +, satp_r(csr[satp]) { csr[misa] = traits::XLEN == 32 ? 1ULL << (traits::XLEN - 2) : 2ULL << (traits::XLEN - 2); uart_buf.str(""); // read-only registers diff --git a/riscv/incl/iss/arch/rv32imac.h b/riscv/incl/iss/arch/rv32imac.h index c396c98..df99839 100644 --- a/riscv/incl/iss/arch/rv32imac.h +++ b/riscv/incl/iss/arch/rv32imac.h @@ -28,7 +28,7 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // -// Created on: Thu Sep 21 17:01:54 CEST 2017 +// Created on: Tue Sep 26 17:41:14 CEST 2017 // * rv32imac.h Author: // //////////////////////////////////////////////////////////////////////////////// @@ -103,15 +103,15 @@ template <> struct traits { ICOUNT }; - typedef uint32_t reg_t; + using reg_t = uint32_t; - typedef uint32_t addr_t; + using addr_t = uint32_t; - typedef uint32_t code_word_t; // TODO: check removal + using code_word_t = uint32_t; // TODO: check removal - typedef iss::typed_addr_t virt_addr_t; + using virt_addr_t = iss::typed_addr_t; - typedef iss::typed_addr_t phys_addr_t; + using phys_addr_t = iss::typed_addr_t; constexpr static unsigned reg_bit_width(unsigned r) { const uint32_t RV32IMAC_reg_size[] = {32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, @@ -142,19 +142,19 @@ struct rv32imac : public arch_if { rv32imac(); ~rv32imac(); - virtual void reset(uint64_t address = 0) override; + void reset(uint64_t address = 0) override; - virtual uint8_t *get_regs_base_ptr() override; + uint8_t *get_regs_base_ptr() override; /// deprecated - virtual void get_reg(short idx, std::vector &value) override {} - virtual void set_reg(short idx, const std::vector &value) override {} + void get_reg(short idx, std::vector &value) override {} + void set_reg(short idx, const std::vector &value) override {} /// deprecated - virtual bool get_flag(int flag) override { return false; } - virtual void set_flag(int, bool value) override{}; + bool get_flag(int flag) override { return false; } + void set_flag(int, bool value) override{}; /// deprecated - virtual void update_flags(operations op, uint64_t opr1, uint64_t opr2) override{}; + void update_flags(operations op, uint64_t opr1, uint64_t opr2) override{}; - virtual void notify_phase(exec_phase phase) { + void notify_phase(exec_phase phase) { if (phase == ISTART) { ++reg.icount; reg.PC = reg.NEXT_PC; diff --git a/riscv/incl/iss/arch/rv64ia.h b/riscv/incl/iss/arch/rv64ia.h index 9fec2ba..3b8f611 100644 --- a/riscv/incl/iss/arch/rv64ia.h +++ b/riscv/incl/iss/arch/rv64ia.h @@ -28,7 +28,7 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. // -// Created on: Thu Sep 21 17:01:54 CEST 2017 +// Created on: Tue Sep 26 17:41:14 CEST 2017 // * rv64ia.h Author: // //////////////////////////////////////////////////////////////////////////////// @@ -103,15 +103,15 @@ template <> struct traits { ICOUNT }; - typedef uint64_t reg_t; + using reg_t = uint64_t; - typedef uint64_t addr_t; + using addr_t = uint64_t; - typedef uint64_t code_word_t; // TODO: check removal + using code_word_t = uint64_t; // TODO: check removal - typedef iss::typed_addr_t virt_addr_t; + using virt_addr_t = iss::typed_addr_t; - typedef iss::typed_addr_t phys_addr_t; + using phys_addr_t = iss::typed_addr_t; constexpr static unsigned reg_bit_width(unsigned r) { const uint32_t RV64IA_reg_size[] = {64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, @@ -141,19 +141,19 @@ struct rv64ia : public arch_if { rv64ia(); ~rv64ia(); - virtual void reset(uint64_t address = 0) override; + void reset(uint64_t address = 0) override; - virtual uint8_t *get_regs_base_ptr() override; + uint8_t *get_regs_base_ptr() override; /// deprecated - virtual void get_reg(short idx, std::vector &value) override {} - virtual void set_reg(short idx, const std::vector &value) override {} + void get_reg(short idx, std::vector &value) override {} + void set_reg(short idx, const std::vector &value) override {} /// deprecated - virtual bool get_flag(int flag) override { return false; } - virtual void set_flag(int, bool value) override{}; + bool get_flag(int flag) override { return false; } + void set_flag(int, bool value) override{}; /// deprecated - virtual void update_flags(operations op, uint64_t opr1, uint64_t opr2) override{}; + void update_flags(operations op, uint64_t opr1, uint64_t opr2) override{}; - virtual void notify_phase(exec_phase phase) { + void notify_phase(exec_phase phase) { if (phase == ISTART) { ++reg.icount; reg.PC = reg.NEXT_PC; diff --git a/riscv/incl/iss/debugger/riscv_target_adapter.h b/riscv/incl/iss/debugger/riscv_target_adapter.h new file mode 100644 index 0000000..1346c8a --- /dev/null +++ b/riscv/incl/iss/debugger/riscv_target_adapter.h @@ -0,0 +1,317 @@ +/* + * riscv_target_adapter.h + * + * Created on: 26.09.2017 + * Author: eyck + */ + +#ifndef _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_ +#define _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_ + +#include "iss/arch_if.h" +#include +#include +#include + +#include +#include + +namespace iss { +namespace debugger { +using namespace iss::arch; +using namespace iss::debugger; + +template struct riscv_target_adapter : public target_adapter_base { + + riscv_target_adapter(server_if *srv, iss::arch_if *core) + : target_adapter_base(srv) + , core(core) {} + + /*============== Thread Control ===============================*/ + + /* Set generic thread */ + status set_gen_thread(rp_thread_ref &thread) override; + + /* Set control thread */ + status set_ctrl_thread(rp_thread_ref &thread) override; + + /* Get thread status */ + status is_thread_alive(rp_thread_ref &thread, bool &alive) override; + + /*============= Register Access ================================*/ + + /* Read all registers. buf is 4-byte aligned and it is in + target byte order. If register is not available + corresponding bytes in avail_buf are 0, otherwise + avail buf is 1 */ + status read_registers(std::vector &data, std::vector &avail) override; + + /* Write all registers. buf is 4-byte aligned and it is in target + byte order */ + status write_registers(const std::vector &data) override; + + /* Read one register. buf is 4-byte aligned and it is in + target byte order. If register is not available + corresponding bytes in avail_buf are 0, otherwise + avail buf is 1 */ + status read_single_register(unsigned int reg_no, std::vector &buf, + std::vector &avail_buf) override; + + /* Write one register. buf is 4-byte aligned and it is in target byte + order */ + status write_single_register(unsigned int reg_no, const std::vector &buf) override; + + /*=================== Memory Access =====================*/ + + /* Read memory, buf is 4-bytes aligned and it is in target + byte order */ + status read_mem(uint64_t addr, std::vector &buf) override; + + /* Write memory, buf is 4-bytes aligned and it is in target + byte order */ + status write_mem(uint64_t addr, const std::vector &buf) override; + + status process_query(unsigned int &mask, const rp_thread_ref &arg, rp_thread_info &info) override; + + status thread_list_query(int first, const rp_thread_ref &arg, std::vector &result, size_t max_num, + size_t &num, bool &done) override; + + status current_thread_query(rp_thread_ref &thread) override; + + status offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) override; + + 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 threadinfo_query(int first, std::string &out_buf) override; + + status threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) override; + + status packetsize_query(std::string &out_buf) override; + + status add_break(int type, uint64_t addr, unsigned int length) override; + + status remove_break(int type, uint64_t addr, unsigned int length) override; + + status resume_from_addr(bool step, int sig, uint64_t addr) override; + +protected: + static inline constexpr addr_t map_addr(const addr_t &i) { return i; } + + iss::arch_if *core; + rp_thread_ref thread_idx; +}; + +template status riscv_target_adapter::set_gen_thread(rp_thread_ref &thread) { + thread_idx = thread; + return Ok; +} + +template status riscv_target_adapter::set_ctrl_thread(rp_thread_ref &thread) { + thread_idx = thread; + return Ok; +} + +template status riscv_target_adapter::is_thread_alive(rp_thread_ref &thread, bool &alive) { + alive = 1; + return Ok; +} + +/* List threads. If first is non-zero then start from the first thread, + * otherwise start from arg, result points to array of threads to be + * filled out, result size is number of elements in the result, + * num points to the actual number of threads found, done is + * set if all threads are processed. + */ +template +status riscv_target_adapter::thread_list_query(int first, const rp_thread_ref &arg, + std::vector &result, size_t max_num, size_t &num, + bool &done) { + if (first == 0) { + result.clear(); + result.push_back(thread_idx); + num = 1; + done = true; + return Ok; + } else + return NotSupported; +} + +template status riscv_target_adapter::current_thread_query(rp_thread_ref &thread) { + thread = thread_idx; + return Ok; +} + +template +status riscv_target_adapter::read_registers(std::vector &data, std::vector &avail) { + LOG(TRACE) << "reading target registers"; + // return idx<0?:; + data.clear(); + avail.clear(); + const uint8_t *reg_base = core->get_regs_base_ptr(); + for (size_t reg_no = 0; reg_no < arch::traits::NUM_REGS; ++reg_no) { + auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no)) / 8; + unsigned offset = traits::reg_byte_offset(reg_no); + for (size_t j = 0; j < reg_width; ++j) { + data.push_back(*(reg_base + offset + j)); + avail.push_back(0xff); + } + } + // work around fill with F type registers + if (arch::traits::NUM_REGS < 65) { + auto reg_width = sizeof(typename arch::traits::reg_t); + for (size_t reg_no = 0; reg_no < 33; ++reg_no) { + for (size_t j = 0; j < reg_width; ++j) { + data.push_back(0x0); + avail.push_back(0x00); + } + } + } + return Ok; +} + +template status riscv_target_adapter::write_registers(const std::vector &data) { + auto reg_count = arch::traits::NUM_REGS; + auto *reg_base = core->get_regs_base_ptr(); + auto iter = data.data(); + for (size_t reg_no = 0; reg_no < reg_count; ++reg_no) { + auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no)) / 8; + auto offset = traits::reg_byte_offset(reg_no); + std::copy(iter, iter + reg_width, reg_base); + iter += 4; + reg_base += offset; + } + return Ok; +} + +template +status riscv_target_adapter::read_single_register(unsigned int reg_no, std::vector &data, + std::vector &avail) { + if (reg_no < 65) { + // auto reg_size = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; + auto *reg_base = core->get_regs_base_ptr(); + auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no)) / 8; + data.resize(reg_width); + avail.resize(reg_width); + auto offset = traits::reg_byte_offset(reg_no); + std::copy(reg_base + offset, reg_base + offset + reg_width, data.begin()); + std::fill(avail.begin(), avail.end(), 0xff); + } else { + typed_addr_t a(iss::DEBUG_READ, traits::CSR, reg_no - 65); + data.resize(sizeof(typename traits::reg_t)); + avail.resize(sizeof(typename traits::reg_t)); + std::fill(avail.begin(), avail.end(), 0xff); + core->read(a, data.size(), data.data()); + } + return data.size() > 0 ? Ok : Err; +} + +template +status riscv_target_adapter::write_single_register(unsigned int reg_no, const std::vector &data) { + if (reg_no < 65) { + auto *reg_base = core->get_regs_base_ptr(); + auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no)) / 8; + auto offset = traits::reg_byte_offset(reg_no); + std::copy(data.begin(), data.begin() + reg_width, reg_base + offset); + } else { + typed_addr_t a(iss::DEBUG_WRITE, traits::CSR, reg_no - 65); + core->write(a, data.size(), data.data()); + } + return Ok; +} + +template status riscv_target_adapter::read_mem(uint64_t addr, std::vector &data) { + auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr}); + auto f = [&]() -> status { return core->read(a, data.size(), data.data()); }; + return srv->execute_syncronized(f); +} + +template status riscv_target_adapter::write_mem(uint64_t addr, const std::vector &data) { + auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr}); + return srv->execute_syncronized(&arch_if::write, core, a, data.size(), data.data()); +} + +template +status riscv_target_adapter::process_query(unsigned int &mask, const rp_thread_ref &arg, rp_thread_info &info) { + return NotSupported; +} + +template +status riscv_target_adapter::offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) { + text = 0; + data = 0; + bss = 0; + return Ok; +} + +template status riscv_target_adapter::crc_query(uint64_t addr, size_t len, uint32_t &val) { + return NotSupported; +} + +template status riscv_target_adapter::raw_query(std::string in_buf, std::string &out_buf) { + return NotSupported; +} + +template status riscv_target_adapter::threadinfo_query(int first, std::string &out_buf) { + if (first) { + std::stringstream ss; + ss << "m" << std::hex << thread_idx.val; + out_buf = ss.str(); + } else { + out_buf = "l"; + } + return Ok; +} + +template +status riscv_target_adapter::threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) { + char buf[20]; + memset(buf, 0, 20); + sprintf(buf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x", 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0); + out_buf = buf; + return Ok; +} + +template status riscv_target_adapter::packetsize_query(std::string &out_buf) { + out_buf = "PacketSize=1000"; + return Ok; +} + +template status riscv_target_adapter::add_break(int type, uint64_t addr, unsigned int length) { + auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr}); + auto eaddr = map_addr({iss::CODE, iss::PHYSICAL, addr + length}); + target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val); + LOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex + << saddr.val << std::dec; + LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; + return Ok; +} + +template status riscv_target_adapter::remove_break(int type, uint64_t addr, unsigned int length) { + auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr}); + unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val); + // TODO: check length of addr range + if (handle) { + LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val + << std::dec; + target_adapter_base::bp_lut.removeEntry(handle); + LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; + return Ok; + } + LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; + return Err; +} + +template status riscv_target_adapter::resume_from_addr(bool step, int sig, uint64_t addr) { + unsigned reg_no = arch::traits::PC; + std::vector data(8); + *(reinterpret_cast(&data[0])) = addr; + core->set_reg(reg_no, data); + return resume_from_current(step, sig); +} +} +} + +#endif /* _ISS_DEBUGGER_RISCV_TARGET_ADAPTER_H_ */ diff --git a/riscv/src/CMakeLists.txt b/riscv/src/CMakeLists.txt index 927436b..d7a38c3 100644 --- a/riscv/src/CMakeLists.txt +++ b/riscv/src/CMakeLists.txt @@ -16,8 +16,8 @@ set(APP_SOURCES main.cpp) set(LIBRARY_NAME risc-v) # Define the library -add_library(${LIBRARY_NAME} ${LIB_SOURCES}) - +add_library(${LIBRARY_NAME} SHARED ${LIB_SOURCES}) +SET(${LIBRARY_NAME} -Wl,-whole-archive -l${LIBRARY_NAME} -Wl,-no-whole-archive) set_target_properties(${LIBRARY_NAME} PROPERTIES VERSION ${VERSION} # ${VERSION} was defined in the main CMakeLists. FRAMEWORK FALSE diff --git a/riscv/src/internal/vm_riscv.in.cpp b/riscv/src/internal/vm_riscv.in.cpp index 362ec61..ef5008a 100644 --- a/riscv/src/internal/vm_riscv.in.cpp +++ b/riscv/src/internal/vm_riscv.in.cpp @@ -34,107 +34,24 @@ // //////////////////////////////////////////////////////////////////////////////// -#include +#include +#include #include +#include #include -#include +#include #include -#include "iss/arch/CORE_DEF_NAME.h" -#include "iss/debugger/server.h" -#include "iss/vm_base.h" - -#include "iss/arch/riscv_hart_msu_vp.h" #include +#include + namespace iss { namespace CORE_DEF_NAME { using namespace iss::arch; using namespace llvm; using namespace iss::debugger; -template struct vm_impl; - -template struct target_adapter : public target_adapter_base { - - target_adapter(server_if *srv, vm_impl *vm) : target_adapter_base(srv), vm(vm) {} - - /*============== Thread Control ===============================*/ - - /* Set generic thread */ - status set_gen_thread(rp_thread_ref &thread) override; - - /* Set control thread */ - status set_ctrl_thread(rp_thread_ref &thread) override; - - /* Get thread status */ - status is_thread_alive(rp_thread_ref &thread, bool &alive) override; - - /*============= Register Access ================================*/ - - /* Read all registers. buf is 4-byte aligned and it is in - target byte order. If register is not available - corresponding bytes in avail_buf are 0, otherwise - avail buf is 1 */ - status read_registers(std::vector &data, std::vector &avail) override; - - /* Write all registers. buf is 4-byte aligned and it is in target - byte order */ - status write_registers(const std::vector &data) override; - - /* Read one register. buf is 4-byte aligned and it is in - target byte order. If register is not available - corresponding bytes in avail_buf are 0, otherwise - avail buf is 1 */ - status read_single_register(unsigned int reg_no, std::vector &buf, - std::vector &avail_buf) override; - - /* Write one register. buf is 4-byte aligned and it is in target byte - order */ - status write_single_register(unsigned int reg_no, const std::vector &buf) override; - - /*=================== Memory Access =====================*/ - - /* Read memory, buf is 4-bytes aligned and it is in target - byte order */ - status read_mem(uint64_t addr, std::vector &buf) override; - - /* Write memory, buf is 4-bytes aligned and it is in target - byte order */ - status write_mem(uint64_t addr, const std::vector &buf) override; - - status process_query(unsigned int &mask, const rp_thread_ref &arg, rp_thread_info &info) override; - - status thread_list_query(int first, const rp_thread_ref &arg, std::vector &result, size_t max_num, - size_t &num, bool &done) override; - - status current_thread_query(rp_thread_ref &thread) override; - - status offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) override; - - 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 threadinfo_query(int first, std::string &out_buf) override; - - status threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) override; - - status packetsize_query(std::string &out_buf) override; - - status add_break(int type, uint64_t addr, unsigned int length) override; - - status remove_break(int type, uint64_t addr, unsigned int length) override; - - status resume_from_addr(bool step, int sig, uint64_t addr) override; - -protected: - static inline constexpr addr_t map_addr(const addr_t &i) { return i; } - - vm_impl *vm; - rp_thread_ref thread_idx; -}; - template struct vm_impl : public vm::vm_base { using super = typename vm::vm_base; using virt_addr_t = typename super::virt_addr_t; @@ -151,7 +68,7 @@ template struct vm_impl : public vm::vm_base { target_adapter_if *accquire_target_adapter(server_if *srv) { debugger_if::dbg_enabled = true; if (vm::vm_base::tgt_adapter == nullptr) - vm::vm_base::tgt_adapter = new target_adapter(srv, this); + vm::vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); return vm::vm_base::tgt_adapter; } @@ -326,7 +243,9 @@ template void debug_fn(CODE_WORD insn) { template vm_impl::vm_impl() { this(new ARCH()); } -template vm_impl::vm_impl(ARCH &core, bool dump) : vm::vm_base(core, dump) { +template +vm_impl::vm_impl(ARCH &core, bool dump) +: vm::vm_base(core, dump) { qlut[0] = lut_00.data(); qlut[1] = lut_01.data(); qlut[2] = lut_10.data(); @@ -419,232 +338,25 @@ template inline void vm_impl::gen_trap_check(llvm::BasicBl } // namespace CORE_DEF_NAME -#define CREATE_FUNCS(ARCH) \ - template <> std::unique_ptr create(ARCH * core, unsigned short port, bool dump) { \ - std::unique_ptr> ret = \ - std::make_unique>(*core, dump); \ - debugger::server::run_server(ret.get(), port); \ - return ret; \ - } \ - template <> std::unique_ptr create(std::string inst_name, unsigned short port, bool dump) { \ - return create(new arch::riscv_hart_msu_vp(), port, dump); /* FIXME: memory leak!!!!!!! */ \ - } \ - template <> std::unique_ptr create(ARCH * core, bool dump) { \ - return std::make_unique>(*core, dump); /* FIXME: memory leak!!!!!!! */ \ - } \ - template <> std::unique_ptr create(std::string inst_name, bool dump) { \ - return create(new arch::riscv_hart_msu_vp(), dump); \ - } - -CREATE_FUNCS(arch::CORE_DEF_NAME) - -namespace CORE_DEF_NAME { - -template status target_adapter::set_gen_thread(rp_thread_ref &thread) { - thread_idx = thread; - return Ok; +template <> +std::unique_ptr create(arch::CORE_DEF_NAME *core, unsigned short port, bool dump) { + std::unique_ptr> ret = + std::make_unique>(*core, dump); + debugger::server::run_server(ret.get(), port); + return ret; } -template status target_adapter::set_ctrl_thread(rp_thread_ref &thread) { - thread_idx = thread; - return Ok; +template <> std::unique_ptr create(std::string inst_name, unsigned short port, bool dump) { + return create(new arch::riscv_hart_msu_vp(), port, + dump); /* FIXME: memory leak!!!!!!! */ } -template status target_adapter::is_thread_alive(rp_thread_ref &thread, bool &alive) { - alive = 1; - return Ok; +template <> std::unique_ptr create(arch::CORE_DEF_NAME *core, bool dump) { + return std::make_unique>(*core, dump); /* FIXME: memory leak!!!!!!! */ } -/* List threads. If first is non-zero then start from the first thread, - * otherwise start from arg, result points to array of threads to be - * filled out, result size is number of elements in the result, - * num points to the actual number of threads found, done is - * set if all threads are processed. - */ -template -status target_adapter::thread_list_query(int first, const rp_thread_ref &arg, std::vector &result, - size_t max_num, size_t &num, bool &done) { - if (first == 0) { - result.clear(); - result.push_back(thread_idx); - num = 1; - done = true; - return Ok; - } else - return NotSupported; +template <> std::unique_ptr create(std::string inst_name, bool dump) { + return create(new arch::riscv_hart_msu_vp(), dump); } -template status target_adapter::current_thread_query(rp_thread_ref &thread) { - thread = thread_idx; - return Ok; -} - -template -status target_adapter::read_registers(std::vector &data, std::vector &avail) { - LOG(TRACE) << "reading target registers"; - // return idx<0?:; - data.clear(); - avail.clear(); - const uint8_t* reg_base = vm->get_arch()->get_regs_base_ptr(); - for (size_t reg_no = 0; reg_no < arch::traits::NUM_REGS; ++reg_no) { - auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; - unsigned offset = traits::reg_byte_offset(reg_no); - for (size_t j = 0; j < reg_width; ++j) { - data.push_back(*(reg_base+offset+j)); - avail.push_back(0xff); - } - } - // work around fill with F type registers - if (arch::traits::NUM_REGS < 65) { - auto reg_width = sizeof(typename arch::traits::reg_t); - for (size_t reg_no = 0; reg_no < 33; ++reg_no) { - for (size_t j = 0; j < reg_width; ++j) { - data.push_back(0x0); - avail.push_back(0x00); - } - } - } - return Ok; -} - -template status target_adapter::write_registers(const std::vector &data) { - auto reg_count = arch::traits::NUM_REGS; - auto* reg_base = vm->get_arch()->get_regs_base_ptr(); - auto iter = data.data(); - for (size_t reg_no = 0; reg_no < reg_count; ++reg_no) { - auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; - auto offset = traits::reg_byte_offset(reg_no); - std::copy(iter , iter + reg_width, reg_base); - iter+=4; - reg_base+=offset; - } - return Ok; -} - -template -status target_adapter::read_single_register(unsigned int reg_no, std::vector &data, - std::vector &avail) { - if (reg_no < 65) { - // auto reg_size = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; - auto* reg_base = vm->get_arch()->get_regs_base_ptr(); - auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; - data.resize(reg_width); - avail.resize(reg_width); - auto offset = traits::reg_byte_offset(reg_no); - std::copy(reg_base+offset, reg_base+offset+reg_width, data.begin()); - std::fill(avail.begin(), avail.end(), 0xff); - } else { - typed_addr_t a(iss::DEBUG_READ, traits::CSR, reg_no - 65); - data.resize(sizeof(typename traits::reg_t)); - avail.resize(sizeof(typename traits::reg_t)); - std::fill(avail.begin(), avail.end(), 0xff); - vm->get_arch()->read(a, data.size(), data.data()); - } - return data.size() > 0 ? Ok : Err; -} - -template -status target_adapter::write_single_register(unsigned int reg_no, const std::vector &data) { - if (reg_no < 65){ - auto* reg_base = vm->get_arch()->get_regs_base_ptr(); - auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; - auto offset = traits::reg_byte_offset(reg_no); - std::copy(data.begin(), data.begin() + reg_width, reg_base+offset); - } else { - typed_addr_t a(iss::DEBUG_WRITE, traits::CSR, reg_no - 65); - vm->get_arch()->write(a, data.size(), data.data()); - } - return Ok; -} - -template status target_adapter::read_mem(uint64_t addr, std::vector &data) { - auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr}); - auto f = [&]() -> status { return vm->get_arch()->read(a, data.size(), data.data()); }; - return srv->execute_syncronized(f); -} - -template status target_adapter::write_mem(uint64_t addr, const std::vector &data) { - auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr}); - return srv->execute_syncronized(&arch_if::write, vm->get_arch(), a, data.size(), data.data()); -} - -template -status target_adapter::process_query(unsigned int &mask, const rp_thread_ref &arg, rp_thread_info &info) { - return NotSupported; -} - -template status target_adapter::offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) { - text = 0; - data = 0; - bss = 0; - return Ok; -} - -template status target_adapter::crc_query(uint64_t addr, size_t len, uint32_t &val) { - return NotSupported; -} - -template status target_adapter::raw_query(std::string in_buf, std::string &out_buf) { - return NotSupported; -} - -template status target_adapter::threadinfo_query(int first, std::string &out_buf) { - if (first) { - std::stringstream ss; - ss << "m" << std::hex << thread_idx.val; - out_buf = ss.str(); - } else { - out_buf = "l"; - } - return Ok; -} - -template -status target_adapter::threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) { - char buf[20]; - memset(buf, 0, 20); - sprintf(buf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x", 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0); - out_buf = buf; - return Ok; -} - -template status target_adapter::packetsize_query(std::string &out_buf) { - out_buf = "PacketSize=1000"; - return Ok; -} - -template status target_adapter::add_break(int type, uint64_t addr, unsigned int length) { - auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr}); - auto eaddr = map_addr({iss::CODE, iss::PHYSICAL, addr + length}); - target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val); - LOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex - << saddr.val << std::dec; - LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; - return Ok; -} - -template status target_adapter::remove_break(int type, uint64_t addr, unsigned int length) { - auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr}); - unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val); - // TODO: check length of addr range - if (handle) { - LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val - << std::dec; - target_adapter_base::bp_lut.removeEntry(handle); - LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; - return Ok; - } - LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; - return Err; -} - -template status target_adapter::resume_from_addr(bool step, int sig, uint64_t addr) { - unsigned reg_no = arch::traits::PC; - std::vector data(8); - *(reinterpret_cast(&data[0])) = addr; - vm->get_arch()->set_reg(reg_no, data); - return resume_from_current(step, sig); -} -} // namespace CORE_DEF_NAME } // namespace iss diff --git a/riscv/src/internal/vm_rv32imac.cpp b/riscv/src/internal/vm_rv32imac.cpp index 1d69c8d..949fc4f 100644 --- a/riscv/src/internal/vm_rv32imac.cpp +++ b/riscv/src/internal/vm_rv32imac.cpp @@ -34,107 +34,24 @@ // //////////////////////////////////////////////////////////////////////////////// -#include +#include +#include #include +#include #include -#include +#include #include -#include "iss/arch/rv32imac.h" -#include "iss/debugger/server.h" -#include "iss/vm_base.h" - -#include "iss/arch/riscv_hart_msu_vp.h" #include +#include + namespace iss { namespace rv32imac { using namespace iss::arch; using namespace llvm; using namespace iss::debugger; -template struct vm_impl; - -template struct target_adapter : public target_adapter_base { - - target_adapter(server_if *srv, vm_impl *vm) : target_adapter_base(srv), vm(vm) {} - - /*============== Thread Control ===============================*/ - - /* Set generic thread */ - status set_gen_thread(rp_thread_ref &thread) override; - - /* Set control thread */ - status set_ctrl_thread(rp_thread_ref &thread) override; - - /* Get thread status */ - status is_thread_alive(rp_thread_ref &thread, bool &alive) override; - - /*============= Register Access ================================*/ - - /* Read all registers. buf is 4-byte aligned and it is in - target byte order. If register is not available - corresponding bytes in avail_buf are 0, otherwise - avail buf is 1 */ - status read_registers(std::vector &data, std::vector &avail) override; - - /* Write all registers. buf is 4-byte aligned and it is in target - byte order */ - status write_registers(const std::vector &data) override; - - /* Read one register. buf is 4-byte aligned and it is in - target byte order. If register is not available - corresponding bytes in avail_buf are 0, otherwise - avail buf is 1 */ - status read_single_register(unsigned int reg_no, std::vector &buf, - std::vector &avail_buf) override; - - /* Write one register. buf is 4-byte aligned and it is in target byte - order */ - status write_single_register(unsigned int reg_no, const std::vector &buf) override; - - /*=================== Memory Access =====================*/ - - /* Read memory, buf is 4-bytes aligned and it is in target - byte order */ - status read_mem(uint64_t addr, std::vector &buf) override; - - /* Write memory, buf is 4-bytes aligned and it is in target - byte order */ - status write_mem(uint64_t addr, const std::vector &buf) override; - - status process_query(unsigned int &mask, const rp_thread_ref &arg, rp_thread_info &info) override; - - status thread_list_query(int first, const rp_thread_ref &arg, std::vector &result, size_t max_num, - size_t &num, bool &done) override; - - status current_thread_query(rp_thread_ref &thread) override; - - status offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) override; - - 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 threadinfo_query(int first, std::string &out_buf) override; - - status threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) override; - - status packetsize_query(std::string &out_buf) override; - - status add_break(int type, uint64_t addr, unsigned int length) override; - - status remove_break(int type, uint64_t addr, unsigned int length) override; - - status resume_from_addr(bool step, int sig, uint64_t addr) override; - -protected: - static inline constexpr addr_t map_addr(const addr_t &i) { return i; } - - vm_impl *vm; - rp_thread_ref thread_idx; -}; - template struct vm_impl : public vm::vm_base { using super = typename vm::vm_base; using virt_addr_t = typename super::virt_addr_t; @@ -151,7 +68,7 @@ template struct vm_impl : public vm::vm_base { target_adapter_if *accquire_target_adapter(server_if *srv) { debugger_if::dbg_enabled = true; if (vm::vm_base::tgt_adapter == nullptr) - vm::vm_base::tgt_adapter = new target_adapter(srv, this); + vm::vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); return vm::vm_base::tgt_adapter; } @@ -3999,7 +3916,9 @@ template void debug_fn(CODE_WORD insn) { template vm_impl::vm_impl() { this(new ARCH()); } -template vm_impl::vm_impl(ARCH &core, bool dump) : vm::vm_base(core, dump) { +template +vm_impl::vm_impl(ARCH &core, bool dump) +: vm::vm_base(core, dump) { qlut[0] = lut_00.data(); qlut[1] = lut_01.data(); qlut[2] = lut_10.data(); @@ -4092,232 +4011,24 @@ template inline void vm_impl::gen_trap_check(llvm::BasicBl } // namespace rv32imac -#define CREATE_FUNCS(ARCH) \ - template <> std::unique_ptr create(ARCH * core, unsigned short port, bool dump) { \ - std::unique_ptr> ret = \ - std::make_unique>(*core, dump); \ - debugger::server::run_server(ret.get(), port); \ - return ret; \ - } \ - template <> std::unique_ptr create(std::string inst_name, unsigned short port, bool dump) { \ - return create(new arch::riscv_hart_msu_vp(), port, dump); /* FIXME: memory leak!!!!!!! */ \ - } \ - template <> std::unique_ptr create(ARCH * core, bool dump) { \ - return std::make_unique>(*core, dump); /* FIXME: memory leak!!!!!!! */ \ - } \ - template <> std::unique_ptr create(std::string inst_name, bool dump) { \ - return create(new arch::riscv_hart_msu_vp(), dump); \ - } - -CREATE_FUNCS(arch::rv32imac) - -namespace rv32imac { - -template status target_adapter::set_gen_thread(rp_thread_ref &thread) { - thread_idx = thread; - return Ok; +template <> std::unique_ptr create(arch::rv32imac *core, unsigned short port, bool dump) { + std::unique_ptr> ret = + std::make_unique>(*core, dump); + debugger::server::run_server(ret.get(), port); + return ret; } -template status target_adapter::set_ctrl_thread(rp_thread_ref &thread) { - thread_idx = thread; - return Ok; +template <> std::unique_ptr create(std::string inst_name, unsigned short port, bool dump) { + return create(new arch::riscv_hart_msu_vp(), port, + dump); /* FIXME: memory leak!!!!!!! */ } -template status target_adapter::is_thread_alive(rp_thread_ref &thread, bool &alive) { - alive = 1; - return Ok; +template <> std::unique_ptr create(arch::rv32imac *core, bool dump) { + return std::make_unique>(*core, dump); /* FIXME: memory leak!!!!!!! */ } -/* List threads. If first is non-zero then start from the first thread, - * otherwise start from arg, result points to array of threads to be - * filled out, result size is number of elements in the result, - * num points to the actual number of threads found, done is - * set if all threads are processed. - */ -template -status target_adapter::thread_list_query(int first, const rp_thread_ref &arg, std::vector &result, - size_t max_num, size_t &num, bool &done) { - if (first == 0) { - result.clear(); - result.push_back(thread_idx); - num = 1; - done = true; - return Ok; - } else - return NotSupported; +template <> std::unique_ptr create(std::string inst_name, bool dump) { + return create(new arch::riscv_hart_msu_vp(), dump); } -template status target_adapter::current_thread_query(rp_thread_ref &thread) { - thread = thread_idx; - return Ok; -} - -template -status target_adapter::read_registers(std::vector &data, std::vector &avail) { - LOG(TRACE) << "reading target registers"; - // return idx<0?:; - data.clear(); - avail.clear(); - const uint8_t* reg_base = vm->get_arch()->get_regs_base_ptr(); - for (size_t reg_no = 0; reg_no < arch::traits::NUM_REGS; ++reg_no) { - auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; - unsigned offset = traits::reg_byte_offset(reg_no); - for (size_t j = 0; j < reg_width; ++j) { - data.push_back(*(reg_base+offset+j)); - avail.push_back(0xff); - } - } - // work around fill with F type registers - if (arch::traits::NUM_REGS < 65) { - auto reg_width = sizeof(typename arch::traits::reg_t); - for (size_t reg_no = 0; reg_no < 33; ++reg_no) { - for (size_t j = 0; j < reg_width; ++j) { - data.push_back(0x0); - avail.push_back(0x00); - } - } - } - return Ok; -} - -template status target_adapter::write_registers(const std::vector &data) { - auto reg_count = arch::traits::NUM_REGS; - auto* reg_base = vm->get_arch()->get_regs_base_ptr(); - auto iter = data.data(); - for (size_t reg_no = 0; reg_no < reg_count; ++reg_no) { - auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; - auto offset = traits::reg_byte_offset(reg_no); - std::copy(iter , iter + reg_width, reg_base); - iter+=4; - reg_base+=offset; - } - return Ok; -} - -template -status target_adapter::read_single_register(unsigned int reg_no, std::vector &data, - std::vector &avail) { - if (reg_no < 65) { - // auto reg_size = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; - auto* reg_base = vm->get_arch()->get_regs_base_ptr(); - auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; - data.resize(reg_width); - avail.resize(reg_width); - auto offset = traits::reg_byte_offset(reg_no); - std::copy(reg_base+offset, reg_base+offset+reg_width, data.begin()); - std::fill(avail.begin(), avail.end(), 0xff); - } else { - typed_addr_t a(iss::DEBUG_READ, traits::CSR, reg_no - 65); - data.resize(sizeof(typename traits::reg_t)); - avail.resize(sizeof(typename traits::reg_t)); - std::fill(avail.begin(), avail.end(), 0xff); - vm->get_arch()->read(a, data.size(), data.data()); - } - return data.size() > 0 ? Ok : Err; -} - -template -status target_adapter::write_single_register(unsigned int reg_no, const std::vector &data) { - if (reg_no < 65){ - auto* reg_base = vm->get_arch()->get_regs_base_ptr(); - auto reg_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; - auto offset = traits::reg_byte_offset(reg_no); - std::copy(data.begin(), data.begin() + reg_width, reg_base+offset); - } else { - typed_addr_t a(iss::DEBUG_WRITE, traits::CSR, reg_no - 65); - vm->get_arch()->write(a, data.size(), data.data()); - } - return Ok; -} - -template status target_adapter::read_mem(uint64_t addr, std::vector &data) { - auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr}); - auto f = [&]() -> status { return vm->get_arch()->read(a, data.size(), data.data()); }; - return srv->execute_syncronized(f); -} - -template status target_adapter::write_mem(uint64_t addr, const std::vector &data) { - auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr}); - return srv->execute_syncronized(&arch_if::write, vm->get_arch(), a, data.size(), data.data()); -} - -template -status target_adapter::process_query(unsigned int &mask, const rp_thread_ref &arg, rp_thread_info &info) { - return NotSupported; -} - -template status target_adapter::offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) { - text = 0; - data = 0; - bss = 0; - return Ok; -} - -template status target_adapter::crc_query(uint64_t addr, size_t len, uint32_t &val) { - return NotSupported; -} - -template status target_adapter::raw_query(std::string in_buf, std::string &out_buf) { - return NotSupported; -} - -template status target_adapter::threadinfo_query(int first, std::string &out_buf) { - if (first) { - std::stringstream ss; - ss << "m" << std::hex << thread_idx.val; - out_buf = ss.str(); - } else { - out_buf = "l"; - } - return Ok; -} - -template -status target_adapter::threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) { - char buf[20]; - memset(buf, 0, 20); - sprintf(buf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x", 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0); - out_buf = buf; - return Ok; -} - -template status target_adapter::packetsize_query(std::string &out_buf) { - out_buf = "PacketSize=1000"; - return Ok; -} - -template status target_adapter::add_break(int type, uint64_t addr, unsigned int length) { - auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr}); - auto eaddr = map_addr({iss::CODE, iss::PHYSICAL, addr + length}); - target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val); - LOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex - << saddr.val << std::dec; - LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; - return Ok; -} - -template status target_adapter::remove_break(int type, uint64_t addr, unsigned int length) { - auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr}); - unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val); - // TODO: check length of addr range - if (handle) { - LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val - << std::dec; - target_adapter_base::bp_lut.removeEntry(handle); - LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; - return Ok; - } - LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; - return Err; -} - -template status target_adapter::resume_from_addr(bool step, int sig, uint64_t addr) { - unsigned reg_no = arch::traits::PC; - std::vector data(8); - *(reinterpret_cast(&data[0])) = addr; - vm->get_arch()->set_reg(reg_no, data); - return resume_from_current(step, sig); -} -} // namespace rv32imac } // namespace iss diff --git a/riscv/src/internal/vm_rv64ia.cpp b/riscv/src/internal/vm_rv64ia.cpp index 6d55e51..1262182 100644 --- a/riscv/src/internal/vm_rv64ia.cpp +++ b/riscv/src/internal/vm_rv64ia.cpp @@ -34,107 +34,24 @@ // //////////////////////////////////////////////////////////////////////////////// -#include +#include +#include #include +#include #include -#include +#include #include -#include "iss/arch/rv64ia.h" -#include "iss/debugger/server.h" -#include "iss/vm_base.h" - -#include "iss/arch/riscv_hart_msu_vp.h" #include +#include + namespace iss { namespace rv64ia { using namespace iss::arch; using namespace llvm; using namespace iss::debugger; -template struct vm_impl; - -template struct target_adapter : public target_adapter_base { - - target_adapter(server_if *srv, vm_impl *vm) : target_adapter_base(srv), vm(vm) {} - - /*============== Thread Control ===============================*/ - - /* Set generic thread */ - status set_gen_thread(rp_thread_ref &thread) override; - - /* Set control thread */ - status set_ctrl_thread(rp_thread_ref &thread) override; - - /* Get thread status */ - status is_thread_alive(rp_thread_ref &thread, bool &alive) override; - - /*============= Register Access ================================*/ - - /* Read all registers. buf is 4-byte aligned and it is in - target byte order. If register is not available - corresponding bytes in avail_buf are 0, otherwise - avail buf is 1 */ - status read_registers(std::vector &data, std::vector &avail) override; - - /* Write all registers. buf is 4-byte aligned and it is in target - byte order */ - status write_registers(const std::vector &data) override; - - /* Read one register. buf is 4-byte aligned and it is in - target byte order. If register is not available - corresponding bytes in avail_buf are 0, otherwise - avail buf is 1 */ - status read_single_register(unsigned int reg_no, std::vector &buf, - std::vector &avail_buf) override; - - /* Write one register. buf is 4-byte aligned and it is in target byte - order */ - status write_single_register(unsigned int reg_no, const std::vector &buf) override; - - /*=================== Memory Access =====================*/ - - /* Read memory, buf is 4-bytes aligned and it is in target - byte order */ - status read_mem(uint64_t addr, std::vector &buf) override; - - /* Write memory, buf is 4-bytes aligned and it is in target - byte order */ - status write_mem(uint64_t addr, const std::vector &buf) override; - - status process_query(unsigned int &mask, const rp_thread_ref &arg, rp_thread_info &info) override; - - status thread_list_query(int first, const rp_thread_ref &arg, std::vector &result, size_t max_num, - size_t &num, bool &done) override; - - status current_thread_query(rp_thread_ref &thread) override; - - status offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) override; - - 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 threadinfo_query(int first, std::string &out_buf) override; - - status threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) override; - - status packetsize_query(std::string &out_buf) override; - - status add_break(int type, uint64_t addr, unsigned int length) override; - - status remove_break(int type, uint64_t addr, unsigned int length) override; - - status resume_from_addr(bool step, int sig, uint64_t addr) override; - -protected: - static inline constexpr addr_t map_addr(const addr_t &i) { return i; } - - vm_impl *vm; - rp_thread_ref thread_idx; -}; - template struct vm_impl : public vm::vm_base { using super = typename vm::vm_base; using virt_addr_t = typename super::virt_addr_t; @@ -151,7 +68,7 @@ template struct vm_impl : public vm::vm_base { target_adapter_if *accquire_target_adapter(server_if *srv) { debugger_if::dbg_enabled = true; if (vm::vm_base::tgt_adapter == nullptr) - vm::vm_base::tgt_adapter = new target_adapter(srv, this); + vm::vm_base::tgt_adapter = new riscv_target_adapter(srv, this->get_arch()); return vm::vm_base::tgt_adapter; } @@ -3087,7 +3004,9 @@ template void debug_fn(CODE_WORD insn) { template vm_impl::vm_impl() { this(new ARCH()); } -template vm_impl::vm_impl(ARCH &core, bool dump) : vm::vm_base(core, dump) { +template +vm_impl::vm_impl(ARCH &core, bool dump) +: vm::vm_base(core, dump) { qlut[0] = lut_00.data(); qlut[1] = lut_01.data(); qlut[2] = lut_10.data(); @@ -3180,227 +3099,23 @@ template inline void vm_impl::gen_trap_check(llvm::BasicBl } // namespace rv64ia -#define CREATE_FUNCS(ARCH) \ - template <> std::unique_ptr create(ARCH * core, unsigned short port, bool dump) { \ - std::unique_ptr> ret = std::make_unique>(*core, dump); \ - debugger::server::run_server(ret.get(), port); \ - return ret; \ - } \ - template <> std::unique_ptr create(std::string inst_name, unsigned short port, bool dump) { \ - return create(new arch::riscv_hart_msu_vp(), port, dump); /* FIXME: memory leak!!!!!!! */ \ - } \ - template <> std::unique_ptr create(ARCH * core, bool dump) { \ - return std::make_unique>(*core, dump); /* FIXME: memory leak!!!!!!! */ \ - } \ - template <> std::unique_ptr create(std::string inst_name, bool dump) { \ - return create(new arch::riscv_hart_msu_vp(), dump); \ - } - -CREATE_FUNCS(arch::rv64ia) - -namespace rv64ia { - -template status target_adapter::set_gen_thread(rp_thread_ref &thread) { - thread_idx = thread; - return Ok; +template <> std::unique_ptr create(arch::rv64ia *core, unsigned short port, bool dump) { + std::unique_ptr> ret = std::make_unique>(*core, dump); + debugger::server::run_server(ret.get(), port); + return ret; } -template status target_adapter::set_ctrl_thread(rp_thread_ref &thread) { - thread_idx = thread; - return Ok; +template <> std::unique_ptr create(std::string inst_name, unsigned short port, bool dump) { + return create(new arch::riscv_hart_msu_vp(), port, + dump); /* FIXME: memory leak!!!!!!! */ } -template status target_adapter::is_thread_alive(rp_thread_ref &thread, bool &alive) { - alive = 1; - return Ok; +template <> std::unique_ptr create(arch::rv64ia *core, bool dump) { + return std::make_unique>(*core, dump); /* FIXME: memory leak!!!!!!! */ } -/* List threads. If first is non-zero then start from the first thread, - * otherwise start from arg, result points to array of threads to be - * filled out, result size is number of elements in the result, - * num points to the actual number of threads found, done is - * set if all threads are processed. - */ -template -status target_adapter::thread_list_query(int first, const rp_thread_ref &arg, std::vector &result, - size_t max_num, size_t &num, bool &done) { - if (first == 0) { - result.clear(); - result.push_back(thread_idx); - num = 1; - done = true; - return Ok; - } else - return NotSupported; +template <> std::unique_ptr create(std::string inst_name, bool dump) { + return create(new arch::riscv_hart_msu_vp(), dump); } -template status target_adapter::current_thread_query(rp_thread_ref &thread) { - thread = thread_idx; - return Ok; -} - -template -status target_adapter::read_registers(std::vector &data, std::vector &avail) { - LOG(TRACE) << "reading target registers"; - // return idx<0?:; - data.clear(); - avail.clear(); - std::vector reg_data; - for (size_t reg_no = 0; reg_no < arch::traits::NUM_REGS; ++reg_no) { - auto reg_bit_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no)); - auto reg_width = reg_bit_width / 8; - reg_data.resize(reg_width); - vm->get_arch()->get_reg(reg_no, reg_data); - for (size_t j = 0; j < reg_data.size(); ++j) { - data.push_back(reg_data[j]); - avail.push_back(0xff); - } - } - // work around fill with F type registers - if (arch::traits::NUM_REGS < 65) { - auto reg_width = sizeof(typename arch::traits::reg_t); - for (size_t reg_no = 0; reg_no < 33; ++reg_no) { - for (size_t j = 0; j < reg_width; ++j) { - data.push_back(0x0); - avail.push_back(0x00); - } - } - } - return Ok; -} - -template status target_adapter::write_registers(const std::vector &data) { - size_t data_index = 0; - auto reg_count = arch::traits::NUM_REGS; - std::vector reg_data; - for (size_t reg_no = 0; reg_no < reg_count; ++reg_no) { - auto reg_bit_width = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no)); - auto reg_width = reg_bit_width / 8; - vm->get_arch()->set_reg(reg_no, - std::vector(data.begin() + data_index, data.begin() + data_index + reg_width)); - data_index += reg_width; - } - return Ok; -} - -template -status target_adapter::read_single_register(unsigned int reg_no, std::vector &data, - std::vector &avail) { - if (reg_no < 65) { - // auto reg_size = arch::traits::reg_bit_width(static_cast::reg_e>(reg_no))/8; - data.resize(0); - vm->get_arch()->get_reg(reg_no, data); - avail.resize(data.size()); - std::fill(avail.begin(), avail.end(), 0xff); - } else { - typed_addr_t a(iss::DEBUG_READ, traits::CSR, reg_no - 65); - data.resize(sizeof(typename traits::reg_t)); - avail.resize(sizeof(typename traits::reg_t)); - std::fill(avail.begin(), avail.end(), 0xff); - vm->get_arch()->read(a, data.size(), data.data()); - } - return data.size() > 0 ? Ok : Err; -} - -template -status target_adapter::write_single_register(unsigned int reg_no, const std::vector &data) { - if (reg_no < 65) - vm->get_arch()->set_reg(reg_no, data); - else { - typed_addr_t a(iss::DEBUG_WRITE, traits::CSR, reg_no - 65); - vm->get_arch()->write(a, data.size(), data.data()); - } - return Ok; -} - -template status target_adapter::read_mem(uint64_t addr, std::vector &data) { - auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr}); - auto f = [&]() -> status { return vm->get_arch()->read(a, data.size(), data.data()); }; - return srv->execute_syncronized(f); -} - -template status target_adapter::write_mem(uint64_t addr, const std::vector &data) { - auto a = map_addr({iss::DEBUG_READ, iss::VIRTUAL, 0, addr}); - return srv->execute_syncronized(&arch_if::write, vm->get_arch(), a, data.size(), data.data()); -} - -template -status target_adapter::process_query(unsigned int &mask, const rp_thread_ref &arg, rp_thread_info &info) { - return NotSupported; -} - -template status target_adapter::offsets_query(uint64_t &text, uint64_t &data, uint64_t &bss) { - text = 0; - data = 0; - bss = 0; - return Ok; -} - -template status target_adapter::crc_query(uint64_t addr, size_t len, uint32_t &val) { - return NotSupported; -} - -template status target_adapter::raw_query(std::string in_buf, std::string &out_buf) { - return NotSupported; -} - -template status target_adapter::threadinfo_query(int first, std::string &out_buf) { - if (first) { - std::stringstream ss; - ss << "m" << std::hex << thread_idx.val; - out_buf = ss.str(); - } else { - out_buf = "l"; - } - return Ok; -} - -template -status target_adapter::threadextrainfo_query(const rp_thread_ref &thread, std::string &out_buf) { - char buf[20]; - memset(buf, 0, 20); - sprintf(buf, "%02x%02x%02x%02x%02x%02x%02x%02x%02x", 'R', 'u', 'n', 'n', 'a', 'b', 'l', 'e', 0); - out_buf = buf; - return Ok; -} - -template status target_adapter::packetsize_query(std::string &out_buf) { - out_buf = "PacketSize=1000"; - return Ok; -} - -template status target_adapter::add_break(int type, uint64_t addr, unsigned int length) { - auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr}); - auto eaddr = map_addr({iss::CODE, iss::PHYSICAL, addr + length}); - target_adapter_base::bp_lut.addEntry(++target_adapter_base::bp_count, saddr.val, eaddr.val - saddr.val); - LOG(TRACE) << "Adding breakpoint with handle " << target_adapter_base::bp_count << " for addr 0x" << std::hex - << saddr.val << std::dec; - LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; - return Ok; -} - -template status target_adapter::remove_break(int type, uint64_t addr, unsigned int length) { - auto saddr = map_addr({iss::CODE, iss::PHYSICAL, addr}); - unsigned handle = target_adapter_base::bp_lut.getEntry(saddr.val); - // TODO: check length of addr range - if (handle) { - LOG(TRACE) << "Removing breakpoint with handle " << handle << " for addr 0x" << std::hex << saddr.val - << std::dec; - target_adapter_base::bp_lut.removeEntry(handle); - LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; - return Ok; - } - LOG(TRACE) << "Now having " << target_adapter_base::bp_lut.size() << " breakpoints"; - return Err; -} - -template status target_adapter::resume_from_addr(bool step, int sig, uint64_t addr) { - unsigned reg_no = arch::traits::PC; - std::vector data(8); - *(reinterpret_cast(&data[0])) = addr; - vm->get_arch()->set_reg(reg_no, data); - return resume_from_current(step, sig); -} -} // namespace rv64ia } // namespace iss diff --git a/sc-components b/sc-components index cab7505..3693b05 160000 --- a/sc-components +++ b/sc-components @@ -1 +1 @@ -Subproject commit cab7505af9f4093a93d7e41c519ad937bdc60f81 +Subproject commit 3693b0553602337f702753e208329d0e2a4f99c3