22.8.4.3 Fast Interrupt Handlers

This section gives an overview of the fast interrupt handling sequence when using the AIC. It is assumed that the programmer understands the architecture of the ARM processor, and especially the Processor Interrupt modes and associated status bits.

Assuming that:

  1. The AIC has been programmed, AIC_SVR is loaded with the fast interrupt service routine address, and interrupt source 0 is enabled.
  2. The Instruction at address 0x1C (FIQ exception vector address) is required to vector the fast interrupt. Load the PC with the absolute address of the interrupt handler.
  3. The user does not need nested fast interrupts.

When nFIQ is asserted, if bit “F” of CPSR is 0, the sequence is:

  1. The CPSR is stored in SPSR_fiq, the current value of the program counter is loaded in the FIQ link register (R14_FIQ) and the program counter (R15) is loaded with 0x1C. In the following cycle, during fetch at address 0x20, the ARM core adjusts R14_fiq, decrementing it by four.
  2. The ARM core enters FIQ mode.
  3. The routine must read AIC1_CISR to know if the interrupt is the FIQ or a Secure Internal interrupt.
       ldr r1, =REG_SAIC_CISR 
       ldr r1, [r1]  
       cmp r1, #AIC_CISR_NFIQ  
       beq get_fiqvec_addr

    If FIQ is active, it is processed in priority, even if another interrupt is active.

    get_irqvec_addr   
       ldr r14, =REG_SAIC_IVR   
       b read_vec
    get_fiqvec_addr   
       ldr r14, =REG_SAIC_FVR
    read_vec   
       ldr r0, [r14]

    Now r0 contains the correct vector address, IVR for a Secure Internal interrupt or FVR for FIQ.

    The system can branch to the routine pointed to by r0.

    FIQ_Handler_Branch   
       mov r14, pc   
       bx r0 
  4. The previous step enables branching to the corresponding interrupt service routine. It is not necessary to save the link register R14_fiq and SPSR_fiq if nested fast interrupts are not needed.
  5. The Interrupt Handler can then proceed as required. It is not necessary to save registers R8 to R13 because the FIQ mode has its own dedicated registers and registers R8 to R13 are banked. The other registers, R0 to R7, must be saved before being used, and restored at the end (before the next step).
    Note: If the fast interrupt is programmed to be level-sensitive, the source of the interrupt must be cleared during this phase in order to de-assert interrupt source 0.
  6. Finally, Link register R14_fiq is restored into the PC after decrementing it by four (with instruction SUB PC, LR, #4 for example). This has the effect of returning from the interrupt to whatever was being executed before, loading the CPSR with the SPSR and masking or unmasking the fast interrupt depending on the state saved in the SPSR.
    Note: The “F” bit in SPSR is significant. If it is set, it indicates that the ARM core was just about to mask FIQ interrupts when the mask instruction was interrupted. Hence, when the SPSR is restored, the interrupted instruction is completed (FIQ is masked).

Another way to handle the fast interrupt is to map the interrupt service routine at the address of the ARM vector 0x1C. This method does not use vectoring, so that reading AIC_FVR must be performed at the very beginning of the handler operation. However, this method saves the execution of a branch instruction.