0

I am facing an issue related to Return-From-Interrupt when the IRQ interrupted a load/store multiple instruction.

When the IRQ interrupts a load/store multiple instruction, the ICI field of EPSR indicates that the LDM/STM instruction should be continued on the return from interrupt.

On interrupt entry exception frame(containing caller saved context) is stored on the current stack automatically by the hardware.

In my case, Kernel Software then saves the Callee saved context and prepares a new context, which includes a dummy exception frame on the stack. After preparing the new context the BX LR instruction is executed which pops the dummy exception frame. As the dummy exception frame contains the return-address(return address is pointing to new interrupt handler), execution goes to new interrupt handler.

In this case, if the interrupted instruction was an LDM/STM instruction I get a USAGE-FAULT exception with INVSTATE, because hardware on return-from-interrupt is expecting the appropriate LDM/STM instruction, while the return address is a different location in my case.

The ARM-Architecture Reference Manual mentions three design options that can be implemented for CortexM.

In the Instruction Set Attribute Register 2(ID_ISAR2), bits[11:8]:

  1. None supported. This means the LDM and STM instructions are not interruptible. ARMv7-M reserved.
  2. LDM and STM instructions are restartable.
  3. LDM and STM instructions are continuable.

My hardware is implemented with option 3.

What I am unable to understand is, if I force the ICI field of IPSR to 0, will my LDM/STM instruction be restarted or will I still get an exception?

And even if it gets restarted(considering the interrupted STM instruction) will it push on top of already partially pushed registers, corrupting the stack eventually in this case or will it adjust the stack pointer before restarting the operation.

1 Answer 1

2

The ICI/IT field is part of EPSR, not IPSR, not that it makes a huge amount of difference if you're interacting with xPSR.

If an STM or LDM instruction is interrupted, EPSR is set to indicate the point from which the execution can continue, and then exception entry is triggered. It is therefore the stacked PSR value that contains this information, just as it contains the Thumb bit from the interrupted code. If your new context has zero in the ISI bits of the stacked PSR, you should not see a usage fault exception for the reasons you give. (In the absence of any code, I can't really be more specific than this.)

If LDM and STM are implemented as restartable or continuable, then no, the stack will not be corrupted by this process. (That would be a nightmare!) If LDM and STM are restartable then the stack pointer is simply reset to the value it had at the start of the LDM/STM and the instruction is executed anew; if they are continuable then the stack pointer is not modified but a partial STM/LDM is performed to complete the instruction.

You don't mention exactly how you're achieving a context switch, but I assume you are manually pushing r4-r11 to the process stack, then saving the PSP somewhere and updating it to point to the new context on a different stack, before popping r4-r11 and triggering an exception return - that's certainly the usual way to go about it.

Sign up to request clarification or add additional context in comments.

3 Comments

I originally typed my question providing options as bullets, starting from 0. When it got posted bullets started from 1 instead of 0 changing the information I provided. So in-fact my hardware is implemented with option 3 instead of option 2. Just a small edit but I think it changes the question significantly. So if you could update the answer it would be great.
Moreover I believe the previous xPSR is pushed onto the stack as part of the exception entry process, and the updated return information(ICI field) is available in the current xPSR which is used for the return-from-interrupt. It makes sense as if the new xPSR was pushed on stack, where would we get the previous xPSR from, when we actually return from interrupt to the previous context. Do you have any reference to the exception entry behaviour, where new xPSR is pushed on the stack.?
Answer updated. The documentation is not super clear on the timing of the update of the ICI/IT bits, but it must be before the exception entry stacking. If it were not, then an ISR would have to stack EPSR before using LDM/STM to avoid corruption due to nesting interrupts, which it does not. When it comes to exception return, remember that lots of things (including PC!) are obtained from the stack. No reason EPSR shouldn't work the same way.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.