#include #include #include #include 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(); }