This is a patch series to simplify the current boot prioritization code. The basic idea is to replace the BCV list with a list that contains all bootable objects. It's then easier to make that list authoritative and do all ordering on it. This is a code simplification even without the new "bootorder" file reading code.
-Kevin
Kevin O'Connor (2): Populate drive_g->desc prior to calling add_bcv_internal(). Simplify boot ordering by building an inclusive boot list.
src/ahci.c | 11 +- src/ata.c | 13 +- src/block.c | 20 +--- src/boot.c | 425 ++++++++++++++++++++++-------------------------------- src/boot.h | 20 +-- src/coreboot.c | 20 +++ src/floppy.c | 5 +- src/optionroms.c | 6 +- src/usb-msc.c | 11 +- src/virtio-blk.c | 10 +- 10 files changed, 226 insertions(+), 315 deletions(-)
Make sure the description is populated before registering a drive. --- src/usb-msc.c | 5 ++--- src/virtio-blk.c | 8 +++----- 2 files changed, 5 insertions(+), 8 deletions(-)
diff --git a/src/usb-msc.c b/src/usb-msc.c index 080efdc..48635d9 100644 --- a/src/usb-msc.c +++ b/src/usb-msc.c @@ -235,6 +235,8 @@ usb_msc_init(struct usb_pipe *pipe , strtcpy(rev, data.rev, sizeof(rev)) , pdt, removable); udrive_g->drive.removable = removable; + snprintf(desc, MAXDESCSIZE, "USB Drive %s %s %s", vendor, product, rev); + udrive_g->drive.desc = desc;
if (pdt == USB_MSC_TYPE_CDROM) ret = setup_drive_cdrom(&dop); @@ -243,9 +245,6 @@ usb_msc_init(struct usb_pipe *pipe if (ret) goto fail;
- snprintf(desc, MAXDESCSIZE, "USB Drive %s %s %s", vendor, product, rev); - udrive_g->drive.desc = desc; - return 0; fail: dprintf(1, "Unable to configure USB MSC device.\n"); diff --git a/src/virtio-blk.c b/src/virtio-blk.c index 7a25826..9c9ed83 100644 --- a/src/virtio-blk.c +++ b/src/virtio-blk.c @@ -151,15 +151,13 @@ init_virtio_blk(u16 bdf) vdrive_g->drive.pchs.cylinders = cfg.cylinders; vdrive_g->drive.pchs.heads = cfg.heads; vdrive_g->drive.pchs.spt = cfg.sectors; - - setup_translation(&vdrive_g->drive); - add_bcv_internal(&vdrive_g->drive); - snprintf(desc, MAXDESCSIZE, "Virtio disk PCI:%x:%x", pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf)); - vdrive_g->drive.desc = desc;
+ setup_translation(&vdrive_g->drive); + add_bcv_internal(&vdrive_g->drive); + vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK); return;
Replace the bcv list with a full list of all "bootable objects". All ordering can then be done on this list. The final boot menu, drive mapping, and BEV list generation is then driven from this authoritative list.
Move "Floppy" and "DVD/CD" description prefixes into drive description generation code to simplify boot menu generation.
Rework QEMU's CMOS defined bootorder to work with priority scheme in new boot list.
Have every CBFS entry create it's own BEV entry (instead of one entry for all CBFS payloads). Move CBFS payload detection code into coreboot.c. --- src/ahci.c | 11 +- src/ata.c | 13 +- src/block.c | 20 +--- src/boot.c | 425 ++++++++++++++++++++++-------------------------------- src/boot.h | 20 +-- src/coreboot.c | 20 +++ src/floppy.c | 5 +- src/optionroms.c | 6 +- src/usb-msc.c | 6 +- src/virtio-blk.c | 4 +- 10 files changed, 222 insertions(+), 308 deletions(-)
diff --git a/src/ahci.c b/src/ahci.c index 70c0f1c..03e39ad 100644 --- a/src/ahci.c +++ b/src/ahci.c @@ -382,23 +382,22 @@ ahci_port_init(struct ahci_ctrl_s *ctrl, u32 pnr) // Setup disk geometry translation. setup_translation(&port->drive); // Register with bcv system. - add_bcv_internal(&port->drive); + boot_add_hd(&port->drive); } else { // found cdrom (atapi) port->drive.blksize = CDROM_SECTOR_SIZE; port->drive.sectors = (u64)-1; u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05; - snprintf(port->drive.desc, MAXDESCSIZE, "AHCI/%d: %s ATAPI-%d %s" + snprintf(port->drive.desc, MAXDESCSIZE + , "DVD/CD [AHCI/%d: %s ATAPI-%d %s]" , port->pnr , ata_extract_model(model, MAXMODEL, buffer) , ata_extract_version(buffer) , (iscd ? "DVD/CD" : "Device"));
// fill cdidmap - if (iscd) { - map_cd_drive(&port->drive); - add_baid_cdrom(&port->drive); - } + if (iscd) + boot_add_cd(&port->drive); } dprintf(1, "%s\n", port->drive.desc);
diff --git a/src/ata.c b/src/ata.c index d971480..e01f842 100644 --- a/src/ata.c +++ b/src/ata.c @@ -14,7 +14,7 @@ #include "pci.h" // foreachpci #include "pci_ids.h" // PCI_CLASS_STORAGE_OTHER #include "pci_regs.h" // PCI_INTERRUPT_LINE -#include "boot.h" // add_bcv_hd +#include "boot.h" // boot_add_hd #include "disk.h" // struct ata_s #include "ata.h" // ATA_CB_STAT #include "blockcmd.h" // CDB_CMD_READ_10 @@ -774,7 +774,8 @@ init_drive_atapi(struct atadrive_s *dummy, u16 *buffer) adrive_g->drive.sectors = (u64)-1; u8 iscd = ((buffer[0] >> 8) & 0x1f) == 0x05; char model[MAXMODEL+1]; - snprintf(adrive_g->drive.desc, MAXDESCSIZE, "ata%d-%d: %s ATAPI-%d %s" + snprintf(adrive_g->drive.desc, MAXDESCSIZE + , "DVD/CD [ata%d-%d: %s ATAPI-%d %s]" , adrive_g->chan_gf->chanid, adrive_g->slave , ata_extract_model(model, MAXMODEL, buffer) , ata_extract_version(buffer) @@ -782,10 +783,8 @@ init_drive_atapi(struct atadrive_s *dummy, u16 *buffer) dprintf(1, "%s\n", adrive_g->drive.desc);
// fill cdidmap - if (iscd) { - map_cd_drive(&adrive_g->drive); - add_baid_cdrom(&adrive_g->drive); - } + if (iscd) + boot_add_cd(&adrive_g->drive);
return adrive_g; } @@ -835,7 +834,7 @@ init_drive_ata(struct atadrive_s *dummy, u16 *buffer) setup_translation(&adrive_g->drive);
// Register with bcv system. - add_bcv_internal(&adrive_g->drive); + boot_add_hd(&adrive_g->drive);
return adrive_g; } diff --git a/src/block.c b/src/block.c index cab503c..72b3081 100644 --- a/src/block.c +++ b/src/block.c @@ -226,26 +226,8 @@ add_ordered_drive(struct drive_s **idmap, u8 *count, struct drive_s *drive_g) warn_noalloc(); return; } - struct drive_s **pos = &idmap[*count]; + idmap[*count] = drive_g; *count = *count + 1; - if (CONFIG_THREADS) { - // Add to idmap with assured drive order. - struct drive_s **end = pos; - for (;;) { - struct drive_s **prev = pos - 1; - if (prev < idmap) - break; - struct drive_s *prevdrive = *prev; - if (prevdrive->type < drive_g->type - || (prevdrive->type == drive_g->type - && prevdrive->cntl_id < drive_g->cntl_id)) - break; - pos--; - } - if (pos != end) - memmove(pos+1, pos, (void*)end-(void*)pos); - } - *pos = drive_g; }
// Map a cd diff --git a/src/boot.c b/src/boot.c index 5137345..f7cc8d5 100644 --- a/src/boot.c +++ b/src/boot.c @@ -16,6 +16,20 @@
struct ipl_s IPL;
+struct bootentry_s { + int type; + union { + u32 data; + struct segoff_s vector; + struct drive_s *drive; + }; + int priority; + const char *description; + struct bootentry_s *next; +}; + +struct bootentry_s *BootList; +
/**************************************************************** * Boot setup @@ -56,51 +70,40 @@ loadBootOrder(void) } while(f); }
+#define MAX_BOOT_PRIO 0xff + +int DefaultFloppyPrio = 1; +int DefaultCDPrio = 2; +int DefaultHDPrio = 3; +int DefaultBEVPrio = 4; + void boot_setup(void) { if (! CONFIG_BOOT) return; - dprintf(3, "init boot device ordering\n"); - - memset(&IPL, 0, sizeof(IPL)); - struct ipl_entry_s *ie = &IPL.bev[0]; - - // Floppy drive - ie->type = IPL_TYPE_FLOPPY; - ie->description = "Floppy"; - ie++; - - // First HDD - ie->type = IPL_TYPE_HARDDISK; - ie->description = "Hard Disk"; - ie++; - - // CDROM - if (CONFIG_CDROM_BOOT) { - ie->type = IPL_TYPE_CDROM; - ie->description = "DVD/CD"; - ie++; - } - - if (CONFIG_COREBOOT && CONFIG_COREBOOT_FLASH) { - ie->type = IPL_TYPE_CBFS; - ie->description = "CBFS"; - ie++; - }
- IPL.bevcount = ie - IPL.bev; SET_EBDA(boot_sequence, 0xffff); - if (CONFIG_COREBOOT) { - // XXX - hardcode defaults for coreboot. - IPL.bootorder = 0x87654231; - IPL.checkfloppysig = 1; - } else { + IPL.checkfloppysig = 1; + + if (!CONFIG_COREBOOT) { // On emulators, get boot order from nvram. - IPL.bootorder = (inb_cmos(CMOS_BIOS_BOOTFLAG2) + if (inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1) + IPL.checkfloppysig = 0; + u32 bootorder = (inb_cmos(CMOS_BIOS_BOOTFLAG2) | ((inb_cmos(CMOS_BIOS_BOOTFLAG1) & 0xf0) << 4)); - if (!(inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1)) - IPL.checkfloppysig = 1; + DefaultFloppyPrio = DefaultCDPrio = DefaultHDPrio = MAX_BOOT_PRIO; + int i; + for (i=1; i<4; i++) { + u32 val = bootorder & 0x0f; + bootorder >>= 4; + switch (val) { + case 1: DefaultFloppyPrio = i; break; + case 2: DefaultHDPrio = i; break; + case 3: DefaultCDPrio = i; break; + case 4: DefaultBEVPrio = i; break; + } + } }
loadBootOrder(); @@ -111,169 +114,92 @@ boot_setup(void) * IPL and BCV handlers ****************************************************************/
-// Add a BEV vector for a given pnp compatible option rom. -void -add_bev(u16 seg, u16 bev, u16 desc) +static void +bootentry_add(int type, int prio, u32 data, const char *desc) { if (! CONFIG_BOOT) return; - if (IPL.bevcount >= ARRAY_SIZE(IPL.bev)) + struct bootentry_s *be = malloc_tmp(sizeof(*be)); + if (!be) { + warn_noalloc(); return; - - struct ipl_entry_s *ie = &IPL.bev[IPL.bevcount++]; - ie->type = IPL_TYPE_BEV; - ie->vector = (seg << 16) | bev; - const char *d = "Unknown"; - if (desc) - d = MAKE_FLATPTR(seg, desc); - ie->description = d; + } + be->type = type; + be->priority = prio; + be->data = data; + be->description = desc; + + // Add entry in sorted order. + struct bootentry_s **pprev; + for (pprev = &BootList; *pprev; pprev = &(*pprev)->next) { + struct bootentry_s *pos = *pprev; + if (be->priority < pos->priority) + break; + if (be->priority > pos->priority) + continue; + if (be->type < pos->type) + break; + if (be->type > pos->type) + continue; + if (be->type <= IPL_TYPE_CDROM + && (be->drive->type < pos->drive->type + || (be->drive->type == pos->drive->type + && be->drive->cntl_id < pos->drive->cntl_id))) + break; + } + be->next = *pprev; + *pprev = be; }
-// Add a IPL entry for BAID cdrom. +// Add a BEV vector for a given pnp compatible option rom. void -add_baid_cdrom(struct drive_s *drive_g) +boot_add_bev(u16 seg, u16 bev, u16 desc) { - if (! CONFIG_CDROM_BOOT) - return; - - /* put first cdrom into ipl 3 for compatability with qemu */ - struct ipl_entry_s *ie = &IPL.bev[2]; - if (IPL.bevcount >= ARRAY_SIZE(IPL.bev) && ie->vector) - return; - - if (ie->vector) - ie = &IPL.bev[IPL.bevcount++]; - ie->type = IPL_TYPE_CDROM; - ie->vector = (u32)drive_g; - ie->description = "DVD/CD"; + bootentry_add(IPL_TYPE_BEV, DefaultBEVPrio, SEGOFF(seg, bev).segoff + , desc ? MAKE_FLATPTR(seg, desc) : "Unknown"); + DefaultBEVPrio = MAX_BOOT_PRIO; }
// Add a bcv entry for an expansion card harddrive or legacy option rom void -add_bcv(u16 seg, u16 ip, u16 desc) +boot_add_bcv(u16 seg, u16 ip, u16 desc) { - if (! CONFIG_BOOT) - return; - if (IPL.bcvcount >= ARRAY_SIZE(IPL.bcv)) - return; - - struct ipl_entry_s *ie = &IPL.bcv[IPL.bcvcount++]; - ie->type = BCV_TYPE_EXTERNAL; - ie->vector = (seg << 16) | ip; - const char *d = "Legacy option rom"; - if (desc) - d = MAKE_FLATPTR(seg, desc); - ie->description = d; + bootentry_add(IPL_TYPE_BCV, MAX_BOOT_PRIO, SEGOFF(seg, ip).segoff + , desc ? MAKE_FLATPTR(seg, desc) : "Legacy option rom"); }
-// Add a bcv entry for an internal harddrive void -add_bcv_internal(struct drive_s *drive_g) +boot_add_floppy(struct drive_s *drive_g) { - if (! CONFIG_BOOT) - return; - if (IPL.bcvcount >= ARRAY_SIZE(IPL.bcv)) - return; - - struct ipl_entry_s *ie = &IPL.bcv[IPL.bcvcount++]; - if (CONFIG_THREADS) { - // Add to bcv list with assured drive order. - struct ipl_entry_s *end = ie; - for (;;) { - struct ipl_entry_s *prev = ie - 1; - if (prev < IPL.bcv || prev->type != BCV_TYPE_INTERNAL) - break; - struct drive_s *prevdrive = (void*)prev->vector; - if (prevdrive->type < drive_g->type - || (prevdrive->type == drive_g->type - && prevdrive->cntl_id < drive_g->cntl_id)) - break; - ie--; - } - if (ie != end) - memmove(ie+1, ie, (void*)end-(void*)ie); - } - ie->type = BCV_TYPE_INTERNAL; - ie->vector = (u32)drive_g; - ie->description = ""; + bootentry_add(IPL_TYPE_FLOPPY, DefaultFloppyPrio, (u32)drive_g + , drive_g->desc); }
- -/**************************************************************** - * Boot menu and BCV execution - ****************************************************************/ - -// Show a generic menu item -static int -menu_show_default(struct ipl_entry_s *ie, int menupos) +void +boot_add_hd(struct drive_s *drive_g) { - char desc[33]; - printf("%d. %s\n", menupos - , strtcpy(desc, ie->description, ARRAY_SIZE(desc))); - return 1; + bootentry_add(IPL_TYPE_HARDDISK, DefaultHDPrio, (u32)drive_g + , drive_g->desc); }
-// Show floppy menu item - but only if there exists a floppy drive. -static int -menu_show_floppy(struct ipl_entry_s *ie, int menupos) +void +boot_add_cd(struct drive_s *drive_g) { - int i; - for (i = 0; i < Drives.floppycount; i++) { - struct drive_s *drive_g = getDrive(EXTTYPE_FLOPPY, i); - printf("%d. Floppy [%s]\n", menupos + i, drive_g->desc); - } - return Drives.floppycount; + bootentry_add(IPL_TYPE_CDROM, DefaultCDPrio, (u32)drive_g + , drive_g->desc); }
-// Show menu items from BCV list. -static int -menu_show_harddisk(struct ipl_entry_s *ie, int menupos) +// Add a CBFS payload entry +void +boot_add_cbfs(void *data, const char *desc) { - int i; - for (i = 0; i < IPL.bcvcount; i++) { - struct ipl_entry_s *ie = &IPL.bcv[i]; - struct drive_s *drive_g = (void*)ie->vector; - switch (ie->type) { - case BCV_TYPE_INTERNAL: - printf("%d. %s\n", menupos + i, drive_g->desc); - break; - default: - menu_show_default(ie, menupos+i); - break; - } - } - return IPL.bcvcount; + bootentry_add(IPL_TYPE_CBFS, MAX_BOOT_PRIO, (u32)data, desc); }
-// Show cdrom menu item - but only if there exists a cdrom drive. -static int -menu_show_cdrom(struct ipl_entry_s *ie, int menupos) -{ - struct drive_s *drive_g = (void*)ie->vector; - if (!ie->vector) - return 0; - printf("%d. DVD/CD [%s]\n", menupos, drive_g->desc); - return 1; -}
-// Show coreboot-fs menu item. -static int -menu_show_cbfs(struct ipl_entry_s *ie, int menupos) -{ - int count = 0; - struct cbfs_file *file = NULL; - for (;;) { - file = cbfs_findprefix("img/", file); - if (!file) - break; - const char *filename = cbfs_filename(file); - printf("%d. Payload [%s]\n", menupos + count, &filename[4]); - count++; - if (count > 8) - break; - } - return count; -} +/**************************************************************** + * Boot menu and BCV execution + ****************************************************************/
// Show IPL option menu. static void @@ -300,31 +226,15 @@ interactive_bootmenu(void) printf("Select boot device:\n\n"); wait_threads();
- int subcount[ARRAY_SIZE(IPL.bev)]; - int menupos = 1; - int i; - for (i = 0; i < IPL.bevcount; i++) { - struct ipl_entry_s *ie = &IPL.bev[i]; - int sc; - switch (ie->type) { - case IPL_TYPE_FLOPPY: - sc = menu_show_floppy(ie, menupos); - break; - case IPL_TYPE_HARDDISK: - sc = menu_show_harddisk(ie, menupos); - break; - case IPL_TYPE_CDROM: - sc = menu_show_cdrom(ie, menupos); - break; - case IPL_TYPE_CBFS: - sc = menu_show_cbfs(ie, menupos); - break; - default: - sc = menu_show_default(ie, menupos); - break; - } - subcount[i] = sc; - menupos += sc; + // Show menu items + struct bootentry_s *pos = BootList; + int maxmenu = 0; + while (pos) { + char desc[60]; + maxmenu++; + printf("%d. %s\n", maxmenu + , strtcpy(desc, pos->description, ARRAY_SIZE(desc))); + pos = pos->next; }
for (;;) { @@ -332,37 +242,32 @@ interactive_bootmenu(void) if (scan_code == 0x01) // ESC break; - if (scan_code < 1 || scan_code > menupos) + if (scan_code < 1 || scan_code > maxmenu+1) continue; int choice = scan_code - 1;
- // Find out which IPL this was for. - int bev = 0; - while (choice > subcount[bev]) { - choice -= subcount[bev]; - bev++; - } - IPL.bev[bev].subchoice = choice-1; - - // Add user choice to the boot order. - IPL.bootorder = (IPL.bootorder << 4) | (bev+1); + // Find entry and make top priority. + struct bootentry_s **pprev = &BootList; + while (--choice) + pprev = &(*pprev)->next; + pos = *pprev; + *pprev = pos->next; + pos->next = BootList; + BootList = pos; + pos->priority = 0; break; } printf("\n"); }
-// Run the specified bcv. static void -run_bcv(struct ipl_entry_s *ie) +add_bev(int type, u32 vector) { - switch (ie->type) { - case BCV_TYPE_INTERNAL: - map_hd_drive((void*)ie->vector); - break; - case BCV_TYPE_EXTERNAL: - call_bcv(ie->vector >> 16, ie->vector & 0xffff); - break; - } + if (IPL.bevcount >= ARRAY_SIZE(IPL.bev)) + return; + struct ipl_entry_s *bev = &IPL.bev[IPL.bevcount++]; + bev->type = type; + bev->vector = vector; }
// Prepare for boot - show menu and run bcvs. @@ -380,20 +285,48 @@ boot_prep(void) interactive_bootmenu(); wait_threads();
- // Setup floppy boot order - int override = IPL.bev[0].subchoice; - struct drive_s *tmp = Drives.idmap[EXTTYPE_FLOPPY][0]; - Drives.idmap[EXTTYPE_FLOPPY][0] = Drives.idmap[EXTTYPE_FLOPPY][override]; - Drives.idmap[EXTTYPE_FLOPPY][override] = tmp; + // Map drives and populate BEV list + int hdboot = 0, floppyboot = 0; + struct bootentry_s *pos = BootList; + while (pos) { + switch (pos->type) { + case IPL_TYPE_BEV: + add_bev(IPL_TYPE_BEV, pos->data); + break; + case IPL_TYPE_BCV: + call_bcv(pos->vector.seg, pos->vector.offset); + if (!hdboot) + add_bev(IPL_TYPE_HARDDISK, 0); + hdboot = 1; + break; + case IPL_TYPE_FLOPPY: + map_floppy_drive(pos->drive); + if (!floppyboot) + add_bev(IPL_TYPE_FLOPPY, 0); + floppyboot = 1; + break; + case IPL_TYPE_HARDDISK: + map_hd_drive(pos->drive); + if (!hdboot) + add_bev(IPL_TYPE_HARDDISK, 0); + hdboot = 1; + break; + case IPL_TYPE_CDROM: + map_cd_drive(pos->drive); + add_bev(IPL_TYPE_CDROM, (u32)pos->drive); + break; + case IPL_TYPE_CBFS: + add_bev(IPL_TYPE_CBFS, pos->data); + break; + } + pos = pos->next; + }
- // Run BCVs - override = IPL.bev[1].subchoice; - if (override < IPL.bcvcount) - run_bcv(&IPL.bcv[override]); - int i; - for (i=0; i<IPL.bcvcount; i++) - if (i != override) - run_bcv(&IPL.bcv[i]); + // If nothing added a floppy/hd boot - add it manually. + if (!floppyboot) + add_bev(IPL_TYPE_FLOPPY, 0); + if (!hdboot) + add_bev(IPL_TYPE_HARDDISK, 0); }
@@ -462,6 +395,7 @@ boot_cdrom(struct ipl_entry_s *ie)
if (!ie->vector) return; + printf("Booting from DVD/CD...\n");
struct drive_s *drive_g = (void*)ie->vector; int status = cdrom_boot(drive_g); @@ -486,16 +420,8 @@ boot_cbfs(struct ipl_entry_s *ie) { if (!CONFIG_COREBOOT || !CONFIG_COREBOOT_FLASH) return; - int count = ie->subchoice; - struct cbfs_file *file = NULL; - for (;;) { - file = cbfs_findprefix("img/", file); - if (!file) - return; - if (count--) - continue; - cbfs_run_payload(file); - } + printf("Booting from CBFS...\n"); + cbfs_run_payload((void*)ie->vector); }
static void @@ -504,32 +430,22 @@ do_boot(u16 seq_nr) if (! CONFIG_BOOT) panic("Boot support not compiled in.\n");
- u32 bootdev = IPL.bootorder; - bootdev >>= 4 * seq_nr; - bootdev &= 0xf; - - /* Translate bootdev to an IPL table offset by subtracting 1 */ - bootdev -= 1; - - if (bootdev >= IPL.bevcount) { + if (seq_nr >= IPL.bevcount) { printf("No bootable device.\n"); // Loop with irqs enabled - this allows ctrl+alt+delete to work. for (;;) wait_irq(); }
- /* Do the loading, and set up vector as a far pointer to the boot - * address, and bootdrv as the boot drive */ - struct ipl_entry_s *ie = &IPL.bev[bootdev]; - char desc[33]; - printf("Booting from %s...\n" - , strtcpy(desc, ie->description, ARRAY_SIZE(desc))); - + // Boot the given BEV type. + struct ipl_entry_s *ie = &IPL.bev[seq_nr]; switch (ie->type) { case IPL_TYPE_FLOPPY: + printf("Booting from Floppy...\n"); boot_disk(0x00, IPL.checkfloppysig); break; case IPL_TYPE_HARDDISK: + printf("Booting from Hard Disk...\n"); boot_disk(0x80, 1); break; case IPL_TYPE_CDROM: @@ -539,6 +455,7 @@ do_boot(u16 seq_nr) boot_cbfs(ie); break; case IPL_TYPE_BEV: + printf("Booting from ROM...\n"); call_boot_entry(ie->vector >> 16, ie->vector & 0xffff, 0); break; } diff --git a/src/boot.h b/src/boot.h index 778aebd..f1a428e 100644 --- a/src/boot.h +++ b/src/boot.h @@ -9,16 +9,12 @@
struct ipl_entry_s { u16 type; - u16 subchoice; u32 vector; - const char *description; };
struct ipl_s { struct ipl_entry_s bev[8]; - struct ipl_entry_s bcv[8]; - int bevcount, bcvcount; - u32 bootorder; + int bevcount; int checkfloppysig; char **fw_bootorder; int fw_bootorder_count; @@ -29,9 +25,7 @@ struct ipl_s { #define IPL_TYPE_CDROM 0x03 #define IPL_TYPE_CBFS 0x20 #define IPL_TYPE_BEV 0x80 - -#define BCV_TYPE_EXTERNAL 0x80 -#define BCV_TYPE_INTERNAL 0x02 +#define IPL_TYPE_BCV 0x81
/**************************************************************** @@ -41,11 +35,13 @@ struct ipl_s { // boot.c extern struct ipl_s IPL; void boot_setup(void); -void add_bev(u16 seg, u16 bev, u16 desc); -void add_bcv(u16 seg, u16 ip, u16 desc); +void boot_add_bev(u16 seg, u16 bev, u16 desc); +void boot_add_bcv(u16 seg, u16 ip, u16 desc); struct drive_s; -void add_bcv_internal(struct drive_s *drive_g); -void add_baid_cdrom(struct drive_s *drive_g); +void boot_add_floppy(struct drive_s *drive_g); +void boot_add_hd(struct drive_s *drive_g); +void boot_add_cd(struct drive_s *drive_g); +void boot_add_cbfs(void *data, const char *desc);
void boot_prep(void);
diff --git a/src/coreboot.c b/src/coreboot.c index cdbf337..dab0a54 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -12,6 +12,7 @@ #include "biosvar.h" // GET_EBDA #include "lzmadecode.h" // LzmaDecode #include "smbios.h" // smbios_init +#include "boot.h" // boot_add_cbfs
/**************************************************************** @@ -593,9 +594,28 @@ cbfs_run_payload(struct cbfs_file *file) } }
+// Register payloads in "img/" directory with boot system. +static void +register_cbfs_payload(void) +{ + struct cbfs_file *file = NULL; + for (;;) { + file = cbfs_findprefix("img/", file); + if (!file) + break; + const char *filename = cbfs_filename(file); + char *desc = malloc_tmp(MAXDESCSIZE); + if (!desc) + break; + snprintf(desc, MAXDESCSIZE, "Payload [%s]", &filename[4]); + boot_add_cbfs(file, desc); + } +} + void coreboot_setup(void) { coreboot_fill_map(); cbfs_setup(); + register_cbfs_payload(); } diff --git a/src/floppy.c b/src/floppy.c index 6491b96..8986e39 100644 --- a/src/floppy.c +++ b/src/floppy.c @@ -13,6 +13,7 @@ #include "cmos.h" // inb_cmos #include "pic.h" // eoi_pic1 #include "bregs.h" // struct bregs +#include "boot.h" // boot_add_floppy
#define FLOPPY_SIZE_CODE 0x02 // 512 byte sectors #define FLOPPY_DATALEN 0xff // Not used - because size code is 0x02 @@ -111,12 +112,12 @@ addFloppy(int floppyid, int ftype, int driver) drive_g->floppy_type = ftype; drive_g->sectors = (u64)-1; drive_g->desc = desc; - snprintf(desc, MAXDESCSIZE, "drive %c", 'A' + floppyid); + snprintf(desc, MAXDESCSIZE, "Floppy [drive %c]", 'A' + floppyid);
memcpy(&drive_g->lchs, &FloppyInfo[ftype].chs , sizeof(FloppyInfo[ftype].chs));
- map_floppy_drive(drive_g); + boot_add_floppy(drive_g); return drive_g; }
diff --git a/src/optionroms.c b/src/optionroms.c index 19672f7..2ac4325 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -412,17 +412,17 @@ optionrom_setup(void) struct pnp_data *pnp = get_pnp_rom(rom); if (! pnp) { // Legacy rom. - add_bcv(FLATPTR_TO_SEG(rom), OPTION_ROM_INITVECTOR, 0); + boot_add_bcv(FLATPTR_TO_SEG(rom), OPTION_ROM_INITVECTOR, 0); continue; } // PnP rom. if (pnp->bev) // Can boot system - add to IPL list. - add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname); + boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname); else // Check for BCV (there may be multiple). while (pnp && pnp->bcv) { - add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname); + boot_add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname); pnp = get_pnp_next(rom, pnp); } } diff --git a/src/usb-msc.c b/src/usb-msc.c index 48635d9..378143e 100644 --- a/src/usb-msc.c +++ b/src/usb-msc.c @@ -11,7 +11,7 @@ #include "biosvar.h" // GET_GLOBAL #include "blockcmd.h" // cdb_read #include "disk.h" // DTYPE_USB -#include "boot.h" // add_bcv_internal +#include "boot.h" // boot_add_hd
struct usbdrive_s { struct drive_s drive; @@ -143,7 +143,7 @@ setup_drive_cdrom(struct disk_op_s *op) { op->drive_g->blksize = CDROM_SECTOR_SIZE; op->drive_g->sectors = (u64)-1; - map_cd_drive(op->drive_g); + boot_add_cd(op->drive_g); return 0; }
@@ -171,7 +171,7 @@ setup_drive_hd(struct disk_op_s *op) setup_translation(op->drive_g);
// Register with bcv system. - add_bcv_internal(op->drive_g); + boot_add_hd(op->drive_g);
return 0; } diff --git a/src/virtio-blk.c b/src/virtio-blk.c index 9c9ed83..def8313 100644 --- a/src/virtio-blk.c +++ b/src/virtio-blk.c @@ -13,7 +13,7 @@ #include "biosvar.h" // GET_GLOBAL #include "pci_ids.h" // PCI_DEVICE_ID_VIRTIO_BLK #include "pci_regs.h" // PCI_VENDOR_ID -#include "boot.h" // add_bcv_internal +#include "boot.h" // boot_add_hd #include "virtio-pci.h" #include "virtio-ring.h" #include "virtio-blk.h" @@ -156,7 +156,7 @@ init_virtio_blk(u16 bdf) vdrive_g->drive.desc = desc;
setup_translation(&vdrive_g->drive); - add_bcv_internal(&vdrive_g->drive); + boot_add_hd(&vdrive_g->drive);
vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK);
On Sun, Dec 26, 2010 at 11:27:31PM -0500, Kevin O'Connor wrote:
This is a patch series to simplify the current boot prioritization code. The basic idea is to replace the BCV list with a list that contains all bootable objects. It's then easier to make that list authoritative and do all ordering on it. This is a code simplification even without the new "bootorder" file reading code.
Great refactoring. The previous code was indeed pretty confusing. It took me a while to fully understand how it worked. I will resend my patch on top on this series.
-- Gleb.