diff --git a/riscv/csrs.cc b/riscv/csrs.cc index fb29ac5b..3a1c1132 100644 --- a/riscv/csrs.cc +++ b/riscv/csrs.cc @@ -2097,13 +2097,25 @@ vstopi_csr_t::vstopi_csr_t(processor_t* const proc, const reg_t addr): } reg_t vstopi_csr_t::read() const noexcept { + reg_t hvictl = state->hvictl->read(); + bool vti = hvictl & HVICTL_VTI; + reg_t enabled_interrupts = state->mip->read() & state->mie->read() & state->hideleg->read(); enabled_interrupts >>= 1; // VSSIP -> SSIP, etc - if (!enabled_interrupts) - return 0; // no enabled pending interrupt to VS-mode - reg_t selected_interrupt = proc->select_an_interrupt_with_default_priority(enabled_interrupts); - reg_t identity = ctz(selected_interrupt); + reg_t identity; + if (vti) { + if (!(enabled_interrupts & MIP_SEIP)) + return 0; + + identity = IRQ_S_EXT; + } else { + if (!enabled_interrupts) + return 0; // no enabled pending interrupt to VS-mode + + reg_t selected_interrupt = proc->select_an_interrupt_with_default_priority(enabled_interrupts); + identity = ctz(selected_interrupt); + } return set_field((reg_t)1, MTOPI_IID, identity); // vstopi.IPRIO is 1 if hvictl.IPRIOM is 0 }