Hi Everybody: I've ran into the quintessential "it works on Linux but does not work on FreeBSD" vendor comment regarding the boxes ability to reboot successfully. I'm running FreeBSD-6.1 but this also applies the FreeBSD-CURRENT as well. The problem boils down to the fact that the BIOS does set the ResetRegister bit in the FADT feature flags. However, I've noticed that latest stable Linux kernel has the following logic with respect to the reset register: acpi_reboot(): 18 /* Is the reset register supported? */ 19 if (!(acpi_gbl_FADT.flags & ACPI_FADT_RESET_REGISTER) || 20 rr->bit_width != 8 || rr->bit_offset != 0) 21 return; http://lxr.linux.no/linux+v2.6.28/drivers/acpi/reboot.c CURRENT looks like this via the shutdown_final EVENTHANDLE: acpi_shutdown_final(): 1821 } else if ((howto & RB_HALT) == 0 && 1822 (AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) && 1823 sc->acpi_handle_reboot) { 1824 /* Reboot using the reset register. */ http://www.freebsd.org/cgi/cvsweb.cgi/src/sys/dev/acpica/acpi.c?rev=1.254 Two questions: 1) Why is the sysctl acpi_handle_reboot zero by default? Shouldn't it be more prudent to rely on the ACPI reboot hook than the legacy keyboard controller methods? I realize there is some history here but it would seem to me that the "&&" should be an "||" which would allow me to override the ACPI_FADT_RESET_REGISTER flag and force an ACPI reset? 2) Is there something to be said for a patch like this: -- acpi.c.0 2009-01-25 19:56:48.000000000 -0500 +++ acpi.c 2009-01-25 20:10:34.000000000 -0500 _at__at_ -1818,18 +1818,20 _at__at_ DELAY(1000000); printf("ACPI power-off failed - timeout\n"); } - } else if ((howto & RB_HALT) == 0 && - (AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) && - sc->acpi_handle_reboot) { - /* Reboot using the reset register. */ - status = AcpiHwLowLevelWrite( - AcpiGbl_FADT.ResetRegister.BitWidth, - AcpiGbl_FADT.ResetValue, &AcpiGbl_FADT.ResetRegister); - if (ACPI_FAILURE(status)) { - printf("ACPI reset failed - %s\n", AcpiFormatException(status)); - } else { - DELAY(1000000); - printf("ACPI reset failed - timeout\n"); + } else if ((howto & RB_HALT) == 0 && sc->acpi_handle_reboot) { + if ((AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER) || + (AcpiGbl_FADT.ResetRegister.BitWidth != 8) || + (AcpiGbl_FADT.ResetRegister.BitOffset != 0)) { + /* Reboot using the reset register. */ + status = AcpiHwLowLevelWrite( + AcpiGbl_FADT.ResetRegister.BitWidth, + AcpiGbl_FADT.ResetValue, &AcpiGbl_FADT.ResetRegister); + if (ACPI_FAILURE(status)) { + printf("ACPI reset failed - %s\n", AcpiFormatException(status)); + } else { + DELAY(1000000); + printf("ACPI reset failed - timeout\n"); + } } } else if (sc->acpi_do_disable && panicstr == NULL) { /* Basically, if the ResetRegister is filled in despite the FADT feature flags bit, trust it and move forward (Linux logic). That's the reason why my box reboots correctly on Linux and utterly hangs miserably on FreeBSD. I understand this is a BIOS/ACPI bug, I understand the keyboard controller reboot method should probably be emulated in the BIOS (though the vendor could argue they no longer support legacy methods which is to me not necessarily a bad thing), and I understand that FreeBSD is not Linux. With that all said, I don't see the downside here with respect to reboot with respect to either points (allow the user to force the issue or believe the ResetRegister values themselves as a test for validity). Feedback most appreciated! Thanks! -apsReceived on Mon Jan 26 2009 - 01:00:23 UTC
This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:39:41 UTC