kern/94939: [acpi] [patch] reboot(8) fails on IBM / Intel blades

Devon H. O'Dell dodell at iXsystems.com
Sat Mar 25 23:10:15 UTC 2006


>Number:         94939
>Category:       kern
>Synopsis:       [acpi] [patch] reboot(8) fails on IBM / Intel blades
>Confidential:   no
>Severity:       critical
>Priority:       high
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Sat Mar 25 23:10:13 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator:     Devon H. O'Dell
>Release:        6.1-PRERELEASE
>Organization:
iXsystems
>Environment:
FreeBSD maria.fdev.iXsystems.com 6.1-PRERELEASE FreeBSD 6.1-PRERELEASE #8: Sat Mar 25 10:53:25 PST 2006     root at maria.fdev.iXsystems.com:/usr/obj/usr/src/sys/BLADE  amd64

>Description:
Intel SBX82 blades do not have a keyboard controller and thus
do not reset by traditional means. This also has the implication
that they sit there and do nothing after running reboot(8).

These blades rely on ACPI for rebooting, as discussed in the
ACPI specification 4.7.3.6 (PDF page 95). Without this
support, it is impossible to reboot these blades from within
the operating system (without doing evil things to the CPU).
>How-To-Repeat:
Obtain root privileges on a blade. Run reboot(8).
>Fix:
I (very briefly) spoke with njl@ on this issue in an email.
He suggested putting it somewhere else, though I'm sort of 
curious as to where it should go otherwise. The patch is 
in acpi_shutdown_final, which is supposed to execute after 
everything, since it is used to halt the system. I'd be 
happy to put this in its own function and use 
EVENTHANDLER(9) to run it later, if possible.

The patch is attached here, and is also available at
http://www.sitetronics.com/~dodell/acpi.diff

Index: sys/dev/acpica/acpi.c
===================================================================
RCS file: /home/dodell/cvs/src/sys/dev/acpica/acpi.c,v
retrieving revision 1.219
diff -u -r1.219 acpi.c
--- sys/dev/acpica/acpi.c       7 Nov 2005 21:52:06 -0000       1.219
+++ sys/dev/acpica/acpi.c       25 Mar 2006 23:04:11 -0000
@@ -48,9 +48,14 @@
 #include <sys/sbuf.h>
 #include <sys/smp.h>

+#include <vm/vm.h>
+#include <vm/pmap.h>
+
 #include <machine/clock.h>
 #include <machine/resource.h>
 #include <machine/bus.h>
+#include <machine/cpufunc.h>
+#include <machine/pci_cfgreg.h>
 #include <sys/rman.h>
 #include <isa/isavar.h>
 #include <isa/pnpvar.h>
@@ -1636,6 +1641,49 @@
            DELAY(1000000);
            printf("ACPI power-off failed - timeout\n");
        }
+    } else if ((howto & RB_AUTOBOOT) != 0 && AcpiGbl_FADT->ResetRegSup) {
+       switch (AcpiGbl_FADT->ResetRegister.AddressSpaceId) {
+       case ACPI_ADR_SPACE_SYSTEM_MEMORY:
+       {
+           char *addr;
+
+           if (AcpiGbl_FADT->ResetRegister.Address == 0)
+               panic("NULL Reset Address");
+
+           addr = pmap_mapdev(
+               (vm_offset_t)AcpiGbl_FADT->ResetRegister.Address,
+               (size_t)AcpiGbl_FADT->ResetRegister.RegisterBitWidth);
+           *addr = AcpiGbl_FADT->ResetValue;
+       }
+       break;
+       case ACPI_ADR_SPACE_SYSTEM_IO:
+       {
+           uint64_t port;
+
+           port = AcpiGbl_FADT->ResetRegister.Address;
+           outb(port, AcpiGbl_FADT->ResetValue);
+       }
+       break;
+       case ACPI_ADR_SPACE_PCI_CONFIG:
+       {
+           uint64_t gas = AcpiGbl_FADT->ResetRegister.Address;
+           int bus, device, function, offset;
+
+           bus = 0;
+            device = (gas & ACPI_GAS_DEVICE_MASK) >> ACPI_GAS_DEVICE_SHIFT;
+           function = (gas & ACPI_GAS_FUNCTION_MASK) >>
+               ACPI_GAS_FUNCTION_SHIFT;
+           offset = (gas & ACPI_GAS_OFFSET_MASK);
+
+           pci_cfgregwrite(bus, device, function, offset,
+               AcpiGbl_FADT->ResetValue, 1);
+       }
+       break;
+       default:
+           printf("I didn't match any address space types!\n");
+       }
+       DELAY(1000000);
+       printf("ACPI reboot failed - timeout\n");
     } else if (panicstr == NULL) {
        printf("Shutting down ACPI\n");
        AcpiTerminate();
Index: sys/dev/acpica/acpivar.h
===================================================================
RCS file: /home/dodell/cvs/src/sys/dev/acpica/acpivar.h,v
retrieving revision 1.100
diff -u -r1.100 acpivar.h
--- sys/dev/acpica/acpivar.h    6 Dec 2005 14:47:28 -0000       1.100
+++ sys/dev/acpica/acpivar.h    25 Mar 2006 22:25:42 -0000
@@ -426,5 +426,11 @@
 /* Use the device logging level for ktr(4). */
 #define        KTR_ACPI                KTR_DEV

+#define ACPI_GAS_DEVICE_MASK 0x0000FFFF00000000ULL
+#define ACPI_GAS_DEVICE_SHIFT 32
+#define ACPI_GAS_FUNCTION_MASK 0x00000000FFFF0000ULL
+#define ACPI_GAS_FUNCTION_SHIFT 16
+#define ACPI_GAS_OFFSET_MASK 0x000000000000FFFFULL
+
 #endif /* _KERNEL */
 #endif /* !_ACPIVAR_H_ */

>Release-Note:
>Audit-Trail:
>Unformatted:


More information about the freebsd-bugs mailing list