acpi_func.h revision 1.1 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