Search code examples
armcortex-a

Cortex-A9 SMP GICC_RPR always be 0, interrupt not triggered


Context

on i.MX6Quad board, when the system running, I found that Core3 can not deal with any interrupt.

view the GIC interface registers by Trace32, the GICC_RPR is always 0, which means the highest priority event is running, so it explain the uppon question: lower priority event cannot be processed.

Question

I have insert a instruction : write 0 to GICC_EOI , which can change GICC_RPR to idle priority(0xFF), but it doesn't work, keep 0.

Goal

I want to do priority drop and deactivate success.

References

  • gic arch specf : 3.2.1 Priority drop and interrupt deactivation

Priority drop is the drop in the Running priority that occurs on a valid write > to an EOIR, either the GICC_EOIR or the GICC_AEOIR.

On priority drop, the running priority is reduced from the priority of the interrupt referenced by the EOIR write to either


Solution

  • Writing Zero to EOI does not help. When an interrupt fires, you have to read GICC_IAR register. The value you get is the interrupt number that fired. If you are in legacy mode, you have to write this interrupt number to EOI to retire this interrupt. If you are in priority drop mode, writing this number to EOI decreases the priority, writing the same value to DI will retire the interrupt (check GICC_CTLR to confirm your mode). Hope this clears up the confusion with RPR and EOI.

    Some pointers to debug your issue: 1. Check the GICD_ITARGET registers to see there are interrupts pointed at CPU3. 2. Ensure the interrupts that you are expecting in CPU3 (if anything specific) is not masked in the distributor 3. Check GICC_PMR for CPU3 to see that the priority is not too high. An interrupt is forwarded from distributor to cpu interface only if its priority is higher than the value in this register 4. Check CPU interface for CPU3 is enabled 5. Check GICD_ISPEND to see if the interrupt in question is pending

    NOTE: Be careful when using T32 to debug GIC. T32 works by reading values from registers/memory. This has undesired effects on some GIC registers, for eg GICC_IAR register can only read once to acknowledge the interrupt. Further reads will return spurious interrupt numbers. When T32 is connected and a window is opened to read GICC registers, this will cause an 'orphan' interrupt that no one can take care of. I would suggest putting in logs in the interrupt handling logic to debug issues.