From ae0a54664c76f1d2a2a7a268266d47b4e8c12a4c Mon Sep 17 00:00:00 2001 From: Avi Kivity Date: Mon, 15 Aug 2011 17:17:38 +0300 Subject: 440fx: fix PAM, PCI holes The current implementation of PAM and the PCI holes is broken in several ways: - PCI BARs are not restricted to the PCI hole (a BAR may hide memory) - PCI devices do not respect PAM (if a PCI device maps a region while PAM maps the region to RAM, the request will be honored) This patch fixes things by introducing a pci address space, and using memory region aliases to represent PAM regions, SMRAM, and PCI holes. The memory hierarchy looks something like system_memory | +--- low memory alias (0-0xe0000000) | | | +-- ram@0 | +--- high memory alias (0x100000000-EOM) | | | +-- ram@0xe0000000 | +--- pci hole alias (end of low memory-0x100000000) | | | +-- pci@end-of-low-memory | | +--- pam[n] (0xc0000-0xc3fff etc) (when set to pci, priority 1) | | | +-- pci@0xc4000 etc | +--- smram (0xa0000-0xbffff) (when set to pci/vga, priority 1) | +-- pci@0xa0000 etc ram (simple ram region) pci | +--- BARn | +--- VGA 0xa0000-0xbffff | +--- ROMs Signed-off-by: Avi Kivity Signed-off-by: Anthony Liguori --- hw/pc.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'hw/pc.c') diff --git a/hw/pc.c b/hw/pc.c index a29a29f..263fb1a 100644 --- a/hw/pc.c +++ b/hw/pc.c @@ -964,7 +964,9 @@ void pc_memory_init(MemoryRegion *system_memory, const char *kernel_cmdline, const char *initrd_filename, ram_addr_t below_4g_mem_size, - ram_addr_t above_4g_mem_size) + ram_addr_t above_4g_mem_size, + MemoryRegion *pci_memory, + MemoryRegion **ram_memory) { char *filename; int ret, linux_boot, i; @@ -982,6 +984,7 @@ void pc_memory_init(MemoryRegion *system_memory, ram = g_malloc(sizeof(*ram)); memory_region_init_ram(ram, NULL, "pc.ram", below_4g_mem_size + above_4g_mem_size); + *ram_memory = ram; ram_below_4g = g_malloc(sizeof(*ram_below_4g)); memory_region_init_alias(ram_below_4g, "ram-below-4g", ram, 0, below_4g_mem_size); @@ -1026,7 +1029,7 @@ void pc_memory_init(MemoryRegion *system_memory, isa_bios = g_malloc(sizeof(*isa_bios)); memory_region_init_alias(isa_bios, "isa-bios", bios, bios_size - isa_bios_size, isa_bios_size); - memory_region_add_subregion_overlap(system_memory, + memory_region_add_subregion_overlap(pci_memory, 0x100000 - isa_bios_size, isa_bios, 1); @@ -1034,13 +1037,13 @@ void pc_memory_init(MemoryRegion *system_memory, option_rom_mr = g_malloc(sizeof(*option_rom_mr)); memory_region_init_ram(option_rom_mr, NULL, "pc.rom", PC_ROM_SIZE); - memory_region_add_subregion_overlap(system_memory, + memory_region_add_subregion_overlap(pci_memory, PC_ROM_MIN_VGA, option_rom_mr, 1); /* map all the bios at the top of memory */ - memory_region_add_subregion(system_memory, + memory_region_add_subregion(pci_memory, (uint32_t)(-bios_size), bios); -- cgit v1.1