45 lines
1.2 KiB
C
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();
|
|
}
|