Now that the atomic ops are in, I'd like to commit the first building
block for acpi global lock support.

Index: arch/amd64/amd64/acpi_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/amd64/amd64/acpi_machdep.c,v
retrieving revision 1.51
diff -u -p -r1.51 acpi_machdep.c
--- arch/amd64/amd64/acpi_machdep.c     17 Oct 2012 22:49:27 -0000      1.51
+++ arch/amd64/amd64/acpi_machdep.c     19 Nov 2012 16:45:39 -0000
@@ -168,6 +168,48 @@ havebase:
        return (1);
 }
 
+/* Section 5.2.10.1: global lock acquire/release functions */
+#define        GL_BIT_PENDING  0x01
+#define        GL_BIT_OWNED    0x02
+
+/*
+ * Acquire the global lock.  If busy, set the pending bit.  The caller
+ * will wait for notification from the BIOS that the lock is available
+ * and then attempt to acquire it again.
+ */
+int
+acpi_acquire_global_lock(uint32_t *lock)
+{
+       uint32_t        new, old;
+
+       do {
+               old = *lock;
+               new = (old & ~GL_BIT_PENDING) | GL_BIT_OWNED;
+               if ((old & GL_BIT_OWNED) != 0)
+                       new |= GL_BIT_PENDING;
+       } while (x86_atomic_cas_int32(lock, old, new) == 0);
+
+       return ((new & GL_BIT_PENDING) == 0);
+}
+
+/*
+ * Release the global lock, returning whether there is a waiter pending.
+ * If the BIOS set the pending bit, OSPM must notify the BIOS when it
+ * releases the lock.
+ */
+int
+acpi_release_global_lock(uint32_t *lock)
+{
+       uint32_t        new, old;
+
+       do {
+               old = *lock;
+               new = old & ~(GL_BIT_PENDING | GL_BIT_OWNED);
+       } while (x86_atomic_cas_int32(lock, old, new) == 0);
+
+       return ((old & GL_BIT_PENDING) != 0);
+}
+
 #ifndef SMALL_KERNEL
 
 void
Index: arch/i386/i386/acpi_machdep.c
===================================================================
RCS file: /cvs/src/sys/arch/i386/i386/acpi_machdep.c,v
retrieving revision 1.45
diff -u -p -r1.45 acpi_machdep.c
--- arch/i386/i386/acpi_machdep.c       17 Oct 2012 22:49:27 -0000      1.45
+++ arch/i386/i386/acpi_machdep.c       19 Nov 2012 16:45:40 -0000
@@ -183,6 +183,48 @@ havebase:
        return (1);
 }
 
+/* Section 5.2.10.1: global lock acquire/release functions */
+#define        GL_BIT_PENDING  0x01
+#define        GL_BIT_OWNED    0x02
+
+/*
+ * Acquire the global lock.  If busy, set the pending bit.  The caller
+ * will wait for notification from the BIOS that the lock is available
+ * and then attempt to acquire it again.
+ */
+int
+acpi_acquire_global_lock(uint32_t *lock)
+{
+       uint32_t        new, old;
+
+       do {
+               old = *lock;
+               new = (old & ~GL_BIT_PENDING) | GL_BIT_OWNED;
+               if ((old & GL_BIT_OWNED) != 0)
+                       new |= GL_BIT_PENDING;
+       } while (i386_atomic_cas_int32(lock, old, new) == 0);
+
+       return ((new & GL_BIT_PENDING) == 0);
+}
+
+/*
+ * Release the global lock, returning whether there is a waiter pending.
+ * If the BIOS set the pending bit, OSPM must notify the BIOS when it
+ * releases the lock.
+ */
+int
+acpi_release_global_lock(uint32_t *lock)
+{
+       uint32_t        new, old;
+
+       do {
+               old = *lock;
+               new = old & ~(GL_BIT_PENDING | GL_BIT_OWNED);
+       } while (i386_atomic_cas_int32(lock, old, new) == 0);
+
+       return ((old & GL_BIT_PENDING) != 0);
+}
+
 #ifndef SMALL_KERNEL
 
 void
Index: dev/acpi/acpivar.h
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpivar.h,v
retrieving revision 1.74
diff -u -p -r1.74 acpivar.h
--- dev/acpi/acpivar.h  8 Oct 2012 21:47:50 -0000       1.74
+++ dev/acpi/acpivar.h  19 Nov 2012 16:45:41 -0000
@@ -325,6 +325,9 @@ int acpi_dotask(struct acpi_softc *);
 void   acpi_powerdown_task(void *, int);
 void   acpi_sleep_task(void *, int);
 
+int    acpi_acquire_global_lock(uint32_t *);
+int    acpi_release_global_lock(uint32_t *);
+
 void   acpi_pciroots_attach(struct device *, void *, cfprint_t);
 
 #endif
Index: dev/acpi/dsdt.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.197
diff -u -p -r1.197 dsdt.c
--- dev/acpi/dsdt.c     16 Jul 2012 15:27:11 -0000      1.197
+++ dev/acpi/dsdt.c     19 Nov 2012 16:45:41 -0000
@@ -726,11 +726,8 @@ aml_delchildren(struct aml_node *node)
 void aml_unlockfield(struct aml_scope *, struct aml_value *);
 void aml_lockfield(struct aml_scope *, struct aml_value *);
 
-long acpi_acquire_global_lock(void*);
-long acpi_release_global_lock(void*);
 static long global_lock_count = 0;
-#define acpi_acquire_global_lock(x) 1
-#define acpi_release_global_lock(x) 0
+
 void
 aml_lockfield(struct aml_scope *scope, struct aml_value *field)
 {

Reply via email to