On Thu, Dec 30, 2010 at 08:01:15AM +0200, Gleb Natapov wrote: > On Wed, Dec 29, 2010 at 08:23:13PM -0500, Kevin O'Connor wrote: > > Playing around with this a little further, I came up with the below. > > I'm not sure if it's better. > > > For me it looks more complicated (may be because I am more familiar with > my own code ;))
The basic idea is to completely build the search string in the bootprio_find_X() function and then have it call find_prio() to return the priority. >I see that you are starting to add regular expressions > engine! Yes - I'm not happy about that. Ultimately, rom loading needs some "fuzzy" matching capability, though. > > I added a "magic" syntax to support rom instances (eg, > > /r...@genroms/linuxboot.bin, /p...@i0cf8/s...@3/rom2). I also stubbed > > out some (admittedly wrong) pci bus path support. > > > For supporting multiple pci buses we need to keep track of pci bus > topology in upper layers. Bus number in bdf is meaningless for device > path purposes. Agreed. I just need some way to make sure a bus2 device doesn't grab the priority of a bus0 request. > To boot from a certain file on a device OpenFirmware uses following > syntax: /path/to/device:filename i.e parameter goes after ':'. Thanks. > qemu -drive file=/dev/null,if=none,id=d1,media=cdrom -device > ide-drive,drive=d1,bootindex=0 \ Thanks. I've updated the patch - see below. -Kevin diff --git a/src/boot.c b/src/boot.c index e83dcdc..b47f0fe 100644 --- a/src/boot.c +++ b/src/boot.c @@ -13,6 +13,7 @@ #include "boot.h" // func defs #include "cmos.h" // inb_cmos #include "paravirt.h" // romfile_loadfile +#include "pci.h" //pci_bdf_to_* /**************************************************************** @@ -29,7 +30,7 @@ loadBootOrder(void) if (!f) return; - int i; + int i = 0; BootorderCount = 1; while (f[i]) { if (f[i] == '\n') @@ -48,38 +49,119 @@ loadBootOrder(void) do { Bootorder[i] = f; f = strchr(f, '\n'); - if (f) { - *f = '\0'; - f++; - dprintf(3, "%d: %s\n", i, Bootorder[i]); - i++; - } + if (f) + *(f++) = '\0'; + dprintf(3, "%d: %s\n", i+1, Bootorder[i]); + i++; } while(f); } -int bootprio_find_pci_device(int bdf) +// See if 'str' matches 'glob' - if glob contains an '*' character it +// will match any number of characters in str that aren't a '/' or the +// next glob character. +static char * +glob_prefix(const char *glob, const char *str) { + for (;;) { + if (!*glob && (!*str || *str == '/')) + return (char*)str; + if (*glob == *str) { + glob++; + str++; + continue; + } + if (*glob != '*') + return NULL; + if (*str && *str != '/' && *str != glob[1]) + str++; + else + glob++; + } +} + +// Search the bootorder list for the given glob pattern. +static int +find_prio(const char *glob) +{ + int i; + for (i = 0; i < BootorderCount; i++) + if (glob_prefix(glob, Bootorder[i])) + return i+1; return -1; } +#define FW_PCI_DOMAIN "/p...@i0cf8" + +static char * +build_pci_path(char *buf, int max, const char *devname, int bdf) +{ + // Build the string path of a bdf - for example: /p...@i0cf8/i...@1,2 + char *p = buf; + int bus = pci_bdf_to_bus(bdf); + if (bus) + // XXX - this isn't the correct path syntax + p += snprintf(p, max, "/bus%x", bus); + + int dev = pci_bdf_to_dev(bdf), fn = pci_bdf_to_fn(bdf); + if (fn) + snprintf(p, buf+max-p, "%s/%...@%x,%x", FW_PCI_DOMAIN, devname, dev, fn); + else + snprintf(p, buf+max-p, "%s/%...@%x", FW_PCI_DOMAIN, devname, dev); + return buf; +} + +int bootprio_find_pci_device(int bdf) +{ + // Find pci device - for example: /p...@i0cf8/ether...@5 + char pci[256]; + return find_prio(build_pci_path(pci, sizeof(pci), "*", bdf)); +} + int bootprio_find_ata_device(int bdf, int chanid, int slave) { - return -1; + if (bdf == -1) + // support only pci machine for now + return -1; + // Find ata drive - for example: /p...@i0cf8/i...@1,1/dr...@1/d...@0 + char pci[256], desc[256]; + build_pci_path(pci, sizeof(pci), "*", bdf); + snprintf(desc, sizeof(desc), "%s/dr...@%x/d...@%x", pci, chanid, slave); + return find_prio(desc); } -int bootprio_find_fdc_device(int bfd, int port, int fdid) +int bootprio_find_fdc_device(int bdf, int port, int fdid) { - return -1; + if (bdf == -1) + // support only pci machine for now + return -1; + // Find floppy - for example: /p...@i0cf8/i...@1/f...@03f1/flo...@0 + char pci[256], desc[256]; + build_pci_path(pci, sizeof(pci), "isa", bdf); + snprintf(desc, sizeof(desc), "%s/f...@%04x/flo...@%x", pci, port, fdid); + return find_prio(desc); } int bootprio_find_pci_rom(int bdf, int instance) { - return -1; + // Find pci rom - for example: /p...@i0cf8/s...@3:rom2 + char pci[256], desc[256]; + build_pci_path(pci, sizeof(pci), "*", bdf); + if (instance) { + snprintf(desc, sizeof(desc), "%s:rom%d", pci, instance); + return find_prio(desc); + } + return find_prio(pci); } int bootprio_find_named_rom(const char *name, int instance) { - return -1; + // Find named rom - for example: /r...@genroms/linuxboot.bin + char desc[256]; + if (instance) + snprintf(desc, sizeof(desc), "/r...@%s:rom%d", name, instance); + else + snprintf(desc, sizeof(desc), "/r...@%s", name); + return find_prio(desc); } @@ -167,6 +249,8 @@ bootentry_add(int type, int prio, u32 data, const char *desc) be->priority = prio; be->data = data; be->description = desc ?: "?"; + dprintf(3, "Registering bootable: %s (type:%d prio:%d data:%x)\n" + , be->description, type, prio, data); // Add entry in sorted order. struct bootentry_s **pprev; _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios