diff options
author | Avi Kivity <avi@redhat.com> | 2011-08-15 17:17:38 +0300 |
---|---|---|
committer | Anthony Liguori <aliguori@us.ibm.com> | 2011-08-22 10:47:49 -0500 |
commit | ae0a54664c76f1d2a2a7a268266d47b4e8c12a4c (patch) | |
tree | b4a664a81fe572ce96640fdc74b0ec2ca172ee2a /hw/pc_piix.c | |
parent | be20f9e902ca47ea84e1b1c1e89b0a55d59b4c11 (diff) |
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 <avi@redhat.com>
Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/pc_piix.c')
-rw-r--r-- | hw/pc_piix.c | 23 |
1 files changed, 17 insertions, 6 deletions
diff --git a/hw/pc_piix.c b/hw/pc_piix.c index a9fe5964d8..75d96d97c6 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -22,6 +22,8 @@ * THE SOFTWARE. */ +#include <glib.h> + #include "hw.h" #include "pc.h" #include "apic.h" @@ -93,6 +95,8 @@ static void pc_init1(MemoryRegion *system_memory, DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS]; BusState *idebus[MAX_IDE_BUS]; ISADevice *rtc_state; + MemoryRegion *ram_memory; + MemoryRegion *pci_memory; pc_cpus_init(cpu_model); @@ -108,11 +112,15 @@ static void pc_init1(MemoryRegion *system_memory, below_4g_mem_size = ram_size; } + pci_memory = g_new(MemoryRegion, 1); + memory_region_init(pci_memory, "pci", INT64_MAX); + /* allocate ram and load rom/bios */ if (!xen_enabled()) { pc_memory_init(system_memory, kernel_filename, kernel_cmdline, initrd_filename, - below_4g_mem_size, above_4g_mem_size); + below_4g_mem_size, above_4g_mem_size, + pci_memory, &ram_memory); } if (!xen_enabled()) { @@ -130,7 +138,14 @@ static void pc_init1(MemoryRegion *system_memory, if (pci_enabled) { pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, isa_irq, - system_memory, system_io, ram_size); + system_memory, system_io, ram_size, + below_4g_mem_size, + 0x100000000ULL - below_4g_mem_size, + 0x100000000ULL + above_4g_mem_size, + (sizeof(target_phys_addr_t) == 4 + ? 0 + : ((uint64_t)1 << 62)), + pci_memory, ram_memory); } else { pci_bus = NULL; i440fx_state = NULL; @@ -202,10 +217,6 @@ static void pc_init1(MemoryRegion *system_memory, smbus_eeprom_init(smbus, 8, NULL, 0); } - if (i440fx_state) { - i440fx_init_memory_mappings(i440fx_state); - } - if (pci_enabled) { pc_pci_device_init(pci_bus); } |