- // Looks like a rom - map it to just above end of memory.
- u32 mappos = ALIGN(GET_EBDA(ram_size), OPTION_ROM_ALIGN);
- pci_config_writel(bdf, PCI_ROM_ADDRESS, mappos | PCI_ROM_ADDRESS_ENABLE);
-
- struct rom_header *rom = (struct rom_header *)mappos;
- if (rom->signature != OPTION_ROM_SIGNATURE) {
- dprintf(6, "No option rom signature (got %x)\n", rom->signature);
- goto fail;
+ // Looks like a rom - enable it.
+ pci_config_writel(bdf, PCI_ROM_ADDRESS, orig | PCI_ROM_ADDRESS_ENABLE);
+
+ u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
+ struct rom_header *rom = (struct rom_header *)orig;
+ for (;;) {
+ dprintf(5, "Inspecting possible rom at %p (vd=%x bdf=%x)\n"
+ , rom, vendev, bdf);
+ if (rom->signature != OPTION_ROM_SIGNATURE) {
+ dprintf(6, "No option rom signature (got %x)\n", rom->signature);
+ goto fail;
+ }
+ if (!rom->pcioffset) {
+ dprintf(6, "No PCI offset\n");
+ goto fail;
+ }
+ struct pci_data *pci = (struct pci_data *)((u32)rom + rom->pcioffset);
+ if (pci->signature != PCI_ROM_SIGNATURE) {
+ dprintf(6, "Invalid pci signature (got %x)\n", pci->signature);
+ goto fail;
+ }
+ u32 vd = (pci->device << 16) | pci->vendor;
+ if (vd == vendev && pci->type == 0)
+ // A match
+ break;
+ dprintf(6, "Didn't match vendev (got %x) or type (got %d)\n"
+ , vd, pci->type);
+ if (pci->indicator & 0x80) {
+ dprintf(6, "No more images left\n");
+ goto fail;
+ }
+ rom = (struct rom_header *)((u32)rom + pci->ilen * 512);