smol-gilbraltar/kernel/spinlock.c
2024-12-23 23:44:47 +01:00

45 lines
1.2 KiB
C

#include <log.h>
#include <stdbool.h>
#include <stdint.h>
#include <synchronize.h>
static bool enabled = false;
void gilbraltar_spinlock_init(void) { enabled = true; }
void gilbraltar_spinlock_acquire(enum level level, uint32_t *s) {
if (level >= IRQ)
gilbraltar_enter_critical(level);
if (enabled) {
gilbraltar_log(DEBUG, "Acquire %08lx.\r\n", (uintptr_t)s);
__asm__ __volatile("mov x1, %0\n"
"mov w2, #1\n"
"prfm pstl1keep, [x1]\n"
"sevl\n"
"1: wfe\n"
"ldaxr w3, [x1]\n"
"cbnz w3, 1b\n"
"stxr w3, w2, [x1]\n"
"cbnz w3, 1b\n"
:
: "r"((uintptr_t)&s[0])
: "x1", "x2", "x3");
gilbraltar_log(DEBUG, "%08lx acquired.\r\n", (uintptr_t)s);
}
}
void gilbraltar_spinlock_release(enum level level, uint32_t *s) {
if (enabled) {
__asm__ __volatile("mov x1, %0\n"
"stlr wzr, [x1]\n"
:
: "r"((uintptr_t)&s[0])
: "x1");
}
if (level >= IRQ)
gilbraltar_leave_critical();
}