summaryrefslogtreecommitdiffstats
path: root/sys/dev/acpica
diff options
context:
space:
mode:
authornjl <njl@FreeBSD.org>2004-05-05 20:04:14 +0000
committernjl <njl@FreeBSD.org>2004-05-05 20:04:14 +0000
commitf6bbab06a9c9c5ee8915e070a39d0c0285b9cfa1 (patch)
tree5200dfd19b49a6bca75c01e2650ddabae2247eee /sys/dev/acpica
parent394d08093f3875935167a6a05f1679f87a1c9189 (diff)
downloadFreeBSD-src-f6bbab06a9c9c5ee8915e070a39d0c0285b9cfa1.zip
FreeBSD-src-f6bbab06a9c9c5ee8915e070a39d0c0285b9cfa1.tar.gz
Add an MI implementation of the ACPI global lock routines and retire the
individual asm versions. The global lock is shared between the BIOS and OS and thus cannot use our mutexes. It is defined in section 5.2.9.1 of the ACPI specification. Reviewed by: marcel, bde, jhb
Diffstat (limited to 'sys/dev/acpica')
-rw-r--r--sys/dev/acpica/Osd/OsdSynch.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/sys/dev/acpica/Osd/OsdSynch.c b/sys/dev/acpica/Osd/OsdSynch.c
index 5f3398e..34b66fd 100644
--- a/sys/dev/acpica/Osd/OsdSynch.c
+++ b/sys/dev/acpica/Osd/OsdSynch.c
@@ -389,3 +389,47 @@ AcpiOsReleaseLock (ACPI_HANDLE Handle, UINT32 Flags)
return;
mtx_unlock(m);
}
+
+/* Section 5.2.9.1: global lock acquire/release functions */
+#define GL_ACQUIRED (-1)
+#define GL_BUSY 0
+#define GL_BIT_PENDING 0x1
+#define GL_BIT_OWNED 0x2
+#define GL_BIT_MASK (GL_BIT_PENDING | GL_BIT_OWNED)
+
+/*
+ * 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_MASK) | GL_BIT_OWNED) |
+ ((old >> 1) & GL_BIT_PENDING));
+ } while (atomic_cmpset_acq_int(lock, old, new) == 0);
+
+ return ((new < GL_BIT_MASK) ? GL_ACQUIRED : GL_BUSY);
+}
+
+/*
+ * 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_MASK;
+ } while (atomic_cmpset_rel_int(lock, old, new) == 0);
+
+ return (old & GL_BIT_PENDING);
+}
OpenPOWER on IntegriCloud