summaryrefslogtreecommitdiff
path: root/src/dev/pci
diff options
context:
space:
mode:
Diffstat (limited to 'src/dev/pci')
-rw-r--r--src/dev/pci/PciHost.py64
-rw-r--r--src/dev/pci/SConscript48
-rw-r--r--src/dev/pci/host.cc228
-rw-r--r--src/dev/pci/host.hh330
-rw-r--r--src/dev/pci/types.hh74
5 files changed, 744 insertions, 0 deletions
diff --git a/src/dev/pci/PciHost.py b/src/dev/pci/PciHost.py
new file mode 100644
index 000000000..f4f9e45e8
--- /dev/null
+++ b/src/dev/pci/PciHost.py
@@ -0,0 +1,64 @@
+# Copyright (c) 2015 ARM Limited
+# All rights reserved
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder. You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Andreas Sandberg
+
+from m5.SimObject import SimObject
+from m5.params import *
+from m5.proxy import *
+from Device import PioDevice
+from Platform import Platform
+
+class PciHost(PioDevice):
+ type = 'PciHost'
+ cxx_class = 'PciHost'
+ cxx_header = "dev/pci/host.hh"
+ abstract = True
+
+class GenericPciHost(PciHost):
+ type = 'GenericPciHost'
+ cxx_class = 'GenericPciHost'
+ cxx_header = "dev/pci/host.hh"
+
+ platform = Param.Platform(Parent.any, "Platform to use for interrupts")
+
+ conf_base = Param.Addr("Config space base address")
+ conf_size = Param.Addr("Config space base address")
+ conf_device_bits = Param.UInt8(8, "Number of bits used to as an "
+ "offset a devices address space")
+
+ pci_pio_base = Param.Addr(0, "Base address for PCI IO accesses")
+ pci_mem_base = Param.Addr(0, "Base address for PCI memory accesses")
+ pci_dma_base = Param.Addr(0, "Base address for DMA memory accesses")
diff --git a/src/dev/pci/SConscript b/src/dev/pci/SConscript
new file mode 100644
index 000000000..b892a2905
--- /dev/null
+++ b/src/dev/pci/SConscript
@@ -0,0 +1,48 @@
+# -*- mode:python -*-
+
+# Copyright (c) 2015 ARM Limited
+# All rights reserved.
+#
+# The license below extends only to copyright in the software and shall
+# not be construed as granting a license to any other intellectual
+# property including but not limited to intellectual property relating
+# to a hardware implementation of the functionality of the software
+# licensed hereunder. You may use the software subject to the license
+# terms below provided that you ensure that this notice is replicated
+# unmodified and in its entirety in all distributions of the software,
+# modified or unmodified, in source code or in binary form.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met: redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer;
+# redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution;
+# neither the name of the copyright holders nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+#
+# Authors: Andreas Sandberg
+
+Import('*')
+
+if env['TARGET_ISA'] == 'null':
+ Return()
+
+SimObject('PciHost.py')
+Source('host.cc')
+
+DebugFlag('PciHost')
diff --git a/src/dev/pci/host.cc b/src/dev/pci/host.cc
new file mode 100644
index 000000000..bcf49df86
--- /dev/null
+++ b/src/dev/pci/host.cc
@@ -0,0 +1,228 @@
+/*
+ * Copyright (c) 2015 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Sandberg
+ */
+
+#include "dev/pci/host.hh"
+
+#include <utility>
+
+#include "debug/PciHost.hh"
+#include "dev/pcidev.hh"
+#include "dev/platform.hh"
+#include "params/GenericPciHost.hh"
+#include "params/PciHost.hh"
+
+
+PciHost::PciHost(const PciHostParams *p)
+ : PioDevice(p)
+{
+}
+
+PciHost::~PciHost()
+{
+}
+
+PciHost::DeviceInterface
+PciHost::registerDevice(PciDevice *device, PciBusAddr bus_addr, PciIntPin pin)
+{
+ auto map_entry = devices.emplace(bus_addr, device);
+
+ DPRINTF(PciHost, "%02x:%02x.%i: Registering device\n",
+ bus_addr.bus, bus_addr.dev, bus_addr.func);
+
+ fatal_if(!map_entry.second,
+ "%02x:%02x.%i: PCI bus ID collision\n",
+ bus_addr.bus, bus_addr.dev, bus_addr.func);
+
+ return DeviceInterface(*this, bus_addr, pin);
+}
+
+PciDevice *
+PciHost::getDevice(const PciBusAddr &addr)
+{
+ auto device = devices.find(addr);
+ return device != devices.end() ? device->second : nullptr;
+}
+
+const PciDevice *
+PciHost::getDevice(const PciBusAddr &addr) const
+{
+ auto device = devices.find(addr);
+ return device != devices.end() ? device->second : nullptr;
+}
+
+PciHost::DeviceInterface::DeviceInterface(
+ PciHost &_host,
+ PciBusAddr &bus_addr, PciIntPin interrupt_pin)
+ : host(_host),
+ busAddr(bus_addr), interruptPin(interrupt_pin)
+{
+}
+
+const std::string
+PciHost::DeviceInterface::name() const
+{
+ return csprintf("%s.interface[%02x:%02x.%i]",
+ host.name(), busAddr.bus, busAddr.dev, busAddr.func);
+}
+
+void
+PciHost::DeviceInterface::postInt()
+{
+ DPRINTF(PciHost, "postInt\n");
+
+ host.postInt(busAddr, interruptPin);
+}
+
+void
+PciHost::DeviceInterface::clearInt()
+{
+ DPRINTF(PciHost, "clearInt\n");
+
+ host.clearInt(busAddr, interruptPin);
+}
+
+
+GenericPciHost::GenericPciHost(const GenericPciHostParams *p)
+ : PciHost(p),
+ platform(*p->platform),
+ confBase(p->conf_base), confSize(p->conf_size),
+ confDeviceBits(p->conf_device_bits),
+ pciPioBase(p->pci_pio_base), pciMemBase(p->pci_mem_base),
+ pciDmaBase(p->pci_dma_base)
+{
+}
+
+GenericPciHost::~GenericPciHost()
+{
+}
+
+
+Tick
+GenericPciHost::read(PacketPtr pkt)
+{
+ const auto dev_addr(decodeAddress(pkt->getAddr() - confBase));
+ const Addr size(pkt->getSize());
+
+ DPRINTF(PciHost, "%02x:%02x.%i: read: offset=0x%x, size=0x%x\n",
+ dev_addr.first.bus, dev_addr.first.dev, dev_addr.first.func,
+ dev_addr.second,
+ size);
+
+ PciDevice *const pci_dev(getDevice(dev_addr.first));
+ if (pci_dev) {
+ // @todo Remove this after testing
+ pkt->headerDelay = pkt->payloadDelay = 0;
+ return pci_dev->readConfig(pkt);
+ } else {
+ uint8_t *pkt_data(pkt->getPtr<uint8_t>());
+ std::fill(pkt_data, pkt_data + size, 0xFF);
+ pkt->makeAtomicResponse();
+ return 0;
+ }
+}
+
+Tick
+GenericPciHost::write(PacketPtr pkt)
+{
+ const auto dev_addr(decodeAddress(pkt->getAddr() - confBase));
+
+ DPRINTF(PciHost, "%02x:%02x.%i: write: offset=0x%x, size=0x%x\n",
+ dev_addr.first.bus, dev_addr.first.dev, dev_addr.first.func,
+ dev_addr.second,
+ pkt->getSize());
+
+ PciDevice *const pci_dev(getDevice(dev_addr.first));
+ panic_if(!pci_dev,
+ "%02x:%02x.%i: Write to config space on non-existent PCI device\n",
+ dev_addr.first.bus, dev_addr.first.dev, dev_addr.first.func);
+
+ // @todo Remove this after testing
+ pkt->headerDelay = pkt->payloadDelay = 0;
+
+ return pci_dev->writeConfig(pkt);
+}
+
+AddrRangeList
+GenericPciHost::getAddrRanges() const
+{
+ return AddrRangeList({ RangeSize(confBase, confSize) });
+}
+
+std::pair<PciBusAddr, Addr>
+GenericPciHost::decodeAddress(Addr addr)
+{
+ const Addr offset(addr & mask(confDeviceBits));
+ const Addr bus_addr(addr >> confDeviceBits);
+
+ return std::make_pair(
+ PciBusAddr(bits(bus_addr, 15, 8),
+ bits(bus_addr, 7, 3),
+ bits(bus_addr, 2, 0)),
+ offset);
+}
+
+
+void
+GenericPciHost::postInt(const PciBusAddr &addr, PciIntPin pin)
+{
+ platform.postPciInt(mapPciInterrupt(addr, pin));
+}
+
+void
+GenericPciHost::clearInt(const PciBusAddr &addr, PciIntPin pin)
+{
+ platform.clearPciInt(mapPciInterrupt(addr, pin));
+}
+
+
+uint32_t
+GenericPciHost::mapPciInterrupt(const PciBusAddr &addr, PciIntPin pin) const
+{
+ const PciDevice *dev(getDevice(addr));
+ assert(dev);
+
+ return dev->interruptLine();
+}
+
+
+GenericPciHost *
+GenericPciHostParams::create()
+{
+ return new GenericPciHost(this);
+}
diff --git a/src/dev/pci/host.hh b/src/dev/pci/host.hh
new file mode 100644
index 000000000..0e6d580ab
--- /dev/null
+++ b/src/dev/pci/host.hh
@@ -0,0 +1,330 @@
+/*
+ * Copyright (c) 2015 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Sandberg
+ */
+
+#ifndef __DEV_PCI_HOST_HH__
+#define __DEV_PCI_HOST_HH__
+
+#include "dev/io_device.hh"
+#include "dev/pci/types.hh"
+
+struct PciHostParams;
+struct GenericPciHostParams;
+
+class PciDevice;
+class Platform;
+
+/**
+ * The PCI host describes the interface between PCI devices and a
+ * simulated system.
+ *
+ * The PCI host controller has three main responsibilities:
+ * <ol>
+ * <li>Expose a configuration memory space that allows devices to
+ * be discovered and configured.
+ * <li>Map and deliver interrupts to the CPU.
+ * <li>Map memory addresses from the PCI bus's various memory
+ * spaces (Legacy IO, non-prefetchable memory, and
+ * prefetchable memory) to physical memory.
+ * </ol>
+ *
+ * PCI devices need to register themselves with a PCI host using the
+ * PciHost::registerDevice() call. This call returns a
+ * PciHost::DeviceInterface that provides for common functionality
+ * such as interrupt delivery and memory mapping.
+ *
+ * The PciHost class itself provides very little functionality. Simple
+ * PciHost functionality is implemented by the GenericPciHost class.
+ */
+class PciHost : public PioDevice
+{
+ public:
+ PciHost(const PciHostParams *p);
+ virtual ~PciHost();
+
+ public:
+ /**
+ * @{
+ * @name Device interface
+ */
+
+ /**
+ * Callback interface from PCI devices to the host.
+ *
+ * Devices get an instance of this object when they register
+ * themselves with the host using the PciHost::registerDevice()
+ * call.
+ */
+ class DeviceInterface
+ {
+ friend class ::PciHost;
+
+ protected:
+ /**
+ * Instantiate a device interface
+ *
+ * @param host PCI host that this device belongs to.
+ * @param bus_addr The device's position on the PCI bus
+ * @param pin Interrupt pin
+ */
+ DeviceInterface(PciHost &host, PciBusAddr &bus_addr, PciIntPin pin);
+
+ public:
+ DeviceInterface() = delete;
+ void operator=(const DeviceInterface &) = delete;
+
+ const std::string name() const;
+
+ /**
+ * Post a PCI interrupt to the CPU.
+ */
+ void postInt();
+
+ /**
+ * Clear a posted PCI interrupt
+ */
+ void clearInt();
+
+ /**
+ * Calculate the physical address of an IO location on the PCI
+ * bus.
+ *
+ * @param addr Address in the PCI IO address space
+ * @return Address in the system's physical address space.
+ */
+ Addr pioAddr(Addr addr) const { return host.pioAddr(busAddr, addr); }
+
+ /**
+ * Calculate the physical address of a non-prefetchable memory
+ * location in the PCI address space.
+ *
+ * @param addr Address in the PCI memory address space
+ * @return Address in the system's physical address space.
+ */
+ Addr memAddr(Addr addr) const { return host.memAddr(busAddr, addr); }
+
+ /**
+ * Calculate the physical address of a prefetchable memory
+ * location in the PCI address space.
+ *
+ * @param addr Address in the PCI DMA memory address space
+ * @return Address in the system's physical address space.
+ */
+ Addr dmaAddr(Addr addr) const { return host.dmaAddr(busAddr, addr); }
+
+ protected:
+ PciHost &host;
+
+ const PciBusAddr busAddr;
+ const PciIntPin interruptPin;
+ };
+
+ /**
+ * Register a PCI device with the host.
+ *
+ * @param device Device to register
+ * @param bus_addr The device's position on the PCI bus
+ * @param pin Interrupt pin
+ * @return A device-specific DeviceInterface instance.
+ */
+ virtual DeviceInterface registerDevice(PciDevice *device,
+ PciBusAddr bus_addr, PciIntPin pin);
+
+ /** @} */
+
+ protected:
+ /**
+ * @{
+ * @name PciHost controller interface
+ */
+
+ /**
+ * Post an interrupt to the CPU.
+ *
+ * @param bus_addr The device's position on the PCI bus
+ * @param pin PCI interrupt pin
+ */
+ virtual void postInt(const PciBusAddr &bus_addr, PciIntPin pin) = 0;
+
+ /**
+ * Post an interrupt to the CPU.
+ *
+ * @param bus_addr The device's position on the PCI bus
+ * @param pin PCI interrupt pin
+ */
+ virtual void clearInt(const PciBusAddr &bus_addr, PciIntPin pin) = 0;
+
+ /**
+ * Calculate the physical address of an IO location on the PCI
+ * bus.
+ *
+ * @param bus_addr The device's position on the PCI bus
+ * @param pci_addr Address in the PCI IO address space
+ * @return Address in the system's physical address space.
+ */
+ virtual Addr pioAddr(const PciBusAddr &bus_addr, Addr pci_addr) const = 0;
+
+ /**
+ * Calculate the physical address of a non-prefetchable memory
+ * location in the PCI address space.
+ *
+ * @param bus_addr The device's position on the PCI bus
+ * @param pci_addr Address in the PCI memory address space
+ * @return Address in the system's physical address space.
+ */
+ virtual Addr memAddr(const PciBusAddr &bus_addr, Addr pci_addr) const = 0;
+
+
+ /**
+ * Calculate the physical address of a prefetchable memory
+ * location in the PCI address space.
+ *
+ * @param bus_addr The device's position on the PCI bus
+ * @param pci_addr Address in the PCI DMA memory address space
+ * @return Address in the system's physical address space.
+ */
+ virtual Addr dmaAddr(const PciBusAddr &bus_addr, Addr pci_addr) const = 0;
+
+ /** @} */
+
+ protected:
+ /**
+ * Retrieve a PCI device from its bus address.
+ *
+ * @return Pointer to a PciDevice instance or nullptr if the
+ * device doesn't exist.
+ */
+ PciDevice *getDevice(const PciBusAddr &addr);
+
+ /**
+ * Retrieve a PCI device from its bus address.
+ *
+ * @return Pointer to a constant PciDevice instance or nullptr if
+ * the device doesn't exist.
+ */
+ const PciDevice *getDevice(const PciBusAddr &addr) const;
+
+ private:
+ /** Currently registered PCI devices */
+ std::map<PciBusAddr, PciDevice *> devices;
+};
+
+/**
+ * Configurable generic PCI host interface
+ *
+ * The GenericPciHost provides a configurable generic PCI host
+ * implementation.
+ *
+ * The generic controller binds to one range of physical addresses to
+ * implement the PCI subsystem's configuraiton space. The base
+ * address, size and mapping between memory addresses and PCI devices
+ * are all configurable as simulation parameters. The basic
+ * implementation supports both the Configuration Access Mechanism
+ * (CAM) and Enhanced Configuration Access Mechanism (ECAM)
+ * configuration space layout. The layouts can be configured by
+ * changing the number of bits allocated to each device in the
+ * configuration space. ECAM uses 12 bits per device, while CAM uses 8
+ * bits per device.
+ *
+ * Interrupts are delivered via the Platform::postInt() and
+ * Platform::clearInt() calls. Interrupt numbers are mapped statically
+ * using the interrupt line (PciDevice::interruptLine()) returned from
+ * the device. Implementations may override mapPciInterrupt() to
+ * dynamically map a PciBusAddr and PciIntPin to a platform-specific
+ * interrupt.
+ *
+ * All PCI memory spaces (IO, prefetchable, and non-prefetchable)
+ * support a simple base+offset mapping that can be configured using
+ * simulation parameters. The base defaults to 0 for all of them.
+ */
+class GenericPciHost : public PciHost
+{
+ public:
+ GenericPciHost(const GenericPciHostParams *p);
+ virtual ~GenericPciHost();
+
+ public: // PioDevice
+ Tick read(PacketPtr pkt) override;
+ Tick write(PacketPtr pkt) override;
+
+ AddrRangeList getAddrRanges() const override;
+
+ protected: // PciHost
+ Addr pioAddr(const PciBusAddr &bus_addr, Addr pci_addr) const override {
+ return pciPioBase + pci_addr;
+ }
+
+ Addr memAddr(const PciBusAddr &bus_addr, Addr pci_addr) const override {
+ return pciMemBase + pci_addr;
+ }
+
+ Addr dmaAddr(const PciBusAddr &bus_addr, Addr pci_addr) const override {
+ return pciDmaBase + pci_addr;
+ }
+
+ protected: // Configuration address space handling
+ /**
+ * Decode a configuration space address.
+ *
+ *
+ * @param addr Offset into the configuration space
+ * @return Tuple containing the PCI bus address and an offset into
+ * the device's configuration space.
+ */
+ virtual std::pair<PciBusAddr, Addr> decodeAddress(Addr address);
+
+ protected: // Interrupt handling
+ void postInt(const PciBusAddr &addr, PciIntPin pin) override;
+ void clearInt(const PciBusAddr &addr, PciIntPin pin) override;
+
+ virtual uint32_t mapPciInterrupt(const PciBusAddr &bus_addr,
+ PciIntPin pin) const;
+
+ protected:
+ Platform &platform;
+
+ const Addr confBase;
+ const Addr confSize;
+ const uint8_t confDeviceBits;
+
+ const Addr pciPioBase;
+ const Addr pciMemBase;
+ const Addr pciDmaBase;
+};
+
+#endif // __DEV_PCI_HOST_HH__
diff --git a/src/dev/pci/types.hh b/src/dev/pci/types.hh
new file mode 100644
index 000000000..298fe92f4
--- /dev/null
+++ b/src/dev/pci/types.hh
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2015 ARM Limited
+ * All rights reserved
+ *
+ * The license below extends only to copyright in the software and shall
+ * not be construed as granting a license to any other intellectual
+ * property including but not limited to intellectual property relating
+ * to a hardware implementation of the functionality of the software
+ * licensed hereunder. You may use the software subject to the license
+ * terms below provided that you ensure that this notice is replicated
+ * unmodified and in its entirety in all distributions of the software,
+ * modified or unmodified, in source code or in binary form.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * Authors: Andreas Sandberg
+ */
+
+#ifndef __DEV_PCI_TYPES_HH__
+#define __DEV_PCI_TYPES_HH__
+
+struct PciBusAddr
+{
+ public:
+ PciBusAddr() = delete;
+
+ constexpr PciBusAddr(uint8_t _bus, uint8_t _dev, uint8_t _func)
+ : bus(_bus), dev(_dev), func(_func) {}
+
+ constexpr bool operator<(const PciBusAddr &rhs) const {
+ return sortValue() < rhs.sortValue();
+ }
+
+ uint8_t bus;
+ uint8_t dev;
+ uint8_t func;
+
+ protected:
+ constexpr uint32_t sortValue() const {
+ return (bus << 16) | (dev << 8) | func;
+ }
+};
+
+enum class PciIntPin : uint8_t
+{
+ NO_INT=0,
+ INTA,
+ INTB,
+ INTC,
+ INTD
+};
+
+#endif // __DEV_PCI_TYPES_HH__