From: yuchenq <[email protected]>
Committer: Nadav Har'El <[email protected]>
Branch: master
osv: fix keyboard reset, add pci reset
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
Message-Id: <[email protected]>
---
diff --git a/arch/x64/power.cc b/arch/x64/power.cc
--- a/arch/x64/power.cc
+++ b/arch/x64/power.cc
@@ -55,16 +55,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");
--
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/0000000000001f715705986d8b8c%40google.com.