Reorganize boot code.
authorKevin O'Connor <kevin@koconnor.net>
Sun, 8 Feb 2009 20:44:08 +0000 (15:44 -0500)
committerKevin O'Connor <kevin@koconnor.net>
Sun, 8 Feb 2009 20:44:08 +0000 (15:44 -0500)
Simplify keyboard handling in post_menu.c, and move to util.c.
Move remaining functions in post_menu.c to boot.c; remove post_menu.c.
Also, remove broken check for F12 when in boot menu.
Move BEV setup code from post.c to boot.c.
Move option rom BEV adding code from optionroms.c to boot.c.
Avoid calling BX_PANIC during boot if there is an alternative.

Makefile
src/boot.c
src/boot.h
src/optionroms.c
src/post.c
src/post_menu.c [deleted file]
src/util.c
src/util.h

index 186ef51f25ef6224d0640ca7895d956282c80a39..34a7535432b3477362c1977fbf5519d18b3b651f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -12,7 +12,7 @@ SRCBOTH=output.c util.c floppy.c ata.c misc.c mouse.c kbd.c pci.c \
         serial.c clock.c pic.c cdrom.c ps2port.c smpdetect.c resume.c \
         pnpbios.c pirtable.c
 SRC16=$(SRCBOTH) system.c disk.c apm.c pcibios.c vgahooks.c font.c
-SRC32=$(SRCBOTH) post.c shadow.c post_menu.c memmap.c coreboot.c boot.c \
+SRC32=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
       acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c
 
 cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
index 6db213a43e8b78d081cee4f8bac6f786a2428bbc..5bcb4a412ae3878874c66d0bd79410cb3f932dc2 100644 (file)
 #include "disk.h" // cdrom_boot
 #include "bregs.h" // struct bregs
 #include "boot.h" // struct ipl_s
+#include "cmos.h" // inb_cmos
 
 struct ipl_s IPL;
 
-//--------------------------------------------------------------------------
-// print_boot_device
-//   displays the boot device
-//--------------------------------------------------------------------------
+
+/****************************************************************
+ * IPL handlers
+ ****************************************************************/
+
+void
+boot_setup()
+{
+    if (! CONFIG_BOOT)
+        return;
+    dprintf(3, "init boot device ordering\n");
+
+    memset(&IPL, 0, sizeof(IPL));
+
+    // Floppy drive
+    struct ipl_entry_s *ip = &IPL.table[0];
+    ip->type = IPL_TYPE_FLOPPY;
+    ip++;
+
+    // First HDD
+    ip->type = IPL_TYPE_HARDDISK;
+    ip++;
+
+    // CDROM
+    if (CONFIG_CDROM_BOOT) {
+        ip->type = IPL_TYPE_CDROM;
+        ip++;
+    }
+
+    IPL.count = ip - IPL.table;
+    SET_EBDA(boot_sequence, 0xffff);
+    if (CONFIG_COREBOOT) {
+        // XXX - hardcode defaults for coreboot.
+        IPL.bootorder = 0x00000231;
+        IPL.checkfloppysig = 1;
+    } else {
+        // On emulators, get boot order from nvram.
+        IPL.bootorder = (inb_cmos(CMOS_BIOS_BOOTFLAG2)
+                         | ((inb_cmos(CMOS_BIOS_BOOTFLAG1) & 0xf0) << 4));
+        if (!(inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1))
+            IPL.checkfloppysig = 1;
+    }
+}
+
+// Add a BEV vector for a given pnp compatible option rom.
+void
+add_bev(u16 seg, u16 bev, u16 desc)
+{
+    // Found a device that thinks it can boot the system.  Record
+    // its BEV and product name string.
+
+    if (! CONFIG_BOOT)
+        return;
+
+    if (IPL.count >= ARRAY_SIZE(IPL.table))
+        return;
+
+    struct ipl_entry_s *ip = &IPL.table[IPL.count];
+    ip->type = IPL_TYPE_BEV;
+    ip->vector = (seg << 16) | bev;
+    if (desc)
+        ip->description = MAKE_FLATPTR(seg, desc);
+
+    IPL.count++;
+}
+
+
+/****************************************************************
+ * Printing helpers
+ ****************************************************************/
 
 static const char drivetypes[][10]={
     "", "Floppy", "Hard Disk", "CD-Rom", "Network"
 };
 
