1e33b78a6SSoby Mathew/* 286822f24SManish 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 10*d7e9372fSVarun Wadekar .globl spin_trylock 11e33b78a6SSoby Mathew .globl spin_unlock 12e33b78a6SSoby Mathew 130147bef5SEtienne Carriere#if ARM_ARCH_AT_LEAST(8, 0) 140147bef5SEtienne Carriere/* 150147bef5SEtienne Carriere * According to the ARMv8-A Architecture Reference Manual, "when the global 160147bef5SEtienne Carriere * monitor for a PE changes from Exclusive Access state to Open Access state, 170147bef5SEtienne Carriere * an event is generated.". This applies to both AArch32 and AArch64 modes of 180147bef5SEtienne Carriere * ARMv8-A. As a result, no explicit SEV with unlock is required. 190147bef5SEtienne Carriere */ 200147bef5SEtienne Carriere#define COND_SEV() 210147bef5SEtienne Carriere#else 220147bef5SEtienne Carriere#define COND_SEV() sev 230147bef5SEtienne Carriere#endif 24e33b78a6SSoby Mathew 2586822f24SManish V Badarkhe/* 2686822f24SManish V Badarkhe * Function: spin_lock 2786822f24SManish V Badarkhe * ------------------- 2886822f24SManish V Badarkhe * Acquires a spinlock by continuously attempting to set it. 2986822f24SManish V Badarkhe * Will block (spin) until the lock is successfully acquired. 3086822f24SManish V Badarkhe * 3186822f24SManish V Badarkhe * Arguments: 3286822f24SManish V Badarkhe * r0 - Pointer to the spinlock variable (uint32_t *lock) 3386822f24SManish V Badarkhe * 3486822f24SManish V Badarkhe * Return: 3586822f24SManish V Badarkhe * None 3686822f24SManish V Badarkhe * 3786822f24SManish V Badarkhe * Description: 3886822f24SManish V Badarkhe * Blocks until the lock is acquired using LDREX/STREX with WFE for wait. 3986822f24SManish V Badarkhe */ 40e33b78a6SSoby Mathewfunc spin_lock 41e33b78a6SSoby Mathew mov r2, #1 42e33b78a6SSoby Mathew1: 43e33b78a6SSoby Mathew ldrex r1, [r0] 44e33b78a6SSoby Mathew cmp r1, #0 45e33b78a6SSoby Mathew wfene 46e33b78a6SSoby Mathew strexeq r1, r2, [r0] 47e33b78a6SSoby Mathew cmpeq r1, #0 48e33b78a6SSoby Mathew bne 1b 49e33b78a6SSoby Mathew dmb 50e33b78a6SSoby Mathew bx lr 51e33b78a6SSoby Mathewendfunc spin_lock 52e33b78a6SSoby Mathew 5386822f24SManish V Badarkhe/* 5486822f24SManish V Badarkhe * Function: spin_trylock 5586822f24SManish V Badarkhe * ---------------------- 5686822f24SManish V Badarkhe * Attempts to acquire the spinlock once without blocking. 5786822f24SManish V Badarkhe * 5886822f24SManish V Badarkhe * Arguments: 5986822f24SManish V Badarkhe * r0 - Pointer to the spinlock variable (uint32_t *lock) 6086822f24SManish V Badarkhe * 6186822f24SManish V Badarkhe * Return: 6286822f24SManish V Badarkhe * r0 - 1 if lock was successfully acquired 6386822f24SManish V Badarkhe * 0 if lock was already held 6486822f24SManish V Badarkhe * 6586822f24SManish V Badarkhe * Description: 6686822f24SManish V Badarkhe * Tries once to acquire the lock using LDREX/STREX. 6786822f24SManish V Badarkhe */ 6886822f24SManish V Badarkhefunc spin_trylock 6986822f24SManish V Badarkhe mov r2, #1 7086822f24SManish V Badarkhe ldrex r1, [r0] 7186822f24SManish V Badarkhe cmp r1, #0 7286822f24SManish V Badarkhe strexeq r1, r2, [r0] 7386822f24SManish V Badarkhe cmpeq r1, #0 7486822f24SManish V Badarkhe dmb 7586822f24SManish V Badarkhe moveq r0, #1 7686822f24SManish V Badarkhe movne r0, #0 7786822f24SManish V Badarkhe bx lr 7886822f24SManish V Badarkheendfunc spin_trylock 79e33b78a6SSoby Mathew 8086822f24SManish V Badarkhe/* 8186822f24SManish V Badarkhe * Function: spin_unlock 8286822f24SManish V Badarkhe * --------------------- 8386822f24SManish V Badarkhe * Releases the spinlock by clearing its value. 8486822f24SManish V Badarkhe * 8586822f24SManish V Badarkhe * Arguments: 8686822f24SManish V Badarkhe * r0 - Pointer to the spinlock variable (uint32_t *lock) 8786822f24SManish V Badarkhe * 8886822f24SManish V Badarkhe * Return: 8986822f24SManish V Badarkhe * None 9086822f24SManish V Badarkhe * 9186822f24SManish V Badarkhe * Description: 9286822f24SManish V Badarkhe * Releases the lock using store-release and sends SEV. 9386822f24SManish V Badarkhe */ 94e33b78a6SSoby Mathewfunc spin_unlock 95e33b78a6SSoby Mathew mov r1, #0 96e33b78a6SSoby Mathew stl r1, [r0] 970147bef5SEtienne Carriere COND_SEV() 98e33b78a6SSoby Mathew bx lr 99e33b78a6SSoby Mathewendfunc spin_unlock 100