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 | |
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')
-rw-r--r-- | sys/arch/amd64/amd64/acpi_machdep.c | 40 | ||||
-rw-r--r-- | sys/arch/i386/i386/acpi_machdep.c | 40 | ||||
-rw-r--r-- | sys/dev/acpi/acpivar.h | 8 |
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 |