mirror of
https://github.com/openhwgroup/cve2.git
synced 2025-04-22 21:17:59 -04:00
[dv] Add recoverable NMI handling to cosim
Ibex implements a custom recoverable NMI handling scheme. This adds modeling of it to the cosim.
This commit is contained in:
parent
587dc364e9
commit
cedabf062a
2 changed files with 36 additions and 4 deletions
|
@ -105,10 +105,6 @@ bool SpikeCosim::step(uint32_t write_reg, uint32_t write_reg_data, uint32_t pc,
|
|||
bool sync_trap) {
|
||||
assert(write_reg < 32);
|
||||
|
||||
if (pc_is_mret(pc)) {
|
||||
nmi_mode = false;
|
||||
}
|
||||
|
||||
uint32_t initial_pc = (processor->get_state()->pc & 0xffffffff);
|
||||
bool initial_pc_match = initial_pc == pc;
|
||||
|
||||
|
@ -172,6 +168,11 @@ bool SpikeCosim::step(uint32_t write_reg, uint32_t write_reg_data, uint32_t pc,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (!sync_trap && pc_is_mret(pc) && nmi_mode) {
|
||||
// Do handling for recoverable NMI
|
||||
leave_nmi_mode();
|
||||
}
|
||||
|
||||
// Check register writes from executed instruction match what is expected
|
||||
auto ®_changes = processor->get_state()->log_reg_write;
|
||||
|
||||
|
@ -288,6 +289,19 @@ void SpikeCosim::on_csr_write(const commit_log_reg_t::value_type ®_change) {
|
|||
fixup_csr(cosim_write_csr, cosim_write_csr_data);
|
||||
}
|
||||
|
||||
void SpikeCosim::leave_nmi_mode() {
|
||||
nmi_mode = false;
|
||||
|
||||
// Restore CSR status from mstack
|
||||
uint32_t mstatus = processor->get_csr(CSR_MSTATUS);
|
||||
mstatus = set_field(mstatus, MSTATUS_MPP, mstack.mpp);
|
||||
mstatus = set_field(mstatus, MSTATUS_MPIE, mstack.mpie);
|
||||
processor->set_csr(CSR_MSTATUS, mstatus);
|
||||
|
||||
processor->set_csr(CSR_MEPC, mstack.epc);
|
||||
processor->set_csr(CSR_MCAUSE, mstack.cause);
|
||||
}
|
||||
|
||||
void SpikeCosim::set_mip(uint32_t mip) {
|
||||
processor->get_state()->mip->write_with_mask(0xffffffff, mip);
|
||||
}
|
||||
|
@ -296,6 +310,13 @@ void SpikeCosim::set_nmi(bool nmi) {
|
|||
if (nmi && !nmi_mode && !processor->get_state()->debug_mode) {
|
||||
processor->get_state()->nmi = true;
|
||||
nmi_mode = true;
|
||||
|
||||
// When NMI is set it is guaranteed NMI trap will be taken at the next step
|
||||
// so save CSR state for recoverable NMI to mstack now.
|
||||
mstack.mpp = get_field(processor->get_csr(CSR_MSTATUS), MSTATUS_MPP);
|
||||
mstack.mpie = get_field(processor->get_csr(CSR_MSTATUS), MSTATUS_MPIE);
|
||||
mstack.epc = processor->get_csr(CSR_MEPC);
|
||||
mstack.cause = processor->get_csr(CSR_MCAUSE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,15 @@ class SpikeCosim : public simif_t, public Cosim {
|
|||
std::vector<std::string> errors;
|
||||
bool nmi_mode;
|
||||
|
||||
typedef struct {
|
||||
uint8_t mpp;
|
||||
bool mpie;
|
||||
uint32_t epc;
|
||||
uint32_t cause;
|
||||
} mstack_t;
|
||||
|
||||
mstack_t mstack;
|
||||
|
||||
void fixup_csr(int csr_num, uint32_t csr_val);
|
||||
|
||||
struct PendingMemAccess {
|
||||
|
@ -54,6 +63,8 @@ class SpikeCosim : public simif_t, public Cosim {
|
|||
|
||||
void on_csr_write(const commit_log_reg_t::value_type ®_change);
|
||||
|
||||
void leave_nmi_mode();
|
||||
|
||||
int insn_cnt;
|
||||
|
||||
public:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue