From: yuchenq <[email protected]>

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..bc3124da 100644
--- a/arch/x64/power.cc
+++ b/arch/x64/power.cc
@@ -54,16 +54,32 @@ void poweroff(void)
     halt();
 }
 
+static 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);
+}
+
+static 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)
+    // 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: "fast reset" via System Control Port A (port 0x92)
     processor::outb(1, 0x92);
-    // 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
+    // Method 3: Reset using the 8042 PS/2 Controller ("keyboard controller")
+    kbd_reboot();
+    // Method 4: PCI reboot
+    pci_reboot();
+    // 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/20191128142931.22753-1-yuchenq%40amazon.de.

Reply via email to