This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Problems with interrupting LDM/STM Cortex M4?

I am seeing stack corruption running a Cortex M4 that seems to be related to interrupting multicycle instructions.

The interrupt occurs during a STMDB sp!, {r4, r5, r6, r7, r8, r9, sl, lr}

The ICI bits at the time of the interrupt equal 7. This means that the STM was partially completed, and should be resumed starting at r7.

However, if I look at the stack at the time of the interrupt, I see 4 words were written by the interrupted STM, namely r4, r5, r6, and r7. This means that

r7 will be written again when the processor resumes the STMDB instruction.

This does not happen all the time. But it forces me to disable interruption of multicycle instructions.

  • Hi, this happens if the STMDB instruction is part of an If-Then instruction block, in this case the instruction is restarted from the beginning after interrupt completion.

    It should not corrupt the stack but may generate problems if the accessed memory is in the peripheral´s region and you unintentionally write twice to a peripheral.

    The reason is because ICI and IT bits are in the same place.

    Could you verify if your multicycle instruction is inside an IT instruction block?, If so, just change the code to avoid it, instead of disabling interrupts.

  • Hi, is it a problem for you? However, "ARMRv7-M Architecture Reference Manual" says "The continuation state of the LDM or STM is held in the ICI bits in the EPSR . It is IMPLEMENTATION DEFINED when interrupts are recognized, so the use of the ICI bits is IMPLEMENTATION DEFINED." in the chapter B1.5.10. The phenomenon would not be surprised. That is, it is not guaranteed of each register to be accessed only once.

    Best regards,
    Yasuhiko Koumoto.

  • The STMDB is not part of an if-then. The core supports interrupting an STM, LDM, PUSH and POP mid-operation. The instruction is not restarted from the beginning, but rather from the register indicated by the ICI bits.

  • This is assembly code generated from GCC. Most functions push registers on the stack, and this results in many STMs with the stack as the destination. If a register is stored twice on the push because of an interrupt, and only popped once on the pop, the stack is corrupt and the program invariably crashes. This is the behavior I am seeing. It is very problematic.

  • You must ensure that if r4, r5,.., r11 are modified by the exception handler, they should be stacked at the beginning of this handler and de-stacked at the end of it, because they are not automatically saved by the processor.

    As in your case r7 has been altered by the exception handler, the value that will be stacked is the new (wrong) r7. But the problem is not limited to multiple Load/Store instructions, it will also happen with any instruction which uses r7 after the exception.

    You should re-write the exception handler and be sure to restore r4,..,r9 to their original values before leaving the handler.

  • Hi Paulgiangrossi,

    You shouldn't need to be doing that. As the other contributors mentioned, there are a few circumstances in which accesses will be repeated, but these are nevertheless harmless. (If the target address was volatile, the compiler should not have accessed it with a multiple access.) For normal memory, repeating the write of the same register to the same address is acceptable behavior. However, you seem to be saying that a register has been written to two different addresses, ie. stacked twice in consecutive locations.

    This is not a known errata for the processor, and I am pretty sure it would have been seen in validation if it were generally true. So it follows that you have hit an unusual corner case in some respect. Can you tell us something more about the chip you are using? Do you know anything about the memory system, for example what wait-states it presents? Where is your stack located in memory? How are you observing the incorrect stack frame contents? Can you tell us about what that interrupt handler does? Does it interfere with the stack pointer in any way?

  • Hi Paul, I see your company has a technical support entitlement and you have submitted this issue as a support case, so I suggest we continue the investigations in that channel where we can more openly discuss non-public technical details with you. I am just setting up the scenario you have described in my simulation testbench.

  • Hi Paul, I have simulated the test case as you described the details, but the processor is behaving normally. Please review the waveforms attached in the support case. The STM was interrupted at the point where it stacked r7. The EPSR correctly indicated that r8 would be the continuation point on return from exception, and that is exactly what happened.

  • I believe this could happen if you're in a multithreaded environment, and a context-switch is happening in the middle of the STM instruction. However, it would happen only if there is an error in the context-switcher.

    Normally (if your context switcher is as simple as it can be), this would not happen, though.

  • Hi  paulgiangrossi,

    I'm sorry for late reply. Do you say that the re-start address of the STM was incorrect after returning an ISR? If it is true, It should be a problem. Could you change the Cortex-M4 part? It might be a defective product.

    Best regards,
    Yasuhiko Koumoto.

  • Interrupt handler does not modify r4-r11. r7 has not been modified by the exception handler.

  • It's may be an idiot response but, an assembler code generated with GCC can indeed present complexities due to many non- necessary instructions. This is by no means a problem related to the processor. I understand that you are looking to encode access your stack inline later ... Do not get can get the same result using the library GCC, in order to keep the same line of programming?

  • Hi paulgiangrossi,

    please tell me a detailed conclusion of this problem. I am very interested in it. As the results, was it a bug?

    Best regards,
    Yasuhiko Koumoto.

  • Hi Yasuhiko,

    We are still investigating. I will publish results once we have

    determined what the problem is.

    Best,

    Paul Giangrossi

  • Unable to reproduce this problem in RTL simulation. It is reproducible

    on an FPGA prototype. The project resolution is to disable multi-cycle

    instruction interrupts via the Auxiliary Control Register.

    The ARM support case is closed. It is most likely something with our

    implementation.