Hello
I met an issue of FIQ interrupt1023 occurred when two periodic interrupts existed: vector270: priority: 12, group1 (IRQ) and vector27: priority 16, group0 (FIQ).
When the fiq_exception got the INTID1023, I saw that ICC_HPPIR0: 0x1B (27), ICC_AP1R0: 0x1000 (active priority: 12). As the irq_exception will not mask FIQ, I suppose that when the CPU is handling vector270 (IRQ), vector27 (FIQ) comes and interrupts it. But as the priority of vector27 is lower than vector270, interrupt1023 is reported due to no sufficient priority. Is my understanding right ?
If so, what are the recommendations for irq and fiq handling when the system have both IRQ and FIQ interrupts enabled ?
BR, Grace
Grace WANG said:Yes, I saw FIQ exception was taken and ICC_IAR0 returned 1023.
Now that's interesting. If the GIC is asserting the FIQ input, then it shows the HPPI passed all the GIC tests (PMR, RPR...).
Inside the handler (so after you've taken the FIQ exception), could you try:
I'm checking what the state is immediately before and after the read of the IAR.
Hi Martin
What I got:
Thanks. That does seem to be working, IAR0 returned 0x1B which is what you'd expected.
How was the test different to what you had before?
The register values in the previous reply are under the condition that IRQ and FIQ are enabled after those registers are read in the fiq_exception. It makes the scenario more complicated.
So I removed the enabling IRQ and FIQ in the fiq_exception and got:
Thanks.
Grace WANG said:CC_HPPIR0 = 0x3FF ICC_AP0R0 = 0x0 ISR = 0x80
The ISR is showing that the IRQ line is asserted (bit 7) and the FIQ line is de-asserted (bit 6). That's consistent with what the GIC registers are reporting. ICC_HPPIR0 reports if the HPPI is a Group 0 interrupt, 0x3FF means there isn't. It's Group 0 interrupt which the GIC signals as FIQs. We can infer that if we read ICC_HPPIR0, which reports on Group 1 interrupts which are signalled as IRQs, it would report 270 (or some other G1 ID).
The read of ICC_IAR0 rightly returns 1023. IAR0 can only ack Group 0 interrupts, the HPPI is a Group 1 interrupt.
The bit I'm confused by is that you said you have this inside the FIQ handler. That's odd because the GIC isn't signalling an FIQ, it's signalling an IRQ.
Interrupts are asynchronous events, there's no guarantee that the HPPI that caused the initial exception is the one that's still there when you try to handle it. Two possibilities spring to mind:
I think the second is more likely, given what you said about the priorities in the original post.
Grace WANG said: vector270: priority: 12, group1 (IRQ) and vector27: priority 16, group0 (FIQ).
If it's true, it's just unlucky timing. The GIC saw a G0 interrupt, raised an FIQ. While the core was taking the exception, the G1 interrupt became pending and was selected as the HPPI (as its higher priority). When software in the FIQ handler tries to ack the interrupt it fails as the current HPPI is G1. If the handler then returned, I'd expect the core to take an IRQ exception pretty immediately (assuming PSTATE.I=0) and then you'd handle that. Once the G1 interrupt is priority dropped (ICC_EOIR1), the GIC will be able to select the original G0 interrupt as the HPPI again.
I think your assumption is right because I saw ICC_HPPI1 = 0x10E (270) before read of IAR0.
Martin Weidmann said:If the handler then returned, I'd expect the core to take an IRQ exception pretty immediately (assuming PSTATE.I=0) and then you'd handle that. Once the G1 interrupt is priority dropped (ICC_EOIR1), the GIC will be able to select the original G0 interrupt as the HPPI again.
Currently, for the FIQ1023, the CPU will do nothing but stop there. Are you saying that I can make the CPU complete the fiq exception handling after entered vector1023. Then it will go to handle IRQ normally.
If so, what's the safe handling for INT1023 ?
1023 isn't a "real" INTID, it's a reserved value meaning either there is no HPPI or the current HPPI is not acknowledgeable via this register. It's there to stop you accidentally ack'ing an FIQ in the IRQ handler or vice versa
What does CPU need to do for INTID1023 ? only while() in the handler to stop the CPU there ? or save some status and then go back to the main program ?
1023 means you didn't ack an interrupt. Under "normal" operation it's possible to get this, so IRQ/FIQ handlers should be written to cope with it. Typically what I'd expect is that the hander would just return (after clearing up any corrupted registers/stacks/etc). You didn't ack an interrupt, therefore the is nothing for the handler to do.
If you were repeatedly taking an interrupt, then getting 1023 back from the IARs, that would be unusual and worth investigating. So you might do some sort of logging to check if it's happening a lot.