semaphore_take: mov w2, #1 // LOCK value dmb sy // ensure all observers observe data before aquire is attempted ldaxr w1, [x0] // attempt to read and aquire lock cbnz w1, semaphore_take // lock is not zero so loop and try and aquire again stxr w3, w2, [x0] // attempt to store LOCK value cbnz w3, semaphore_take // retry if store failed dmb sy // ensures that all subsequent accesses are observed after gaining of the lock is observed
The above semaphore code worked flawlessly until the moment I added FIQ code.
Now the semaphore leaks thru critical sections even though the FIQ does not come anywhere near the semaphore.
Is there something I need to know about FIQ and LDREX/STREX functions?
The FIQ has the effect of clearing the local monitor on exception return.
(See the architecture manual https://developer.arm.com/docs/ddi0487/latest, B2.9.4 Context switch support)
Thank you both problem solved ... yep just needed CLREX before I did eret on FIQ and fixes problem.
As of vstehle's answer, a CLREX shouldn't be needed. Please try w/o CLREX but with "LDXR" instead of "LDAXR" (see B2.9)
Nope it fails I tried mixing around various combos they don't seem to be paired like you suggest.
"ldaxr" and "stxr" works the same "ldaxr" and "stlxr" and every other combo probably because I have the dmb sy in place.
A forum comment says that ldaxr is essentially ldxr + dmb sy ... or is that not correct
This is actually on a BCM2837 and they have ripped the GIC out and put there own in .. given it is the FIQ behaviour I wonder if that is what is the difference.
I doubt that it is related to the GIC or their interrupt controller. In the end, it pulls the "FIQ" line and the core should handle the FIQ.I seems, the CLREX is sent to all PEs, but the the implicit clearing due to an exception return isn't.
Maybe something to investigate, or maybe just something to "accept" ;-)