Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 38 additions & 99 deletions src/aclic.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -71,9 +71,7 @@ Graphics used are either explicitly available for free, are property of RISC-V I
:pistatus: pass:q[``**__x__**pistatus``]
:xpistatus: pass:q[``xpistatus``]
:pithreshold: pass:q[``pithreshold``]
:mithreshold: pass:q[``mithreshold``]
:sithreshold: pass:q[``sithreshold``]
:xithreshold: pass:q[``xithreshold``]
:xithreshold: pass:q[``eithreshold``]

:eidelivery: pass:q[``eidelivery``]
:eithreshold: pass:q[``eithreshold``]
Expand Down Expand Up @@ -183,8 +181,6 @@ The table below provides a summary of the ACLIC extensions.
| Smaiae | Advanced Interrupt Architecture for Embedded Systems
| Smaclic | Advanced Core Local Interrupt Controller at Machine level
| Ssaclic | Advanced Core Local Interrupt Controller at Supervisor level
| Smivt | Support for interrupt vector table at Machine level
| Ssivt | Support for interrupt vector table at Supervisor level
| Smehv | Synchronous exceptions hardware vectoring
| Smcsps | Conditional stack pointer swap at Machine level
| Sscsps | Conditional stack pointer swap at Supervisor level
Expand All @@ -203,8 +199,6 @@ Each row contains the dependencies of the extension named in the first column.
[%autowidth]
|===
| Extension Name | Sm | Ss | Smcsrind | Sscsrind | Smaiae | Smnip
| Smivt | x | | | | |
| Ssivt | | x | | | |
| Smcsps | x | | | | |
| Sscsps | | x | | | |
| Smtp | (x)| (x)| | | |
Expand Down Expand Up @@ -413,6 +407,25 @@ Therefore, the registers setipnum, clripnum, setienum, clrienum, setipnum_be, an
The iprio portion of it can be accessed as described in the section on indirect access.
The rest is not required.

=== Major interrupt redirection to ACLIC

In ACLIC mode, ACLIC becomes the hart's primary - and only - interrupt controller. The major interrupt sources (i.e, timer interrupt, software interrupt, ...) are forwarded to ACLIC, according to their major identity numbers.

NOTE: all major interrupts keep their identity numbers.

In this mode CLINT is not used and doesn't influence the interrupt handling.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CLINT is not really a thing in the world of RISC-V standards

The M-mode ACLIC domain becomes the only source of interrupt traps for M-mode and S-mode ACLIC domain becomes the only source of interrupt traps for S-mode.

Such unification of major and external interrupts under ACLIC control enables:

* a unified interrupt identity space, simplifying interrupt vectoring
* consistent handling and configuration across all interrupts
* threshold control via the existing external interrupt threshold register
* elimination of multiple top-priority interrupt registers in favor of a single one

If the ACLIC mode is turned off (legacy mode), the system works as per the RISC-V privileged specification. In that case, the CLINT is a primary interrupt controller and the ACLIC an external (secondary) interrupt controller.
In legacy mode, the major interrupts doesn't have configurable priority.

=== State Enable

Access to existing and repurposed AIA CSRs is already controlled by the state enables defined in Smaia/Ssaia.
Expand Down Expand Up @@ -634,7 +647,6 @@ It provides additional state to resume execution of the previous handler after a
----
Number Name Description
(NEW) 0x346 mpistatus Previous interrupt context
(NEW) 0xFB1 mithreshold Interrupt enable threshold
(NEW) 0x347 mipreemptcfg Interrupt preemption configuration
----

Expand All @@ -658,14 +670,6 @@ A mask for filtering out the bits of a priority number that will participate in
NIPPRIO_MASK = ~(2^(mipreemptcfg.preemptmsk) - 1)
----

==== New Interrupt enable threshold ({mithreshold}) CSR

A new WLRL M-mode CSR, {mithreshold},
determines the minimum interrupt priority (maximum priority number)
for an interrupt to be considered enabled at the hart.

Register {mithreshold} implements exactly IPRIOLEN bits.

==== New Previous Interrupt Status ({mpistatus}) CSR

