|
|
|
@ -494,6 +494,13 @@ void state_t::reset(processor_t* const proc, reg_t max_isa) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (proc->extension_enabled_const(EXT_SMRNMI)) { |
|
|
|
csrmap[CSR_MNSCRATCH] = std::make_shared<basic_csr_t>(proc, CSR_MNSCRATCH, 0); |
|
|
|
csrmap[CSR_MNEPC] = mnepc = std::make_shared<epc_csr_t>(proc, CSR_MNEPC); |
|
|
|
csrmap[CSR_MNCAUSE] = std::make_shared<const_csr_t>(proc, CSR_MNCAUSE, (reg_t)1 << (xlen - 1)); |
|
|
|
csrmap[CSR_MNSTATUS] = mnstatus = std::make_shared<mnstatus_csr_t>(proc, CSR_MNSTATUS); |
|
|
|
} |
|
|
|
|
|
|
|
if (proc->extension_enabled_const(EXT_SSTC)) { |
|
|
|
stimecmp = std::make_shared<stimecmp_csr_t>(proc, CSR_STIMECMP, MIP_STIP); |
|
|
|
vstimecmp = std::make_shared<stimecmp_csr_t>(proc, CSR_VSTIMECMP, MIP_VSTIP); |
|
|
|
@ -660,7 +667,8 @@ void processor_t::take_interrupt(reg_t pending_interrupts) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (!state.debug_mode && enabled_interrupts) { |
|
|
|
const bool nmie = !(state.mnstatus && !get_field(state.mnstatus->read(), MNSTATUS_NMIE)); |
|
|
|
if (!state.debug_mode && nmie && enabled_interrupts) { |
|
|
|
// nonstandard interrupts have highest priority
|
|
|
|
if (enabled_interrupts >> (IRQ_M_EXT + 1)) |
|
|
|
enabled_interrupts = enabled_interrupts >> (IRQ_M_EXT + 1) << (IRQ_M_EXT + 1); |
|
|
|
@ -849,8 +857,13 @@ void processor_t::take_trap(trap_t& t, reg_t epc) |
|
|
|
} else { |
|
|
|
// Handle the trap in M-mode
|
|
|
|
set_virt(false); |
|
|
|
reg_t vector = (state.mtvec->read() & 1) && interrupt ? 4 * bit : 0; |
|
|
|
state.pc = (state.mtvec->read() & ~(reg_t)1) + vector; |
|
|
|
const reg_t vector = (state.mtvec->read() & 1) && interrupt ? 4 * bit : 0; |
|
|
|
const reg_t trap_handler_address = (state.mtvec->read() & ~(reg_t)1) + vector; |
|
|
|
// RNMI exception vector is implementation-defined. Since we don't model
|
|
|
|
// RNMI sources, the feature isn't very useful, so pick an invalid address.
|
|
|
|
const reg_t rnmi_trap_handler_address = 0; |
|
|
|
const bool nmie = !(state.mnstatus && !get_field(state.mnstatus->read(), MNSTATUS_NMIE)); |
|
|
|
state.pc = !nmie ? rnmi_trap_handler_address : trap_handler_address; |
|
|
|
state.mepc->write(epc); |
|
|
|
state.mcause->write(t.cause()); |
|
|
|
state.mtval->write(t.get_tval()); |
|
|
|
|