diff --git a/CMakeLists.txt b/CMakeLists.txt index 0414294..a9d5943 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 8f181e19e14e3fe5cfba340b47795c7b48b7844a + GIT_TAG 5d1ab03db17819fc113d3c4182cf0cee666085f2 GIT_SHALLOW OFF UPDATE_DISCONNECTED NOT ${UPDATE_EXTERNAL_PROJECT} # When enabled, this option causes the update step to be skipped. ) diff --git a/src/iss/debugger/riscv_target_adapter.h b/src/iss/debugger/riscv_target_adapter.h index be2b75b..64988d4 100644 --- a/src/iss/debugger/riscv_target_adapter.h +++ b/src/iss/debugger/riscv_target_adapter.h @@ -80,6 +80,8 @@ template class riscv_target_adapter : public target_adapter_base avail buf is 1 */ status read_registers(std::vector& data, std::vector& avail) override; + status trigger_debugger_stop_event() override; + /* Write all registers. buf is 4-byte aligned and it is in target byte order */ status write_registers(const std::vector& data) override; @@ -183,6 +185,10 @@ template status riscv_target_adapter::current_thread_query return Ok; } +template status riscv_target_adapter::trigger_debugger_stop_event() { + core->cancel_wait(); + return Ok; +} template status riscv_target_adapter::read_registers(std::vector& data, std::vector& avail) { CPPLOG(TRACE) << "reading target registers"; data.clear(); diff --git a/src/sysc/core2sc_adapter.h b/src/sysc/core2sc_adapter.h index 09eba47..5f1e38a 100644 --- a/src/sysc/core2sc_adapter.h +++ b/src/sysc/core2sc_adapter.h @@ -255,13 +255,24 @@ template class core2sc_adapter : public PLAT, public sc2core_if void wait_until(uint64_t flags) { SCCDEBUG(owner->hier_name()) << "Sleeping until interrupt"; PLAT::wait_until(flags); + wfi_inst.store(true, std::memory_order_relaxed); std::function f = [this]() { while((this->csr[iss::arch::mip] & this->csr[iss::arch::mie]) == 0) { - sc_core::wait(this->wfi_evt); + sc_core::wait(this->wfi_evt | this->debugger_stop_evt); + bool is_debugger_stop_evt = this->debugger_stop_evt.triggered(); + if(is_debugger_stop_evt) break; } SCCINFO(this->owner->hier_name()) << "Got WFI event"; }; owner->exec_on_sysc(f); + wfi_inst.store(false, std::memory_order_relaxed); + } + + void cancel_wait() { + if(wfi_inst.load(std::memory_order_relaxed) == true) { + SCCDEBUG(owner->hier_name()) << "Trigger debugger stop event"; + this->debugger_stop_evt.notify(sc_core::SC_ZERO_TIME); + } } private: @@ -344,8 +355,10 @@ template class core2sc_adapter : public PLAT, public sc2core_if sysc::riscv::core_complex_if* const owner{nullptr}; util::LoggerDelegate log_delegate; sc_core::sc_event wfi_evt; + sc_core::sc_event debugger_stop_evt; unsigned to_host_wr_cnt = 0; bool first{true}; + std::atomic wfi_inst{false}; mutex_t sync_mtx; }; } // namespace sysc