changeset 198dfef33403 in /z/repo/gem5
details: http://repo.gem5.org/gem5?cmd=changeset;node=198dfef33403
description:
        dev, arm: Add support for linux generic pci host driver

        This change adds support for a generic pci host bus driver that
        has been included in recent Linux kernel instead of the more
        bespoke one we've been using to date. It also works with
        aarch64 so it provides PCI support for 64-bit ARM Linux.

        To make this work a new configuration option pci_io_base is added
        to the RealView platform that should be set to the start of
        the memory used as memory mapped IO ports (IO ports that are
        memory mapped, not regular memory mapped IO). And a parameter
        pci_cfg_gen_offsets which specifies if the config space
        offsets should be used that the generic driver expects.

        To use the pci-host-generic device you need to:
        pci_io_base = 0x2f000000 (Valid for VExpress EMM)
        pci_cfg_gen_offsets = True

        and add the following to your device tree:

            pci {
                compatible = "pci-host-ecam-generic";
                device_type = "pci";
                #address-cells = <0x3>;
                #size-cells = <0x2>;
                #interrupt-cells = <0x1>;
                //bus-range = <0x0 0x1>;

                // CPU_PHYSICAL(2)  SIZE(2)
                // Note, some DTS blobs only support 1 size
                reg = <0x0 0x30000000 0x0 0x10000000>;

                // IO (1), no bus address (2), cpu address (2), size (2)
                // MMIO (1), at address (2), cpu address (2), size (2)
                ranges = <0x01000000 0x0 0x00000000 0x0 0x2f000000 0x0 0x10000>,
                         <0x02000000 0x0 0x40000000 0x0 0x40000000 0x0 
0x10000000>;

                // With gem5 we typically use INTA/B/C/D one per device
                interrupt-map = <0x0000 0x0 0x0 0x1 0x1 0x0 0x11 0x1
                                 0x0000 0x0 0x0 0x2 0x1 0x0 0x12 0x1
                                 0x0000 0x0 0x0 0x3 0x1 0x0 0x13 0x1
                                 0x0000 0x0 0x0 0x4 0x1 0x0 0x14 0x1>;

                // Only match INTA/B/C/D and not BDF
                interrupt-map-mask = <0x0000 0x0 0x0 0x7>;
            };

diffstat:

 src/dev/arm/RealView.py |   5 +++++
 src/dev/arm/realview.cc |  27 ++++++++++++++++++++++++---
 src/dev/arm/realview.hh |   3 +++
 3 files changed, 32 insertions(+), 3 deletions(-)

diffs (90 lines):

diff -r 7565dcd505a4 -r 198dfef33403 src/dev/arm/RealView.py
--- a/src/dev/arm/RealView.py   Wed Sep 03 07:43:03 2014 -0400
+++ b/src/dev/arm/RealView.py   Wed Sep 03 07:43:04 2014 -0400
@@ -180,7 +180,10 @@
     type = 'RealView'
     cxx_header = "dev/arm/realview.hh"
     system = Param.System(Parent.any, "system")
+    pci_io_base = Param.Addr(0, "Base address of PCI IO Space")
     pci_cfg_base = Param.Addr(0, "Base address of PCI Configuraiton Space")
+    pci_cfg_gen_offsets = Param.Bool(False, "Should the offsets used for PCI 
cfg access"
+            " be compatible with the pci-generic-host or the legacy host 
bridge?")
     mem_start_addr = Param.Addr(0, "Start address of main memory")
     max_mem_size = Param.Addr('256MB', "Maximum amount of RAM supported by 
platform")
 
@@ -597,6 +600,8 @@
         self.mmc_fake.clk_domain      = clkdomain
 
 class VExpress_EMM64(VExpress_EMM):
+    pci_io_base = 0x2f000000
+    pci_cfg_gen_offsets = True
     def setupBootLoader(self, mem_bus, cur_sys, loc):
         self.nvmem = SimpleMemory(range = AddrRange(0, size = '64MB'))
         self.nvmem.port = mem_bus.master
diff -r 7565dcd505a4 -r 198dfef33403 src/dev/arm/realview.cc
--- a/src/dev/arm/realview.cc   Wed Sep 03 07:43:03 2014 -0400
+++ b/src/dev/arm/realview.cc   Wed Sep 03 07:43:04 2014 -0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2009 ARM Limited
+ * Copyright (c) 2009, 2014 ARM Limited
  * All rights reserved
  *
  * The license below extends only to copyright in the software and shall
@@ -63,6 +63,21 @@
 {}
 
 void
+RealView::initState()
+{
+    Addr junk;
+    bool has_gen_pci_host;
+    has_gen_pci_host = system->kernelSymtab->findAddress("gen_pci_setup", 
junk);
+
+    if (has_gen_pci_host && !params()->pci_cfg_gen_offsets)
+        warn("Kernel supports generic PCI host but PCI Config offsets "
+                "configured for legacy. Set pci_cfg_gen_offsets to True");
+    if (has_gen_pci_host && !params()->pci_io_base)
+        warn("Kernel supports generic PCI host but PCI IO base is set "
+                "to 0. Set pci_io_base to the start of PCI IO space");
+}
+
+void
 RealView::postConsoleInt()
 {
     warn_once("Don't know what interrupt to post for console.\n");
@@ -100,13 +115,19 @@
 {
     if (bus != 0)
         return ULL(-1);
-    return params()->pci_cfg_base | ((func & 7) << 16) | ((dev & 0x1f) << 19);
+
+    Addr cfg_offset = 0;
+    if (params()->pci_cfg_gen_offsets)
+        cfg_offset |= ((func & 7) << 12) | ((dev & 0x1f) << 15);
+    else
+        cfg_offset |= ((func & 7) << 16) | ((dev & 0x1f) << 19);
+    return params()->pci_cfg_base | cfg_offset;
 }
 
 Addr
 RealView::calcPciIOAddr(Addr addr)
 {
-    return addr;
+    return params()->pci_io_base + addr;
 }
 
 Addr
diff -r 7565dcd505a4 -r 198dfef33403 src/dev/arm/realview.hh
--- a/src/dev/arm/realview.hh   Wed Sep 03 07:43:03 2014 -0400
+++ b/src/dev/arm/realview.hh   Wed Sep 03 07:43:04 2014 -0400
@@ -79,6 +79,9 @@
      */
     RealView(const Params *p);
 
+    /** In init do some checks to help verify we're setup correctly */
+    virtual void initState();
+
     /** Give platform a pointer to interrupt controller */
     void setGic(BaseGic *_gic) { gic = _gic; }
 
_______________________________________________
gem5-dev mailing list
gem5-dev@gem5.org
http://m5sim.org/mailman/listinfo/gem5-dev

Reply via email to