summary refs log tree commit diff stats
path: root/hw/pc_piix.c
diff options
context:
space:
mode:
authorAvi Kivity <avi@redhat.com>2011-08-15 17:17:38 +0300
committerAnthony Liguori <aliguori@us.ibm.com>2011-08-22 10:47:49 -0500
commitae0a54664c76f1d2a2a7a268266d47b4e8c12a4c (patch)
treeb4a664a81fe572ce96640fdc74b0ec2ca172ee2a /hw/pc_piix.c
parentbe20f9e902ca47ea84e1b1c1e89b0a55d59b4c11 (diff)
downloadfocaccia-qemu-ae0a54664c76f1d2a2a7a268266d47b4e8c12a4c.tar.gz
focaccia-qemu-ae0a54664c76f1d2a2a7a268266d47b4e8c12a4c.zip
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.c23
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);
     }