-void
+// display a device name
+static void
 printf_bootdev(u16 bootdev)
 {
     u16 type = IPL.table[bootdev].type;
@@ -31,8 +99,10 @@ printf_bootdev(u16 bootdev)
     /* NIC appears as type 0x80 */
     if (type == IPL_TYPE_BEV)
         type = 0x4;
-    if (type == 0 || type > 0x4)
-        BX_PANIC("Bad drive type\n");
+    if (type == 0 || type > 0x4) {
+        printf("Unknown");
+        return;
+    }
     printf("%s", drivetypes[type]);
 
     /* print product string if BEV */
@@ -47,6 +117,7 @@ printf_bootdev(u16 bootdev)
     }
 }
 
+// display the boot device
 static void
 print_boot_device(u16 bootdev)
 {
@@ -55,16 +126,10 @@ print_boot_device(u16 bootdev)
     printf("...\n");
 }
 
-//--------------------------------------------------------------------------
-// print_boot_failure
-//   displays the reason why boot failed
-//--------------------------------------------------------------------------
+// display the reason why a boot failed
 static void
 print_boot_failure(u16 type, u8 reason)
 {
-    if (type == 0 || type > 0x3)
-        BX_PANIC("Bad drive type\n");
-
     printf("Boot failed");
     if (type < 4) {
         /* Report the reason too */
@@ -76,6 +141,61 @@ print_boot_failure(u16 type, u8 reason)
     printf("\n\n");
 }
 
+
+/****************************************************************
+ * Boot menu
+ ****************************************************************/
+
+void
+interactive_bootmenu()
+{
+    if (! CONFIG_BOOTMENU)
+        return;
+
+    while (get_keystroke(0) >= 0)
+        ;
+
+    printf("Press F12 for boot menu.\n\n");
+
+    int scan_code = get_keystroke(2500);
+    if (scan_code != 0x86)
+        /* not F12 */
+        return;
+
+    while (get_keystroke(0) >= 0)
+        ;
+
+    printf("Select boot device:\n\n");
+
+    int count = IPL.count;
+    int i;
+    for (i = 0; i < count; i++) {
+        printf("%d. ", i+1);
+        printf_bootdev(i);
+        printf("\n");
+    }
+
+    for (;;) {
+        scan_code = get_keystroke(1000);
+        if (scan_code == 0x01)
+            // ESC
+            break;
+        if (scan_code >= 0 && scan_code <= count + 1) {
+            // Add user choice to the boot order.
+            u16 choice = scan_code - 1;
+            u32 bootorder = IPL.bootorder;
+            IPL.bootorder = (bootorder << 4) | choice;
+            break;
+        }
+    }
+    printf("\n");
+}
+
+
+/****************************************************************
+ * Boot code (int 18/19)
+ ****************************************************************/
+
 static void
 try_boot(u16 seq_nr)
 {
index a5fe08ea4ffff454d38fcd5c11072f097eb791ca..d6cddcb5c6073e6c401ddfe8fbf9d85ef3da025c 100644 (file)
@@ -33,9 +33,8 @@ struct ipl_s {
 
 // boot.c
 extern struct ipl_s IPL;
-void printf_bootdev(u16 bootdev);
-
-// post_menu.c
+void boot_setup();
+void add_bev(u16 seg, u16 bev, u16 desc);
 void interactive_bootmenu();
 
 #endif // __BOOT_H
index 97e9d42b7a7521b03c9ff8cdf327a3096c5ebf5a..d9c4e0e3efacd770e9492fbb5736014cb219fb49 100644 (file)
@@ -148,30 +148,6 @@ get_pci_rom(struct rom_header *rom)
     return pci;
 }
 
-// Add a BEV vector for a given pnp compatible option rom.
-static void
-add_ipl(struct rom_header *rom, struct pnp_data *pnp)
-{
-    // Found a device that thinks it can boot the system.  Record
-    // its BEV and product name string.
-
-    if (! CONFIG_BOOT)
-        return;
-
-    if (IPL.count >= ARRAY_SIZE(IPL.table))
-        return;
-
-    struct ipl_entry_s *ip = &IPL.table[IPL.count];
-    ip->type = IPL_TYPE_BEV;
-    ip->vector = (FLATPTR_TO_SEG(rom) << 16) | pnp->bev;
-
-    u16 desc = pnp->productname;
-    if (desc)
-        ip->description = MAKE_FLATPTR(FLATPTR_TO_SEG(rom), desc);
-
-    IPL.count++;
-}
-
 // Copy a rom to its permanent location below 1MiB
 static struct rom_header *
 copy_rom(struct rom_header *rom)
@@ -349,7 +325,7 @@ optionrom_setup()
         // PnP rom.
         if (pnp->bev)
             // Can boot system - add to IPL list.
-            add_ipl(rom, pnp);
+            add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname);
         else
             // Check for BCV (there may be multiple).
             while (pnp && pnp->bcv) {
index 5f3cfaadc74056eedf66282806723b5080fb5c91..5985a570bb37c2e909f56946772919793d567aa7 100644 (file)
@@ -149,45 +149,6 @@ init_bios_tables(void)
     acpi_bios_init();
 }
 
-static void
-init_boot_vectors()
-{
-    if (! CONFIG_BOOT)
-        return;
-    dprintf(3, "init boot device ordering\n");
-
-    memset(&IPL, 0, sizeof(IPL));
-
-    // Floppy drive
-    struct ipl_entry_s *ip = &IPL.table[0];
-    ip->type = IPL_TYPE_FLOPPY;
-    ip++;
-
-    // First HDD
-    ip->type = IPL_TYPE_HARDDISK;
-    ip++;
-
-    // CDROM
-    if (CONFIG_CDROM_BOOT) {
-        ip->type = IPL_TYPE_CDROM;
-        ip++;
-    }
-
-    IPL.count = ip - IPL.table;
-    SET_EBDA(boot_sequence, 0xffff);
-    if (CONFIG_COREBOOT) {
-        // XXX - hardcode defaults for coreboot.
-        IPL.bootorder = 0x00000231;
-        IPL.checkfloppysig = 1;
-    } else {
-        // On emulators, get boot order from nvram.
-        IPL.bootorder = (inb_cmos(CMOS_BIOS_BOOTFLAG2)
-                         | ((inb_cmos(CMOS_BIOS_BOOTFLAG1) & 0xf0) << 4));
-        if (!(inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1))
-            IPL.checkfloppysig = 1;
-    }
-}
-
 // Main setup code.
 static void
 post()
@@ -219,11 +180,11 @@ post()
     init_bios_tables();
     memmap_finalize();
 
+    boot_setup();
+
     floppy_drive_setup();
     hard_drive_setup();
 
-    init_boot_vectors();
-
     optionrom_setup();
 }
 
diff --git a/src/post_menu.c b/src/post_menu.c
deleted file mode 100644 (file)
index 3182d3c..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-// Menu presented during final phase of "post".
-//
-// Copyright (C) 2008  Kevin O'Connor <kevin@koconnor.net>
-// Copyright (C) 2002  MandrakeSoft S.A.
-//
-// This file may be distributed under the terms of the GNU LGPLv3 license.
-
-#include "biosvar.h" // GET_EBDA
-#include "util.h" // mdelay
-#include "bregs.h" // struct bregs
-#include "boot.h" // IPL
-
-static int
-check_for_keystroke()
-{
-    struct bregs br;
-    memset(&br, 0, sizeof(br));
-    br.ah = 1;
-    call16_int(0x16, &br);
-    return !(br.flags & F_ZF);
-}
-
-static int
-get_keystroke()
-{
-    struct bregs br;
-    memset(&br, 0, sizeof(br));
-    call16_int(0x16, &br);
-    return br.ah;
-}
-
-static void
-usleep(u32 usec)
-{
-    struct bregs br;
-    memset(&br, 0, sizeof(br));
-    br.ah = 0x86;
-    br.cx = usec >> 16;
-    br.dx = usec;
-    call16_int(0x15, &br);
-}
-
-static int
-timed_check_for_keystroke(int msec)
-{
-    while (msec > 0) {
-        if (check_for_keystroke())
-            return 1;
-        usleep(50*1000);
-        msec -= 50;
-    }
-    return 0;
-}
-
-void
-interactive_bootmenu()
-{
-    if (! CONFIG_BOOTMENU)
-        return;
-
-    while (check_for_keystroke())
-        get_keystroke();
-
-    printf("Press F12 for boot menu.\n\n");
-
-    if (!timed_check_for_keystroke(2500))
-        return;
-    int scan_code = get_keystroke();
-    if (scan_code != 0x86)
-        /* not F12 */
-        return;
-
-    while (check_for_keystroke())
-        get_keystroke();
-
-    printf("Select boot device:\n\n");
-
-    int count = IPL.count;
-    int i;
-    for (i = 0; i < count; i++) {
-        printf("%d. ", i+1);
-        printf_bootdev(i);
-        printf("\n");
-    }
-
-    for (;;) {
-        scan_code = get_keystroke();
-        if (scan_code == 0x01 || scan_code == 0x58)
-            /* ESC or F12 */
-            break;
-        if (scan_code <= count + 1) {
-            // Add user choice to the boot order.
-            u16 choice = scan_code - 1;
-            u32 bootorder = IPL.bootorder;
-            IPL.bootorder = (bootorder << 4) | choice;
-            break;
-        }
-    }
-    printf("\n");
-}
index ad918d738bd7d55607838e171e3e442407ca40a9..6a0849b507ce3cac446963dcc4ec79651f7dbbe1 100644 (file)
@@ -165,3 +165,50 @@ memmove(void *d, const void *s, size_t len)
 
     return d;
 }
+
+// Wait for 'usec' microseconds with irqs enabled.
+static void
+usleep(u32 usec)
+{
+    struct bregs br;
+    memset(&br, 0, sizeof(br));
+    br.ah = 0x86;
+    br.cx = usec >> 16;
+    br.dx = usec;
+    call16_int(0x15, &br);
+}
+
+// See if a keystroke is pending in the keyboard buffer.
+static int
+check_for_keystroke()
+{
+    struct bregs br;
+    memset(&br, 0, sizeof(br));
+    br.ah = 1;
+    call16_int(0x16, &br);
+    return !(br.flags & F_ZF);
+}
+
+// Return a keystroke - waiting forever if necessary.
+static int
+get_raw_keystroke()
+{
+    struct bregs br;
+    memset(&br, 0, sizeof(br));
+    call16_int(0x16, &br);
+    return br.ah;
+}
+
+// Read a keystroke - waiting up to 'msec' milliseconds.
+int
+get_keystroke(int msec)
+{
+    for (;;) {
+        if (check_for_keystroke())
+            return get_raw_keystroke();
+        if (msec <= 0)
+            return -1;
+        usleep(50*1000);
+        msec -= 50;
+    }
+}
index 1531ffda0afdb0df0347f59d5b4c0f068c707908..aa82d4bd8a7d542940c1b89a95b6263321e81445 100644 (file)
@@ -83,6 +83,7 @@ inline void __call16_int(struct bregs *callregs, u16 offset);
         __call16_int((callregs), (u32)&irq_trampoline_ ##nr );  \
     } while (0)
 inline void call16_simpint(int nr, u32 *eax, u32 *flags);
+int get_keystroke(int msec);
 
 // output.c
 void debug_serial_setup();