[SeaBIOS] [PATCH RFC] use bootorder file supplied by qemu to order bootable devices

Gleb Natapov gleb at redhat.com
Tue Dec 21 07:55:25 CET 2010


Kevin, any additional comments about this patch?

On Tue, Dec 14, 2010 at 11:42:36AM +0200, Gleb Natapov wrote:
> On Mon, Dec 13, 2010 at 05:02:43PM +0200, Gleb Natapov wrote:
> > On Mon, Dec 13, 2010 at 08:44:08AM -0500, Kevin O'Connor wrote:
> > > On Mon, Dec 13, 2010 at 03:12:51PM +0200, Gleb Natapov wrote:
> > > > On Thu, Dec 09, 2010 at 08:27:10PM -0500, Kevin O'Connor wrote:
> > > > > On Wed, Dec 08, 2010 at 02:00:50PM +0200, Gleb Natapov wrote:
> > > > > > With patch below (goes on top of bev per CD patch) I can specify boot
> > > > > > order from qemu command line between several NICs, CDROMs, floppy and
> > > > > > disk. With qemu command like this:
> > > > > 
> > > > > Hi Gleb.
> > > > > 
> > > > > I'm a bit behind right now, but I'll take a look this weekend.
> > > > > 
> > > > Have you had a chance to look at it? If not yet then here is updated
> > > > version that fix one little bug with boot menu and choosing between
> > > > multiple BCVs:
> > > 
> > > I did look at it, but didn't get a chance to reply.  Here are my
> > > thoughts in brief:
> > > 
> > > * I'm okay with the general layout (read bootorder at start, note
> > >   priority when adding each entry)
> > > 
> > > * The system seems to conflict with the sorting already done by
> > >   add_bcv_internal() and add_ordered_drive() (which was added to
> > >   handle threads adding drives in any order).  The get_boot_priority()
> > >   code you've added isn't right, because there's no guarentee that a
> > >   drive will be added in a repeatable manor (you don't want a user
> > >   without "bootorder" to see different drives being booted on
> > >   different boots).
> > > 
> > Good point. Will fix. Probably will require more invasive changes
> > though.
> > 
> It was easier to fix than I initially thought. All BCVs and BEVs that do
> not have corespondent device paths get the same lowest priority. During
> sorting they stay in the same order at the end.
> 
> I search for ISA bridge dynamically now using pci_find_class(PCI_CLASS_BRIDGE_ISA).
> 
> Signed-off-by: Gleb Natapov <gleb at redhat.com>
> 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 9c94439..157f666 100644
> --- a/src/boot.c
> +++ b/src/boot.c
> @@ -13,10 +13,12 @@
>  #include "boot.h" // struct ipl_s
>  #include "cmos.h" // inb_cmos
>  #include "paravirt.h"
> +#include "pci.h" //pci_bdf_to_*
>  
>  struct ipl_s IPL;
>  
>  
> +
>  /****************************************************************
>   * IPL and BCV handlers
>   ****************************************************************/
> @@ -67,11 +69,56 @@ boot_setup(void)
>          if (!(inb_cmos(CMOS_BIOS_BOOTFLAG1) & 1))
>              IPL.checkfloppysig = 1;
>      }
> +
> +    u32 file = romfile_find("bootorder");
> +    if (!file)
> +        return;
> +
> +    int filesize = romfile_size(file);
> +    dprintf(3, "bootorder file found (len %d)\n", filesize);
> +
> +    if (filesize == 0)
> +        return;
> +
> +    char *f = malloc_tmphigh(filesize);
> +
> +    if (!f) {
> +        warn_noalloc();
> +        return;
> +    }
> +
> +    romfile_copy(file, f, filesize);
> +    int i;
> +    IPL.fw_bootorder_count = 1;
> +    while(f[i]) {
> +        if (f[i] == '\n')
> +            IPL.fw_bootorder_count++;
> +        i++;
> +    }
> +    IPL.fw_bootorder = malloc_tmphigh(IPL.fw_bootorder_count*sizeof(char*));
> +    if (!IPL.fw_bootorder) {
> +        warn_noalloc();
> +        free(f);
> +        return;
> +    }
> +
> +    dprintf(3, "boot order:\n");
> +    i = 0;
> +    do {
> +        IPL.fw_bootorder[i] = f;
> +        f = strchr(f, '\n');
> +        if (f) {
> +            *f = '\0';
> +            f++;
> +            dprintf(3, "%d: %s\n", i, IPL.fw_bootorder[i]);
> +            i++;
> +        }
> +    } while(f);
>  }
>  
>  // 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;
> @@ -85,11 +132,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;
> @@ -104,11 +152,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;
> @@ -122,11 +177,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;
> @@ -154,6 +210,7 @@ add_bcv_internal(struct drive_s *drive_g)
>      ie->type = BCV_TYPE_INTERNAL;
>      ie->vector = (u32)drive_g;
>      ie->description = "";
> +    ie->prio = prio;
>  }
>  
>  
> @@ -323,6 +380,41 @@ run_bcv(struct ipl_entry_s *ie)
>      }
>  }
>  
> +/* Bubble sort! Should be good enough for 8 elements */
> +static void sort_ipls(struct ipl_entry_s *ipls, int iplscount)
> +{
> +    int stop;
> +
> +    if (iplscount == 0)
> +        return;
> +
> +    do {
> +        int i;
> +        stop = 1;
> +        for (i = 0; i < iplscount - 1; i++) {
> +            if (ipls[i].prio > ipls[i+1].prio) {
> +                struct ipl_entry_s tmp;
> +                tmp = ipls[i];
> +                ipls[i] = ipls[i+1];
> +                ipls[i+1] = tmp;
> +                stop = 0;
> +            }
> +        }
> +    } while (!stop);
> +}
> +
> +static void order_boot_devices(void)
> +{
> +    if (IPL.fw_bootorder_count == 0)
> +        return;
> +
> +    sort_ipls(IPL.bcv, IPL.bcvcount);
> +    /* Hard disk IPL inherits priority of the bootable bcv */
> +    IPL.bev[1].prio = IPL.bcv[0].prio;
> +    sort_ipls(IPL.bev, IPL.bevcount);
> +    IPL.bootorder = 0x87654321;
> +}
> +
>  // Prepare for boot - show menu and run bcvs.
>  void
>  boot_prep(void)
> @@ -334,24 +426,38 @@ boot_prep(void)
>  
>      // XXX - show available drives?
>  
> +    order_boot_devices();
> +
>      // Allow user to modify BCV/IPL order.
>      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;
> -
> -    // 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]);
> +    int j;
> +    for (j = 0; j < IPL.bevcount; j++) {
> +        int override;
> +        switch (IPL.bev[j].type) {
> +        case IPL_TYPE_FLOPPY:
> +	    // Setup floppy boot order
> +            override = IPL.bev[j].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;
> +            break;
> +        case IPL_TYPE_HARDDISK:
> +            // Run BCVs
> +            override = IPL.bev[j].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]);
> +	    break;
> +        default:
> +            break;
> +        }
> +    }
>  }
>  
>  
> @@ -529,3 +635,158 @@ handle_19(void)
>      SET_EBDA(boot_sequence, 0);
>      do_boot(0);
>  }
> +
> +/*
> + * function returns string representing firts device path element in 'dp'
> + * and puts pointer to the rest of the device path into 'end'
> + */
> +static char *dev_path_get_node(const char *dp, const char **end)
> +{
> +    int len;
> +    char *node;
> +
> +    dp += 1; /* skip '/' */
> +
> +    *end = strchr(dp, '/');
> +
> +    if (*end == NULL) {
> +        len = strlen(dp); /* last path element */
> +        *end = dp + len;
> +    } else
> +        len = *end - dp;
> +
> +    if (len == 0)
> +        return NULL;
> +
> +    node = malloc_tmphigh(len + 1);
> +    if (!node) {
> +        warn_noalloc();
> +        return NULL;
> +    }
> +    memcpy(node, dp, len);
> +    node[len] = '\0';
> +
> +    return node;
> +}
> +
> +static int match_unit_address(const char *pe, const char *unit_address)
> +{
> +    char *s = strchr(pe, '@');
> +
> +    if (s == NULL)
> +        return 0;
> +
> +    return !strcmp(s + 1, unit_address);
> +}
> +
> +static int match_next_node_address(const char *path, const char *addr,
> +                                   const char **rest)
> +{
> +    char *node = dev_path_get_node(path, rest);
> +
> +    if (!node)
> +        return 0;
> +
> +    int r = match_unit_address(node, addr);
> +    free(node);
> +
> +    return r;
> +}
> +
> +static int match_pci_node(const char *path, int bdf, const char **rest)
> +{
> +    char pci[7];
> +    int dev = pci_bdf_to_dev(bdf), fn = pci_bdf_to_fn(bdf);
> +
> +    if (!fn)
> +        snprintf(pci, sizeof(pci), "%x", dev);
> +    else
> +        snprintf(pci, sizeof(pci), "%x,%x", dev, fn);
> +
> +    return match_next_node_address(path, pci, rest);
> +}
> +
> +#define FW_PCI_DOMAIN "/pci at i0cf8"
> +
> +static u8 find_pci_device(int bdf, u8 start_idx, const char **rest)
> +{
> +    u8 i;
> +
> +    for (i = start_idx; i < IPL.fw_bootorder_count; i++) {
> +        const char *path = IPL.fw_bootorder[i];
> +
> +        /* is pci domain? */
> +        if (memcmp(path, FW_PCI_DOMAIN, strlen(FW_PCI_DOMAIN)))
> +            continue;
> +
> +        if (match_pci_node(path + strlen(FW_PCI_DOMAIN), bdf, rest))
> +            return i;
> +    }
> +
> +    return MAX_BOOT_PRIO;
> +}
> +
> +u8 bootprio_find_pci_device(int bdf)
> +{
> +    const char *rest;
> +
> +    return find_pci_device(bdf, 0, &rest);
> +}
> +
> +u8 bootprio_find_ata_device(int bdf, int chanid, int slave)
> +{
> +    const char *rest;
> +    u8 idx = 0;
> +
> +    if (bdf == -1)
> +        return MAX_BOOT_PRIO; /* support only pci machine for now */
> +
> +    while((idx = find_pci_device(bdf, idx, &rest)) != MAX_BOOT_PRIO) {
> +        if (match_next_node_address(rest, chanid ? "1" : "0", &rest) &&
> +            match_next_node_address(rest, slave ? "1" : "0", &rest))
> +            break;
> +        idx++;
> +    }
> +
> +    return idx;
> +}
> +
> +
> +u8 bootprio_find_fdc_device(int bdf, int port, int fdid)
> +{
> +    const char *rest;
> +    u8 idx = 0;
> +    char addr[5];
> +
> +    if (bdf == -1)
> +        return MAX_BOOT_PRIO; /* support only pci machine for now */
> +
> +    snprintf(addr, sizeof addr, "%04x", port);
> +
> +    while((idx = find_pci_device(bdf, idx, &rest)) != MAX_BOOT_PRIO) {
> +        if (match_next_node_address(rest, addr, &rest) &&
> +            match_next_node_address(rest, fdid ? "1" : "0", &rest))
> +            break;
> +        idx++;
> +    }
> +
> +    return idx;
> +}
> +
> +u8 bootprio_find_named_rom(const char *name)
> +{
> +    u8 i;
> +
> +    for (i = 0; i < IPL.fw_bootorder_count; i++) {
> +        const char *path = IPL.fw_bootorder[i];
> +
> +        /* is this rom file? */
> +        if (memcmp(path, "/rom@", strlen("/rom@")))
> +            continue;
> +
> +        if (strcmp(path + strlen("/rom@"), name))
> +            return i;
> +    }
> +
> +    return MAX_BOOT_PRIO;
> +}
> diff --git a/src/boot.h b/src/boot.h
> index f751d71..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 {
> @@ -20,6 +21,8 @@ struct ipl_s {
>      int bevcount, bcvcount;
>      u32 bootorder;
>      int checkfloppysig;
> +    char **fw_bootorder;
> +    int fw_bootorder_count;
>  };
>  
>  #define IPL_TYPE_FLOPPY      0x01
> @@ -31,6 +34,7 @@ struct ipl_s {
>  #define BCV_TYPE_EXTERNAL    0x80
>  #define BCV_TYPE_INTERNAL    0x02
>  
> +#define MAX_BOOT_PRIO        255
>  
>  /****************************************************************
>   * Function defs
> @@ -39,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/config.h b/src/config.h
> index db3e578..0b575a9 100644
> --- a/src/config.h
> +++ b/src/config.h
> @@ -16,9 +16,9 @@
>  #define CONFIG_COREBOOT 0
>  
>  // Control how verbose debug output is.
> -#define CONFIG_DEBUG_LEVEL 1
> +#define CONFIG_DEBUG_LEVEL 5
>  // Send debugging information to serial port
> -#define CONFIG_DEBUG_SERIAL 0
> +#define CONFIG_DEBUG_SERIAL 1
>  // Screen writes are also sent to debug ports.
>  #define CONFIG_SCREEN_AND_DEBUG 1
>  
> 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 854c33f..0fd9aed 100644
> --- a/src/optionroms.c
> +++ b/src/optionroms.c
> @@ -74,6 +74,34 @@ struct pnp_data {
>  // The end of the last deployed rom.
>  u32 RomEnd = BUILD_ROM_START;
>  
> +static struct rom_dev {
> +    u32 addr;
> +    u8 prio;
> +} rom2prio[92];
> +
> +static int rom2prio_cnt;
> +
> +static void map_rom2prio(void *addr, u8 prio)
> +{
> +    if (rom2prio_cnt < ARRAY_SIZE(rom2prio)) {
> +        rom2prio[rom2prio_cnt].addr = (u32)addr;
> +        rom2prio[rom2prio_cnt].prio = prio;
> +        dprintf(3, "pci rom at memory address %x has boot prio %d\n",
> +                rom2prio[rom2prio_cnt].addr, rom2prio[rom2prio_cnt].prio);
> +        rom2prio_cnt++;
> +    }
> +}
> +
> +static u8 rom2prio_get(u32 addr)
> +{
> +    int i;
> +
> +    for (i = 0; i < rom2prio_cnt; i++)
> +        if (rom2prio[i].addr == addr)
> +            return rom2prio[i].prio;
> +
> +    return -1;
> +}
>  
>  /****************************************************************
>   * Helper functions
> @@ -243,13 +271,18 @@ static void
>  run_file_roms(const char *prefix, int isvga)
>  {
>      u32 file = 0;
> +
>      for (;;) {
>          file = romfile_findprefix(prefix, file);
>          if (!file)
>              break;
>          int ret = romfile_copy(file, (void*)RomEnd, max_rom() - RomEnd);
> -        if (ret > 0)
> -            init_optionrom((void*)RomEnd, 0, isvga);
> +        if (ret > 0) {
> +            void *rom = (void*)RomEnd;
> +            ret = init_optionrom(rom, 0, isvga);
> +            if (!ret && is_valid_rom(rom))
> +                map_rom2prio(rom, bootprio_find_named_rom(romfile_name(file)));
> +        }
>      }
>  }
>  
> @@ -342,7 +375,15 @@ init_pcirom(u16 bdf, int isvga)
>      if (! rom)
>          // No ROM present.
>          return -1;
> -    return init_optionrom(rom, bdf, isvga);
> +
> +    int r = init_optionrom(rom, bdf, isvga);
> +
> +    if (r || !is_valid_rom(rom))
> +        return r;
> +
> +    map_rom2prio(rom, bootprio_find_pci_device(bdf));
> +
> +    return r;
>  }
>  
>  
> @@ -394,21 +435,22 @@ optionrom_setup(void)
>              pos += OPTION_ROM_ALIGN;
>              continue;
>          }
> +        u8 romprio = rom2prio_get(pos);
>          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/paravirt.c b/src/paravirt.c
> index ca646d4..308c809 100644
> --- a/src/paravirt.c
> +++ b/src/paravirt.c
> @@ -345,6 +345,14 @@ int qemu_cfg_size_file(u32 select)
>      return ntohl(LastFile.size);
>  }
>  
> +
> +const char* qemu_cfg_name_file(u32 select)
> +{
> +    if (select != ntohs(LastFile.select))
> +        return NULL;
> +    return LastFile.name;
> +}
> +
>  int qemu_cfg_read_file(u32 select, void *dst, u32 maxlen)
>  {
>      if (!qemu_cfg_present)
> diff --git a/src/paravirt.h b/src/paravirt.h
> index 7d4bc02..99c473b 100644
> --- a/src/paravirt.h
> +++ b/src/paravirt.h
> @@ -71,6 +71,7 @@ struct e820_reservation {
>  u32 qemu_cfg_next_prefix_file(const char *prefix, u32 prevselect);
>  u32 qemu_cfg_find_file(const char *name);
>  int qemu_cfg_size_file(u32 select);
> +const char* qemu_cfg_name_file(u32 select);
>  int qemu_cfg_read_file(u32 select, void *dst, u32 maxlen);
>  
>  // Wrappers that select cbfs or qemu_cfg file interface.
> @@ -94,6 +95,11 @@ static inline int romfile_copy(u32 fileid, void *dst, u32 maxlen) {
>          return cbfs_copyfile((void*)fileid, dst, maxlen);
>      return qemu_cfg_read_file(fileid, dst, maxlen);
>  }
> +static inline const char* romfile_name(u32 fileid) {
> +    if (CONFIG_COREBOOT)
> +        return cbfs_filename((void*)fileid);
> +    return qemu_cfg_name_file(fileid);
> +}
>  
>  u32 qemu_cfg_e820_entries(void);
>  void* qemu_cfg_e820_load_next(void *addr);
> 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/util.c b/src/util.c
> index f9a7533..3892c3c 100644
> --- a/src/util.c
> +++ b/src/util.c
> @@ -262,6 +262,17 @@ strtcpy(char *dest, const char *src, size_t len)
>      return dest;
>  }
>  
> +// locate first occurance of character c in the string s
> +char *
> +strchr(const char *s, int c)
> +{
> +    int i = 0;
> +
> +    while(s[i] && s[i] != c)
> +        i++;
> +
> +    return s[i] ? (char*)&s[i] : NULL;
> +}
>  
>  /****************************************************************
>   * Keyboard calls
> diff --git a/src/util.h b/src/util.h
> index fa7b20f..f5b9446 100644
> --- a/src/util.h
> +++ b/src/util.h
> @@ -209,6 +209,7 @@ void *memcpy(void *d1, const void *s1, size_t len);
>  void iomemcpy(void *d, const void *s, u32 len);
>  void *memmove(void *d, const void *s, size_t len);
>  char *strtcpy(char *dest, const char *src, size_t len);
> +char *strchr(const char *s, int c);
>  int get_keystroke(int msec);
>  
>  // stacks.c
> 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));
> --
> 			Gleb.
> 
> _______________________________________________
> SeaBIOS mailing list
> SeaBIOS at seabios.org
> http://www.seabios.org/mailman/listinfo/seabios

--
			Gleb.



More information about the SeaBIOS mailing list