summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorPaul Irofti <pirofti@cvs.openbsd.org>2012-11-27 17:38:47 +0000
committerPaul Irofti <pirofti@cvs.openbsd.org>2012-11-27 17:38:47 +0000
commit4ce4a3d78f15bc213ebe455a7c1418ae98dc0941 (patch)
treee70799ce089fb1f042e1b117e1356246e947d3cc /sys
parentd51f5cddc8d73c07fbba14de4cd999b975ef3287 (diff)
Add acpi_{acquire,release}_glk locking functions.
These functions represent the basic blocks for using the ACPI global lock that provides mutual exclusion between the OSPM and the BIOS. No functional change. Okay kettenis@, deraadt@.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/amd64/amd64/acpi_machdep.c40
-rw-r--r--sys/arch/i386/i386/acpi_machdep.c40
-rw-r--r--sys/dev/acpi/acpivar.h8
3 files changed, 85 insertions, 3 deletions
diff --git a/sys/arch/amd64/amd64/acpi_machdep.c b/sys/arch/amd64/amd64/acpi_machdep.c
index 99fe248dfcc..3b50812f384 100644
--- a/sys/arch/amd64/amd64/acpi_machdep.c
+++ b/sys/arch/amd64/amd64/acpi_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi_machdep.c,v 1.51 2012/10/17 22:49:27 deraadt Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.52 2012/11/27 17:38:45 pirofti Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -168,6 +168,44 @@ havebase:
return (1);
}
+/*
+ * 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_glk(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_glk(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
diff --git a/sys/arch/i386/i386/acpi_machdep.c b/sys/arch/i386/i386/acpi_machdep.c
index da46d09db66..0b8fe09efcd 100644
--- a/sys/arch/i386/i386/acpi_machdep.c
+++ b/sys/arch/i386/i386/acpi_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpi_machdep.c,v 1.45 2012/10/17 22:49:27 deraadt Exp $ */
+/* $OpenBSD: acpi_machdep.c,v 1.46 2012/11/27 17:38:45 pirofti Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -183,6 +183,44 @@ havebase:
return (1);
}
+/*
+ * 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_glk(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_glk(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
diff --git a/sys/dev/acpi/acpivar.h b/sys/dev/acpi/acpivar.h
index 2f9b0e1afcd..78e8303df3c 100644
--- a/sys/dev/acpi/acpivar.h
+++ b/sys/dev/acpi/acpivar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: acpivar.h,v 1.74 2012/10/08 21:47:50 deraadt Exp $ */
+/* $OpenBSD: acpivar.h,v 1.75 2012/11/27 17:38:46 pirofti Exp $ */
/*
* Copyright (c) 2005 Thorsten Lockert <tholo@sigmasoft.com>
*
@@ -325,6 +325,12 @@ int acpi_dotask(struct acpi_softc *);
void acpi_powerdown_task(void *, int);
void acpi_sleep_task(void *, int);
+/* Section 5.2.10.1: global lock acquire/release functions */
+#define GL_BIT_PENDING 0x01
+#define GL_BIT_OWNED 0x02
+int acpi_acquire_glk(uint32_t *);
+int acpi_release_glk(uint32_t *);
+
void acpi_pciroots_attach(struct device *, void *, cfprint_t);
#endif