From 7bdecfed63f9aa2e412977dfd271a5ec0ae056e7 Mon Sep 17 00:00:00 2001 From: YenHaoChen Date: Wed, 27 Mar 2024 15:30:11 +0800 Subject: [PATCH] AIA: Implement hvictl.VTI behavior in vstopi CSR If hvictl.VTI=0, vstopi returns information about the highest-priority pending-and-enabled major interrupt indicated by vsip and vsie. If hvictl.VTI=1, vstopi return information about a supervisor extenal interrupt if bit 9 is one in both vsip and vsie. --- riscv/csrs.cc | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) 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 }