A new M-mode CSR, {mpistatus}, holds consolidated state of preempted context.
Expand All @@ -688,7 +692,6 @@ mpistatus
----
Number Name Description
(NEW) 0x146 spistatus Previous interrupt context
(NEW) 0x1B1 sithreshold Interrupt enable threshold
----

==== New Previous Interrupt Status ({spistatus}) CSR
Expand All @@ -708,14 +711,6 @@ spistatus
The supervisor {sstatus} register has only a single `spp` bit (to
indicate user/supervisor).

==== New Interrupt enable threshold ({sithreshold}) CSR

A new WLRL S-mode CSR, {sithreshold},
determines the minimum interrupt priority (maximum priority number)
for an interrupt to be considered enabled at the hart.

Register {sithreshold} implements exactly IPRIOLEN bits.

=== Reset Behavior

In general in RISC-V, mandatory reset state is minimized but platform
Expand All @@ -729,12 +724,6 @@ that {sstatus}.`sie` is also reset on entry. It is then responsibility of
the execution environment to ensure that is true before beginning execution
in S-mode.

==== Mandatory reset state

{mithreshold} resets to zero.

The reset behavior of other fields is platform-specific.

=== Operation

When {xithreshold} is a nonzero value,
Expand All @@ -744,7 +733,7 @@ when the following condition holds:

[source]
----
iprio[i] & NIPPRIO_MASK >= xithreshold
iprio[i] & NIPPRIO_MASK >= eithreshold
----

When {xithreshold} is zero,
Expand Down Expand Up @@ -775,96 +764,52 @@ This automatically restores the interrupt enable threshold to the level of the p
If the Smstateen extension is implemented,
then the bit 53 (ACLIC) in mstateen0 is implemented.
If bit 53 (ACLIC) of a controlling mstateen0 CSR is zero,
then access to the new CSRs {spistatus} and {sithreshold} by S-mode or a lower privilege mode
then access to the new CSR {spistatus} by S-mode or a lower privilege mode
results in an illegal instruction exception,
except if the hypervisor extension is implemented,
and the conditions for a virtual instruction exception apply,
in which case a virtual instruction exception is raised
when in VS or VU mode instead of an illegal instruction exception.

== Support for interrupt vector table (Smivt, Ssivt)

These extensions adds a new mode for taking interrupts via a dedicated interrupt vector table.

This increases the range of reachable addresses to the entire address space.
This is useful when handlers are more than 2 MiB away from the vector table entry.

In this new mode, when an interrupt is taken, the hart hardware loads the vector
table entry for the associated interrupt (table pointed to new {xivt} or {xeivt} CSR),
masks off the least-significant bit (for IALIGN=16) or masks of the 2 least-significant bits (for IALIGN=32),
and then jumps to the masked address.
== Smaclic / Ssaclic Changes to {xtvec} CSR Mode

=== Changed and new CSRs
=== Changed CSRs

[source]
----
Number Name Description
0x305 mtvec M-mode Trap-handler base address / interrupt mode
(NEW) 0x307 mivt M-mode Interrupt-handler vector table base address
(NEW) 0x308 meivt M-mode External Interrupt-handler vector table base address
0x105 stvec S-mode Trap-handler base address / interrupt mode
(NEW) 0x107 sivt S-mode Interrupt-handler vector table base address
(NEW) 0x108 seivt S-mode External Interrupt-handler vector table base address
----

==== New {xivt} and {xeivt} CSR

Two new base addresses for vector tables are introduced.
One for internal interrupt (major and local interrupts),
and one for external interrupts.

Both {xivt} and {xeivt} are WARL XLEN-bit CSRs,
which hold the base address of the interrupt vector table.
The address held in {xeivt} is aligned on a 64-byte or greater power-of-two boundary.
Values other than 0 in the low 6 bits are reserved of {xeivt} are reserved.

NOTE: The actual alignment can be determined
by writing ones to the low-order bits
then reading them back.

NOTE: The resulting vector tables, especially for external interrupts,
can consume non-negligible memory space.
To limit the overall memory footprint,
{xivt} or {xeivt} values at different privilege levels may be configured to the same values, respectively.

==== New {xtvec} CSR Mode

Interrupt vector table mode is encoded as a new state in the
existing {xtvec} WARL register, where {xtvec}.`mode` (the two
least-significant bits) is `11`.

