Implement WFI in rvcpp. The umode_wfi test still does not pass, because it relies on a bug in Hazard3 (mstatus.mie disables IRQs in U-mode as well as M-mode, but is supposed to be ignored in U-mode).
This commit is contained in:
parent
78260e86e7
commit
194c9a9052
|
@ -13,6 +13,7 @@ struct RVCore {
|
|||
RVCSR csr;
|
||||
bool load_reserved;
|
||||
MemBase32 &mem;
|
||||
bool stalled_on_wfi;
|
||||
|
||||
// A single flat RAM is handled as a special case, in addition to whatever
|
||||
// is in `mem`, because this avoids virtual calls for the majority of
|
||||
|
@ -27,6 +28,7 @@ struct RVCore {
|
|||
std::fill(std::begin(regs), std::end(regs), 0);
|
||||
pc = reset_vector;
|
||||
load_reserved = false;
|
||||
stalled_on_wfi = false;
|
||||
ram_base = ram_base_;
|
||||
ram_top = ram_base_ + ram_size_;
|
||||
ram = new ux_t[ram_size_ / sizeof(ux_t)];
|
||||
|
|
|
@ -112,6 +112,10 @@ public:
|
|||
return priv;
|
||||
}
|
||||
|
||||
bool get_mstatus_tw() {
|
||||
return mstatus & 0x00200000u;
|
||||
}
|
||||
|
||||
void set_irq_t(bool irq) {
|
||||
irq_t = irq;
|
||||
}
|
||||
|
|
|
@ -151,6 +151,10 @@ void RVCore::step(bool trace) {
|
|||
std::optional<ux_t> irq_target_pc = csr.trap_check_enter_irq(pc);
|
||||
if (irq_target_pc) {
|
||||
// Replace current instruction with IRQ entry
|
||||
stalled_on_wfi = false;
|
||||
} else if (stalled_on_wfi) {
|
||||
// Replace current instruction with jump-to-self
|
||||
pc_wdata = pc;
|
||||
} else if (!fetch0 || ((*fetch0 & 0x3) == 0x3 && (!fetch1 || pmp_straddle))) {
|
||||
exception_cause = XCAUSE_INSTR_FAULT;
|
||||
} else if ((instr & 0x3) == 0x3) {
|
||||
|
@ -588,6 +592,12 @@ void RVCore::step(bool trace) {
|
|||
exception_cause = XCAUSE_ECALL_U + csr.get_true_priv();
|
||||
} else if (RVOPC_MATCH(instr, EBREAK)) {
|
||||
exception_cause = XCAUSE_EBREAK;
|
||||
} else if (RVOPC_MATCH(instr, WFI)) {
|
||||
if (csr.get_true_priv() == PRV_U && csr.get_mstatus_tw()) {
|
||||
exception_cause = XCAUSE_INSTR_ILLEGAL;
|
||||
} else {
|
||||
stalled_on_wfi = true;
|
||||
}
|
||||
} else {
|
||||
exception_cause = XCAUSE_INSTR_ILLEGAL;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue