If hvictl.VTI=1, there are two interrupt candidates for VS level. One is
a supervisor extenal interrupt if bit 9 is one in both vsip and vsie.
The other one is specified by hvictl.IID if hvictl.IID is not 9. The
hvictl.DPR determines the priority order between two interrupts.
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.
The pair hvictl.IID=9 and hvictl.IPRIO=0 generally represent no
interrupt in hvictl.
While zeroing also signifies no interrupt, this intermediate commit in
the AIA series aims to explicitly state the absence of an interrupt
condition to prevent confusion in subsequent intermediate commits.
AIA introduces the concept of inaccessible CSR, where accessing from
M-mode or HS-mode raises an illegal instruction exception, but doing so
from VS-mode or VU-mode raises a virtual instruction exception.
Without IMSIC, mtopei and stopei do not exist. In contrast, vstopei is
an inaccessible CSR even without IMSIC, i.e., exits and is HS-qualified.
In summary, accessing stopei from M-mode or HS-mode (v=0) raises illegal
instruction, and accessing stopei (actually vstopei) from VS-mode or
VU-mode (v=1) raises virtual instruction.
The AIA spec specifies the sie[n] behavior conditionally:
(1) When mideleg[n]=0 and mvien[n]=0, sie[n] is read-only 0.
(2) When mideleg[n]=0 and mvien[n]=1, sie[n] is writable.
(3) When mideleg[n]=1, sie[n] is an alias of mie[n].
Points (1) and (3) describe the same behavior without AIA. This commit
provides the behavior of point (2).
The AIA spec specifies the sip[n] behavior conditionally:
(1) When mideleg[n]=0 and mvien[n]=0, sip[n] is read-only 0.
(2) When mideleg[n]=0 and mvien[n]=1, sip[n] is an alias of mvip[n].
(3) When mideleg[n]=1, sip[n] is an alias of mip[n].
Points (1) and (3) describe the same behavior without AIA. This commit
provides the behavior of point (2).
When mvien.SEIP=0, mip.SEIP includes the software-writable bit, i.e.,
mvip.SEIP.
When mvien.SEIP=1, mip.SEIP is read-only and does not include the value
of mvip.SEIP.
The mip.SEIP is the logical-OR of a software-writable bit and signal
from an external interrupt controller (e.g., APLIC or IMSIC). The AIA
spec lets the software-writable bit be the mvip.SEIP.
This commit follows the concept that the mvip.SEIP is a sub-component of
mip.SEIP. Writing mip.SEIP actually updates the software-writable bit,
i.e., mvip.SEIP. Reading mip.SEIP returns a value consisting of the
software-writable bit, i.e., mvip.SEIP. The SEIP bit in mip::val becomes
a placeholder for the external interrupt controller.
Accessing mvip.SEIP reads from and writes to mvip.SEIP normally.
Reference: https://github.com/riscv/riscv-aia/issues/64
When mvien.SSIP=0, mvip.SSIP is an alias of mip.SSIP. Accessing
mvip.SSIP reads from and writes to mip.SSIP.
When mvien.SSIP=1, mvip.SSIP is a separate writable bit independent of
mip.SSIP. Accessing mvip.SSIP reads from and writes to the separate,
writable, independent bit normally.
When mvien is read-only 0, mvip.SEIP and mvip.SSIP are aliases of
mip.SEIP and mip.SSIP. Accessing mvip.SEIP and mvip.SSIP reads from and
writes to mip.SEIP and mip.SSIP.
Accessing mvip.STIP reads from and writes to mip.STIP if menvcfg.STCE=1;
otherwise, mvip.STIP is read-only 0.
The original decoder in spike doesn't support extracting fields such as
funct7 or opcode. This commit adds support for usage in other projects.
Signed-off-by: Tianrui Wei <tianrui@tianruiwei.com>