For each BAID/BCV/BEV lookup its boot priority in boot order file. If there is no entry for a device there assign it the lowest boot priority.
Signed-off-by: Gleb Natapov gleb@redhat.com --- src/ahci.c | 4 ++-- src/ata.c | 10 ++++++++-- src/boot.c | 38 ++++++++++++++++++++++++++++++++++---- src/boot.h | 15 +++++++++++---- src/floppy.c | 22 ++++++++++++++++++++-- src/optionroms.c | 19 ++++++++++++++++--- src/usb-msc.c | 2 +- src/virtio-blk.c | 2 +- 8 files changed, 93 insertions(+), 19 deletions(-)
diff --git a/src/ahci.c b/src/ahci.c index 70c0f1c..a209c86 100644 --- a/src/ahci.c +++ b/src/ahci.c @@ -382,7 +382,7 @@ 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); + add_bcv_internal(&port->drive, MAX_BOOT_PRIO); } else { // found cdrom (atapi) port->drive.blksize = CDROM_SECTOR_SIZE; @@ -397,7 +397,7 @@ ahci_port_init(struct ahci_ctrl_s *ctrl, u32 pnr) // fill cdidmap if (iscd) { map_cd_drive(&port->drive); - add_baid_cdrom(&port->drive); + add_baid_cdrom(&port->drive, MAX_BOOT_PRIO); } } dprintf(1, "%s\n", port->drive.desc); diff --git a/src/ata.c b/src/ata.c index d971480..e45de50 100644 --- a/src/ata.c +++ b/src/ata.c @@ -783,8 +783,11 @@ init_drive_atapi(struct atadrive_s *dummy, u16 *buffer)
// fill cdidmap if (iscd) { + int prio = bootprio_find_ata_device(adrive_g->chan_gf->pci_bdf, + adrive_g->chan_gf->chanid, + adrive_g->slave); map_cd_drive(&adrive_g->drive); - add_baid_cdrom(&adrive_g->drive); + add_baid_cdrom(&adrive_g->drive, prio); }
return adrive_g; @@ -834,8 +837,11 @@ init_drive_ata(struct atadrive_s *dummy, u16 *buffer) // Setup disk geometry translation. setup_translation(&adrive_g->drive);
+ int prio = bootprio_find_ata_device(adrive_g->chan_gf->pci_bdf, + adrive_g->chan_gf->chanid, + adrive_g->slave); // Register with bcv system. - add_bcv_internal(&adrive_g->drive); + add_bcv_internal(&adrive_g->drive, prio);
return adrive_g; } diff --git a/src/boot.c b/src/boot.c index 5137345..8a9246e 100644 --- a/src/boot.c +++ b/src/boot.c @@ -113,7 +113,7 @@ boot_setup(void)
// Add a BEV vector for a given pnp compatible option rom. void -add_bev(u16 seg, u16 bev, u16 desc) +add_bev(u16 seg, u16 bev, u16 desc, u8 prio) { if (! CONFIG_BOOT) return; @@ -127,11 +127,12 @@ add_bev(u16 seg, u16 bev, u16 desc) if (desc) d = MAKE_FLATPTR(seg, desc); ie->description = d; + ie->prio = prio; }
// Add a IPL entry for BAID cdrom. void -add_baid_cdrom(struct drive_s *drive_g) +add_baid_cdrom(struct drive_s *drive_g, u8 prio) { if (! CONFIG_CDROM_BOOT) return; @@ -146,11 +147,18 @@ add_baid_cdrom(struct drive_s *drive_g) ie->type = IPL_TYPE_CDROM; ie->vector = (u32)drive_g; ie->description = "DVD/CD"; + ie->prio = prio; +} + +void set_floppy_baid_prio(u8 prio) +{ + struct ipl_entry_s *ie = &IPL.bev[0]; + ie->prio = prio; }
// Add a bcv entry for an expansion card harddrive or legacy option rom void -add_bcv(u16 seg, u16 ip, u16 desc) +add_bcv(u16 seg, u16 ip, u16 desc, u8 prio) { if (! CONFIG_BOOT) return; @@ -164,11 +172,12 @@ add_bcv(u16 seg, u16 ip, u16 desc) if (desc) d = MAKE_FLATPTR(seg, desc); ie->description = d; + ie->prio = prio; }
// Add a bcv entry for an internal harddrive void -add_bcv_internal(struct drive_s *drive_g) +add_bcv_internal(struct drive_s *drive_g, u8 prio) { if (! CONFIG_BOOT) return; @@ -196,6 +205,7 @@ add_bcv_internal(struct drive_s *drive_g) ie->type = BCV_TYPE_INTERNAL; ie->vector = (u32)drive_g; ie->description = ""; + ie->prio = prio; }
@@ -571,3 +581,23 @@ handle_19(void) SET_EBDA(boot_sequence, 0); do_boot(0); } + +u8 bootprio_find_pci_device(int bdf) +{ + return MAX_BOOT_PRIO; +} + +u8 bootprio_find_ata_device(int bdf, int chanid, int slave) +{ + return MAX_BOOT_PRIO; +} + +u8 bootprio_find_fdc_device(int bfd, int port, int fdid) +{ + return MAX_BOOT_PRIO; +} + +u8 bootprio_find_named_rom(const char *name) +{ + return MAX_BOOT_PRIO; +} diff --git a/src/boot.h b/src/boot.h index 778aebd..5a4c6ea 100644 --- a/src/boot.h +++ b/src/boot.h @@ -12,6 +12,7 @@ struct ipl_entry_s { u16 subchoice; u32 vector; const char *description; + u8 prio; };
struct ipl_s { @@ -33,6 +34,7 @@ struct ipl_s { #define BCV_TYPE_EXTERNAL 0x80 #define BCV_TYPE_INTERNAL 0x02
+#define MAX_BOOT_PRIO 255
/**************************************************************** * Function defs @@ -41,12 +43,17 @@ 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 add_bev(u16 seg, u16 bev, u16 desc, u8 prio); +void add_bcv(u16 seg, u16 ip, u16 desc, u8 prio); struct drive_s; -void add_bcv_internal(struct drive_s *drive_g); -void add_baid_cdrom(struct drive_s *drive_g); +void add_bcv_internal(struct drive_s *drive_g, u8 prio); +void add_baid_cdrom(struct drive_s *drive_g, u8 prio); +void set_floppy_baid_prio(u8 prio);
void boot_prep(void); +u8 bootprio_find_pci_device(int bdf); +u8 bootprio_find_ata_device(int bdf, int chanid, int slave); +u8 bootprio_find_fdc_device(int bfd, int port, int fdid); +u8 bootprio_find_named_rom(const char *name);
#endif // __BOOT_H diff --git a/src/floppy.c b/src/floppy.c index 6491b96..7dd3083 100644 --- a/src/floppy.c +++ b/src/floppy.c @@ -13,6 +13,9 @@ #include "cmos.h" // inb_cmos #include "pic.h" // eoi_pic1 #include "bregs.h" // struct bregs +#include "pci.h" // pci_to_bdf +#include "pci_ids.h" // PCI_CLASS_BRIDGE_ISA +#include "boot.h" // bootprio_find_fdc_device
#define FLOPPY_SIZE_CODE 0x02 // 512 byte sectors #define FLOPPY_DATALEN 0xff // Not used - because size code is 0x02 @@ -131,10 +134,25 @@ floppy_setup(void) // XXX - disable floppies on coreboot for now. } else { u8 type = inb_cmos(CMOS_FLOPPY_DRIVE_TYPE); - if (type & 0xf0) + unsigned int prio0 = -1, prio1 = -1; + int bdf = pci_find_class(PCI_CLASS_BRIDGE_ISA); /* isa-to-pci bridge */ + + if (type & 0xf0) { addFloppy(0, type >> 4, DTYPE_FLOPPY); - if (type & 0x0f) + prio0 = bootprio_find_fdc_device(bdf, 0x3f0, 0); + } + if (type & 0x0f) { addFloppy(1, type & 0x0f, DTYPE_FLOPPY); + prio1 = bootprio_find_fdc_device(bdf, 0x3f0, 1); + } + if (prio1 < prio0) { + /* if B has lower boot priority swap it with A */ + struct drive_s *tmp = Drives.idmap[EXTTYPE_FLOPPY][0]; + Drives.idmap[EXTTYPE_FLOPPY][0] = Drives.idmap[EXTTYPE_FLOPPY][1]; + Drives.idmap[EXTTYPE_FLOPPY][1] = tmp; + set_floppy_baid_prio(prio1); + } else + set_floppy_baid_prio(prio0); }
outb(0x02, PORT_DMA1_MASK_REG); diff --git a/src/optionroms.c b/src/optionroms.c index 19672f7..171ec1c 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -75,6 +75,7 @@ struct pnp_data { u32 RomEnd = BUILD_ROM_START;
+ /**************************************************************** * Helper functions ****************************************************************/ @@ -220,6 +221,17 @@ setRomSource(u64 *sources, struct rom_header *rom, u64 source) sources[((u32)rom - BUILD_ROM_START) / OPTION_ROM_ALIGN] = source; }
+static u8 +getRomPriority(u64 *sources, struct rom_header *rom) +{ + u64 source = sources[((u32)rom - BUILD_ROM_START) / OPTION_ROM_ALIGN]; + if (!source) + return -1; + if (source & RS_PCIROM) + return bootprio_find_pci_device(source); + return bootprio_find_named_rom(romfile_name(source)); +} +
/**************************************************************** * Roms in CBFS @@ -408,21 +420,22 @@ optionrom_setup(void) pos += OPTION_ROM_ALIGN; continue; } + u8 romprio = getRomPriority(sources, rom); pos += ALIGN(rom->size * 512, OPTION_ROM_ALIGN); struct pnp_data *pnp = get_pnp_rom(rom); if (! pnp) { // Legacy rom. - add_bcv(FLATPTR_TO_SEG(rom), OPTION_ROM_INITVECTOR, 0); + add_bcv(FLATPTR_TO_SEG(rom), OPTION_ROM_INITVECTOR, 0, romprio); continue; } // PnP rom. if (pnp->bev) // Can boot system - add to IPL list. - add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname); + add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname, romprio); else // Check for BCV (there may be multiple). while (pnp && pnp->bcv) { - add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname); + add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname, romprio); pnp = get_pnp_next(rom, pnp); } } diff --git a/src/usb-msc.c b/src/usb-msc.c index 080efdc..c3ffe0b 100644 --- a/src/usb-msc.c +++ b/src/usb-msc.c @@ -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); + add_bcv_internal(op->drive_g, MAX_BOOT_PRIO);
return 0; } diff --git a/src/virtio-blk.c b/src/virtio-blk.c index 7a25826..3d2b7a6 100644 --- a/src/virtio-blk.c +++ b/src/virtio-blk.c @@ -153,7 +153,7 @@ init_virtio_blk(u16 bdf) vdrive_g->drive.pchs.spt = cfg.sectors;
setup_translation(&vdrive_g->drive); - add_bcv_internal(&vdrive_g->drive); + add_bcv_internal(&vdrive_g->drive, bootprio_find_pci_device(bdf));
snprintf(desc, MAXDESCSIZE, "Virtio disk PCI:%x:%x", pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf));