diff --git a/arch/x64/arch.hh b/arch/x64/arch.hh index ccbd887dfa3065dc5cbb7c119dee4d9d15649729..9f4a59dc0ed62c052ba3ac32a531bf914d0eac69 100644 --- a/arch/x64/arch.hh +++ b/arch/x64/arch.hh @@ -41,6 +41,11 @@ inline void wait_for_interrupt() processor::sti_hlt(); } +inline void halt_no_interrupts() +{ + processor::cli_hlt(); +} + class irq_flag { public: // need to clear the red zone when playing with the stack. also, can't diff --git a/arch/x64/exceptions.cc b/arch/x64/exceptions.cc index bd62d23fca325a6c6b20945572a92da7b079cd84..48d3ac5a1ebdad14483756dcf81fa2cf5f32893d 100644 --- a/arch/x64/exceptions.cc +++ b/arch/x64/exceptions.cc @@ -263,7 +263,7 @@ void divide_error(exception_frame *ef) extern "C" void nmi(exception_frame* ef) { while (true) { - processor::halt_no_interrupts(); + processor::cli_hlt(); } } diff --git a/arch/x64/processor.hh b/arch/x64/processor.hh index a07e6bbbdcb45d7e8c469dfcc8fce7574938b0d8..02cc17780170ffcf00e931450fafed78dc049307 100644 --- a/arch/x64/processor.hh +++ b/arch/x64/processor.hh @@ -237,7 +237,7 @@ inline void wrfsbase(u64 data) asm volatile("wrfsbase %0" : : "r"(data)); } -inline void halt_no_interrupts() { +inline void cli_hlt() { asm volatile ("cli; hlt" : : : "memory"); } diff --git a/core/power.cc b/core/power.cc index 7874ec1dc14be15d215ca792349f0eaf3ed5906a..6015968ec0acfdba82586c039628540d0c0110c1 100644 --- a/core/power.cc +++ b/core/power.cc @@ -9,10 +9,13 @@ #include <osv/debug.hh> #include <smp.hh> #include <processor.hh> +#include <arch.hh> +#ifndef AARCH64_PORT_STUB extern "C" { #include "acpi.h" } +#endif /* !AARCH64_PORT_STUB */ namespace osv { @@ -23,13 +26,18 @@ namespace osv { void halt(void) { +#ifndef AARCH64_PORT_STUB crash_other_processors(); - while (true) - processor::halt_no_interrupts(); +#endif /* !AARCH64_PORT_STUB */ + + while (true) { + arch::halt_no_interrupts(); + } } void poweroff(void) { +#ifndef AARCH64_PORT_STUB ACPI_STATUS status = AcpiEnterSleepStatePrep(ACPI_STATE_S5); if (ACPI_FAILURE(status)) { debug("AcpiEnterSleepStatePrep failed: %s\n", AcpiFormatException(status)); @@ -40,7 +48,9 @@ void poweroff(void) debug("AcpiEnterSleepState failed: %s\n", AcpiFormatException(status)); halt(); } - // We shouldn't get here. +#endif /* !AARCH64_PORT_STUB */ + + // We shouldn't get here on x86. halt(); } @@ -48,10 +58,13 @@ void poweroff(void) // some reson fails. void reboot(void) { +#ifdef __x86_64__ // It would be nice if AcpiReset() worked, but it doesn't seem to work // (on qemu & kvm), so let's resort to brute force... processor::outb(1, 0x92); debug("osv::reboot() did not work :(\n"); +#endif /* __x86_64__ */ + halt(); }