diff --git a/headers/os/drivers/ACPI.h b/headers/os/drivers/ACPI.h index 1c22d082e2..5667c4faa8 100644 --- a/headers/os/drivers/ACPI.h +++ b/headers/os/drivers/ACPI.h @@ -224,6 +224,7 @@ struct acpi_module_info { status_t (*prepare_sleep_state)(uint8 state, void (*wakeFunc)(void), size_t size); status_t (*enter_sleep_state)(uint8 state); + status_t (*reboot)(void); }; diff --git a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c index 328cda1a31..965aeba039 100644 --- a/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c +++ b/src/add-ons/kernel/bus_managers/acpi/acpi_busman.c @@ -1,4 +1,5 @@ /* + * Copyright 2009, Vincent Duvert, vincent.duvert@free.fr * Copyright 2009, Clemens Zeidler, haiku@clemens-zeidler.de * Copyright 2008, Axel Dörfler, axeld@pinc-software.de. * Copyright 2006, Bryan Varner. All rights reserved. @@ -533,6 +534,29 @@ enter_sleep_state(uint8 state) } +static status_t +reboot(void) +{ + ACPI_STATUS status; + + TRACE("reboot\n"); + + if (AcpiGbl_FADT.Flags & ACPI_FADT_RESET_REGISTER == 0) + return B_UNSUPPORTED; + + status = AcpiHwLowLevelWrite(AcpiGbl_FADT.ResetRegister.BitWidth, + AcpiGbl_FADT.ResetValue, &AcpiGbl_FADT.ResetRegister); + + if (status != AE_OK) { + ERROR("Reset failed, status = %d\n", status); + return B_ERROR; + } + + snooze(1000000); + ERROR("Reset failed, timeout\n"); + return B_ERROR; +} + struct acpi_module_info gACPIModule = { { B_ACPI_MODULE_NAME, @@ -566,5 +590,6 @@ struct acpi_module_info gACPIModule = { evaluate_object, evaluate_method, prepare_sleep_state, - enter_sleep_state + enter_sleep_state, + reboot }; diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index d46586ec19..57abd172be 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -103,7 +103,7 @@ x86_optimized_functions gOptimizedFunctions = { static status_t -acpi_shutdown(void) +acpi_shutdown(bool rebootSystem) { if (debug_debugger_running()) return B_ERROR; @@ -112,11 +112,16 @@ acpi_shutdown(void) if (get_module(B_ACPI_MODULE_NAME, (module_info**)&acpi) != B_OK) return B_NOT_SUPPORTED; - status_t status = acpi->prepare_sleep_state(ACPI_POWER_STATE_OFF, NULL, 0); - if (status == B_OK) { - //cpu_status state = disable_interrupts(); - status = acpi->enter_sleep_state(ACPI_POWER_STATE_OFF); - //restore_interrupts(state); + status_t status; + if (rebootSystem) { + status = acpi->reboot(); + } else { + status = acpi->prepare_sleep_state(ACPI_POWER_STATE_OFF, NULL, 0); + if (status == B_OK) { + //cpu_status state = disable_interrupts(); + status = acpi->enter_sleep_state(ACPI_POWER_STATE_OFF); + //restore_interrupts(state); + } } put_module(B_ACPI_MODULE_NAME); @@ -822,14 +827,12 @@ error: status_t arch_cpu_shutdown(bool rebootSystem) { - if (!rebootSystem) { - status_t status = acpi_shutdown(); - if (status != B_OK) - status = apm_shutdown(); - - return status; - } - + if (acpi_shutdown(rebootSystem) == B_OK) + return B_OK; + + if (!rebootSystem) + return apm_shutdown(); + cpu_status state = disable_interrupts(); // try to reset the system using the keyboard controller