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
A read of ICC_IARn returns 1023 either when there is no HPPI or the HPPI is one that you can't ack via that register at this time.
As ICC_HPPIR0 reports 0x1B (27) you know there is a HPPI. Now, just because there is a HPPI doesn't mean the GIC will signal an IRQ or FIQ to the core. The HPPI might be masked either by ICC_PMR (priority mask) or ICC_RPR (running priority). Running priority is derived from the ICC_APxR0_EL1 registers.
Grace WANG said: 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 ?
Each INTID has a configurable priority, meaning you can't (architecturally) infer the relative of priorities of two interrupts based on their INITDs. I know on some interrupt controllers INTID and priority are connected, but it is not true for GICs. If you're see the FIQ exception then that implies the HPPI beat both the PMR and RPR, that means it's higher priority than the already active priority.
A couple of questions:
Hi Martion
Yes, I saw FIQ exception was taken and ICC_IAR0 returned 1023.
The ICC_RPR is 0x60 - I think it means the running priority is 12, which is the priority of the configured IRQ (vector270).
ICC_PMR is 0xF8, so I think PMR does not mask any interrupts.
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.