diff options
author | Kevin O'Connor <kevin@koconnor.net> | 2009-02-08 15:44:08 -0500 |
---|---|---|
committer | Kevin O'Connor <kevin@koconnor.net> | 2009-02-08 15:44:08 -0500 |
commit | 9f4e1d9ad54ceb4876c4457907766799ab15f1a3 (patch) | |
tree | 3565a9b2a457aceda5ff8c6bd13f4f89da556900 | |
parent | 60b69990a521993a901abc07b17f5135c2a5ecb5 (diff) | |
download | seabios-hppa-9f4e1d9ad54ceb4876c4457907766799ab15f1a3.zip seabios-hppa-9f4e1d9ad54ceb4876c4457907766799ab15f1a3.tar.gz seabios-hppa-9f4e1d9ad54ceb4876c4457907766799ab15f1a3.tar.bz2 |
Reorganize boot code.
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.
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | src/boot.c | 148 | ||||
-rw-r--r-- | src/boot.h | 5 | ||||
-rw-r--r-- | src/optionroms.c | 26 | ||||
-rw-r--r-- | src/post.c | 43 | ||||
-rw-r--r-- | src/post_menu.c | 100 | ||||
-rw-r--r-- | src/util.c | 47 | ||||
-rw-r--r-- | src/util.h | 1 |
8 files changed, 188 insertions, 184 deletions
@@ -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 \ @@ -11,19 +11,87 @@ #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) { @@ -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 diff --git a/src/optionroms.c b/src/optionroms.c index 97e9d42..d9c4e0e 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -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) { @@ -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 index 3182d3c..0000000 --- a/src/post_menu.c +++ /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"); -} @@ -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; + } +} @@ -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(); |