summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--hw/pc.c121
1 files changed, 53 insertions, 68 deletions
diff --git a/hw/pc.c b/hw/pc.c
index f9cfd1f..0627174 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -754,6 +754,27 @@ static void pc_init_ne2k_isa(NICInfo *nd, qemu_irq *pic)
nb_ne2k++;
}
+static int load_option_rom(const char *oprom, target_phys_addr_t start,
+ target_phys_addr_t end)
+{
+ int size;
+
+ size = get_image_size(oprom);
+ if (size > 0 && start + size > end) {
+ fprintf(stderr, "Not enough space to load option rom '%s'\n",
+ oprom);
+ exit(1);
+ }
+ size = load_image_targphys(oprom, start, end - start);
+ if (size < 0) {
+ fprintf(stderr, "Could not load option rom '%s'\n", oprom);
+ exit(1);
+ }
+ /* Round up optiom rom size to the next 2k boundary */
+ size = (size + 2047) & ~2047;
+ return size;
+}
+
/* PC hardware initialisation */
static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
const char *boot_device,
@@ -763,9 +784,9 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
{
char buf[1024];
int ret, linux_boot, i;
- ram_addr_t ram_addr, vga_ram_addr, bios_offset, vga_bios_offset, option_rom_start = 0;
+ ram_addr_t ram_addr, vga_ram_addr, bios_offset, option_rom_offset;
ram_addr_t below_4g_mem_size, above_4g_mem_size = 0;
- int bios_size, isa_bios_size, vga_bios_size;
+ int bios_size, isa_bios_size, oprom_area_size;
PCIBus *pci_bus;
int piix3_devfn = -1;
CPUState *env;
@@ -856,40 +877,6 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
fprintf(stderr, "qemu: could not load PC BIOS '%s'\n", buf);
exit(1);
}
-
- if (using_vga) {
- /* VGA BIOS load */
- if (cirrus_vga_enabled) {
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_CIRRUS_FILENAME);
- } else {
- snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
- }
- vga_bios_size = get_image_size(buf);
- if (vga_bios_size <= 0 || vga_bios_size > 65536)
- goto vga_bios_error;
- vga_bios_offset = qemu_ram_alloc(65536);
-
- ret = load_image(buf, phys_ram_base + vga_bios_offset);
- if (ret != vga_bios_size) {
-vga_bios_error:
- fprintf(stderr, "qemu: could not load VGA BIOS '%s'\n", buf);
- exit(1);
- }
- /* Round up vga bios size to the next 2k boundary */
- vga_bios_size = (vga_bios_size + 2047) & ~2047;
- option_rom_start = 0xc0000 + vga_bios_size;
-
- /* setup basic memory access */
- cpu_register_physical_memory(0xc0000, vga_bios_size,
- vga_bios_offset | IO_MEM_ROM);
- }
-
- /* No point in placing option roms before this address, since bochs bios
- * will only start looking for it at 0xc8000 */
- if (option_rom_start < 0xc8000)
- option_rom_start = 0xc8000;
-
-
/* map the last 128KB of the BIOS in ISA space */
isa_bios_size = bios_size;
if (isa_bios_size > (128 * 1024))
@@ -898,40 +885,38 @@ vga_bios_error:
isa_bios_size,
(bios_offset + bios_size - isa_bios_size) | IO_MEM_ROM);
- {
- ram_addr_t option_rom_offset;
- int size, offset;
-
- offset = option_rom_start;
- if (linux_boot) {
- option_rom_offset = qemu_ram_alloc(TARGET_PAGE_SIZE);
- load_linux(phys_ram_base + option_rom_offset,
- kernel_filename, initrd_filename, kernel_cmdline);
- cpu_register_physical_memory(option_rom_start, TARGET_PAGE_SIZE,
- option_rom_offset | IO_MEM_ROM);
- offset += TARGET_PAGE_SIZE;
- }
- for (i = 0; i < nb_option_roms; i++) {
- size = get_image_size(option_rom[i]);
- if (size < 0) {
- fprintf(stderr, "Could not load option rom '%s'\n",
- option_rom[i]);
- exit(1);
- }
- if (size > (0xe0000 - offset))
- goto option_rom_error;
- option_rom_offset = qemu_ram_alloc(size);
- ret = load_image(option_rom[i], phys_ram_base + option_rom_offset);
- if (ret != size) {
- option_rom_error:
- fprintf(stderr, "Could not fit %soption roms in available space\n", using_vga ? "VGA bios and " : "");
- exit(1);
- }
- size = (size + 4095) & ~4095;
- cpu_register_physical_memory(offset, size, option_rom_offset | IO_MEM_ROM);
- offset += size;
+
+ option_rom_offset = qemu_ram_alloc(0x20000);
+ oprom_area_size = 0;
+ cpu_register_physical_memory(0xc0000, 0x20000,
+ option_rom_offset | IO_MEM_ROM);
+
+ if (using_vga) {
+ /* VGA BIOS load */
+ if (cirrus_vga_enabled) {
+ snprintf(buf, sizeof(buf), "%s/%s", bios_dir,
+ VGABIOS_CIRRUS_FILENAME);
+ } else {
+ snprintf(buf, sizeof(buf), "%s/%s", bios_dir, VGABIOS_FILENAME);
}
+ oprom_area_size = load_option_rom(buf, 0xc0000, 0xe0000);
+ }
+ /* Although video roms can grow larger than 0x8000, the area between
+ * 0xc0000 - 0xc8000 is reserved for them. It means we won't be looking
+ * for any other kind of option rom inside this area */
+ if (oprom_area_size < 0x8000)
+ oprom_area_size = 0x8000;
+
+ if (linux_boot) {
+ load_linux(phys_ram_base + option_rom_offset + oprom_area_size,
+ kernel_filename, initrd_filename, kernel_cmdline);
+ oprom_area_size += 2048;
+ }
+
+ for (i = 0; i < nb_option_roms; i++) {
+ oprom_area_size += load_option_rom(option_rom[i],
+ 0xc0000 + oprom_area_size, 0xe0000);
}
/* map all the bios at the top of memory */
OpenPOWER on IntegriCloud