Port-amd64 archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

ACPI Global lock broken on amd64



Hi,

I decided to spend some time figuring out why ACPI was broken on my 
amd64 laptop. The problem manifests itself as a spew of ACPI global 
lock errors on boot:

ACPI Warning (evmisc-0657): Cannot release the ACPI Global Lock, it has 
not been acquired [20070320]
ACPI Exception (exutils-0431): AE_NOT_ACQUIRED, Could not release Global 
Lock [20070320]
ACPI Warning (evmisc-0657): Cannot release the ACPI Global Lock, it has 
not been acquired [20070320]
ACPI Exception (exutils-0431): AE_NOT_ACQUIRED, Could not release Global 
Lock [20070320]
...

and any attempt to invoke ACPI methods at runtime (envstat(8), 
shutdown/reboot, ...) results in a wedge.

It turns out that the asm code in sys/arch/amd64/include/acpi_func.h is 
the culprit. It quite simply generates bogus code and could never have 
worked as-is from day one.

I've attached a patch (which re-syncs the amd64 asm code with the i386 
version) which I'd like the amd64 asm experts to review. With this 
patch, normal ACPI service is resumed (FSVO "normal").

Cheers, Steve
Index: acpi_func.h
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/include/acpi_func.h,v
retrieving revision 1.2
diff -u -r1.2 acpi_func.h
--- acpi_func.h 24 Dec 2005 20:06:47 -0000      1.2
+++ acpi_func.h 15 Feb 2008 13:34:55 -0000
@@ -9,36 +9,36 @@
 
 #define        ACPI_ACQUIRE_GLOBAL_LOCK(GLptr, Acq) \
 do { \
-       unsigned long dummy; \
        __asm volatile( \
-       "1:     movl (%1),%%eax         ;" \
+       "1:     movl %1,%%eax           ;" \
        "       movl %%eax,%%edx        ;" \
        "       andq %2,%%rdx           ;" \
        "       btsl $0x1,%%edx         ;" \
        "       adcl $0x0,%%edx         ;" \
        "       lock                    ;" \
-       "       cmpxchgl %%edx,(%1)     ;" \
+       "       cmpxchgl %%edx,%1       ;" \
        "       jnz 1b                  ;" \
+       "       andb $0x3,%%dl          ;" \
        "       cmpb $0x3,%%dl          ;" \
        "       sbbl %%eax,%%eax        " \
-       : "=a" (Acq), "=c" (dummy) \
-       : "c" (GLptr), "i" (~1L) \
-       : "dx"); \
+       : "=&a" (Acq), "+m" (*GLptr) \
+       : "i" (~1L) \
+       : "rdx"); \
+       (Acq) = -1; \
 } while (0)
 
 #define ACPI_RELEASE_GLOBAL_LOCK(GLptr, Acq) \
 do { \
-       unsigned long dummy; \
        __asm volatile( \
-       "1:     movl (%1),%%eax         ;" \
+       "1:     movl %1,%%eax           ;" \
        "       andq %2,%%rdx           ;" \
        "       lock                    ;" \
-       "       cmpxchgl %%edx,(%1)     ;" \
+       "       cmpxchgl %%edx,%1       ;" \
        "       jnz 1b                  ;" \
        "       andl $0x1,%%eax         ;" \
-       : "=a" (Acq), "=c" (dummy) \
-       : "c" (GLptr), "i" (~3L) \
-       : "dx"); \
+       : "=&a" (Acq), "+m" (*GLptr) \
+       : "i" (~3L) \
+       : "rdx"); \
 } while (0)
 
 #define        ACPI_FLUSH_CPU_CACHE()          wbinvd()


Home | Main Index | Thread Index | Old Index