==== Smivt Changes to {xtvec} CSR Mode

The PC upon interrupt is changed as follows:

[source]
----
mode PC on Interrupt
00 OBASE # Direct mode
01 OBASE+4*exccode # Vectored mode
11 M[VTBASE+XLEN/8*vtoffset] & VTMASK # Interrupt vector table mode
01 VECT # Vectored mode
11 Reserved
10 Reserved

where:
M[a] = Contents of memory address at address "a"
VTMASK = ~0x1 if IALIGN=16 or ~0x3 if IALIGN=32
exccode = xcause.Exception Code
vtoffset = Interrupt Identity # Corresponds to ACLIC topi[25:16]

OBASE = xtvec[XLEN-1:2]<<2 # Vector base is at least 4-byte aligned
if external interrupt:
VTBASE = xeivt[XLEN-1:6]<<6 # External Interrupt Vector Table base is at least 64-byte aligned
vtoffset = Minor Interrupt Identity
# Corresponds to xtopei[26:16] with interrupt delivery from interrupt file or ACLIC
if ACLIC mode:
VECT = M[OBASE+XLEN/8*vtoffset] & VTMASK
else
VTBASE = xivt[XLEN-1:2]<<2 # Interrupt Vector Table base is at least 4-byte aligned
vtoffset = Major Interrupt Identity
VECT = OBASE+4*exccode
----

In interrupt vector table mode, when interrupts are taken, the interrupt behavior is modified as follows:
If vectored mode is selected in {xtvec}, and ACLIC mode is selected in {eidelivery}, when interrupts are taken, the interrupt behavior is modified as follows:
After executing the required side-effects as required with the existing behavior,
the hart then fetches an XLEN-bit handler address with permissions corresponding to the handler's mode
from the in-memory table whose base address (VTBASE).
The trap handler function address is fetched from `VTBASE+XLEN/8*exccode`.
from the in-memory table whose base address (OBASE).
The trap handler function address is fetched from `OBASE+XLEN/8*exccode`.
If the fetch is successful, the hart clears the low bit(s) (depending on IALIGN) of the handler address,
and sets the PC to this handler address.
The masked vector table entry bit(s) are reserved and should be zero.
Expand All @@ -883,7 +828,7 @@ Memory writes to the vector table require an instruction barrier (_fence.i_) to

It is recommended that the second fetch be ignored for hardware triggers and breakpoints.

==== Vector table fault handling
=== Vector table fault handling

Faults that occur during the fetch of interrupt vector table entries are only recoverable,
if the double trap extension(s) are implemented.
Expand All @@ -910,7 +855,7 @@ side-affects of the trap may only be executed if they allow resuming of operatio

NOTE: Resuming after a fault on a vector table fetch is currently only seen as useful for instruction page faults.

==== State Enable
=== State Enable

If the Smstateen extension is implemented,
then the bit 53 (ACLIC) in mstateen0 is implemented.
Expand All @@ -924,6 +869,8 @@ when in VS or VU mode instead of an illegal instruction exception.

== Synchronous exceptions hardware vectoring- Smehv

NOTE: TBD

The Smehv extension depends upon the Smivt extension.

Accelerating synchronous exception handlers through vectoring may reduce interrupt latency.
Expand Down Expand Up @@ -1152,19 +1099,11 @@ push:
sr a4, OFFSET(sp) # Save xepc
sr a5, OFFSET(sp) # Save xpistatus
bgez a0, handle_exc # Handle synchronous exception
csrr a0, xtopi # Read major interrupt number into a0
li a1, xEI # Write major identity of external interrupt to a1
beq a0, a1, handle_ei # Handle external interrupt
# clear major interrupt pending bit - no single instruction equivalent
shift_idenity:
csrrw a0, xtopei, zero # Read interrupt number into a0 and clear pending bit
srli a0, a0, 16 # Right shift topi value to have idenity aligned with bit 0.
finish_push:
csrrsi zero, xstatus, XIE # Enable interrupts

handle_ei:
csrr a0, xtopei # Read minor interrupt number into a0
j shift_identity # Jump back to rest of push sequence

handle_exc:
csrr a1, xtval # Get xcause of interrupted context
csrr a2, xtval2 # Get xepc of interrupt context
Expand Down