SWRZ119 February 2022 CC1311R3
Arm® Errata #838869: Store immediate overlapping exception return operation might vector to incorrect interrupt
Revision B
Configurations Affected:
This erratum only affects systems where writeable memory locations can exhibit more than one wait state (system SRAM does not have wait states).
The Arm®Cortex®-M4 processor includes a write buffer that permits execution to continue while a store is waiting on the bus. Under specific timing conditions, during an exception return while this buffer is still in use by a store instruction, a late change in selection of the next interrupt to be taken might result in a mismatch between the interrupt acknowledged by the interrupt controller and the vector fetched by the processor.
Conditions:
STR/STRH/STRB <Rt>, [<Rn>,#imm]
STR/STRH/STRB <Rt>, [<Rn>,#imm]!
STR/STRH/STRB <Rt>, [<Rn>,#imm]
Implications:
The processor should execute interrupt handler C, and on completion of handler C the processor should execute the handler for B. If the previously listed conditions are met, then this erratum results in the processor erroneously clearing the pending state of interrupt C, and then twice executing the handler for B. The first time the handler for B is executed it will be at the priority level for interrupt C. If interrupt C is pended by a level-based interrupt that is cleared by C's handler then interrupt C will be pended again after the handler for B has completed and the handler for C will be executed. If interrupt C is level based, then this interrupt will eventually become re-pending and subsequently be handled. If interrupt C is a single pulse interrupt, there is a possibility that this interrupt will be lost.
This bug is triggered in a rare condition. In cases where STORE experiences more than 2 wait cycles, workarounds must be used by the software developer.
Recommended workaround:
Ensure a DSB instruction occurs between the store and the BX instruction. For exception handlers written in C, this can be achieved by inserting the appropriate set of intrinsics or inline assembly just before the end of the interrupt function, for example:
ARMCC:
...
__schedule_barrier(); __asm{DSB}; __schedule_barrier(); }
GCC:
...
__asm volatile (“dsb 0xf” ::: “memory”); }
The workaround for this bug will not be added automatically by the compiler.
Alternate workaround:
Disable CPU write buffering (register CPU_SCS.ACTLR.DISDEFWBUF) at the cost of significantly reduced execution speed.