SPRUI30H November 2015 – May 2024 DRA745 , DRA746 , DRA750 , DRA756
The ARP32 CPU supports extensive automatic context save and restore during interrupt processing to reduce the effective interrupt latency significantly.
While processing all maskable interrupts (INT15-INT4) , SWI and UNDEF, the ARP32 CPU saves off all key registers into shadow registers and during an interrupt return, via the BIRP instruction, restores them back:
Both saving and restoring happens in a single cycle in parallel to interrupt vector fetch or the return branch execution. Also, as long as interrupt nesting is not enabled, there is absolutely no need of any additional context save (or restore) by the software at the start (or end) of the interrupt service routine. Hence, these interrupts have extremely low effective latency and are considered fast.
While processing the non-maskable interrupt (NMI), however, the CPU does not do extensive context save and restore. Only the CSR register is saved off to NMISCSR and during an NMI return, via the BNRP instruction, CSR is restored back. So, at the beginning of an NMI ISR, the software ensures to save off the complete CPU state to stack and restore them back before issuing a BNRP instruction (to accomplish a return from NMI):
Thus, the interrupt behavior of the ARP32 CPU makes all maskable interrupts (INT15-INT4), SWI, and UNDEF as fast, and non-maskable interrupt (NMI) as just correct. The maskable interrupts (INT15-INT4) are used as the functional interrupt(s) of the system and the NMI are used to handle/service System Error, Exception scenarios (for example, a bus fault on program or data access).
The following example illustrates the process of context save and restore within an NMI service routine. In this example, the
NMIHandler()
is the actual software NMI handler function and a single unified stack across background and interrupt handler code is intended.
__NonMaskableInterruptHandlerWrapper:
; Save off Arch regs first
STRF R7, R0
; Save off HLA regs
MVC LSA0, R0
MVC LEA0, R1
MVC LCNT0, R2
MVC LSA1, R3
MVC LEA1, R4
MVC LCNT1, R5
MVC LCNT0RLD, R6
STRF R6, R0
; Now call the actual handler function
CALL NMIHandler
NOP
; Restore HLA regs
LDRF R0, R6
MVC R0, LSA0
MVC R1, LEA0
MVC R2, LCNT0
MVC R3, LSA1
MVC R4, LEA1
MVC R5, LCNT1
MVC R6, LCNT0RLD
; Restore Arch regs
LDRF R0, R7
; Return from NMI ISR
BNRP
NOP
Note that in the example, during context restore, a write to LCNT0 also gets written to LCNT0RLD. Hence, the LCNT0RLD register is restored after LCNT0 is restored.