1

When ARM chips(cortex-A7)are compiled in thumb mode, the program may run abnormally, and the exception point has been located. The problematic C code is:

while (locked && result) 
{
    // while loop body
}

The assembly code compiled from the while( locked && result ) statement in thumb mode is as follows:

0x000e21c0 <+120>:    cmp    r3, #0
0x000e21c2 <+122>:    ite    eq
0x000e21c4 <+124>:    moveq    r3, #0
0x000e21c6 <+126>:    andne.w    r3, r11, #1
0x000e21ca <+130>:    cmp    r3, #0
0x000e21cc <+132>:    beq.n    0xe226c 

In which the value of locked is loaded into r3. Under normal circumstances, if locked=0, the code execution logic is 0x000e21c2 -> 0x000e21c4 -> 0x000e21ca. However, when the program runs to 0x000e21c4 (at this point, the value of PC is already 0x000e21ca), an interrupt occurs. The chip automatically gives the PC pointer (0x000e21ca) to the LR jump register, and then jumps to the interrupt handler function IRQ.

In the interrupt handling function, in order to normally jump back to the moment when the interrupt is triggered, the operation sub r0,lr,#4 is executed to roll back one instruction. At this time, lr=0x000e21ca - 4 = 0x000e21c6, resulting in PC=0x000e21c6 when exiting the interrupt, while the normal situation should be 0x000e21c4.

IRQ:
        ...
        sub     r0,lr,#4       
        ...
        stmfd   sp!,{r0-r2,r4,r5}

The above logic will cause the program to enter the while loop body when locked = 0, resulting in abnormal program operation.

Therefore, I would like to know how to operate the LR register in the interrupt handling function in this case, in order to ensure that after exiting the interrupt function, it returns to the normal code logic.

xukai
  • 27
  • 2
  • "the operation sub r0,lr,#4 is executed to roll back one instruction", one instruction in Thumb mode suppose to be '2' bytes, isn't it ? – user3124812 May 18 '23 at 09:11
  • The Thumb-2 instructions are 16-bit or 32-bit, and it is difficult to know in an interrupt handler which bytes to back up LR to reach the location of the interrupt breakpoint. I have also tried LR minus 2, but there are still problems. – xukai May 18 '23 at 10:43
  • If I read the docs correctly, in case of a hardware interrupt, the saved LR should be the address of the next instruction to execute. So if you see the value `0x000e21ca` then the `cmp` instruction has not yet executed. You should be able to return directly to this address without adjustment. Subtracting 4 or any other value from the LR seems wrong. – Nate Eldredge May 18 '23 at 17:04
  • The error is most likely on exit for the IRQ, which isn't shown. `movs pc, lr` is a normal return. What is the `lr` on return. As the code did not save `r0` it is clobbered, but what value is subtracted doesn't matter unless this is moved to `lr` before an `movs pc, lr`... Please show the IRQ return sequence. – artless noise May 18 '23 at 20:25

1 Answers1

0

There are multiple lr registers on a Cortex-A CPU. These are called banked registers. An interrupt will transition to irq mode, where there is a banked (different copy) of lr. Upon returning, the cpsr is restored and the mode is change which results in the original copy of the lr being used.

If your interrupt system is not structured like this, you have broken a Cortex-A model and need to explain. If you have ported some system from a Cortex-M framework, you may have inadvertently caused this issue. So the code in the 'loop body' is entirely correct. It is the interrupt handler that is suspect, but it is unclear as to the issue without knowing larger system level constructs of how the 'main line' and interrupts are interacting.

artless noise
  • 21,212
  • 6
  • 68
  • 105
  • You would never mess with the lr value on Cortex-M, either. – Tom V May 19 '23 at 10:55
  • I guess I was not clear. The `lr_irq` can be modified on a Cortex-A as a scratch and will not impact user mode. In a Cortex-M it will. Depending on what the scheduler design is, these are key points and so the CPU models are not interchangeable. There are reasons to 'mess with the lr', but if you do so, it is completely different exception models and they do not translate. – artless noise May 19 '23 at 14:28