From 026ad213a88fad997fb65444b798eb551e2a7c21 Mon Sep 17 00:00:00 2001 From: Eyck Jentzsch Date: Mon, 9 Oct 2017 22:52:19 +0200 Subject: [PATCH] Added custom rcmd to use with gdb 'monitor' command. Currently implemented are 2 commands: monitor sysc print_time monitor sysc break 1 us --- riscv.sc/incl/sysc/SiFive/core_complex.h | 4 ++ riscv.sc/src/sysc/core_complex.cpp | 61 +++++++++++++++++++++--- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/riscv.sc/incl/sysc/SiFive/core_complex.h b/riscv.sc/incl/sysc/SiFive/core_complex.h index 824032c..816b0cf 100644 --- a/riscv.sc/incl/sysc/SiFive/core_complex.h +++ b/riscv.sc/incl/sysc/SiFive/core_complex.h @@ -50,6 +50,9 @@ class vm_if; namespace arch { template struct riscv_hart_msu_vp; } +namespace debugger { +struct target_adapter_if; +} } namespace sysc { @@ -120,6 +123,7 @@ protected: std::unique_ptr cpu; std::unique_ptr vm; sc_core::sc_time curr_clk; + iss::debugger::target_adapter_if* tgt_adapter; }; } /* namespace SiFive */ diff --git a/riscv.sc/src/sysc/core_complex.cpp b/riscv.sc/src/sysc/core_complex.cpp index 67d7fa3..421af5a 100644 --- a/riscv.sc/src/sysc/core_complex.cpp +++ b/riscv.sc/src/sysc/core_complex.cpp @@ -34,17 +34,24 @@ // //////////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include - #include "scc/report.h" +#include "iss/arch/riscv_hart_msu_vp.h" +#include "iss/arch/rv32imac.h" +#include "iss/iss.h" +#include "iss/vm_types.h" +#include "iss/debugger/server.h" +#include "iss/debugger/gdb_session.h" +#include "iss/debugger/target_adapter_if.h" +#include "iss/debugger/encoderdecoder.h" +#include "sysc/SiFive/core_complex.h" + namespace sysc { namespace SiFive { +namespace { +iss::debugger::encoder_decoder encdec; +} class core_wrapper : public iss::arch::riscv_hart_msu_vp { public: using core_type = iss::arch::rv32imac; @@ -73,6 +80,36 @@ private: core_complex *const owner; }; +int cmd_sysc(int argc, char* argv[], iss::debugger::out_func of, iss::debugger::data_func df, iss::debugger::target_adapter_if* tgt_adapter){ + if(argc>1) { + if(strcasecmp(argv[1], "print_time")==0){ + std::string t = sc_core::sc_time_stamp().to_string(); + of(t.c_str()); + char buf[64]; + encdec.enc_string(t.c_str(), buf, 63); + df(buf); + return iss::Ok; + } else if(strcasecmp(argv[1], "break")==0){ + sc_core::sc_time t; + if(argc==4){ + t= scc::parse_from_string(argv[2], argv[3]); + } else if(argc==3){ + t= scc::parse_from_string(argv[2]); + } else + return iss::Err; + // no check needed as it is only called if debug server is active + tgt_adapter->add_break_condition([t]()->unsigned{ + LOG(TRACE)<<"Checking condition at "<=t?std::numeric_limits::max():0; + }); + return iss::Ok; + } + return iss::Err; + } + return iss::Err; + +} + void core_wrapper::notify_phase(exec_phase phase) { core_type::notify_phase(phase); if (phase == ISTART) owner->sync(); @@ -89,7 +126,8 @@ core_complex::core_complex(sc_core::sc_module_name name) , NAMED(gdb_server_port, 0, this) , NAMED(dump_ir, false, this) , read_lut(tlm_dmi_ext()) -, write_lut(tlm_dmi_ext()) { +, write_lut(tlm_dmi_ext()) +, tgt_adapter(nullptr){ initiator.register_invalidate_direct_mem_ptr([=](uint64_t start, uint64_t end) -> void { auto lut_entry = read_lut.getEntry(start); @@ -115,6 +153,15 @@ void core_complex::before_end_of_elaboration() { cpu = std::make_unique(this); vm = iss::create(cpu.get(), gdb_server_port.value, dump_ir.value); vm->setDisassEnabled(enable_disass.value); + auto* srv = iss::debugger::server::get(); + if(srv) tgt_adapter = srv->get_target(); + if(tgt_adapter) + tgt_adapter->add_custom_command({ + "sysc", + [this](int argc, char* argv[], iss::debugger::out_func of, iss::debugger::data_func df)-> int { + return cmd_sysc(argc, argv, of, df, tgt_adapter); + }, + "SystemC sub-commands: break