7. Nesting of Interrupt, NMI and Exception

This section summarized the nesting of Interrupt, NMI and Exception.

  • An interrupt can preempt another interrupt, and an exception can preempt another exception, but NMI cannot preempt another NMI, explained as below:

    • If the core is in NMI handling mode, and it encounters another NMI, then this new NMI will be masked. Therefore, NMI cannot preempt another NMI. Please see NMI Masking for more details.

    • If the core is in exception handling mode, and it encounters another exception, then exception nesting will happen. Please see Priority of Exception for more details.

    • If the core is in interrupt handling mode, and it encounters another interrupt, then interrupt nesting may happen. Please see (CLIC mode) Interrupt Preemption for more details.

  • And preemption also happens between interrupts, exceptions or NMIs, explained as below:

    • If the core is in interrupt handling mode, and it encounters an exception, then the core will enter exception handling mode.

    • If the core is in NMI handling mode, and it encounters an exception, then the core will enter exception handling mode.

    • If the core is in interrupt handling mode, and it encounters an NMI, then the core will enter NMI handling mode.

    • If the core is in exception handling mode, and it encounters an NMI, then the core will enter NMI handling mode.

Note

The global interrupt-enable bit msttaus.MIE is cleared to zero automatically when the core is in exception/NMI handling mode, so the core will not take any interrupt herein (unless the software to turn on mstatus.MIE explicitly in exception/NMI handler).

7.1. Two Levels of NMI/Exception State Save Stacks

As described in last section, the Nuclei processor core can support 3 kinds of NMI/Exception preemption:

  • An NMI preempts an exception

  • An exception preempts another exception

  • An exception preempts another NMI

Note

Since NMI is masked when the core is in NMI handling mode, one NMI cannot preempt another NMI.

In order to make sure the context (e.g., mepc, mcause, etc.) is not corrupted during nesting, the Nuclei processor core has implemented a configurable hardware feature, that is, self-defined Two Levels of NMI/Exception State Save Stacks which can save up to 3-levels NMI/Exception core execution states.

Two Levels of NMI/Exception State Save Stacks

Fig. 7.1 Two Levels of NMI/Exception State Save Stacks

As depicted in Two Levels of NMI/Exception State Save Stacks, this implementation can supports up to 2-levels recoverable NMI/Exception nesting, detailed in the next sections.

7.2. Enter NMI/Exception Preemption

When take an NMI or exception, hardware behaviors of the Nuclei processor core are as below:

  • Stop executing the current program, and jump to a new PC to execute.

    • If it is an exception trap, then the jump target PC is the address defined in mtvec.

    • If it is an NMI trap, then the jump target PC is the address defined in mnvec.

  • NMI/Exception is handling in Machine Mode, so the Privilege Mode will be switched to the Machine Mode when the core takes one NMI/Exception.

  • Updates the following relevant CSRs’ specified fields in the way as shown in Two Levels of NMI/Exception State Save Stacks:

    • mepc: record the PC encountered the handling NMI/Exception, and can be used to restore the PC after exiting the handling NMI/Exception.

    • msaveepc1: the first level NMI/Exception State Save Stack, records value of mepc. This CSR is used to restore the value of mepc when the core returns from the handling NMI/Exception.

    • msaveepc2: the second level NMI/Exception State Save Stack, records the value of msaveepc1. This CSR is used to restore the value of msaveepc1 when the core returns from the handling NMI/Exception.

    • mstatus: following the RISC-V standard privileged architecture.

      • MPIE: save the value of MIE before taking the handling NMI/Exception.

      • MPP: save the value of Privilege Mode before taking the handling NMI/Exception.

    • msavestatus:

      • MPIE1: the first level NMI/Exception State Save Stack, records the value of MPIE. This CSR is used to restore the value of MPIE when the core returns from the handling NMI/Exception.

      • MPIE2: the second level NMI/Exception State Save Stack, records the value of MPIE1. This CSR is used to restore the value of MPIE1 when the core returns from the handling NMI/Exception.

      • MPP1: the first level NMI/Exception State Save Stack, records the value of MPP. This CSR is used to restore the value of MPP when the core returns from the handling NMI/Exception.

      • MPP2: the second level NMI/Exception State Save Stack, records the value of MPP1. This CSR is used to restore the value of MPP1 when the core returns from the handling NMI/Exception.

    • mcause: save the cause of the handling NMI/Exception.

    • msavecause1: the first level NMI/Exception State Save Stack, records the value of mcause.

    • msavecause2: the second level NMI/Exception State Save Stack, records the value of msavecause1.

    • msubm:

      • TYP: save the trap type of the current handling NMI/Exception

      • PTYP: records value of TYP.

      • PTYP1: the first level NMI/Exception State Save Stack, records the value of PTYP. This CSR is used to restore the value of PTYP when the core returns from the handling NMI/Exception.

      • PTYP2: the second level NMI/Exception State Save Stack, records the value of PTYP1. This CSR is used to restore the value of PTYP1 when the core returns from the handling NMI/Exception.

7.3. Exit NMI/Exception Preemption

After handling the NMI/Exception, the core needs to exit from the NMI/Exception handler eventually, and return to execute the main program or handle the next level preempted NMI/Exception. Before exit the current NMI/Exception handler, the relevant CSRs and core status need to be restored by executing the mret instruction. The hardware behavior of the processor after executing mret instruction are:

  • Stop the execution of the current program, and start from the PC address defined by the CSR mepc.

  • According to the value of mstatus.MPP to update the Privilege Mode.

  • Update the fields of the relevant CSRs in reversed way as shown in Two Levels of NMI/Exception State Save Stacks:

    • mepc

    • msaveepc1

    • msavestatus

    • mcause

    • msavecause1

    • msubm

      • TYP

      • PTYP

      • PTYP