I am working on an ARM Cortex-A5 core of a custom processor and getting a really weird issue which seem to be unexplainable from the SW point of view. The issue is that at some point when stress-testing the system (rebooting hundreds of times), sometimes a Prefetch abort is happening when returning from some SVC call. The calls are implemented as following:
User mode code:
;...Stuff
BL foo
;.. Stuff.
foo
PUSH {r4,lr}
SVC #0x1a
POP {r4,pc}
SVC handler:
SVC_Handler
PUSH {r0-r12,lr}
;... Do stuff
POP {r0-r12,lr}
SUBS pc,lr,#0
When the abort is happening, the LR_USR is pointing to the instruction next to BL foo, but IFAR has a value of zero as well as r4. So is LR_ABT has a value of 0x4, which makes sense if we tried to branch to the address zero. Given these observations it looks like the POP {r4,pc} instruction is fetching two zeros from the stack instead of the correct values, which are in the stack at the correct positions as observed with the debugger after the abort is hit (they are two words above the SP_USR). So it looks like either the stack is updated with the correct values after the pop instruction is happening, or the POP instruction is just buggy.
It worth noting that the code and the stack are in a cacheable memory. User mode and SVC mode have distinct stacks.
Can this effect be explained from the SW point of view or it is likely a hardware bug (memory/cache controller?). Have anyone seen something similar in their career? Unfortunately it is possible to debug only post-mortem. And instrumenting the code is shifting the bug away to another call (Yes, it is Heisenbug...)