aboutsummaryrefslogtreecommitdiff
path: root/riscv/processor.cc
diff options
context:
space:
mode:
Diffstat (limited to 'riscv/processor.cc')
-rw-r--r--riscv/processor.cc13
1 files changed, 10 insertions, 3 deletions
diff --git a/riscv/processor.cc b/riscv/processor.cc
index ec3c998..6fe64ab 100644
--- a/riscv/processor.cc
+++ b/riscv/processor.cc
@@ -303,9 +303,15 @@ bool processor_t::is_handled_in_vs()
void processor_t::take_interrupt(reg_t pending_interrupts)
{
- const reg_t s_pending_interrupts = state.nonvirtual_sip->read() & state.nonvirtual_sie->read();
- const reg_t vstopi = state.vstopi->read();
- const reg_t vs_pending_interrupt = vstopi ? (reg_t(1) << get_field(vstopi, MTOPI_IID)) : 0;
+ reg_t s_pending_interrupts = 0;
+ reg_t vstopi = 0;
+ reg_t vs_pending_interrupt = 0;
+
+ if (extension_enable_table[EXT_SSAIA]) {
+ s_pending_interrupts = state.nonvirtual_sip->read() & state.nonvirtual_sie->read();
+ vstopi = state.vstopi->read();
+ vs_pending_interrupt = vstopi ? (reg_t(1) << get_field(vstopi, MTOPI_IID)) : 0;
+ }
// Do nothing if no pending interrupts
if (!pending_interrupts && !s_pending_interrupts && !vs_pending_interrupt) {
@@ -441,6 +447,7 @@ void processor_t::take_trap(trap_t& t, reg_t epc)
bool supv_double_trap = false;
if (interrupt) {
vsdeleg = (curr_virt && state.prv <= PRV_S) ? state.hideleg->read() : 0;
+ vsdeleg >>= 1;
hsdeleg = (state.prv <= PRV_S) ? (state.mideleg->read() | state.nonvirtual_sip->read()) : 0;
bit &= ~((reg_t)1 << (max_xlen - 1));
} else {