On amd64/i386 there is this nasty thing called SMM mode. This allows
BIOS writers to run code behind the back of the OS to do all sorts of
crazy stuff like simulating a legacy PC keyboard controller on systems
that don't have one, or spin up the fan in your laptop when it is
about to melt. On a lot of hardware it is therefore poking the same
hardware registers that are also used by the ACPI code that's running
in the OS. Ever witnessed what happens if two kids want to play with
the same toy?
So in order to prevent bad things from happening, ACPI defines a
locking protocol to make sure the OS and the SMM BIOS code don't
access the same hardware at the same time. Currently OpenBSD doesn't
do this locking properly. The diff below changes this, enabling the
locking protocol for access to registers that need it.
I've successfully tested this diff on my x220 and on a absolutely
lowest end hp laptop that I bought to do some radeondrm(4)
development. Seems to work fine on those machines. So it's time to
get this more widely tested.
Things to test are suspend/resume, whether the battery status is
properly reported and updated, whether the acpitz(4) temperature
sensors are still working, etc., etc. So please run with it for a bit
and report any breakage.
Thanks,
Mark
P.S. This diff might help machines that where OpenBSD sometimes
reports crazy temperatures. But needs to be tested on other
machines as well!.
Index: dsdt.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/dsdt.c,v
retrieving revision 1.203
diff -u -p -r1.203 dsdt.c
--- dsdt.c 2 Jun 2013 17:21:38 -0000 1.203
+++ dsdt.c 30 Jun 2013 18:43:51 -0000
@@ -770,7 +770,7 @@ aml_lockfield(struct aml_scope *scope, s
/* Spin to acquire lock */
while (!st) {
- st =
acpi_acquire_global_lock(&acpi_softc->sc_facs->global_lock);
+ st = acpi_acquire_glk(&acpi_softc->sc_facs->global_lock);
/* XXX - yield/delay? */
}
@@ -790,7 +790,7 @@ aml_unlockfield(struct aml_scope *scope,
return;
/* Release lock */
- st = acpi_release_global_lock(&acpi_softc->sc_facs->global_lock);
+ st = acpi_release_glk(&acpi_softc->sc_facs->global_lock);
if (!st)
return;