FIQ Exception with INTID 1023 During Mixed IRQ and FIQ Handling

The ARM Cortex-R52 processor, when configured with the Generic Interrupt Controller (GIC) version 3, can encounter a scenario where a Fast Interrupt Request (FIQ) exception is taken, but the Interrupt Acknowledge Register (ICC_IAR0) returns an Interrupt ID (INTID) of 1023. This value is a reserved identifier in the GICv3 architecture, indicating that either no Highest Priority Pending Interrupt (HPPI) is available or the current HPPI cannot be acknowledged via the specific register being accessed. This situation typically arises when the system is handling both IRQ and FIQ interrupts concurrently, and the priorities of these interrupts are not managed correctly.

In the described scenario, two periodic interrupts are configured: vector270 with a priority of 12 (Group 1, IRQ) and vector27 with a priority of 16 (Group 0, FIQ). The FIQ exception is taken when the CPU is handling the IRQ (vector270), and the FIQ (vector27) arrives. However, due to the priority configuration, the FIQ is not acknowledged, leading to the INTID 1023 being reported. This behavior is consistent with the GICv3 architecture, where the FIQ exception is taken but the interrupt cannot be acknowledged because the active priority (from the IRQ) is higher than the incoming FIQ.

The key issue here is the interaction between the IRQ and FIQ handling mechanisms, particularly when the IRQ is already being serviced and a lower-priority FIQ arrives. The GICv3 architecture allows for nested interrupts, but the priority management must be carefully handled to avoid scenarios where the CPU is stuck in an exception handler due to an unacknowledged interrupt.

Priority Masking and GICv3 Register Configuration

The root cause of the INTID 1023 issue lies in the priority masking and the configuration of the GICv3 registers. The Cortex-R52 uses the ICC_PMR (Priority Mask Register) and ICC_RPR (Running Priority Register) to determine which interrupts are eligible to be signaled to the CPU. The ICC_PMR sets a threshold for interrupt priorities, and only interrupts with a higher priority than the value in ICC_PMR are signaled. The ICC_RPR reflects the priority of the currently executing interrupt, and any incoming interrupt must have a higher priority than the value in ICC_RPR to preempt the current interrupt.

In this case, the ICC_PMR is set to 0xF8, which does not mask any interrupts, as the priority values for both vector270 (12) and vector27 (16) are lower than 0xF8. However, the ICC_RPR is set to 0x60, which corresponds to a priority of 12 (the priority of vector270). When the FIQ (vector27) arrives, its priority (16) is lower than the running priority (12), so it cannot preempt the IRQ. As a result, the GIC signals the FIQ exception but does not allow the interrupt to be acknowledged, leading to the INTID 1023 being returned by ICC_IAR0.

Additionally, the GICv3 architecture differentiates between Group 0 (FIQ) and Group 1 (IRQ) interrupts. Group 0 interrupts can only be acknowledged via ICC_IAR0, while Group 1 interrupts are acknowledged via ICC_IAR1. This separation ensures that the CPU does not accidentally acknowledge an FIQ in an IRQ handler or vice versa. In the described scenario, the FIQ exception is taken, but the interrupt is not acknowledged because the HPPI is a Group 1 interrupt (vector270), which cannot be acknowledged via ICC_IAR0.

Implementing Safe FIQ and IRQ Handling with Priority Management

To resolve the INTID 1023 issue and ensure robust handling of mixed IRQ and FIQ interrupts, the following steps should be taken:

  1. Priority Configuration: Ensure that the priorities of IRQ and FIQ interrupts are configured correctly. In this case, the FIQ (vector27) has a lower priority (16) than the IRQ (vector270, priority 12). To allow the FIQ to preempt the IRQ, the FIQ should be assigned a higher priority than the IRQ. For example, setting the FIQ priority to 8 would allow it to preempt the IRQ.

  2. Handling INTID 1023 in Exception Handlers: The FIQ handler should be designed to handle the case where ICC_IAR0 returns INTID 1023. This is a normal condition in the GICv3 architecture, and the handler should simply return without attempting to acknowledge the interrupt. The following code snippet demonstrates how to handle this scenario in the FIQ handler:

    FIQ_Handler:
        // Read ICC_IAR0 to acknowledge the interrupt
        MRS x0, ICC_IAR0_EL1
        CMP x0, #1023
        BEQ FIQ_Handler_Exit  // If INTID is 1023, exit the handler
    
        // Handle the FIQ interrupt here
        ...
    
    FIQ_Handler_Exit:
        // Clear any corrupted registers or stacks
        ...
    
        // Return from the FIQ exception
        ERET
    
  3. Nested Interrupt Handling: If nested interrupts are required, the system should be designed to handle the case where an IRQ becomes pending while an FIQ is being handled. This can be achieved by enabling IRQs in the FIQ handler after saving the necessary context. The following code snippet demonstrates this approach:

    FIQ_Handler:
        // Save the context
        ...
    
        // Enable IRQs to allow nested interrupts
        MSR DAIFClr, #2  // Clear the IRQ mask bit in DAIF
    
        // Handle the FIQ interrupt here
        ...
    
        // Disable IRQs before restoring the context
        MSR DAIFSet, #2  // Set the IRQ mask bit in DAIF
    
        // Restore the context
        ...
    
        // Return from the FIQ exception
        ERET
    
  4. Logging and Debugging: Implement logging in the exception handlers to track the occurrence of INTID 1023 and other unusual conditions. This can help identify patterns or issues in the interrupt handling logic. For example, the following code snippet logs the value of ICC_IAR0 when INTID 1023 is encountered:

    FIQ_Handler:
        // Read ICC_IAR0 to acknowledge the interrupt
        MRS x0, ICC_IAR0_EL1
        CMP x0, #1023
        BNE FIQ_Handler_Process
    
        // Log the occurrence of INTID 1023
        LDR x1, =log_buffer
        STR x0, [x1]
        B FIQ_Handler_Exit
    
    FIQ_Handler_Process:
        // Handle the FIQ interrupt here
        ...
    
    FIQ_Handler_Exit:
        // Clear any corrupted registers or stacks
        ...
    
        // Return from the FIQ exception
        ERET
    

By following these steps, the system can handle mixed IRQ and FIQ interrupts safely and efficiently, avoiding the pitfalls associated with INTID 1023 and ensuring that all interrupts are processed correctly.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *