config, x86: Ensure that PCI devs get bridged to the memory bus
authorJiuyue Ma <majiuyue@ncic.ac.cn>
Thu, 17 Jul 2014 04:05:41 +0000 (12:05 +0800)
committerJiuyue Ma <majiuyue@ncic.ac.cn>
Thu, 17 Jul 2014 04:05:41 +0000 (12:05 +0800)
This patch force IO device to be mapped to 0xC0000000-0xFFFF0000 by
reserve anything between the end of memory and 3GB if memory is less
than 3GB. It also statically bridge these address range to the IO bus,
which guaranty access to pci address space will pass though bridge to
iobus.

Committed by: Nilay Vaish <nilay@cs.wisc.edu>

configs/common/FSConfig.py

index d3b78897260204e7afb84086881ee42e2669a3f5..ee9bef929eb1036f3e8687b45366de859abb1a0a 100644 (file)
@@ -348,14 +348,15 @@ def connectX86ClassicSystem(x86_sys, numCPUs):
     x86_sys.bridge = Bridge(delay='50ns')
     x86_sys.bridge.master = x86_sys.iobus.slave
     x86_sys.bridge.slave = x86_sys.membus.master
-    # Allow the bridge to pass through the IO APIC (two pages),
-    # everything in the IO address range up to the local APIC, and
-    # then the entire PCI address space and beyond
+    # Allow the bridge to pass through:
+    #  1) kernel configured PCI device memory map address: address range
+    #     [0xC0000000, 0xFFFF0000). (The upper 64kB are reserved for m5ops.)
+    #  2) the bridge to pass through the IO APIC (two pages, already contained in 1),
+    #  3) everything in the IO address range up to the local APIC, and
+    #  4) then the entire PCI address space and beyond.
     x86_sys.bridge.ranges = \
         [
-        AddrRange(x86_sys.pc.south_bridge.io_apic.pio_addr,
-                  x86_sys.pc.south_bridge.io_apic.pio_addr +
-                  APIC_range_size - 1),
+        AddrRange(0xC0000000, 0xFFFF0000),
         AddrRange(IO_address_space_base,
                   interrupts_address_space_base - 1),
         AddrRange(pci_config_address_space_base,
@@ -521,11 +522,19 @@ def makeLinuxX86System(mem_mode, numCPUs = 1, mdesc = None,
         X86E820Entry(addr = 0x100000,
                 size = '%dB' % (self.mem_ranges[0].size() - 0x100000),
                 range_type = 1),
-        # Reserve the last 16kB of the 32-bit address space for the
-        # m5op interface
-        X86E820Entry(addr=0xFFFF0000, size='64kB', range_type=2),
         ]
 
+    # Mark [mem_size, 3GB) as reserved if memory less than 3GB, which force
+    # IO devices to be mapped to [0xC0000000, 0xFFFF0000). Requests to this
+    # specific range can pass though bridge to iobus.
+    if len(self.mem_ranges) == 1:
+        entries.append(X86E820Entry(addr = self.mem_ranges[0].size(),
+            size='%dB' % (0xC0000000 - self.mem_ranges[0].size()),
+            range_type=2))
+
+    # Reserve the last 16kB of the 32-bit address space for the m5op interface
+    entries.append(X86E820Entry(addr=0xFFFF0000, size='64kB', range_type=2))
+
     # In case the physical memory is greater than 3GB, we split it into two
     # parts and add a separate e820 entry for the second part.  This entry
     # starts at 0x100000000,  which is the first address after the space