Add support for gcc v3.x compilers.
[seabios.git] / src / optionroms.c
index 6bc28fa6e490b7411888f28e67cb95bc263a9ba9..2856217a85ce9ad3eac8e9dc7d9fd762f016b646 100644 (file)
@@ -84,7 +84,7 @@ static void
 callrom(struct rom_header *rom, u16 offset, u16 bdf)
 {
     u16 seg = FLATPTR_TO_SEG(rom);
-    dprintf(1, "Running option rom at %x:%x\n", seg, offset);
+    dprintf(1, "Running option rom at %04x:%04x\n", seg, offset);
 
     struct bregs br;
     memset(&br, 0, sizeof(br));
@@ -111,8 +111,12 @@ call_bcv(u16 seg, u16 ip)
 static int
 is_valid_rom(struct rom_header *rom)
 {
+    dprintf(6, "Checking rom %p (sig %x size %d)\n"
+            , rom, rom->signature, rom->size);
     if (rom->signature != OPTION_ROM_SIGNATURE)
         return 0;
+    if (! rom->size)
+        return 0;
     u32 len = rom->size * 512;
     u8 sum = checksum(rom, len);
     if (sum != 0) {
@@ -165,7 +169,8 @@ copy_rom(struct rom_header *rom)
         dprintf(1, "Option rom %p doesn't fit.\n", rom);
         return NULL;
     }
-    dprintf(4, "Copying option rom from %p to %x\n", rom, next_rom);
+    dprintf(4, "Copying option rom (size %d) from %p to %x\n"
+            , romsize, rom, next_rom);
     memcpy((void*)next_rom, rom, romsize);
     return (struct rom_header *)next_rom;
 }
@@ -182,17 +187,19 @@ lookup_hardcode(u32 vendev)
         && ((OPTIONROM_VENDEV_2 >> 16)
             | ((OPTIONROM_VENDEV_2 & 0xffff)) << 16) == vendev)
         return copy_rom((struct rom_header *)OPTIONROM_MEM_2);
-    struct rom_header *rom = cb_find_optionrom(vendev);
-    if (rom)
-        return copy_rom(rom);
-    return NULL;
+    int ret = cbfs_copy_optionrom((void*)next_rom, BUILD_BIOS_ADDR - next_rom
+                                  , vendev);
+    if (ret < 0)
+        return NULL;
+    return (struct rom_header *)next_rom;
 }
 
 // Map the option rom of a given PCI device.
 static struct rom_header *
 map_optionrom(u16 bdf, u32 vendev)
 {
-    dprintf(6, "Attempting to map option rom on dev %x\n", bdf);
+    dprintf(6, "Attempting to map option rom on dev %02x:%02x.%x\n"
+            , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf));
 
     u8 htype = pci_config_readb(bdf, PCI_HEADER_TYPE);
     if ((htype & 0x7f) != PCI_HEADER_TYPE_NORMAL) {
@@ -209,7 +216,9 @@ map_optionrom(u16 bdf, u32 vendev)
     if (!sz || sz == 0xffffffff)
         goto fail;
 
-    if (orig < 16*1024*1024) {
+    if (orig == sz || (u32)(orig + 4*1024*1024) < 20*1024*1024) {
+        // Don't try to map to a pci addresses at its max, in the last
+        // 4MiB of ram, or the first 16MiB of ram.
         dprintf(6, "Preset rom address doesn't look valid\n");
         goto fail;
     }
@@ -253,19 +262,10 @@ fail:
     return NULL;
 }
 
-// Attempt to map and initialize the option rom on a given PCI device.
+// Adjust for the size of an option rom; allow it to resize.
 static struct rom_header *
-init_optionrom(u16 bdf)
+verifysize_optionrom(struct rom_header *rom, u16 bdf)
 {
-    u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
-    dprintf(4, "Attempting to init PCI bdf %x (dev/ven %x)\n", bdf, vendev);
-    struct rom_header *rom = lookup_hardcode(vendev);
-    if (! rom)
-        rom = map_optionrom(bdf, vendev);
-    if (! rom)
-        // No ROM present.
-        return NULL;
-
     if (! is_valid_rom(rom))
         return NULL;
 
@@ -278,6 +278,23 @@ init_optionrom(u16 bdf)
     return rom;
 }
 
+// Attempt to map and initialize the option rom on a given PCI device.
+static struct rom_header *
+init_optionrom(u16 bdf)
+{
+    u32 vendev = pci_config_readl(bdf, PCI_VENDOR_ID);
+    dprintf(4, "Attempting to init PCI bdf %02x:%02x.%x (dev/ven %x)\n"
+            , pci_bdf_to_bus(bdf), pci_bdf_to_dev(bdf), pci_bdf_to_fn(bdf)
+            , vendev);
+    struct rom_header *rom = lookup_hardcode(vendev);
+    if (! rom)
+        rom = map_optionrom(bdf, vendev);
+    if (! rom)
+        // No ROM present.
+        return NULL;
+    return verifysize_optionrom(rom, bdf);
+}
+
 
 /****************************************************************
  * Non-VGA option rom init
@@ -317,6 +334,16 @@ optionrom_setup()
                 continue;
             init_optionrom(bdf);
         }
+
+        // Find and deploy CBFS roms not associated with a device.
+        struct cbfs_file *tmp = NULL;
+        for (;;) {
+            tmp = cbfs_copy_gen_optionrom(
+                (void*)next_rom, BUILD_BIOS_ADDR - next_rom, tmp);
+            if (!tmp)
+                break;
+            verifysize_optionrom((void*)next_rom, 0);
+        }
     }
 
     // All option roms found and deployed - now build BEV/BCV vectors.