Add -option-rom option to allow loading of PCI option ROMs, by Anthony Liguori.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2292 c046a42c-6fe2-441c-8c8c-71466251a162
diff --git a/hw/pc.c b/hw/pc.c
index 70be346..917d972 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -451,7 +451,7 @@
 {
     char buf[1024];
     int ret, linux_boot, initrd_size, i;
-    unsigned long bios_offset, vga_bios_offset;
+    unsigned long bios_offset, vga_bios_offset, option_rom_offset;
     int bios_size, isa_bios_size;
     PCIBus *pci_bus;
     int piix3_devfn = -1;
@@ -518,6 +518,23 @@
     cpu_register_physical_memory(0x100000 - isa_bios_size, 
                                  isa_bios_size, 
                                  (bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
+
+    option_rom_offset = 0;
+    for (i = 0; i < nb_option_roms; i++) {
+	int offset = bios_offset + bios_size + option_rom_offset;
+	int size;
+
+	size = load_image(option_rom[i], phys_ram_base + offset);
+	if ((size + option_rom_offset) > 0x10000) {
+	    fprintf(stderr, "Too many option ROMS\n");
+	    exit(1);
+	}
+	cpu_register_physical_memory(0xd0000 + option_rom_offset,
+				     size, offset | IO_MEM_ROM);
+	option_rom_offset += size + 2047;
+	option_rom_offset -= (option_rom_offset % 2048);
+    }
+
     /* map all the bios at the top of memory */
     cpu_register_physical_memory((uint32_t)(-bios_size), 
                                  bios_size, bios_offset | IO_MEM_ROM);
diff --git a/qemu-doc.texi b/qemu-doc.texi
index f76ffd0..1dd33fe 100644
--- a/qemu-doc.texi
+++ b/qemu-doc.texi
@@ -326,6 +326,10 @@
 Windows 2000 is installed, you no longer need this option (this option
 slows down the IDE transfers).
 
+@item -option-rom file
+Load the contents of file as an option ROM.  This option is useful to load
+things like EtherBoot.
+
 @end table
 
 USB options:
diff --git a/vl.c b/vl.c
index 5e06b0d..cfe94c8 100644
--- a/vl.c
+++ b/vl.c
@@ -174,6 +174,8 @@
 int fd_bootchk = 1;
 int no_reboot = 0;
 int daemonize = 0;
+const char *option_rom[MAX_OPTION_ROMS];
+int nb_option_roms;
 
 /***********************************************************/
 /* x86 ISA bus support */
@@ -6336,6 +6338,7 @@
 #ifndef _WIN32
 	   "-daemonize      daemonize QEMU after initializing\n"
 #endif
+	   "-option-rom rom load a file, rom, into the option ROM space\n"
            "\n"
            "During emulation, the following keys are useful:\n"
            "ctrl-alt-f      toggle full screen\n"
@@ -6418,6 +6421,7 @@
     QEMU_OPTION_no_reboot,
     QEMU_OPTION_daemonize,
     QEMU_OPTION_disk,
+    QEMU_OPTION_option_rom,
 };
 
 typedef struct QEMUOption {
@@ -6500,6 +6504,7 @@
     { "no-acpi", 0, QEMU_OPTION_no_acpi },
     { "no-reboot", 0, QEMU_OPTION_no_reboot },
     { "daemonize", 0, QEMU_OPTION_daemonize },
+    { "option-rom", HAS_ARG, QEMU_OPTION_option_rom },
     { NULL },
 };
 
@@ -7276,6 +7281,14 @@
 	    case QEMU_OPTION_daemonize:
 		daemonize = 1;
 		break;
+	    case QEMU_OPTION_option_rom:
+		if (nb_option_roms >= MAX_OPTION_ROMS) {
+		    fprintf(stderr, "Too many option ROMs\n");
+		    exit(1);
+		}
+		option_rom[nb_option_roms] = optarg;
+		nb_option_roms++;
+		break;
             }
         }
     }
@@ -7368,6 +7381,15 @@
     /* init the memory */
     phys_ram_size = ram_size + vga_ram_size + bios_size;
 
+    for (i = 0; i < nb_option_roms; i++) {
+	int ret = get_image_size(option_rom[i]);
+	if (ret == -1) {
+	    fprintf(stderr, "Could not load option rom '%s'\n", option_rom[i]);
+	    exit(1);
+	}
+	phys_ram_size += ret;
+    }
+
     phys_ram_base = qemu_vmalloc(phys_ram_size);
     if (!phys_ram_base) {
         fprintf(stderr, "Could not allocate physical memory\n");
diff --git a/vl.h b/vl.h
index 5561a27..b63145e 100644
--- a/vl.h
+++ b/vl.h
@@ -154,6 +154,10 @@
 extern int smp_cpus;
 extern int no_quit;
 
+#define MAX_OPTION_ROMS 16
+extern const char *option_rom[MAX_OPTION_ROMS];
+extern int nb_option_roms;
+
 /* XXX: make it dynamic */
 #if defined (TARGET_PPC) || defined (TARGET_SPARC64)
 #define BIOS_SIZE ((512 + 32) * 1024)