diff options
author | Paul Irofti <pirofti@cvs.openbsd.org> | 2012-11-27 17:38:47 +0000 |
---|---|---|
committer | Paul Irofti <pirofti@cvs.openbsd.org> | 2012-11-27 17:38:47 +0000 |
commit | 4ce4a3d78f15bc213ebe455a7c1418ae98dc0941 (patch) | |
tree | e70799ce089fb1f042e1b117e1356246e947d3cc /sys/arch | |
parent | d51f5cddc8d73c07fbba14de4cd999b975ef3287 (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/arch')
-rw-r--r-- | sys/arch/amd64/amd64/acpi_machdep.c | 40 | ||||
-rw-r--r-- | sys/arch/i386/i386/acpi_machdep.c | 40 |
2 files changed, 78 insertions, 2 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 |