1 /* $NetBSD: acpi_func.h,v 1.1 2008/05/24 22:16:20 jmcneill Exp $ */ 2 3 #include <machine/cpufunc.h> 4 5 #include <sys/atomic.h> 6 7 #define GL_ACQUIRED (-1) 8 #define GL_BUSY 0 9 #define GL_BIT_PENDING 1 10 #define GL_BIT_OWNED 2 11 #define GL_BIT_MASK (GL_BIT_PENDING | GL_BIT_OWNED) 12 13 #define ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \ 14 do { \ 15 (Acq) = acpi_acquire_global_lock(&((GLptr)->GlobalLock)); \ 16 } while (0) 17 18 #define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \ 19 do { \ 20 (Acq) = acpi_release_global_lock(&((GLptr)->GlobalLock)); \ 21 } while (0) 22 23 static inline int 24 acpi_acquire_global_lock(uint32_t *lock) 25 { 26 uint32_t new, old, val; 27 28 do { 29 old = *lock; 30 new = ((old & ~GL_BIT_MASK) | GL_BIT_OWNED) | 31 ((old >> 1) & GL_BIT_PENDING); 32 val = atomic_cas_32(lock, old, new); 33 } while (__predict_false(val != old)); 34 35 return ((new < GL_BIT_MASK) ? GL_ACQUIRED : GL_BUSY); 36 } 37 38 static inline int 39 acpi_release_global_lock(uint32_t *lock) 40 { 41 uint32_t new, old, val; 42 43 do { 44 old = *lock; 45 new = old & ~GL_BIT_MASK; 46 val = atomic_cas_32(lock, old, new); 47 } while (__predict_false(val != old)); 48 49 return old & GL_BIT_PENDING; 50 } 51 52 #define ACPI_FLUSH_CPU_CACHE() wbinvd() 53