On Thu, Nov 28, 2019 at 4:29 PM 'YuChen Qian' via OSv Development < [email protected]> wrote:
> 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 > Note that the comment is somewhat misleading - this code doesn't "clear all keyboard buffers". What it really does is to wait until the keyboard controller's *input buffer* (and only that buffer) has room. The *input buffer *is what will need to hold our following command (which we send via port 0x64), and we are not supposed to send a new command before the previous one was handled. This 0x2 bit is cleared when the controller is ready for a new command, so only when it's cleared can we send that command. Linux has a timeout in this loop (around 128ms), I guess to avoid hanging forever with malfunctioning hardware, but we can live with an infinite loop too. I'll commit this patch as-is, if you want to further improve things, feel free to send a followup patch. Thanks! + 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 > . > -- 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/CANEVyjvMYdHqXxD%3DTMhvmiArLVSeyDgGYunZ8eawW%2Bdu7dpRRQ%40mail.gmail.com.
