From 5fd15be942d8342fff24c54d2aab2cc50a10e9a5 Mon Sep 17 00:00:00 2001 From: Peter Rugg Date: Thu, 5 Sep 2024 13:53:39 +0100 Subject: [PATCH] Clarify interrupt dispatch with N-mode --- model/riscv_sys_control.sail | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/model/riscv_sys_control.sail b/model/riscv_sys_control.sail index 87348f697..f417ed4b2 100644 --- a/model/riscv_sys_control.sail +++ b/model/riscv_sys_control.sail @@ -277,13 +277,16 @@ function dispatchInterrupt(priv : Privilege) -> option((InterruptType, Privilege /* If we don't have different privilege levels, we don't need to check delegation. * Absence of U-mode implies absence of S-mode. */ - if not(extensionEnabled(Ext_U)) | (not(extensionEnabled(Ext_S)) & not(extensionEnabled(Ext_N))) then { - let enabled_pending = mip.bits & mie.bits; - match findPendingInterrupt(enabled_pending) { - Some(i) => let r = (i, Machine) in Some(r), - None() => None() - } - } else { + let multipleModesSupported = extensionEnabled(Ext_U); + if not(multipleModesSupported) then { + assert(priv == Machine, "invalid current privilege") + }; + /* Even with U-mode, we don't need to check delegation when M-mode is the only + one that can take interrupts, i.e. when we don't have S-mode and don't have + the N extension + */ + let delegationPossible = extensionEnabled(Ext_S) | extensionEnabled(Ext_N); + if multipleModesSupported & delegationPossible then { match getPendingSet(priv) { None() => None(), Some(ip, p) => match findPendingInterrupt(ip) { @@ -291,6 +294,12 @@ function dispatchInterrupt(priv : Privilege) -> option((InterruptType, Privilege Some(i) => let r = (i, p) in Some(r) } } + } else { + let enabled_pending = mip.bits & mie.bits; + match findPendingInterrupt(enabled_pending) { + Some(i) => let r = (i, Machine) in Some(r), + None() => None() + } } }