From 031ef55b50361adff3d1d2766543d2f9c6ce1998 Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 27 Dec 2010 19:26:57 -0500 Subject: [PATCH] Add stubs to permit devices to specify their boot priority. Add support for passing in priorities to bootlist system. Based on patch by: Gleb Natapov --- src/ahci.c | 4 +- src/ata.c | 13 +++++-- src/boot.c | 99 +++++++++++++++++++++++++++++++++--------------- src/boot.h | 18 +++++---- src/coreboot.c | 2 +- src/floppy.c | 7 +++- src/ioport.h | 1 + src/optionroms.c | 25 +++++++++--- src/usb-msc.c | 4 +- src/virtio-blk.c | 2 +- 10 files changed, 122 insertions(+), 53 deletions(-) diff --git a/src/ahci.c b/src/ahci.c index 03e39ad..a7f458f 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. - boot_add_hd(&port->drive); + boot_add_hd(&port->drive, -1); } 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) - boot_add_cd(&port->drive); + boot_add_cd(&port->drive, -1); } dprintf(1, "%s\n", port->drive.desc); diff --git a/src/ata.c b/src/ata.c index e01f842..872c5e3 100644 --- a/src/ata.c +++ b/src/ata.c @@ -783,8 +783,12 @@ init_drive_atapi(struct atadrive_s *dummy, u16 *buffer) dprintf(1, "%s\n", adrive_g->drive.desc); // fill cdidmap - if (iscd) - boot_add_cd(&adrive_g->drive); + if (iscd) { + int prio = bootprio_find_ata_device(adrive_g->chan_gf->pci_bdf, + adrive_g->chan_gf->chanid, + adrive_g->slave); + boot_add_cd(&adrive_g->drive, prio); + } return adrive_g; } @@ -833,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. - boot_add_hd(&adrive_g->drive); + boot_add_hd(&adrive_g->drive, prio); return adrive_g; } diff --git a/src/boot.c b/src/boot.c index 62d6487..d37e10f 100644 --- a/src/boot.c +++ b/src/boot.c @@ -16,23 +16,9 @@ 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; -}; - -static struct bootentry_s *BootList; - /**************************************************************** - * Boot setup + * Boot priority ordering ****************************************************************/ static void @@ -70,6 +56,36 @@ loadBootOrder(void) } while(f); } +int bootprio_find_pci_device(int bdf) +{ + return -1; +} + +int bootprio_find_ata_device(int bdf, int chanid, int slave) +{ + return -1; +} + +int bootprio_find_fdc_device(int bfd, int port, int fdid) +{ + return -1; +} + +int bootprio_find_pci_rom(int bdf, int instance) +{ + return -1; +} + +int bootprio_find_named_rom(const char *name, int instance) +{ + return -1; +} + + +/**************************************************************** + * Boot setup + ****************************************************************/ + #define DEFAULT_PRIO 9999 static int DefaultFloppyPrio = 101; @@ -112,9 +128,23 @@ boot_setup(void) /**************************************************************** - * IPL and BCV handlers + * BootList handling ****************************************************************/ +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; +}; + +static struct bootentry_s *BootList; + static void bootentry_add(int type, int prio, u32 data, const char *desc) { @@ -152,49 +182,56 @@ bootentry_add(int type, int prio, u32 data, const char *desc) *pprev = be; } +// Return the given priority if it's set - defaultprio otherwise. +static inline int defPrio(int priority, int defaultprio) { + return (priority < 0) ? defaultprio : priority; +} + // Add a BEV vector for a given pnp compatible option rom. void -boot_add_bev(u16 seg, u16 bev, u16 desc) +boot_add_bev(u16 seg, u16 bev, u16 desc, int prio) { - bootentry_add(IPL_TYPE_BEV, DefaultBEVPrio, SEGOFF(seg, bev).segoff + bootentry_add(IPL_TYPE_BEV, defPrio(prio, DefaultBEVPrio) + , SEGOFF(seg, bev).segoff , desc ? MAKE_FLATPTR(seg, desc) : "Unknown"); DefaultBEVPrio = DEFAULT_PRIO; } // Add a bcv entry for an expansion card harddrive or legacy option rom void -boot_add_bcv(u16 seg, u16 ip, u16 desc) +boot_add_bcv(u16 seg, u16 ip, u16 desc, int prio) { - bootentry_add(IPL_TYPE_BCV, DEFAULT_PRIO, SEGOFF(seg, ip).segoff + bootentry_add(IPL_TYPE_BCV, defPrio(prio, DEFAULT_PRIO) + , SEGOFF(seg, ip).segoff , desc ? MAKE_FLATPTR(seg, desc) : "Legacy option rom"); } void -boot_add_floppy(struct drive_s *drive_g) +boot_add_floppy(struct drive_s *drive_g, int prio) { - bootentry_add(IPL_TYPE_FLOPPY, DefaultFloppyPrio, (u32)drive_g - , drive_g->desc); + bootentry_add(IPL_TYPE_FLOPPY, defPrio(prio, DefaultFloppyPrio) + , (u32)drive_g, drive_g->desc); } void -boot_add_hd(struct drive_s *drive_g) +boot_add_hd(struct drive_s *drive_g, int prio) { - bootentry_add(IPL_TYPE_HARDDISK, DefaultHDPrio, (u32)drive_g - , drive_g->desc); + bootentry_add(IPL_TYPE_HARDDISK, defPrio(prio, DefaultHDPrio) + , (u32)drive_g, drive_g->desc); } void -boot_add_cd(struct drive_s *drive_g) +boot_add_cd(struct drive_s *drive_g, int prio) { - bootentry_add(IPL_TYPE_CDROM, DefaultCDPrio, (u32)drive_g - , drive_g->desc); + bootentry_add(IPL_TYPE_CDROM, defPrio(prio, DefaultCDPrio) + , (u32)drive_g, drive_g->desc); } // Add a CBFS payload entry void -boot_add_cbfs(void *data, const char *desc) +boot_add_cbfs(void *data, const char *desc, int prio) { - bootentry_add(IPL_TYPE_CBFS, DEFAULT_PRIO, (u32)data, desc); + bootentry_add(IPL_TYPE_CBFS, defPrio(prio, DEFAULT_PRIO), (u32)data, desc); } diff --git a/src/boot.h b/src/boot.h index f1a428e..fa455d5 100644 --- a/src/boot.h +++ b/src/boot.h @@ -35,14 +35,18 @@ struct ipl_s { // boot.c extern struct ipl_s IPL; void boot_setup(void); -void boot_add_bev(u16 seg, u16 bev, u16 desc); -void boot_add_bcv(u16 seg, u16 ip, u16 desc); +void boot_add_bev(u16 seg, u16 bev, u16 desc, int prio); +void boot_add_bcv(u16 seg, u16 ip, u16 desc, int prio); struct drive_s; -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_add_floppy(struct drive_s *drive_g, int prio); +void boot_add_hd(struct drive_s *drive_g, int prio); +void boot_add_cd(struct drive_s *drive_g, int prio); +void boot_add_cbfs(void *data, const char *desc, int prio); void boot_prep(void); +int bootprio_find_pci_device(int bdf); +int bootprio_find_ata_device(int bdf, int chanid, int slave); +int bootprio_find_fdc_device(int bfd, int port, int fdid); +int bootprio_find_pci_rom(int bdf, int instance); +int bootprio_find_named_rom(const char *name, int instance); #endif // __BOOT_H diff --git a/src/coreboot.c b/src/coreboot.c index dab0a54..503a6d2 100644 --- a/src/coreboot.c +++ b/src/coreboot.c @@ -608,7 +608,7 @@ register_cbfs_payload(void) if (!desc) break; snprintf(desc, MAXDESCSIZE, "Payload [%s]", &filename[4]); - boot_add_cbfs(file, desc); + boot_add_cbfs(file, desc, -1); } } diff --git a/src/floppy.c b/src/floppy.c index 8986e39..bfca63f 100644 --- a/src/floppy.c +++ b/src/floppy.c @@ -14,6 +14,8 @@ #include "pic.h" // eoi_pic1 #include "bregs.h" // struct bregs #include "boot.h" // boot_add_floppy +#include "pci.h" // pci_to_bdf +#include "pci_ids.h" // PCI_CLASS_BRIDGE_ISA #define FLOPPY_SIZE_CODE 0x02 // 512 byte sectors #define FLOPPY_DATALEN 0xff // Not used - because size code is 0x02 @@ -117,7 +119,10 @@ addFloppy(int floppyid, int ftype, int driver) memcpy(&drive_g->lchs, &FloppyInfo[ftype].chs , sizeof(FloppyInfo[ftype].chs)); - boot_add_floppy(drive_g); + int bdf = pci_find_class(PCI_CLASS_BRIDGE_ISA); /* isa-to-pci bridge */ + int prio = bootprio_find_fdc_device(bdf, PORT_FD_BASE, floppyid); + + boot_add_floppy(drive_g, prio); return drive_g; } diff --git a/src/ioport.h b/src/ioport.h index 5bd7f28..3282fb4 100644 --- a/src/ioport.h +++ b/src/ioport.h @@ -43,6 +43,7 @@ #define PORT_LPT1 0x0378 #define PORT_SERIAL3 0x03e8 #define PORT_ATA1_CTRL_BASE 0x03f4 +#define PORT_FD_BASE 0x03f0 #define PORT_FD_DOR 0x03f2 #define PORT_FD_STATUS 0x03f4 #define PORT_FD_DATA 0x03f5 diff --git a/src/optionroms.c b/src/optionroms.c index 2ac4325..a94b46c 100644 --- a/src/optionroms.c +++ b/src/optionroms.c @@ -220,6 +220,16 @@ setRomSource(u64 *sources, struct rom_header *rom, u64 source) sources[((u32)rom - BUILD_ROM_START) / OPTION_ROM_ALIGN] = source; } +static int +getRomPriority(u64 *sources, struct rom_header *rom, int instance) +{ + u64 source = sources[((u32)rom - BUILD_ROM_START) / OPTION_ROM_ALIGN]; + if (!source) + return -1; + if (source & RS_PCIROM) + return bootprio_find_pci_rom(source, instance); + return bootprio_find_named_rom(romfile_name(source), instance); +} /**************************************************************** * Roms in CBFS @@ -412,19 +422,24 @@ optionrom_setup(void) struct pnp_data *pnp = get_pnp_rom(rom); if (! pnp) { // Legacy rom. - boot_add_bcv(FLATPTR_TO_SEG(rom), OPTION_ROM_INITVECTOR, 0); + boot_add_bcv(FLATPTR_TO_SEG(rom), OPTION_ROM_INITVECTOR, 0 + , getRomPriority(sources, rom, 0)); continue; } // PnP rom. - if (pnp->bev) + if (pnp->bev) { // Can boot system - add to IPL list. - boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname); - else + boot_add_bev(FLATPTR_TO_SEG(rom), pnp->bev, pnp->productname + , getRomPriority(sources, rom, 0)); + } else { // Check for BCV (there may be multiple). + int instance = 0; while (pnp && pnp->bcv) { - boot_add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname); + boot_add_bcv(FLATPTR_TO_SEG(rom), pnp->bcv, pnp->productname + , getRomPriority(sources, rom, instance++)); pnp = get_pnp_next(rom, pnp); } + } } } diff --git a/src/usb-msc.c b/src/usb-msc.c index 378143e..2a6c31a 100644 --- a/src/usb-msc.c +++ b/src/usb-msc.c @@ -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; - boot_add_cd(op->drive_g); + boot_add_cd(op->drive_g, -1); return 0; } @@ -171,7 +171,7 @@ setup_drive_hd(struct disk_op_s *op) setup_translation(op->drive_g); // Register with bcv system. - boot_add_hd(op->drive_g); + boot_add_hd(op->drive_g, -1); return 0; } diff --git a/src/virtio-blk.c b/src/virtio-blk.c index def8313..834523a 100644 --- a/src/virtio-blk.c +++ b/src/virtio-blk.c @@ -156,7 +156,7 @@ init_virtio_blk(u16 bdf) vdrive_g->drive.desc = desc; setup_translation(&vdrive_g->drive); - boot_add_hd(&vdrive_g->drive); + boot_add_hd(&vdrive_g->drive, bootprio_find_pci_device(bdf)); vp_set_status(ioaddr, VIRTIO_CONFIG_S_ACKNOWLEDGE | VIRTIO_CONFIG_S_DRIVER | VIRTIO_CONFIG_S_DRIVER_OK); -- 2.25.1