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.

Reply via email to