public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
From: Jeremy Katz <katzj-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
Cc: kvm-devel <kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org>
Subject: Re: [PATCH] Add support for a basic boot menu to the	bios
Date: Wed, 19 Sep 2007 16:08:06 -0400	[thread overview]
Message-ID: <1190232486.10222.37.camel@localhost.localdomain> (raw)
In-Reply-To: <46ED8B5B.40903-atKUWr5tajBWk0Htik3J/w@public.gmane.org>

[-- Attachment #1: Type: text/plain, Size: 1690 bytes --]

On Sun, 2007-09-16 at 22:00 +0200, Avi Kivity wrote:
> > The attached patch adds support for a relatively basic boot device
> > selection menu to the bochs bios code.  
[snip]
> This is nice!  Two comments:
> 
> - it would be nice for qemu to provide the bios an indication if the 
> '-boot' parameter was specified to qemu.  if so, the bios should skip 
> the menu on first bootup, reducing the boot delay.  On subsequent boots 
> the menu should be offered.  This is primarily useful in managed 
> environments.

While this could be nice, at the same time, -boot is going to be getting
passed for a long time, even when it's no longer needed, just due to
people not updating their tools.  So I almost think it's better to take
the 3 second hit since it's going to be there every other time.  We
could tweak it to be a little bit less, but 3 seems in line with what
other BIOSes seem to do.

> - coding this stuff in rombios32.c instead of rombios.c (with its 
> strange idea of C) is *much* preferable for maintainability.  As far as 
> i can tell, there is no reason not to do so, especially for code which 
> is not called from the 16-bit OS.

The code is called from the 16-bit OS, though.  It needs to be done
after rom scanning has been done so that we can show network or not as
appropriate.  And unless I'm missing something, calling into rombios32.c
outside of rombios32_init() is going to add just as much
hard-to-maintain code.

Updated patch against kvm git attached that actually works with kvm.
Also ends up being a little bit simpler because we're doing less mucking
around with the timer.

Signed-off-by: Jeremy Katz <katzj-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Jeremy

[-- Attachment #2: kvm-bootmenu.patch --]
[-- Type: text/x-patch, Size: 5865 bytes --]

diff --git a/bios/BIOS-bochs-latest b/bios/BIOS-bochs-latest
index c10ae62..e13af69 100644
Binary files a/bios/BIOS-bochs-latest and b/bios/BIOS-bochs-latest differ
diff --git a/bios/BIOS-bochs-legacy b/bios/BIOS-bochs-legacy
index 131e62b..5c03460 100644
Binary files a/bios/BIOS-bochs-legacy and b/bios/BIOS-bochs-legacy differ
diff --git a/bios/rombios.c b/bios/rombios.c
index ac918ad..4ebdb71 100644
--- a/bios/rombios.c
+++ b/bios/rombios.c
@@ -1950,6 +1950,228 @@ print_cdromboot_failure( code )
   return;
 }
 
+#define WAIT_HZ 18
+/**
+ * Check for keystroke.
+ * @returns    True if keystroke available, False if not.
+ */
+Bit8u check_for_keystroke()
+{
+ASM_START
+    mov  ax, #0x100
+    int  #0x16
+    jz   no_key
+    mov  al, #1
+    jmp  done
+no_key:
+    xor  al, al
+done:
+ASM_END
+}
+
+/**
+ * Get keystroke.
+ * @returns    BIOS scan code.
+ */
+Bit8u get_keystroke()
+{
+ASM_START
+    mov  ax, #0x0
+    int  #0x16
+    xchg ah, al
+ASM_END
+}
+
+/**
+ * Waits (sleeps) for the given number of ticks.
+ * Checks for keystroke.
+ *
+ * @returns BIOS scan code if available, 0 if not.
+ * @param   ticks       Number of ticks to sleep.
+ * @param   stop_on_key Whether to stop immediately upon keypress.
+ */
+Bit8u wait(ticks, stop_on_key)
+  Bit16u ticks;
+  Bit8u stop_on_key;
+{
+    long ticks_to_wait, delta;
+    Bit32u prev_ticks, t;
+    Bit8u scan_code = 0;
+
+    /*
+     * The 0:046c wraps around at 'midnight' according to a 18.2Hz clock.
+     * We also have to be careful about interrupt storms.
+     */
+    ticks_to_wait = ticks;
+    prev_ticks = read_dword(0x0, 0x46c);
+    do
+    {
+        t = read_dword(0x0, 0x46c);
+        if (t > prev_ticks)
+        {
+            delta = t - prev_ticks;     /* The temp var is required or bcc screws up. */
+            ticks_to_wait -= delta;
+        }
+        else if (t < prev_ticks)
+            ticks_to_wait -= t;         /* wrapped */
+        prev_ticks = t;
+
+        if (check_for_keystroke())
+        {
+            scan_code = get_keystroke();
+            bios_printf(BIOS_PRINTF_DEBUG, "Key pressed: %x\n", scan_code);
+            if (stop_on_key)
+                return scan_code;
+        }
+    } while (ticks_to_wait > 0);
+    return scan_code;
+}
+
+static void clearscreen() {
+    /* Hide cursor, clear screen and move cursor to starting position */
+ASM_START
+        push bx
+        push cx
+        push dx
+
+        mov  ax, #0x100
+        mov  cx, #0x1000
+        int  #0x10
+
+        mov  ax, #0x700
+        mov  bh, #7
+        xor  cx, cx
+        mov  dx, #0x184f
+        int  #0x10
+
+        mov  ax, #0x200
+        xor  bx, bx
+        xor  dx, dx
+        int  #0x10
+
+        pop  dx
+        pop  cx
+        pop  bx
+ASM_END
+}
+
+int bootmenu(selected)
+  int selected;
+{
+    Bit8u scode;
+    int max;
+
+    /* get the number of boot devices */
+    max = read_word(IPL_SEG, IPL_COUNT_OFFSET);
+
+    for(;;) {
+        clearscreen();
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\n\n\n\n\n\n");
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "          Select boot device\n\n");
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "            1. Floppy\n");
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "            2. Hard drive\n");
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "            3. CD-ROM\n");
+        if (max == 4)
+            bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "            4. Network\n");
+        bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\n          Currently selected: %d\n", selected);
+
+        do {
+            scode = wait(WAIT_HZ, 1);
+        } while (scode == 0);
+        switch(scode) {
+        case 0x02:
+        case 0x03:
+        case 0x04:
+            selected = scode - 1;
+            break;
+        case 0x05:
+            if (max == 4)
+                selected = scode -1 ;
+            else
+                scode = 0;
+            break;
+        case 0x48:
+            selected -= 1;
+            if (selected < 1)
+                selected = 1;
+            scode = 0;
+            break;
+        case 0x50:
+            selected += 1;
+            if (selected > max)
+                selected = max;
+            scode = 0;
+            break;
+        case 0x1c:
+            break;
+        default:
+            scode = 0;
+            break;
+        }
+        if (scode != 0)
+            break;
+    }
+
+    switch (selected) {
+    case 1:
+        return 0x3D;
+    case 2:
+        return 0x3E;
+    case 3:
+        return 0x3F;
+    case 4:
+        return 0x58;
+    default:
+        return 0;
+    }
+}
+
+void interactive_bootkey()
+{
+    Bit16u i;
+    Bit8u scan = 0;
+
+    bios_printf(BIOS_PRINTF_SCREEN | BIOS_PRINTF_INFO, "\n\nPress F10 to select boot device.\n");
+    for (i = 3; i > 0; i--)
+    {
+        scan = wait(WAIT_HZ, 0);
+        switch (scan) {
+        case 0x3D:
+        case 0x3E:
+        case 0x3F:
+        case 0x58:
+            break;
+        case 0x44:
+            scan = bootmenu(inb_cmos(0x3d));
+            break;
+        default:
+            scan = 0;
+            break;
+        }
+        if (scan != 0)
+            break;
+    }
+
+    /* set the default based on the keypress or menu */
+    switch(scan) {
+    case 0x3D:
+        outb_cmos(0x3d, 0x01);
+        break;
+    case 0x3E:
+        outb_cmos(0x3d, 0x02);
+        break;
+    case 0x3F:
+        outb_cmos(0x3d, 0x03);
+        break;
+    case 0x58:
+        outb_cmos(0x3d, 0x04);
+        break;
+    default:
+        break;
+    }
+}
+
+
 void
 nmi_handler_msg()
 {
@@ -10226,6 +10448,8 @@ post_default_ints:
   ;;
 #endif // BX_ELTORITO_BOOT
 
+  call _interactive_bootkey
+
   sti        ;; enable interrupts
   int  #0x19
 

[-- Attachment #3: Type: text/plain, Size: 228 bytes --]

-------------------------------------------------------------------------
This SF.net email is sponsored by: Microsoft
Defy all challenges. Microsoft(R) Visual Studio 2005.
http://clk.atdmt.com/MRT/go/vse0120000070mrt/direct/01/

[-- Attachment #4: Type: text/plain, Size: 186 bytes --]

_______________________________________________
kvm-devel mailing list
kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
https://lists.sourceforge.net/lists/listinfo/kvm-devel

  parent reply	other threads:[~2007-09-19 20:08 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-09-12 19:55 [PATCH] Add support for a basic boot menu to the bios Jeremy Katz
     [not found] ` <1189626953.16586.6.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-09-12 20:19   ` Anthony Liguori
     [not found]     ` <46E849DE.3040103-rdkfGonbjUSkNkDKm+mE6A@public.gmane.org>
2007-09-12 20:25       ` Jeremy Katz
2007-09-14 20:14   ` Anthony Liguori
2007-09-16 20:00   ` Avi Kivity
     [not found]     ` <46ED8B5B.40903-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-09-17 15:23       ` Luca
     [not found]         ` <68676e00709170823m3247c3eaj7d268166ecc8c013-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2007-09-17 17:30           ` Avi Kivity
2007-09-19 20:08       ` Jeremy Katz [this message]
     [not found]         ` <1190232486.10222.37.camel-bi+AKbBUZKY6gyzm1THtWbp2dZbC/Bob@public.gmane.org>
2007-09-20  6:02           ` Avi Kivity

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1190232486.10222.37.camel@localhost.localdomain \
    --to=katzj-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
    --cc=avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org \
    --cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox