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.
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 \
#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;
/* 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 */
}
}
+// display the boot device
static void
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 */
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)
{
// 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
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)
// 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) {
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()
init_bios_tables();
memmap_finalize();
+ boot_setup();
+
floppy_drive_setup();
hard_drive_setup();
- init_boot_vectors();
-
optionrom_setup();
}
+++ /dev/null
-// 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");
-}
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;
+ }
+}
__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();