summaryrefslogtreecommitdiff
path: root/services/std_svc/lfa/lfa_relocatable.S
diff options
context:
space:
mode:
Diffstat (limited to 'services/std_svc/lfa/lfa_relocatable.S')
-rw-r--r--services/std_svc/lfa/lfa_relocatable.S108
1 files changed, 108 insertions, 0 deletions
diff --git a/services/std_svc/lfa/lfa_relocatable.S b/services/std_svc/lfa/lfa_relocatable.S
new file mode 100644
index 000000000..7436584bb
--- /dev/null
+++ b/services/std_svc/lfa/lfa_relocatable.S
@@ -0,0 +1,108 @@
+/*
+ * Copyright (c) 2026, Arm Limited and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <asm_macros.S>
+#include <platform_def.h>
+
+/* Relocatable code section */
+
+ .globl lfa_r_holding_lock
+ .globl lfa_r_holding_wait
+ .globl lfa_r_holding_unlock
+ .globl lfa_r_holding_wait_warm_reset
+
+/*
+ * The 'rfunc' macro is a modified version of the 'func' macro in
+ * "include/common/asm_macros_common.S". It differs in that it does not change
+ * the section to ".text.asm". See the original version for comments.
+ */
+ .macro rfunc _name, _align=2
+ .cfi_sections .debug_frame
+ .section .lfa_relocatable_code.\_name, "ax"
+ .type \_name, %function
+ .cfi_startproc
+ .align \_align
+ \_name:
+#if ENABLE_BTI
+ bti jc
+#endif
+ .endm
+
+/*
+ * Enable holding lock.
+ *
+ * void lfa_r_holding_lock(spinlock_t *lock);
+ */
+rfunc lfa_r_holding_lock
+ mov w1, #1
+ stlr w1, [x0]
+ ret
+endfunc lfa_r_holding_lock
+
+/*
+ * Release hold.
+ *
+ * Use store-release to unconditionally clear the spinlock variable.
+ * Store operation generates an event to all cores waiting in WFE
+ * when address is monitored by the global monitor.
+ *
+ * void lfa_r_holding_unlock(spinlock_t *lock);
+ */
+rfunc lfa_r_holding_unlock
+ mov w1, #0
+ stlr w1, [x0]
+ ret
+endfunc lfa_r_holding_unlock
+
+/*
+ * Check lock using load-exclusive instruction.
+ *
+ * void lfa_r_holding_wait(spinlock_t *lock);
+ */
+rfunc lfa_r_holding_wait
+ sevl
+l1: wfe
+ ldaxr w1, [x0]
+ cbnz w1, l1
+ ret
+endfunc lfa_r_holding_wait
+
+/*
+ * Check lock using load-exclusive instruction.
+ * Issue RMR_EL3 for warm reset if lock is unlocked
+ *
+ * void lfa_r_holding_wait(spinlock_t *lock);
+ */
+rfunc lfa_r_holding_wait_warm_reset
+ sevl
+l2:
+ wfe
+ ldaxr w1, [x0]
+ cbnz w1, l2
+l3:
+ wfi
+ b l3
+endfunc lfa_r_holding_wait_warm_reset
+
+/* Relocatable data section */
+
+ .globl lfa_r_holding_lock_var
+ .globl lfa_r_ep_addresses
+ .globl lfa_r_context_ids
+
+.align 8
+.section .lfa_relocatable_data.lfa_r_holding_lock_var, "aw"
+lfa_r_holding_lock_var: .quad 0x0
+
+.align 8
+.section .lfa_relocatable_data.lfa_r_ep_addresses, "aw"
+lfa_r_ep_addresses:
+ .fill PLATFORM_CORE_COUNT, 8, 0x0
+
+.align 8
+.section .lfa_relocatable_data.lfa_r_context_ids, "aw"
+lfa_r_context_ids:
+ .fill PLATFORM_CORE_COUNT, 8, 0x0