The original keyboard reset does not wait a for short period, so we see the triple fault being triggered even if the keyboard reset is successful sometimes. Added a wait there to make sure the keyboard reset completes before triggering the triple fault.
Added PCI reset, and enabled ACPI reset. ACPI reset does not work currently on kvm and qemu, but nevertheless we should try it first. Signed-off-by: YuChen Qian <[email protected]> Reviewed-by: Hendrik Borghorst <[email protected]> Reviewed-by: Marius Hillenbrand <[email protected]> Cc-Team: kaos-brimstone <[email protected]> CR: https://code.amazon.com/reviews/CR-14659421 --- arch/x64/power.cc | 30 +++++++++++++++++++++++------- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/arch/x64/power.cc b/arch/x64/power.cc index 61d56bcc..d62ed84e 100644 --- a/arch/x64/power.cc +++ b/arch/x64/power.cc @@ -54,16 +54,32 @@ void poweroff(void) halt(); } +void pci_reboot(void) { + u8 v = processor::inb(0x0cf9) & ~6; + processor::outb(v|2, 0x0cf9); // request hard reset + usleep(50); + processor::outb(v|6, 0x0cf9); // actually do the reset + usleep(50); +} + +void kbd_reboot(void) { + while (processor::inb(0x64) & 0x02); // clear all keyboard buffers + processor::outb(0xfe, 0x64); + usleep(50); +} + void reboot(void) { - // It would be nice if AcpiReset() worked, but it doesn't seem to work - // (on qemu & kvm), so let's resort to other techniques, which appear - // to work. Hopefully one of them will work on any hypervisor. - // Method 1: "fast reset" via System Control Port A (port 0x92) - processor::outb(1, 0x92); + // Method 1: AcpiReset, does not work on qemu or kvm now because the reset + // register is not supported. Nevertheless, we should try it first + AcpiReset(); // Method 2: Reset using the 8042 PS/2 Controller ("keyboard controller") - processor::outb(0xfe, 0x64); - // Method 3: Cause triple fault by loading a broken IDT and triggering an + kbd_reboot(); + // Method 3: PCI reboot + pci_reboot(); + // Method 4: "fast reset" via System Control Port A (port 0x92) + processor::outb(1, 0x92); + // Method 5: Cause triple fault by loading a broken IDT and triggering an // interrupt. processor::lidt(processor::desc_ptr(0, 0)); __asm__ __volatile__("int3"); -- 2.17.1 Amazon Development Center Germany GmbH Krausenstr. 38 10117 Berlin Geschaeftsfuehrung: Christian Schlaeger, Ralf Herbrich Eingetragen am Amtsgericht Charlottenburg unter HRB 149173 B Sitz: Berlin Ust-ID: DE 289 237 879 -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/20191127134607.15293-1-yuchenq%40amazon.de.
