1e33b78a6SSoby Mathew/* 2*86822f24SManish V Badarkhe * Copyright (c) 2016-2025, Arm Limited and Contributors. All rights reserved. 3e33b78a6SSoby Mathew * 482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause 5e33b78a6SSoby Mathew */ 6e33b78a6SSoby Mathew 7e33b78a6SSoby Mathew#include <asm_macros.S> 8e33b78a6SSoby Mathew 9e33b78a6SSoby Mathew .globl spin_lock 10e33b78a6SSoby Mathew .globl spin_unlock 11e33b78a6SSoby Mathew 120147bef5SEtienne Carriere#if ARM_ARCH_AT_LEAST(8, 0) 130147bef5SEtienne Carriere/* 140147bef5SEtienne Carriere * According to the ARMv8-A Architecture Reference Manual, "when the global 150147bef5SEtienne Carriere * monitor for a PE changes from Exclusive Access state to Open Access state, 160147bef5SEtienne Carriere * an event is generated.". This applies to both AArch32 and AArch64 modes of 170147bef5SEtienne Carriere * ARMv8-A. As a result, no explicit SEV with unlock is required. 180147bef5SEtienne Carriere */ 190147bef5SEtienne Carriere#define COND_SEV() 200147bef5SEtienne Carriere#else 210147bef5SEtienne Carriere#define COND_SEV() sev 220147bef5SEtienne Carriere#endif 23e33b78a6SSoby Mathew 24*86822f24SManish V Badarkhe/* 25*86822f24SManish V Badarkhe * Function: spin_lock 26*86822f24SManish V Badarkhe * ------------------- 27*86822f24SManish V Badarkhe * Acquires a spinlock by continuously attempting to set it. 28*86822f24SManish V Badarkhe * Will block (spin) until the lock is successfully acquired. 29*86822f24SManish V Badarkhe * 30*86822f24SManish V Badarkhe * Arguments: 31*86822f24SManish V Badarkhe * r0 - Pointer to the spinlock variable (uint32_t *lock) 32*86822f24SManish V Badarkhe * 33*86822f24SManish V Badarkhe * Return: 34*86822f24SManish V Badarkhe * None 35*86822f24SManish V Badarkhe * 36*86822f24SManish V Badarkhe * Description: 37*86822f24SManish V Badarkhe * Blocks until the lock is acquired using LDREX/STREX with WFE for wait. 38*86822f24SManish V Badarkhe */ 39e33b78a6SSoby Mathewfunc spin_lock 40e33b78a6SSoby Mathew mov r2, #1 41e33b78a6SSoby Mathew1: 42e33b78a6SSoby Mathew ldrex r1, [r0] 43e33b78a6SSoby Mathew cmp r1, #0 44e33b78a6SSoby Mathew wfene 45e33b78a6SSoby Mathew strexeq r1, r2, [r0] 46e33b78a6SSoby Mathew cmpeq r1, #0 47e33b78a6SSoby Mathew bne 1b 48e33b78a6SSoby Mathew dmb 49e33b78a6SSoby Mathew bx lr 50e33b78a6SSoby Mathewendfunc spin_lock 51e33b78a6SSoby Mathew 52*86822f24SManish V Badarkhe/* 53*86822f24SManish V Badarkhe * Function: spin_trylock 54*86822f24SManish V Badarkhe * ---------------------- 55*86822f24SManish V Badarkhe * Attempts to acquire the spinlock once without blocking. 56*86822f24SManish V Badarkhe * 57*86822f24SManish V Badarkhe * Arguments: 58*86822f24SManish V Badarkhe * r0 - Pointer to the spinlock variable (uint32_t *lock) 59*86822f24SManish V Badarkhe * 60*86822f24SManish V Badarkhe * Return: 61*86822f24SManish V Badarkhe * r0 - 1 if lock was successfully acquired 62*86822f24SManish V Badarkhe * 0 if lock was already held 63*86822f24SManish V Badarkhe * 64*86822f24SManish V Badarkhe * Description: 65*86822f24SManish V Badarkhe * Tries once to acquire the lock using LDREX/STREX. 66*86822f24SManish V Badarkhe */ 67*86822f24SManish V Badarkhefunc spin_trylock 68*86822f24SManish V Badarkhe mov r2, #1 69*86822f24SManish V Badarkhe ldrex r1, [r0] 70*86822f24SManish V Badarkhe cmp r1, #0 71*86822f24SManish V Badarkhe strexeq r1, r2, [r0] 72*86822f24SManish V Badarkhe cmpeq r1, #0 73*86822f24SManish V Badarkhe dmb 74*86822f24SManish V Badarkhe moveq r0, #1 75*86822f24SManish V Badarkhe movne r0, #0 76*86822f24SManish V Badarkhe bx lr 77*86822f24SManish V Badarkheendfunc spin_trylock 78e33b78a6SSoby Mathew 79*86822f24SManish V Badarkhe/* 80*86822f24SManish V Badarkhe * Function: spin_unlock 81*86822f24SManish V Badarkhe * --------------------- 82*86822f24SManish V Badarkhe * Releases the spinlock by clearing its value. 83*86822f24SManish V Badarkhe * 84*86822f24SManish V Badarkhe * Arguments: 85*86822f24SManish V Badarkhe * r0 - Pointer to the spinlock variable (uint32_t *lock) 86*86822f24SManish V Badarkhe * 87*86822f24SManish V Badarkhe * Return: 88*86822f24SManish V Badarkhe * None 89*86822f24SManish V Badarkhe * 90*86822f24SManish V Badarkhe * Description: 91*86822f24SManish V Badarkhe * Releases the lock using store-release and sends SEV. 92*86822f24SManish V Badarkhe */ 93e33b78a6SSoby Mathewfunc spin_unlock 94e33b78a6SSoby Mathew mov r1, #0 95e33b78a6SSoby Mathew stl r1, [r0] 960147bef5SEtienne Carriere COND_SEV() 97e33b78a6SSoby Mathew bx lr 98e33b78a6SSoby Mathewendfunc spin_unlock 99