Five EmbedDev logo Five EmbedDev

An Embedded RISC-V Blog
RISC-V Instruction Set Manual, Volume I: RISC-V User-Level ISA , 20191214- December 2019

22 “N” Standard Extension for User-Level Interrupts, Version 1.1

This is a placeholder for a more complete writeup of the N extension, and to form a basis for discussion.

An ongoing topic of discussion is whether, for systems needing only M and U privilege modes, the N extension should be supplanted by S-mode without virtual memory (i.e., with satp hardwired to zero). This approach would have similar hardware cost and would simplify the architecture.

This chapter presents a proposal for adding RISC-V user-level interrupt and exception handling. When the N extension is present, and the outer execution environment has delegated designated interrupts and exceptions to user-level, then hardware can transfer control directly to a user-level trap handler without invoking the outer execution environment.

User-level interrupts are primarily intended to support secure embedded systems with only M-mode and U-mode present, but can also be supported in systems running Unix-like operating systems to support user-level trap handling.

When used in an Unix environment, the user-level interrupts would likely not replace conventional signal handling, but could be used as a building block for further extensions that generate user-level events such as garbage collection barriers, integer overflow, floating-point traps.

22.1 Additional CSRs

New user-visible CSRs are added to support the N extension. Their encodings are listed in Table [ucsrnames] in Chapter [chap:priv-csrs].

22.1.1 User Status Register (ustatus)

The ustatus register is a UXLEN-bit read/write register formatted as shown in Figure 1.1. The ustatus register keeps track of and controls the hart’s current operating state.

User-mode status register (ustatus).

The user interrupt-enable bit UIE disables user-level interrupts when clear. The value of UIE is copied into UPIE when a user-level trap is taken, and the value of UIE is set to zero to provide atomicity for the user-level trap handler.

The UIE and UPIE bits are mirrored in the mstatus and sstatus registers in the same bit positions.

There is no UPP bit to hold the previous privilege mode as it can only be user mode.

A new instruction, URET, is used to return from traps in U-mode. URET copies UPIE into UIE, then sets UPIE, before copying uepc to the pc.

UPIE is set after the UPIE/UIE stack is popped to enable interrupts and help catch coding errors.

22.1.2 User Interrupt Registers (uip and uie)

The uip register is a UXLEN-bit read/write register containing information on pending interrupts, while uie is the corresponding UXLEN-bit read/write register containing interrupt enable bits.

User interrupt-pending register (uip).
User interrupt-enable register (uie).

Three types of interrupts are defined: software interrupts, timer interrupts, and external interrupts. A user-level software interrupt is triggered on the current hart by writing 1 to its user software interrupt-pending (USIP) bit in the uip register. A pending user-level software interrupt can be cleared by writing 0 to the USIP bit in uip. User-level software interrupts are disabled when the USIE bit in the uie register is clear.

The ABI should provide a mechanism to send interprocessor interrupts to other harts, which will ultimately cause the USIP bit to be set in the recipient hart’s uip register.

All bits besides USIP in the uip register are read-only.

A user-level timer interrupt is pending if the UTIP bit in the uip register is set. User-level timer interrupts are disabled when the UTIE bit in the uie register is clear. The ABI should provide a mechanism to clear a pending timer interrupt.

A user-level external interrupt is pending if the UEIP bit in the uip register is set. User-level external interrupts are disabled when the UEIE bit in the uie register is clear. The ABI should provide facilities to mask, unmask, and query the cause of external interrupts.

The uip and uie registers are subsets of the mip and mie registers. Reading any field, or writing any writable field, of uip/uie effects a read or write of the homonymous field of mip/mie. If S-mode is implemented, the uip and uie registers are also subsets of the sip and sie registers.

22.1.3 Machine Trap Delegation Registers (medeleg and mideleg)

In systems with the N extension, the medeleg and mideleg registers, described in Chapter [machine], must be implemented.

In systems that implement S-mode, medeleg and mideleg behave as described in Chapter [machine]. In systems with only M and U privilege modes, setting a bit in medeleg or mideleg delegates the corresponding trap in U-mode to the U-mode trap handler.

22.1.4 Supervisor Trap Delegation Registers (sedeleg and sideleg)

For systems with both S-mode and the N extension, new CSRs sedeleg and sideleg are added. These registers have the same layout as the machine trap delegation registers, medeleg and mideleg.

sedeleg and sideleg allow S-mode to delegate traps to U-mode. Only bits corresponding to traps that have been delegated to S-mode are writable; the others are hardwired to zero. Setting a bit in sedeleg or sideleg delegates the corresponding trap in U-mode to the U-mode trap handler.

22.1.5 Other CSRs

The uscratch, uepc, ucause, utvec, and utval CSRs are defined analogously to the mscratch, mepc, mcause, mtvec, and mtval CSRs.

A more complete writeup is to follow.

22.2 N Extension Instructions

The URET instruction is added to perform the analogous function to MRET and SRET.

22.3 Reducing Context-Swap Overhead

The user-level interrupt-handling registers add considerable state to the user-level context, yet will usually rarely be active in normal use. In particular, uepc, ucause, and utval are only valid during execution of a trap handler.

An NS field can be added to mstatus and sstatus following the format of the FS and XS fields to reduce context-switch overhead when the values are not live. Execution of URET will place the uepc, ucause, and utval back into initial state.