Some ACPI systems do not support legacy mode and do not provide an smi_cmd
port within the FADT. This is mentioned in the following:

http://www.acpi.info/DOWNLOADS/ACPIspec40a.pdf (p119, SMI_CMD)
http://wiki.osdev.org/ACPI (Switching to ACPI Mode)

OpenBSD aborts ACPI initialisation if the FADT does not provide an smi_cmd
port. The diff below permits ACPI initialisation to complete in such a case.
In my case, this allows halt -p to shut down a Xen HVM DomU.

Nathanael


Index: acpi.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpi.c,v
retrieving revision 1.197
diff -p -u -r1.197 acpi.c
--- acpi.c      28 Jul 2010 14:39:43 -0000      1.197
+++ acpi.c      7 Aug 2010 19:30:21 -0000
@@ -599,15 +599,6 @@ acpi_attach(struct device *parent, struc
        }

        /*
-        * Check if we are able to enable ACPI control
-        */
-       if (!sc->sc_fadt->smi_cmd ||
-           (!sc->sc_fadt->acpi_enable && !sc->sc_fadt->acpi_disable)) {
-               printf(", ACPI control unavailable\n");
-               return;
-       }
-
-       /*
         * Set up a pointer to the firmware control structure
         */
        if (sc->sc_fadt->hdr_revision < 3 || sc->sc_fadt->x_firmware_ctl == 0)
@@ -685,14 +676,18 @@ acpi_attach(struct device *parent, struc
         * This may prevent thermal control on some systems where
         * that actually does work
         */
-       acpi_write_pmreg(sc, ACPIREG_SMICMD, 0, sc->sc_fadt->acpi_enable);
-       idx = 0;
-       do {
-               if (idx++ > ACPIEN_RETRIES) {
-                       printf(", can't enable ACPI\n");
-                       return;
-               }
-       } while (!(acpi_read_pmreg(sc, ACPIREG_PM1_CNT, 0) & ACPI_PM1_SCI_EN));
+       if (sc->sc_fadt->smi_cmd && sc->sc_fadt->acpi_enable) {
+               acpi_write_pmreg(sc, ACPIREG_SMICMD, 0,
+                   sc->sc_fadt->acpi_enable);
+               idx = 0;
+               do {
+                       if (idx++ > ACPIEN_RETRIES) {
+                               printf(", can't enable ACPI\n");
+                               return;
+                       }
+               } while (!(acpi_read_pmreg(sc, ACPIREG_PM1_CNT, 0) &
+                   ACPI_PM1_SCI_EN));
+       }

        printf("\n%s: tables", DEVNAME(sc));
        SIMPLEQ_FOREACH(entry, &sc->sc_tables, q_next) {
Index: acpicpu.c
===================================================================
RCS file: /cvs/src/sys/dev/acpi/acpicpu.c,v
retrieving revision 1.57
diff -p -u -r1.57 acpicpu.c
--- acpicpu.c   21 Jul 2010 19:35:15 -0000      1.57
+++ acpicpu.c   7 Aug 2010 19:30:22 -0000
@@ -394,7 +394,8 @@ acpicpu_attach(struct device *parent, st
                        sc->sc_flags |= FLAGS_NOPCT;
                else if (sc->sc_pss_len > 0) {
                        /* Notify BIOS we are handing p-states */
-                       if (sc->sc_acpi->sc_fadt->pstate_cnt)
+                       if (sc->sc_acpi->sc_fadt->smi_cmd &&
+                           sc->sc_acpi->sc_fadt->pstate_cnt)
                                acpi_write_pmreg(sc->sc_acpi, ACPIREG_SMICMD, 0,
                                sc->sc_acpi->sc_fadt->pstate_cnt);

Reply via email to