Skip to content

Commit ad01da6

Browse files
committed
WFI: Reacquire control of the core in the debugger after it executes a WFI instruction.
A new gdb_stop_evt event was added, triggered when the debugger issues a stop request. The thread now waits on wfi_evt or gdb_stop_evt (SystemC OR event list). After waking, it checks whether gdb_stop_evt triggered; if so, it exits the loop immediately.
1 parent 0521018 commit ad01da6

File tree

2 files changed

+20
-1
lines changed

2 files changed

+20
-1
lines changed

src/iss/debugger/riscv_target_adapter.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,8 @@ template <typename ARCH> class riscv_target_adapter : public target_adapter_base
8080
avail buf is 1 */
8181
status read_registers(std::vector<uint8_t>& data, std::vector<uint8_t>& avail) override;
8282

83+
status trigger_debugger_stop_event() override;
84+
8385
/* Write all registers. buf is 4-byte aligned and it is in target
8486
byte order */
8587
status write_registers(const std::vector<uint8_t>& data) override;
@@ -183,6 +185,10 @@ template <typename ARCH> status riscv_target_adapter<ARCH>::current_thread_query
183185
return Ok;
184186
}
185187

188+
template <typename ARCH> status riscv_target_adapter<ARCH>::trigger_debugger_stop_event() {
189+
core->cancel_wait();
190+
return Ok;
191+
}
186192
template <typename ARCH> status riscv_target_adapter<ARCH>::read_registers(std::vector<uint8_t>& data, std::vector<uint8_t>& avail) {
187193
CPPLOG(TRACE) << "reading target registers";
188194
data.clear();

src/sysc/core2sc_adapter.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,13 +244,24 @@ template <typename PLAT> class core2sc_adapter : public PLAT, public sc2core_if
244244
void wait_until(uint64_t flags) {
245245
SCCDEBUG(owner->hier_name()) << "Sleeping until interrupt";
246246
PLAT::wait_until(flags);
247+
wfi_inst.store(true, std::memory_order_relaxed);
247248
std::function<void(void)> f = [this]() {
248249
while((this->csr[iss::arch::mip] & this->csr[iss::arch::mie]) == 0) {
249-
sc_core::wait(this->wfi_evt);
250+
sc_core::wait(this->wfi_evt | this->debugger_stop_evt);
251+
bool is_debugger_stop_evt = this->debugger_stop_evt.triggered();
252+
if(is_debugger_stop_evt) break;
250253
}
251254
SCCINFO(this->owner->hier_name()) << "Got WFI event";
252255
};
253256
owner->exec_on_sysc(f);
257+
wfi_inst.store(false, std::memory_order_relaxed);
258+
}
259+
260+
void cancel_wait() {
261+
if(wfi_inst.load(std::memory_order_relaxed) == true) {
262+
SCCDEBUG(owner->hier_name()) << "Trigger debugger stop event";
263+
this->debugger_stop_evt.notify(sc_core::SC_ZERO_TIME);
264+
}
254265
}
255266

256267
private:
@@ -338,8 +349,10 @@ template <typename PLAT> class core2sc_adapter : public PLAT, public sc2core_if
338349
util::LoggerDelegate log_delegate;
339350
util::LoggerDelegate disass_delegate;
340351
sc_core::sc_event wfi_evt;
352+
sc_core::sc_event debugger_stop_evt;
341353
unsigned to_host_wr_cnt = 0;
342354
bool first{true};
355+
std::atomic<bool> wfi_inst{false};
343356
mutex_t sync_mtx;
344357
};
345358
} // namespace sysc

0 commit comments

Comments
 (0)