We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
I'm testing GIC and ARM A53 connectivity. I can see that GIC is forwarding the IRQ request and ARM core has received it(shows in ISR reg). However, my IRQ handler is not getting called. Here is how I'm registering it..
void main () { ... __enable_irq(); ... } __irq void irqHandler(void) { printf("Hello from the IRQ handler\n"); ... }
void main () {
...
__enable_irq();
}
__irq void irqHandler(void) {
printf("Hello from the IRQ handler\n");
Have you actually added the interrupt handling function to the interrupt vector table?
P
Hi Peter,
I have, but I'm not confident if I did it correctly. But, even if the vector table is not initialized properly, shouldn't I see core branching to an illegal address and not remain stuck in an infinite loop in have put in my code(after configuring interrupt source)?
If the vector table isn't set up properly then branching to an illegal address is highly likely to end up in an infinite loop (if you don't have a fault handler correctly configured, then branching to the fault handler itself faults, and causes a fault -> infinite loop of the fault never getting processed and cleared).
That is interesting. But, through a source code debugger, I am able to see that the control is stuck in the infinite loop I have put in my code.
You also need to consider the exception routing bits in SCR_EL3 and HCR_EL2.
In ARMv8-A, the asynchronous exceptions (IRQ, FIQ and SError) must have a target Exception Level (or EL) specified. For example:
SCR_EL3.IRQ == 1 HCR_EL2.IMO == X
Would mean that IRQs are routed to EL3. That is, if the core is in EL0/1/2 when the IRQ is asserted the exception will be taken to EL3 - regardless of the PSTATE.I value. If the core is in EL3 when the IRQ is asserted, the exception will be taken to EL3 if PSTATE.I is 0.
Another example:
SCR_EL3.IRQ == 0 SCR_EL3.NS == 1 HCR_EL2.IMO == 1
IRQs are routed to EL2. If the core is in NS.EL0/1 when the IRQ is asserted the exception will be taken to EL2 - regardless of the PSTATE.I value. If the core is in EL2 when the IRQ is asserted, the exception will be taken to EL2 if PSTATE.I is 0.
The interesting case is when the IRQ is asserted while in EL3. Taking an exception cannot cause entry to a lower privilege level. As the IRQ is routed to EL2, if the core is in EL3 the interrupted is "pended". That is the core won't take the exception until you drop to a lower EL.
You might also want to double check that the interrupt signal is actually asserted. You can check this using the ISR_EL1.
Hello @Martin Weidmann,
Thanks for the very helpful reply.
I checked ISR_EL1 and it's value is 0x80, signifying an IRQ.
I tried setting SCR_EL3.IRQ = 0x1, so that the IRQ will have EL3 as target exception level. At this point, the control goes to vector table to an entry that looks like Synchronous Exception for EL2.
I know my questions are pretty basic and I should read the TRM(which I'm doing), but do you have any idea how to proceed?
Here's my vector table code:
monitor_vectors
B . ; Current EL 32bits: Synchronous
ALIGN 128
B irqHandler ; IRQ/vIRQ
B fiqHandler ; FIQ/vFIQ
B . ; Error/vError
B . ; Current EL 64bits: Synchronous <<<<<<< This is where the code branches to
B . ; Lower EL SPx: Synchronous
B . ; Lower EL SP0: Synchronous
.......
LDR x0, =monitor_vectors
MSR VBAR_EL3, x0
I suspect that you got an exception within an exception. That is, the IRQ was taken, but by taking the IRQ you triggered another exception. Either that, or you've got your vector table alignment wrong.
If you are using a Fast Model or a DSM, I'd suggest enabling TARMAC trace. It will let you see what happened cycle by cycle.
For the exception you are seeing check the values of ESR_ELn, ELR_ELn and SPSR_ELn (where "n" is the EL you're in, which I'm assuming is 3). If it really is a synchronous exception, between them they should tell you what type of exception you've taken and where (VA+EL) you took it from.
On the vector table alignment... What is the address of the first instruction in your vector table and what is the value in VBAR_EL3? I'm guessing you're using armasm from the code snippet you posted. In your vector table source file, are setting the alignment requirement for the linker? Something "ALIGN=12" in the AREA directive. For example:
AREA VECTORS, CODE, ALIGN=12
I checked and it seems that the exception hasn't been preempted by another:
ESR_EL3 = 0x0
ELR_EL3 = <Location of my while loop>
SPSR_EL3.A = 1
.C= 1
.Z = 1
VBAR_EL3 is correctly pointing to my vector table.
I do this on top of my vector table(copied from an ARM example)
PRESERVE8
AREA core_bootcode_section, CODE, READONLY, ALIGN=12
Does the SPSR_EL3 show that you came from EL3 with SP_EL3 selected? (I'm assuming yes, given the vector table entry you said you were at).
If yes, that I think something slightly different happened. Before the interrupt you took a different (synchronous) exception. Taking the exception set the mask bits, masking the later interrupt. As the vector table entry for the synchronous exception was a branch to self, the code looped forever.
It would be worth sanity checking what is actually in memory at the address pointed at by ELR_EL3. Also you could try setting a breakpoint just before the loop in your code, and stepping through a couple of iterations.
Yes, that is correct.
I stepped through iterations for loop in my code. Here's what happens:
1) Control hits loop. ISR = 0, ELR_EL3=0 and SPSR_EL3=0
2) I step for 3-4 iterations.
3) ISR = 0x80 (i.e. ISR.IRQ_PENDING =1)
4) I step once more.
5) ELR_EL3=<address of my loop>, SPSR_EL3=0x6000030D( i.e. A, C, Z, D_E = 1)
I can't figure out what is going wrong here. Thanks a lot for your effort and help.
The SPSR value looks as expected, and it looks like you took the IRQ. Meaning execution should have jumped to "VBAR_EL3 + 0x280", which is the IRQ vector for coming from same EL with ELx selected. But you see it jumpt to "VBAR_EL3 + 0x200" when you stepped to (5)?
Hi Martin. Finally got it working! I was missing a "ALIGN 128" directive at starting of the vector table(as you can see in the code snippet above). It was your last reply that hinted me to check.
Thanks a lot for walking me through this.