from m5.SimObject import SimObject
from m5.params import *
from m5.proxy import *
-from Pci import PciDevice
+from PciDevice import PciDevice
class CopyEngine(PciDevice):
type = 'CopyEngine'
from m5.SimObject import SimObject
from m5.params import *
from m5.proxy import *
-from Pci import PciDevice
+from PciDevice import PciDevice
class EtherObject(SimObject):
type = 'EtherObject'
from m5.SimObject import SimObject
from m5.params import *
-from Pci import PciDevice
+from PciDevice import PciDevice
class IdeID(Enum): vals = ['master', 'slave']
+++ /dev/null
-# Copyright (c) 2013 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.
-#
-# Copyright (c) 2005-2007 The Regents of The University of Michigan
-# All rights reserved.
-#
-# 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: Nathan Binkert
-
-from m5.SimObject import SimObject
-from m5.params import *
-from m5.proxy import *
-from Device import DmaDevice
-from PciHost import PciHost
-
-class PciDevice(DmaDevice):
- type = 'PciDevice'
- cxx_class = 'PciDevice'
- cxx_header = "dev/pcidev.hh"
- abstract = True
-
- host = Param.PciHost(Parent.any, "PCI host")
- pci_bus = Param.Int("PCI bus")
- pci_dev = Param.Int("PCI device number")
- pci_func = Param.Int("PCI function code")
-
- pio_latency = Param.Latency('30ns', "Programmed IO latency")
- config_latency = Param.Latency('20ns', "Config read or write latency")
-
- VendorID = Param.UInt16("Vendor ID")
- DeviceID = Param.UInt16("Device ID")
- Command = Param.UInt16(0, "Command")
- Status = Param.UInt16(0, "Status")
- Revision = Param.UInt8(0, "Device")
- ProgIF = Param.UInt8(0, "Programming Interface")
- SubClassCode = Param.UInt8(0, "Sub-Class Code")
- ClassCode = Param.UInt8(0, "Class Code")
- CacheLineSize = Param.UInt8(0, "System Cacheline Size")
- LatencyTimer = Param.UInt8(0, "PCI Latency Timer")
- HeaderType = Param.UInt8(0, "PCI Header Type")
- BIST = Param.UInt8(0, "Built In Self Test")
-
- BAR0 = Param.UInt32(0x00, "Base Address Register 0")
- BAR1 = Param.UInt32(0x00, "Base Address Register 1")
- BAR2 = Param.UInt32(0x00, "Base Address Register 2")
- BAR3 = Param.UInt32(0x00, "Base Address Register 3")
- BAR4 = Param.UInt32(0x00, "Base Address Register 4")
- BAR5 = Param.UInt32(0x00, "Base Address Register 5")
- BAR0Size = Param.MemorySize32('0B', "Base Address Register 0 Size")
- BAR1Size = Param.MemorySize32('0B', "Base Address Register 1 Size")
- BAR2Size = Param.MemorySize32('0B', "Base Address Register 2 Size")
- BAR3Size = Param.MemorySize32('0B', "Base Address Register 3 Size")
- BAR4Size = Param.MemorySize32('0B', "Base Address Register 4 Size")
- BAR5Size = Param.MemorySize32('0B', "Base Address Register 5 Size")
- BAR0LegacyIO = Param.Bool(False, "Whether BAR0 is hardwired legacy IO")
- BAR1LegacyIO = Param.Bool(False, "Whether BAR1 is hardwired legacy IO")
- BAR2LegacyIO = Param.Bool(False, "Whether BAR2 is hardwired legacy IO")
- BAR3LegacyIO = Param.Bool(False, "Whether BAR3 is hardwired legacy IO")
- BAR4LegacyIO = Param.Bool(False, "Whether BAR4 is hardwired legacy IO")
- BAR5LegacyIO = Param.Bool(False, "Whether BAR5 is hardwired legacy IO")
- LegacyIOBase = Param.Addr(0x0, "Base Address for Legacy IO")
-
- CardbusCIS = Param.UInt32(0x00, "Cardbus Card Information Structure")
- SubsystemID = Param.UInt16(0x00, "Subsystem ID")
- SubsystemVendorID = Param.UInt16(0x00, "Subsystem Vendor ID")
- ExpansionROM = Param.UInt32(0x00, "Expansion ROM Base Address")
- CapabilityPtr = Param.UInt8(0x00, "Capability List Pointer offset")
- InterruptLine = Param.UInt8(0x00, "Interrupt Line")
- InterruptPin = Param.UInt8(0x00, "Interrupt Pin")
- MaximumLatency = Param.UInt8(0x00, "Maximum Latency")
- MinimumGrant = Param.UInt8(0x00, "Minimum Grant")
-
- # Capabilities List structures for PCIe devices
- # PMCAP - PCI Power Management Capability
- PMCAPBaseOffset = \
- Param.UInt8(0x00, "Base offset of PMCAP in PCI Config space")
- PMCAPNextCapability = \
- Param.UInt8(0x00, "Pointer to next capability block")
- PMCAPCapId = \
- Param.UInt8(0x00, "Specifies this is the Power Management capability")
- PMCAPCapabilities = \
- Param.UInt16(0x0000, "PCI Power Management Capabilities Register")
- PMCAPCtrlStatus = \
- Param.UInt16(0x0000, "PCI Power Management Control and Status")
-
- # MSICAP - Message Signaled Interrupt Capability
- MSICAPBaseOffset = \
- Param.UInt8(0x00, "Base offset of MSICAP in PCI Config space")
- MSICAPNextCapability = \
- Param.UInt8(0x00, "Pointer to next capability block")
- MSICAPCapId = Param.UInt8(0x00, "Specifies this is the MSI Capability")
- MSICAPMsgCtrl = Param.UInt16(0x0000, "MSI Message Control")
- MSICAPMsgAddr = Param.UInt32(0x00000000, "MSI Message Address")
- MSICAPMsgUpperAddr = Param.UInt32(0x00000000, "MSI Message Upper Address")
- MSICAPMsgData = Param.UInt16(0x0000, "MSI Message Data")
- MSICAPMaskBits = Param.UInt32(0x00000000, "MSI Interrupt Mask Bits")
- MSICAPPendingBits = Param.UInt32(0x00000000, "MSI Pending Bits")
-
- # MSIXCAP - MSI-X Capability
- MSIXCAPBaseOffset = \
- Param.UInt8(0x00, "Base offset of MSIXCAP in PCI Config space")
- MSIXCAPNextCapability = \
- Param.UInt8(0x00, "Pointer to next capability block")
- MSIXCAPCapId = Param.UInt8(0x00, "Specifices this the MSI-X Capability")
- MSIXMsgCtrl = Param.UInt16(0x0000, "MSI-X Message Control")
- MSIXTableOffset = \
- Param.UInt32(0x00000000, "MSI-X Table Offset and Table BIR")
- MSIXPbaOffset = Param.UInt32(0x00000000, "MSI-X PBA Offset and PBA BIR")
-
- # PXCAP - PCI Express Capability
- PXCAPBaseOffset = \
- Param.UInt8(0x00, "Base offset of PXCAP in PCI Config space")
- PXCAPNextCapability = Param.UInt8(0x00, "Pointer to next capability block")
- PXCAPCapId = Param.UInt8(0x00, "Specifies this is the PCIe Capability")
- PXCAPCapabilities = Param.UInt16(0x0000, "PCIe Capabilities")
- PXCAPDevCapabilities = Param.UInt32(0x00000000, "PCIe Device Capabilities")
- PXCAPDevCtrl = Param.UInt16(0x0000, "PCIe Device Control")
- PXCAPDevStatus = Param.UInt16(0x0000, "PCIe Device Status")
- PXCAPLinkCap = Param.UInt32(0x00000000, "PCIe Link Capabilities")
- PXCAPLinkCtrl = Param.UInt16(0x0000, "PCIe Link Control")
- PXCAPLinkStatus = Param.UInt16(0x0000, "PCIe Link Status")
- PXCAPDevCap2 = Param.UInt32(0x00000000, "PCIe Device Capabilities 2")
- PXCAPDevCtrl2 = Param.UInt32(0x00000000, "PCIe Device Control 2")
SimObject('Ethernet.py')
SimObject('I2C.py')
SimObject('Ide.py')
-SimObject('Pci.py')
SimObject('Platform.py')
SimObject('SimpleDisk.py')
SimObject('Terminal.py')
Source('intel_8254_timer.cc')
Source('mc146818.cc')
Source('ns_gige.cc')
-Source('pcidev.cc')
Source('pixelpump.cc')
Source('pktfifo.cc')
Source('platform.cc')
DebugFlag('IdeDisk')
DebugFlag('Intel8254Timer')
DebugFlag('MC146818')
-DebugFlag('PCIDEV')
DebugFlag('SimpleDisk')
DebugFlag('SimpleDiskData')
DebugFlag('Terminal')
#include "dev/alpha/tsunami.hh"
#include "dev/alpha/tsunami_cchip.hh"
#include "dev/alpha/tsunamireg.h"
-#include "dev/pcidev.hh"
+#include "dev/pci/device.hh"
#include "mem/packet.hh"
#include "mem/packet_access.hh"
#include "sim/system.hh"
#include "base/cp_annotate.hh"
#include "base/statistics.hh"
#include "dev/copy_engine_defs.hh"
-#include "dev/pcidev.hh"
+#include "dev/pci/device.hh"
#include "params/CopyEngine.hh"
#include "sim/drain.hh"
#include "sim/eventq.hh"
#define __DEV_ETHERDEVICE_HH__
#include "base/statistics.hh"
-#include "dev/pcidev.hh"
+#include "dev/pci/device.hh"
#include "params/EtherDevice.hh"
#include "params/EtherDevBase.hh"
#include "sim/sim_object.hh"
#include "dev/etherint.hh"
#include "dev/etherpkt.hh"
#include "dev/i8254xGBe_defs.hh"
-#include "dev/pcidev.hh"
+#include "dev/pci/device.hh"
#include "dev/pktfifo.hh"
#include "params/IGbE.hh"
#include "sim/eventq.hh"
#include "base/bitunion.hh"
#include "dev/io_device.hh"
-#include "dev/pcidev.hh"
-#include "dev/pcireg.h"
+#include "dev/pci/device.hh"
#include "params/IdeController.hh"
class IdeDisk;
--- /dev/null
+# Copyright (c) 2013 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.
+#
+# Copyright (c) 2005-2007 The Regents of The University of Michigan
+# All rights reserved.
+#
+# 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: Nathan Binkert
+
+from m5.SimObject import SimObject
+from m5.params import *
+from m5.proxy import *
+from Device import DmaDevice
+from PciHost import PciHost
+
+class PciDevice(DmaDevice):
+ type = 'PciDevice'
+ cxx_class = 'PciDevice'
+ cxx_header = "dev/pci/device.hh"
+ abstract = True
+
+ host = Param.PciHost(Parent.any, "PCI host")
+ pci_bus = Param.Int("PCI bus")
+ pci_dev = Param.Int("PCI device number")
+ pci_func = Param.Int("PCI function code")
+
+ pio_latency = Param.Latency('30ns', "Programmed IO latency")
+ config_latency = Param.Latency('20ns', "Config read or write latency")
+
+ VendorID = Param.UInt16("Vendor ID")
+ DeviceID = Param.UInt16("Device ID")
+ Command = Param.UInt16(0, "Command")
+ Status = Param.UInt16(0, "Status")
+ Revision = Param.UInt8(0, "Device")
+ ProgIF = Param.UInt8(0, "Programming Interface")
+ SubClassCode = Param.UInt8(0, "Sub-Class Code")
+ ClassCode = Param.UInt8(0, "Class Code")
+ CacheLineSize = Param.UInt8(0, "System Cacheline Size")
+ LatencyTimer = Param.UInt8(0, "PCI Latency Timer")
+ HeaderType = Param.UInt8(0, "PCI Header Type")
+ BIST = Param.UInt8(0, "Built In Self Test")
+
+ BAR0 = Param.UInt32(0x00, "Base Address Register 0")
+ BAR1 = Param.UInt32(0x00, "Base Address Register 1")
+ BAR2 = Param.UInt32(0x00, "Base Address Register 2")
+ BAR3 = Param.UInt32(0x00, "Base Address Register 3")
+ BAR4 = Param.UInt32(0x00, "Base Address Register 4")
+ BAR5 = Param.UInt32(0x00, "Base Address Register 5")
+ BAR0Size = Param.MemorySize32('0B', "Base Address Register 0 Size")
+ BAR1Size = Param.MemorySize32('0B', "Base Address Register 1 Size")
+ BAR2Size = Param.MemorySize32('0B', "Base Address Register 2 Size")
+ BAR3Size = Param.MemorySize32('0B', "Base Address Register 3 Size")
+ BAR4Size = Param.MemorySize32('0B', "Base Address Register 4 Size")
+ BAR5Size = Param.MemorySize32('0B', "Base Address Register 5 Size")
+ BAR0LegacyIO = Param.Bool(False, "Whether BAR0 is hardwired legacy IO")
+ BAR1LegacyIO = Param.Bool(False, "Whether BAR1 is hardwired legacy IO")
+ BAR2LegacyIO = Param.Bool(False, "Whether BAR2 is hardwired legacy IO")
+ BAR3LegacyIO = Param.Bool(False, "Whether BAR3 is hardwired legacy IO")
+ BAR4LegacyIO = Param.Bool(False, "Whether BAR4 is hardwired legacy IO")
+ BAR5LegacyIO = Param.Bool(False, "Whether BAR5 is hardwired legacy IO")
+ LegacyIOBase = Param.Addr(0x0, "Base Address for Legacy IO")
+
+ CardbusCIS = Param.UInt32(0x00, "Cardbus Card Information Structure")
+ SubsystemID = Param.UInt16(0x00, "Subsystem ID")
+ SubsystemVendorID = Param.UInt16(0x00, "Subsystem Vendor ID")
+ ExpansionROM = Param.UInt32(0x00, "Expansion ROM Base Address")
+ CapabilityPtr = Param.UInt8(0x00, "Capability List Pointer offset")
+ InterruptLine = Param.UInt8(0x00, "Interrupt Line")
+ InterruptPin = Param.UInt8(0x00, "Interrupt Pin")
+ MaximumLatency = Param.UInt8(0x00, "Maximum Latency")
+ MinimumGrant = Param.UInt8(0x00, "Minimum Grant")
+
+ # Capabilities List structures for PCIe devices
+ # PMCAP - PCI Power Management Capability
+ PMCAPBaseOffset = \
+ Param.UInt8(0x00, "Base offset of PMCAP in PCI Config space")
+ PMCAPNextCapability = \
+ Param.UInt8(0x00, "Pointer to next capability block")
+ PMCAPCapId = \
+ Param.UInt8(0x00, "Specifies this is the Power Management capability")
+ PMCAPCapabilities = \
+ Param.UInt16(0x0000, "PCI Power Management Capabilities Register")
+ PMCAPCtrlStatus = \
+ Param.UInt16(0x0000, "PCI Power Management Control and Status")
+
+ # MSICAP - Message Signaled Interrupt Capability
+ MSICAPBaseOffset = \
+ Param.UInt8(0x00, "Base offset of MSICAP in PCI Config space")
+ MSICAPNextCapability = \
+ Param.UInt8(0x00, "Pointer to next capability block")
+ MSICAPCapId = Param.UInt8(0x00, "Specifies this is the MSI Capability")
+ MSICAPMsgCtrl = Param.UInt16(0x0000, "MSI Message Control")
+ MSICAPMsgAddr = Param.UInt32(0x00000000, "MSI Message Address")
+ MSICAPMsgUpperAddr = Param.UInt32(0x00000000, "MSI Message Upper Address")
+ MSICAPMsgData = Param.UInt16(0x0000, "MSI Message Data")
+ MSICAPMaskBits = Param.UInt32(0x00000000, "MSI Interrupt Mask Bits")
+ MSICAPPendingBits = Param.UInt32(0x00000000, "MSI Pending Bits")
+
+ # MSIXCAP - MSI-X Capability
+ MSIXCAPBaseOffset = \
+ Param.UInt8(0x00, "Base offset of MSIXCAP in PCI Config space")
+ MSIXCAPNextCapability = \
+ Param.UInt8(0x00, "Pointer to next capability block")
+ MSIXCAPCapId = Param.UInt8(0x00, "Specifices this the MSI-X Capability")
+ MSIXMsgCtrl = Param.UInt16(0x0000, "MSI-X Message Control")
+ MSIXTableOffset = \
+ Param.UInt32(0x00000000, "MSI-X Table Offset and Table BIR")
+ MSIXPbaOffset = Param.UInt32(0x00000000, "MSI-X PBA Offset and PBA BIR")
+
+ # PXCAP - PCI Express Capability
+ PXCAPBaseOffset = \
+ Param.UInt8(0x00, "Base offset of PXCAP in PCI Config space")
+ PXCAPNextCapability = Param.UInt8(0x00, "Pointer to next capability block")
+ PXCAPCapId = Param.UInt8(0x00, "Specifies this is the PCIe Capability")
+ PXCAPCapabilities = Param.UInt16(0x0000, "PCIe Capabilities")
+ PXCAPDevCapabilities = Param.UInt32(0x00000000, "PCIe Device Capabilities")
+ PXCAPDevCtrl = Param.UInt16(0x0000, "PCIe Device Control")
+ PXCAPDevStatus = Param.UInt16(0x0000, "PCIe Device Status")
+ PXCAPLinkCap = Param.UInt32(0x00000000, "PCIe Link Capabilities")
+ PXCAPLinkCtrl = Param.UInt16(0x0000, "PCIe Link Control")
+ PXCAPLinkStatus = Param.UInt16(0x0000, "PCIe Link Status")
+ PXCAPDevCap2 = Param.UInt32(0x00000000, "PCIe Device Capabilities 2")
+ PXCAPDevCtrl2 = Param.UInt32(0x00000000, "PCIe Device Control 2")
# unmodified and in its entirety in all distributions of the software,
# modified or unmodified, in source code or in binary form.
#
+# Copyright (c) 2006 The Regents of The University of Michigan
+# All rights reserved.
+#
# 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
# (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
+# Authors: Steve Reinhardt
+# Gabe Black
+# Andreas Sandberg
Import('*')
if env['TARGET_ISA'] == 'null':
Return()
+SimObject('PciDevice.py')
+Source('device.cc')
+DebugFlag('PciDevice')
+
SimObject('PciHost.py')
Source('host.cc')
-
DebugFlag('PciHost')
+
--- /dev/null
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * 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: Ali Saidi
+ * Andrew Schultz
+ * Miguel Serrano
+ */
+
+/* @file
+ * A single PCI device configuration space entry.
+ */
+
+#include "dev/pci/device.hh"
+
+#include <list>
+#include <string>
+#include <vector>
+
+#include "base/inifile.hh"
+#include "base/intmath.hh"
+#include "base/misc.hh"
+#include "base/str.hh"
+#include "base/trace.hh"
+#include "debug/PciDevice.hh"
+#include "mem/packet.hh"
+#include "mem/packet_access.hh"
+#include "sim/byteswap.hh"
+#include "sim/core.hh"
+
+
+PciDevice::PciDevice(const PciDeviceParams *p)
+ : DmaDevice(p),
+ _busAddr(p->pci_bus, p->pci_dev, p->pci_func),
+ PMCAP_BASE(p->PMCAPBaseOffset),
+ PMCAP_ID_OFFSET(p->PMCAPBaseOffset+PMCAP_ID),
+ PMCAP_PC_OFFSET(p->PMCAPBaseOffset+PMCAP_PC),
+ PMCAP_PMCS_OFFSET(p->PMCAPBaseOffset+PMCAP_PMCS),
+ MSICAP_BASE(p->MSICAPBaseOffset),
+ MSIXCAP_BASE(p->MSIXCAPBaseOffset),
+ MSIXCAP_ID_OFFSET(p->MSIXCAPBaseOffset+MSIXCAP_ID),
+ MSIXCAP_MXC_OFFSET(p->MSIXCAPBaseOffset+MSIXCAP_MXC),
+ MSIXCAP_MTAB_OFFSET(p->MSIXCAPBaseOffset+MSIXCAP_MTAB),
+ MSIXCAP_MPBA_OFFSET(p->MSIXCAPBaseOffset+MSIXCAP_MPBA),
+ PXCAP_BASE(p->PXCAPBaseOffset),
+
+ hostInterface(p->host->registerDevice(this, _busAddr,
+ (PciIntPin)p->InterruptPin)),
+ pioDelay(p->pio_latency),
+ configDelay(p->config_latency)
+{
+ fatal_if(p->InterruptPin >= 5,
+ "Invalid PCI interrupt '%i' specified.", p->InterruptPin);
+
+ config.vendor = htole(p->VendorID);
+ config.device = htole(p->DeviceID);
+ config.command = htole(p->Command);
+ config.status = htole(p->Status);
+ config.revision = htole(p->Revision);
+ config.progIF = htole(p->ProgIF);
+ config.subClassCode = htole(p->SubClassCode);
+ config.classCode = htole(p->ClassCode);
+ config.cacheLineSize = htole(p->CacheLineSize);
+ config.latencyTimer = htole(p->LatencyTimer);
+ config.headerType = htole(p->HeaderType);
+ config.bist = htole(p->BIST);
+
+ config.baseAddr[0] = htole(p->BAR0);
+ config.baseAddr[1] = htole(p->BAR1);
+ config.baseAddr[2] = htole(p->BAR2);
+ config.baseAddr[3] = htole(p->BAR3);
+ config.baseAddr[4] = htole(p->BAR4);
+ config.baseAddr[5] = htole(p->BAR5);
+ config.cardbusCIS = htole(p->CardbusCIS);
+ config.subsystemVendorID = htole(p->SubsystemVendorID);
+ config.subsystemID = htole(p->SubsystemID);
+ config.expansionROM = htole(p->ExpansionROM);
+ config.capabilityPtr = htole(p->CapabilityPtr);
+ // Zero out the 7 bytes of reserved space in the PCI Config space register.
+ bzero(config.reserved, 7*sizeof(uint8_t));
+ config.interruptLine = htole(p->InterruptLine);
+ config.interruptPin = htole(p->InterruptPin);
+ config.minimumGrant = htole(p->MinimumGrant);
+ config.maximumLatency = htole(p->MaximumLatency);
+
+ // Initialize the capability lists
+ // These structs are bitunions, meaning the data is stored in host
+ // endianess and must be converted to Little Endian when accessed
+ // by the guest
+ // PMCAP
+ pmcap.pid = (uint16_t)p->PMCAPCapId; // pid.cid
+ pmcap.pid |= (uint16_t)p->PMCAPNextCapability << 8; //pid.next
+ pmcap.pc = p->PMCAPCapabilities;
+ pmcap.pmcs = p->PMCAPCtrlStatus;
+
+ // MSICAP
+ msicap.mid = (uint16_t)p->MSICAPCapId; //mid.cid
+ msicap.mid |= (uint16_t)p->MSICAPNextCapability << 8; //mid.next
+ msicap.mc = p->MSICAPMsgCtrl;
+ msicap.ma = p->MSICAPMsgAddr;
+ msicap.mua = p->MSICAPMsgUpperAddr;
+ msicap.md = p->MSICAPMsgData;
+ msicap.mmask = p->MSICAPMaskBits;
+ msicap.mpend = p->MSICAPPendingBits;
+
+ // MSIXCAP
+ msixcap.mxid = (uint16_t)p->MSIXCAPCapId; //mxid.cid
+ msixcap.mxid |= (uint16_t)p->MSIXCAPNextCapability << 8; //mxid.next
+ msixcap.mxc = p->MSIXMsgCtrl;
+ msixcap.mtab = p->MSIXTableOffset;
+ msixcap.mpba = p->MSIXPbaOffset;
+
+ // allocate MSIX structures if MSIXCAP_BASE
+ // indicates the MSIXCAP is being used by having a
+ // non-zero base address.
+ // The MSIX tables are stored by the guest in
+ // little endian byte-order as according the
+ // PCIe specification. Make sure to take the proper
+ // actions when manipulating these tables on the host
+ uint16_t msixcap_mxc_ts = msixcap.mxc & 0x07ff;
+ if (MSIXCAP_BASE != 0x0) {
+ int msix_vecs = msixcap_mxc_ts + 1;
+ MSIXTable tmp1 = {{0UL,0UL,0UL,0UL}};
+ msix_table.resize(msix_vecs, tmp1);
+
+ MSIXPbaEntry tmp2 = {0};
+ int pba_size = msix_vecs / MSIXVECS_PER_PBA;
+ if ((msix_vecs % MSIXVECS_PER_PBA) > 0) {
+ pba_size++;
+ }
+ msix_pba.resize(pba_size, tmp2);
+ }
+ MSIX_TABLE_OFFSET = msixcap.mtab & 0xfffffffc;
+ MSIX_TABLE_END = MSIX_TABLE_OFFSET +
+ (msixcap_mxc_ts + 1) * sizeof(MSIXTable);
+ MSIX_PBA_OFFSET = msixcap.mpba & 0xfffffffc;
+ MSIX_PBA_END = MSIX_PBA_OFFSET +
+ ((msixcap_mxc_ts + 1) / MSIXVECS_PER_PBA)
+ * sizeof(MSIXPbaEntry);
+ if (((msixcap_mxc_ts + 1) % MSIXVECS_PER_PBA) > 0) {
+ MSIX_PBA_END += sizeof(MSIXPbaEntry);
+ }
+
+ // PXCAP
+ pxcap.pxid = (uint16_t)p->PXCAPCapId; //pxid.cid
+ pxcap.pxid |= (uint16_t)p->PXCAPNextCapability << 8; //pxid.next
+ pxcap.pxcap = p->PXCAPCapabilities;
+ pxcap.pxdcap = p->PXCAPDevCapabilities;
+ pxcap.pxdc = p->PXCAPDevCtrl;
+ pxcap.pxds = p->PXCAPDevStatus;
+ pxcap.pxlcap = p->PXCAPLinkCap;
+ pxcap.pxlc = p->PXCAPLinkCtrl;
+ pxcap.pxls = p->PXCAPLinkStatus;
+ pxcap.pxdcap2 = p->PXCAPDevCap2;
+ pxcap.pxdc2 = p->PXCAPDevCtrl2;
+
+ BARSize[0] = p->BAR0Size;
+ BARSize[1] = p->BAR1Size;
+ BARSize[2] = p->BAR2Size;
+ BARSize[3] = p->BAR3Size;
+ BARSize[4] = p->BAR4Size;
+ BARSize[5] = p->BAR5Size;
+
+ legacyIO[0] = p->BAR0LegacyIO;
+ legacyIO[1] = p->BAR1LegacyIO;
+ legacyIO[2] = p->BAR2LegacyIO;
+ legacyIO[3] = p->BAR3LegacyIO;
+ legacyIO[4] = p->BAR4LegacyIO;
+ legacyIO[5] = p->BAR5LegacyIO;
+
+ for (int i = 0; i < 6; ++i) {
+ if (legacyIO[i]) {
+ BARAddrs[i] = p->LegacyIOBase + letoh(config.baseAddr[i]);
+ config.baseAddr[i] = 0;
+ } else {
+ BARAddrs[i] = 0;
+ uint32_t barsize = BARSize[i];
+ if (barsize != 0 && !isPowerOf2(barsize)) {
+ fatal("BAR %d size %d is not a power of 2\n", i, BARSize[i]);
+ }
+ }
+ }
+}
+
+Tick
+PciDevice::readConfig(PacketPtr pkt)
+{
+ int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
+
+ /* Return 0 for accesses to unimplemented PCI configspace areas */
+ if (offset >= PCI_DEVICE_SPECIFIC &&
+ offset < PCI_CONFIG_SIZE) {
+ warn_once("Device specific PCI config space "
+ "not implemented for %s!\n", this->name());
+ switch (pkt->getSize()) {
+ case sizeof(uint8_t):
+ pkt->set<uint8_t>(0);
+ break;
+ case sizeof(uint16_t):
+ pkt->set<uint16_t>(0);
+ break;
+ case sizeof(uint32_t):
+ pkt->set<uint32_t>(0);
+ break;
+ default:
+ panic("invalid access size(?) for PCI configspace!\n");
+ }
+ } else if (offset > PCI_CONFIG_SIZE) {
+ panic("Out-of-range access to PCI config space!\n");
+ }
+
+ switch (pkt->getSize()) {
+ case sizeof(uint8_t):
+ pkt->set<uint8_t>(config.data[offset]);
+ DPRINTF(PciDevice,
+ "readConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
+ _busAddr.dev, _busAddr.func, offset,
+ (uint32_t)pkt->get<uint8_t>());
+ break;
+ case sizeof(uint16_t):
+ pkt->set<uint16_t>(*(uint16_t*)&config.data[offset]);
+ DPRINTF(PciDevice,
+ "readConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
+ _busAddr.dev, _busAddr.func, offset,
+ (uint32_t)pkt->get<uint16_t>());
+ break;
+ case sizeof(uint32_t):
+ pkt->set<uint32_t>(*(uint32_t*)&config.data[offset]);
+ DPRINTF(PciDevice,
+ "readConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
+ _busAddr.dev, _busAddr.func, offset,
+ (uint32_t)pkt->get<uint32_t>());
+ break;
+ default:
+ panic("invalid access size(?) for PCI configspace!\n");
+ }
+ pkt->makeAtomicResponse();
+ return configDelay;
+
+}
+
+AddrRangeList
+PciDevice::getAddrRanges() const
+{
+ AddrRangeList ranges;
+ int x = 0;
+ for (x = 0; x < 6; x++)
+ if (BARAddrs[x] != 0)
+ ranges.push_back(RangeSize(BARAddrs[x],BARSize[x]));
+ return ranges;
+}
+
+Tick
+PciDevice::writeConfig(PacketPtr pkt)
+{
+ int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
+
+ /* No effect if we write to config space that is not implemented*/
+ if (offset >= PCI_DEVICE_SPECIFIC &&
+ offset < PCI_CONFIG_SIZE) {
+ warn_once("Device specific PCI config space "
+ "not implemented for %s!\n", this->name());
+ switch (pkt->getSize()) {
+ case sizeof(uint8_t):
+ case sizeof(uint16_t):
+ case sizeof(uint32_t):
+ break;
+ default:
+ panic("invalid access size(?) for PCI configspace!\n");
+ }
+ } else if (offset > PCI_CONFIG_SIZE) {
+ panic("Out-of-range access to PCI config space!\n");
+ }
+
+ switch (pkt->getSize()) {
+ case sizeof(uint8_t):
+ switch (offset) {
+ case PCI0_INTERRUPT_LINE:
+ config.interruptLine = pkt->get<uint8_t>();
+ break;
+ case PCI_CACHE_LINE_SIZE:
+ config.cacheLineSize = pkt->get<uint8_t>();
+ break;
+ case PCI_LATENCY_TIMER:
+ config.latencyTimer = pkt->get<uint8_t>();
+ break;
+ /* Do nothing for these read-only registers */
+ case PCI0_INTERRUPT_PIN:
+ case PCI0_MINIMUM_GRANT:
+ case PCI0_MAXIMUM_LATENCY:
+ case PCI_CLASS_CODE:
+ case PCI_REVISION_ID:
+ break;
+ default:
+ panic("writing to a read only register");
+ }
+ DPRINTF(PciDevice,
+ "writeConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
+ _busAddr.dev, _busAddr.func, offset,
+ (uint32_t)pkt->get<uint8_t>());
+ break;
+ case sizeof(uint16_t):
+ switch (offset) {
+ case PCI_COMMAND:
+ config.command = pkt->get<uint8_t>();
+ break;
+ case PCI_STATUS:
+ config.status = pkt->get<uint8_t>();
+ break;
+ case PCI_CACHE_LINE_SIZE:
+ config.cacheLineSize = pkt->get<uint8_t>();
+ break;
+ default:
+ panic("writing to a read only register");
+ }
+ DPRINTF(PciDevice,
+ "writeConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
+ _busAddr.dev, _busAddr.func, offset,
+ (uint32_t)pkt->get<uint16_t>());
+ break;
+ case sizeof(uint32_t):
+ switch (offset) {
+ case PCI0_BASE_ADDR0:
+ case PCI0_BASE_ADDR1:
+ case PCI0_BASE_ADDR2:
+ case PCI0_BASE_ADDR3:
+ case PCI0_BASE_ADDR4:
+ case PCI0_BASE_ADDR5:
+ {
+ int barnum = BAR_NUMBER(offset);
+
+ if (!legacyIO[barnum]) {
+ // convert BAR values to host endianness
+ uint32_t he_old_bar = letoh(config.baseAddr[barnum]);
+ uint32_t he_new_bar = letoh(pkt->get<uint32_t>());
+
+ uint32_t bar_mask =
+ BAR_IO_SPACE(he_old_bar) ? BAR_IO_MASK : BAR_MEM_MASK;
+
+ // Writing 0xffffffff to a BAR tells the card to set the
+ // value of the bar to a bitmask indicating the size of
+ // memory it needs
+ if (he_new_bar == 0xffffffff) {
+ he_new_bar = ~(BARSize[barnum] - 1);
+ } else {
+ // does it mean something special to write 0 to a BAR?
+ he_new_bar &= ~bar_mask;
+ if (he_new_bar) {
+ BARAddrs[barnum] = BAR_IO_SPACE(he_old_bar) ?
+ hostInterface.pioAddr(he_new_bar) :
+ hostInterface.memAddr(he_new_bar);
+ pioPort.sendRangeChange();
+ }
+ }
+ config.baseAddr[barnum] = htole((he_new_bar & ~bar_mask) |
+ (he_old_bar & bar_mask));
+ }
+ }
+ break;
+
+ case PCI0_ROM_BASE_ADDR:
+ if (letoh(pkt->get<uint32_t>()) == 0xfffffffe)
+ config.expansionROM = htole((uint32_t)0xffffffff);
+ else
+ config.expansionROM = pkt->get<uint32_t>();
+ break;
+
+ case PCI_COMMAND:
+ // This could also clear some of the error bits in the Status
+ // register. However they should never get set, so lets ignore
+ // it for now
+ config.command = pkt->get<uint32_t>();
+ break;
+
+ default:
+ DPRINTF(PciDevice, "Writing to a read only register");
+ }
+ DPRINTF(PciDevice,
+ "writeConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
+ _busAddr.dev, _busAddr.func, offset,
+ (uint32_t)pkt->get<uint32_t>());
+ break;
+ default:
+ panic("invalid access size(?) for PCI configspace!\n");
+ }
+ pkt->makeAtomicResponse();
+ return configDelay;
+}
+
+void
+PciDevice::serialize(CheckpointOut &cp) const
+{
+ SERIALIZE_ARRAY(BARSize, sizeof(BARSize) / sizeof(BARSize[0]));
+ SERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0]));
+ SERIALIZE_ARRAY(config.data, sizeof(config.data) / sizeof(config.data[0]));
+
+ // serialize the capability list registers
+ paramOut(cp, csprintf("pmcap.pid"), uint16_t(pmcap.pid));
+ paramOut(cp, csprintf("pmcap.pc"), uint16_t(pmcap.pc));
+ paramOut(cp, csprintf("pmcap.pmcs"), uint16_t(pmcap.pmcs));
+
+ paramOut(cp, csprintf("msicap.mid"), uint16_t(msicap.mid));
+ paramOut(cp, csprintf("msicap.mc"), uint16_t(msicap.mc));
+ paramOut(cp, csprintf("msicap.ma"), uint32_t(msicap.ma));
+ SERIALIZE_SCALAR(msicap.mua);
+ paramOut(cp, csprintf("msicap.md"), uint16_t(msicap.md));
+ SERIALIZE_SCALAR(msicap.mmask);
+ SERIALIZE_SCALAR(msicap.mpend);
+
+ paramOut(cp, csprintf("msixcap.mxid"), uint16_t(msixcap.mxid));
+ paramOut(cp, csprintf("msixcap.mxc"), uint16_t(msixcap.mxc));
+ paramOut(cp, csprintf("msixcap.mtab"), uint32_t(msixcap.mtab));
+ paramOut(cp, csprintf("msixcap.mpba"), uint32_t(msixcap.mpba));
+
+ // Only serialize if we have a non-zero base address
+ if (MSIXCAP_BASE != 0x0) {
+ uint16_t msixcap_mxc_ts = msixcap.mxc & 0x07ff;
+ int msix_array_size = msixcap_mxc_ts + 1;
+ int pba_array_size = msix_array_size/MSIXVECS_PER_PBA;
+ if ((msix_array_size % MSIXVECS_PER_PBA) > 0) {
+ pba_array_size++;
+ }
+
+ SERIALIZE_SCALAR(msix_array_size);
+ SERIALIZE_SCALAR(pba_array_size);
+
+ for (int i = 0; i < msix_array_size; i++) {
+ paramOut(cp, csprintf("msix_table[%d].addr_lo", i),
+ msix_table[i].fields.addr_lo);
+ paramOut(cp, csprintf("msix_table[%d].addr_hi", i),
+ msix_table[i].fields.addr_hi);
+ paramOut(cp, csprintf("msix_table[%d].msg_data", i),
+ msix_table[i].fields.msg_data);
+ paramOut(cp, csprintf("msix_table[%d].vec_ctrl", i),
+ msix_table[i].fields.vec_ctrl);
+ }
+ for (int i = 0; i < pba_array_size; i++) {
+ paramOut(cp, csprintf("msix_pba[%d].bits", i),
+ msix_pba[i].bits);
+ }
+ }
+
+ paramOut(cp, csprintf("pxcap.pxid"), uint16_t(pxcap.pxid));
+ paramOut(cp, csprintf("pxcap.pxcap"), uint16_t(pxcap.pxcap));
+ paramOut(cp, csprintf("pxcap.pxdcap"), uint32_t(pxcap.pxdcap));
+ paramOut(cp, csprintf("pxcap.pxdc"), uint16_t(pxcap.pxdc));
+ paramOut(cp, csprintf("pxcap.pxds"), uint16_t(pxcap.pxds));
+ paramOut(cp, csprintf("pxcap.pxlcap"), uint32_t(pxcap.pxlcap));
+ paramOut(cp, csprintf("pxcap.pxlc"), uint16_t(pxcap.pxlc));
+ paramOut(cp, csprintf("pxcap.pxls"), uint16_t(pxcap.pxls));
+ paramOut(cp, csprintf("pxcap.pxdcap2"), uint32_t(pxcap.pxdcap2));
+ paramOut(cp, csprintf("pxcap.pxdc2"), uint32_t(pxcap.pxdc2));
+}
+
+void
+PciDevice::unserialize(CheckpointIn &cp)
+{
+ UNSERIALIZE_ARRAY(BARSize, sizeof(BARSize) / sizeof(BARSize[0]));
+ UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0]));
+ UNSERIALIZE_ARRAY(config.data,
+ sizeof(config.data) / sizeof(config.data[0]));
+
+ // unserialize the capability list registers
+ uint16_t tmp16;
+ uint32_t tmp32;
+ paramIn(cp, csprintf("pmcap.pid"), tmp16);
+ pmcap.pid = tmp16;
+ paramIn(cp, csprintf("pmcap.pc"), tmp16);
+ pmcap.pc = tmp16;
+ paramIn(cp, csprintf("pmcap.pmcs"), tmp16);
+ pmcap.pmcs = tmp16;
+
+ paramIn(cp, csprintf("msicap.mid"), tmp16);
+ msicap.mid = tmp16;
+ paramIn(cp, csprintf("msicap.mc"), tmp16);
+ msicap.mc = tmp16;
+ paramIn(cp, csprintf("msicap.ma"), tmp32);
+ msicap.ma = tmp32;
+ UNSERIALIZE_SCALAR(msicap.mua);
+ paramIn(cp, csprintf("msicap.md"), tmp16);;
+ msicap.md = tmp16;
+ UNSERIALIZE_SCALAR(msicap.mmask);
+ UNSERIALIZE_SCALAR(msicap.mpend);
+
+ paramIn(cp, csprintf("msixcap.mxid"), tmp16);
+ msixcap.mxid = tmp16;
+ paramIn(cp, csprintf("msixcap.mxc"), tmp16);
+ msixcap.mxc = tmp16;
+ paramIn(cp, csprintf("msixcap.mtab"), tmp32);
+ msixcap.mtab = tmp32;
+ paramIn(cp, csprintf("msixcap.mpba"), tmp32);
+ msixcap.mpba = tmp32;
+
+ // Only allocate if MSIXCAP_BASE is not 0x0
+ if (MSIXCAP_BASE != 0x0) {
+ int msix_array_size;
+ int pba_array_size;
+
+ UNSERIALIZE_SCALAR(msix_array_size);
+ UNSERIALIZE_SCALAR(pba_array_size);
+
+ MSIXTable tmp1 = {{0UL, 0UL, 0UL, 0UL}};
+ msix_table.resize(msix_array_size, tmp1);
+
+ MSIXPbaEntry tmp2 = {0};
+ msix_pba.resize(pba_array_size, tmp2);
+
+ for (int i = 0; i < msix_array_size; i++) {
+ paramIn(cp, csprintf("msix_table[%d].addr_lo", i),
+ msix_table[i].fields.addr_lo);
+ paramIn(cp, csprintf("msix_table[%d].addr_hi", i),
+ msix_table[i].fields.addr_hi);
+ paramIn(cp, csprintf("msix_table[%d].msg_data", i),
+ msix_table[i].fields.msg_data);
+ paramIn(cp, csprintf("msix_table[%d].vec_ctrl", i),
+ msix_table[i].fields.vec_ctrl);
+ }
+ for (int i = 0; i < pba_array_size; i++) {
+ paramIn(cp, csprintf("msix_pba[%d].bits", i),
+ msix_pba[i].bits);
+ }
+ }
+
+ paramIn(cp, csprintf("pxcap.pxid"), tmp16);
+ pxcap.pxid = tmp16;
+ paramIn(cp, csprintf("pxcap.pxcap"), tmp16);
+ pxcap.pxcap = tmp16;
+ paramIn(cp, csprintf("pxcap.pxdcap"), tmp32);
+ pxcap.pxdcap = tmp32;
+ paramIn(cp, csprintf("pxcap.pxdc"), tmp16);
+ pxcap.pxdc = tmp16;
+ paramIn(cp, csprintf("pxcap.pxds"), tmp16);
+ pxcap.pxds = tmp16;
+ paramIn(cp, csprintf("pxcap.pxlcap"), tmp32);
+ pxcap.pxlcap = tmp32;
+ paramIn(cp, csprintf("pxcap.pxlc"), tmp16);
+ pxcap.pxlc = tmp16;
+ paramIn(cp, csprintf("pxcap.pxls"), tmp16);
+ pxcap.pxls = tmp16;
+ paramIn(cp, csprintf("pxcap.pxdcap2"), tmp32);
+ pxcap.pxdcap2 = tmp32;
+ paramIn(cp, csprintf("pxcap.pxdc2"), tmp32);
+ pxcap.pxdc2 = tmp32;
+ pioPort.sendRangeChange();
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2013 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.
+ *
+ * Copyright (c) 2004-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * 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: Ali Saidi
+ * Andrew Schultz
+ * Nathan Binkert
+ */
+
+/* @file
+ * Interface for devices using PCI configuration
+ */
+
+#ifndef __DEV_PCI_DEVICE_HH__
+#define __DEV_PCI_DEVICE_HH__
+
+#include <cstring>
+#include <vector>
+
+#include "dev/dma_device.hh"
+#include "dev/pci/host.hh"
+#include "dev/pci/pcireg.h"
+#include "params/PciDevice.hh"
+#include "sim/byteswap.hh"
+
+#define BAR_IO_MASK 0x3
+#define BAR_MEM_MASK 0xF
+#define BAR_IO_SPACE_BIT 0x1
+#define BAR_IO_SPACE(x) ((x) & BAR_IO_SPACE_BIT)
+#define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
+
+/**
+ * PCI device, base implementation is only config space.
+ */
+class PciDevice : public DmaDevice
+{
+ protected:
+ const PciBusAddr _busAddr;
+
+ /** The current config space. */
+ PCIConfig config;
+
+ /** The capability list structures and base addresses
+ * @{
+ */
+ const int PMCAP_BASE;
+ const int PMCAP_ID_OFFSET;
+ const int PMCAP_PC_OFFSET;
+ const int PMCAP_PMCS_OFFSET;
+ PMCAP pmcap;
+
+ const int MSICAP_BASE;
+ MSICAP msicap;
+
+ const int MSIXCAP_BASE;
+ const int MSIXCAP_ID_OFFSET;
+ const int MSIXCAP_MXC_OFFSET;
+ const int MSIXCAP_MTAB_OFFSET;
+ const int MSIXCAP_MPBA_OFFSET;
+ int MSIX_TABLE_OFFSET;
+ int MSIX_TABLE_END;
+ int MSIX_PBA_OFFSET;
+ int MSIX_PBA_END;
+ MSIXCAP msixcap;
+
+ const int PXCAP_BASE;
+ PXCAP pxcap;
+ /** @} */
+
+ /** MSIX Table and PBA Structures */
+ std::vector<MSIXTable> msix_table;
+ std::vector<MSIXPbaEntry> msix_pba;
+
+ /** The size of the BARs */
+ uint32_t BARSize[6];
+
+ /** The current address mapping of the BARs */
+ Addr BARAddrs[6];
+
+ /** Whether the BARs are really hardwired legacy IO locations. */
+ bool legacyIO[6];
+
+ /**
+ * Does the given address lie within the space mapped by the given
+ * base address register?
+ */
+ bool
+ isBAR(Addr addr, int bar) const
+ {
+ assert(bar >= 0 && bar < 6);
+ return BARAddrs[bar] <= addr && addr < BARAddrs[bar] + BARSize[bar];
+ }
+
+ /**
+ * Which base address register (if any) maps the given address?
+ * @return The BAR number (0-5 inclusive), or -1 if none.
+ */
+ int
+ getBAR(Addr addr)
+ {
+ for (int i = 0; i <= 5; ++i)
+ if (isBAR(addr, i))
+ return i;
+
+ return -1;
+ }
+
+ /**
+ * Which base address register (if any) maps the given address?
+ * @param addr The address to check.
+ * @retval bar The BAR number (0-5 inclusive),
+ * only valid if return value is true.
+ * @retval offs The offset from the base address,
+ * only valid if return value is true.
+ * @return True iff address maps to a base address register's region.
+ */
+ bool
+ getBAR(Addr addr, int &bar, Addr &offs)
+ {
+ int b = getBAR(addr);
+ if (b < 0)
+ return false;
+
+ offs = addr - BARAddrs[b];
+ bar = b;
+ return true;
+ }
+
+ public: // Host configuration interface
+ /**
+ * Write to the PCI config space data that is stored locally. This may be
+ * overridden by the device but at some point it will eventually call this
+ * for normal operations that it does not need to override.
+ * @param pkt packet containing the write the offset into config space
+ */
+ virtual Tick writeConfig(PacketPtr pkt);
+
+
+ /**
+ * Read from the PCI config space data that is stored locally. This may be
+ * overridden by the device but at some point it will eventually call this
+ * for normal operations that it does not need to override.
+ * @param pkt packet containing the write the offset into config space
+ */
+ virtual Tick readConfig(PacketPtr pkt);
+
+ protected:
+ PciHost::DeviceInterface hostInterface;
+
+ Tick pioDelay;
+ Tick configDelay;
+
+ public:
+ Addr pciToDma(Addr pci_addr) const {
+ return hostInterface.dmaAddr(pci_addr);
+ }
+
+ void intrPost() { hostInterface.postInt(); }
+ void intrClear() { hostInterface.clearInt(); }
+
+ uint8_t interruptLine() const { return letoh(config.interruptLine); }
+
+ /**
+ * Determine the address ranges that this device responds to.
+ *
+ * @return a list of non-overlapping address ranges
+ */
+ AddrRangeList getAddrRanges() const override;
+
+ /**
+ * Constructor for PCI Dev. This function copies data from the
+ * config file object PCIConfigData and registers the device with
+ * a PciHost object.
+ */
+ PciDevice(const PciDeviceParams *params);
+
+ /**
+ * Serialize this object to the given output stream.
+ * @param os The stream to serialize to.
+ */
+ void serialize(CheckpointOut &cp) const override;
+
+ /**
+ * Reconstruct the state of this object from a checkpoint.
+ * @param cp The checkpoint use.
+ * @param section The section name of this object
+ */
+ void unserialize(CheckpointIn &cp) override;
+
+ const PciBusAddr &busAddr() const { return _busAddr; }
+};
+#endif // __DEV_PCI_DEVICE_HH__
#include <utility>
#include "debug/PciHost.hh"
-#include "dev/pcidev.hh"
+#include "dev/pci/device.hh"
#include "dev/platform.hh"
#include "params/GenericPciHost.hh"
#include "params/PciHost.hh"
--- /dev/null
+/*
+ * Copyright (c) 2013 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.
+ *
+ * Copyright (c) 2001-2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * 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: Nathan Binkert
+ * Miguel Serrano
+ */
+
+/* @file
+ * Device register definitions for a device's PCI config space
+ */
+
+#ifndef __PCIREG_H__
+#define __PCIREG_H__
+
+#include <sys/types.h>
+
+#include "base/bitfield.hh"
+#include "base/bitunion.hh"
+
+union PCIConfig {
+ uint8_t data[64];
+
+ struct {
+ uint16_t vendor;
+ uint16_t device;
+ uint16_t command;
+ uint16_t status;
+ uint8_t revision;
+ uint8_t progIF;
+ uint8_t subClassCode;
+ uint8_t classCode;
+ uint8_t cacheLineSize;
+ uint8_t latencyTimer;
+ uint8_t headerType;
+ uint8_t bist;
+ uint32_t baseAddr[6];
+ uint32_t cardbusCIS;
+ uint16_t subsystemVendorID;
+ uint16_t subsystemID;
+ uint32_t expansionROM;
+ uint8_t capabilityPtr;
+ // Was 8 bytes in the legacy PCI spec, but to support PCIe
+ // this field is now 7 bytes with PCIe's addition of the
+ // capability list pointer.
+ uint8_t reserved[7];
+ uint8_t interruptLine;
+ uint8_t interruptPin;
+ uint8_t minimumGrant;
+ uint8_t maximumLatency;
+ };
+};
+
+// Common PCI offsets
+#define PCI_VENDOR_ID 0x00 // Vendor ID ro
+#define PCI_DEVICE_ID 0x02 // Device ID ro
+#define PCI_COMMAND 0x04 // Command rw
+#define PCI_STATUS 0x06 // Status rw
+#define PCI_REVISION_ID 0x08 // Revision ID ro
+#define PCI_CLASS_CODE 0x09 // Class Code ro
+#define PCI_SUB_CLASS_CODE 0x0A // Sub Class Code ro
+#define PCI_BASE_CLASS_CODE 0x0B // Base Class Code ro
+#define PCI_CACHE_LINE_SIZE 0x0C // Cache Line Size ro+
+#define PCI_LATENCY_TIMER 0x0D // Latency Timer ro+
+#define PCI_HEADER_TYPE 0x0E // Header Type ro
+#define PCI_BIST 0x0F // Built in self test rw
+
+// some pci command reg bitfields
+#define PCI_CMD_BME 0x04 // Bus master function enable
+#define PCI_CMD_MSE 0x02 // Memory Space Access enable
+#define PCI_CMD_IOSE 0x01 // I/O space enable
+
+// Type 0 PCI offsets
+#define PCI0_BASE_ADDR0 0x10 // Base Address 0 rw
+#define PCI0_BASE_ADDR1 0x14 // Base Address 1 rw
+#define PCI0_BASE_ADDR2 0x18 // Base Address 2 rw
+#define PCI0_BASE_ADDR3 0x1C // Base Address 3 rw
+#define PCI0_BASE_ADDR4 0x20 // Base Address 4 rw
+#define PCI0_BASE_ADDR5 0x24 // Base Address 5 rw
+#define PCI0_CIS 0x28 // CardBus CIS Pointer ro
+#define PCI0_SUB_VENDOR_ID 0x2C // Sub-Vendor ID ro
+#define PCI0_SUB_SYSTEM_ID 0x2E // Sub-System ID ro
+#define PCI0_ROM_BASE_ADDR 0x30 // Expansion ROM Base Address rw
+#define PCI0_CAP_PTR 0x34 // Capability list pointer ro
+#define PCI0_RESERVED 0x35
+#define PCI0_INTERRUPT_LINE 0x3C // Interrupt Line rw
+#define PCI0_INTERRUPT_PIN 0x3D // Interrupt Pin ro
+#define PCI0_MINIMUM_GRANT 0x3E // Maximum Grant ro
+#define PCI0_MAXIMUM_LATENCY 0x3F // Maximum Latency ro
+
+// Type 1 PCI offsets
+#define PCI1_BASE_ADDR0 0x10 // Base Address 0 rw
+#define PCI1_BASE_ADDR1 0x14 // Base Address 1 rw
+#define PCI1_PRI_BUS_NUM 0x18 // Primary Bus Number rw
+#define PCI1_SEC_BUS_NUM 0x19 // Secondary Bus Number rw
+#define PCI1_SUB_BUS_NUM 0x1A // Subordinate Bus Number rw
+#define PCI1_SEC_LAT_TIMER 0x1B // Secondary Latency Timer ro+
+#define PCI1_IO_BASE 0x1C // I/O Base rw
+#define PCI1_IO_LIMIT 0x1D // I/O Limit rw
+#define PCI1_SECONDARY_STATUS 0x1E // Secondary Status rw
+#define PCI1_MEM_BASE 0x20 // Memory Base rw
+#define PCI1_MEM_LIMIT 0x22 // Memory Limit rw
+#define PCI1_PRF_MEM_BASE 0x24 // Prefetchable Memory Base rw
+#define PCI1_PRF_MEM_LIMIT 0x26 // Prefetchable Memory Limit rw
+#define PCI1_PRF_BASE_UPPER 0x28 // Prefetchable Base Upper 32 rw
+#define PCI1_PRF_LIMIT_UPPER 0x2C // Prefetchable Limit Upper 32 rw
+#define PCI1_IO_BASE_UPPER 0x30 // I/O Base Upper 16 bits rw
+#define PCI1_IO_LIMIT_UPPER 0x32 // I/O Limit Upper 16 bits rw
+#define PCI1_RESERVED 0x34 // Reserved ro
+#define PCI1_ROM_BASE_ADDR 0x38 // Expansion ROM Base Address rw
+#define PCI1_INTR_LINE 0x3C // Interrupt Line rw
+#define PCI1_INTR_PIN 0x3D // Interrupt Pin ro
+#define PCI1_BRIDGE_CTRL 0x3E // Bridge Control rw
+
+// Device specific offsets
+#define PCI_DEVICE_SPECIFIC 0x40 // 192 bytes
+#define PCI_CONFIG_SIZE 0xFF
+
+// Some Vendor IDs
+#define PCI_VENDOR_DEC 0x1011
+#define PCI_VENDOR_NCR 0x101A
+#define PCI_VENDOR_QLOGIC 0x1077
+#define PCI_VENDOR_SIMOS 0x1291
+
+// Some Product IDs
+#define PCI_PRODUCT_DEC_PZA 0x0008
+#define PCI_PRODUCT_NCR_810 0x0001
+#define PCI_PRODUCT_QLOGIC_ISP1020 0x1020
+#define PCI_PRODUCT_SIMOS_SIMOS 0x1291
+#define PCI_PRODUCT_SIMOS_ETHER 0x1292
+
+/**
+ * PCIe capability list offsets internal to the entry.
+ * Actual offsets in the PCI config space are defined in
+ * the python files setting up the system.
+ */
+#define PMCAP_ID 0x00
+#define PMCAP_PC 0x02
+#define PMCAP_PMCS 0x04
+#define PMCAP_SIZE 0x06
+
+#define MSICAP_ID 0x00
+#define MSICAP_MC 0x02
+#define MSICAP_MA 0x04
+#define MSICAP_MUA 0x08
+#define MSICAP_MD 0x0C
+#define MSICAP_MMASK 0x10
+#define MSICAP_MPEND 0x14
+#define MSICAP_SIZE 0x18
+
+#define MSIXCAP_ID 0x00
+#define MSIXCAP_MXC 0x02
+#define MSIXCAP_MTAB 0x04
+#define MSIXCAP_MPBA 0x08
+#define MSIXCAP_SIZE 0x0C
+
+#define PXCAP_ID 0x00
+#define PXCAP_PXCAP 0x02
+#define PXCAP_PXDCAP 0x04
+#define PXCAP_PXDC 0x08
+#define PXCAP_PXDS 0x0A
+#define PXCAP_PXLCAP 0x0C
+#define PXCAP_PXLC 0x10
+#define PXCAP_PXLS 0x12
+#define PXCAP_PXDCAP2 0x24
+#define PXCAP_PXDC2 0x28
+#define PXCAP_SIZE 0x30
+
+/** @struct PMCAP
+ * Defines the Power Management capability register and all its associated
+ * bitfields for a PCIe device.
+ */
+union PMCAP {
+ uint8_t data[6];
+ struct {
+ uint16_t pid; /* 0:7 cid
+ * 8:15 next
+ */
+ uint16_t pc; /* 0:2 vs
+ * 3 pmec
+ * 4 reserved
+ * 5 dsi
+ * 6:8 auxc
+ * 9 d1s
+ * 10 d2s
+ * 11:15 psup
+ */
+ uint16_t pmcs; /* 0:1 ps
+ * 2 reserved
+ * 3 nsfrst
+ * 4:7 reserved
+ * 8 pmee
+ * 9:12 dse
+ * 13:14 dsc
+ * 15 pmes
+ */
+ };
+};
+
+/** @struct MSICAP
+ * Defines the MSI Capability register and its associated bitfields for
+ * the a PCI/PCIe device. Both the MSI capability and the MSIX capability
+ * can be filled in if a device model supports both, but only 1 of
+ * MSI/MSIX/INTx interrupt mode can be selected at a given time.
+ */
+union MSICAP {
+ uint8_t data[24];
+ struct {
+ uint16_t mid; /* 0:7 cid
+ * 8:15 next
+ */
+ uint16_t mc; /* 0 msie;
+ * 1:3 mmc;
+ * 4:6 mme;
+ * 7 c64;
+ * 8 pvm;
+ * 9:15 reserved;
+ */
+ uint32_t ma; /* 0:1 reserved
+ * 2:31 addr
+ */
+ uint32_t mua;
+ uint16_t md;
+ uint32_t mmask;
+ uint32_t mpend;
+ };
+};
+
+/** @struct MSIX
+ * Defines the MSI-X Capability register and its associated bitfields for
+ * a PCIe device.
+ */
+union MSIXCAP {
+ uint8_t data[12];
+ struct {
+ uint16_t mxid; /* 0:7 cid
+ * 8:15 next
+ */
+ uint16_t mxc; /* 0:10 ts;
+ * 11:13 reserved;
+ * 14 fm;
+ * 15 mxe;
+ */
+ uint32_t mtab; /* 0:2 tbir;
+ * 3:31 to;
+ */
+ uint32_t mpba; /* 0:2 pbir;
+ * 3:31> pbao;
+ */
+ };
+};
+
+union MSIXTable {
+ struct {
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+ uint32_t msg_data;
+ uint32_t vec_ctrl;
+ } fields;
+ uint32_t data[4];
+};
+
+#define MSIXVECS_PER_PBA 64
+struct MSIXPbaEntry {
+ uint64_t bits;
+};
+
+/** @struct PXCAP
+ * Defines the PCI Express capability register and its associated bitfields
+ * for a PCIe device.
+ */
+struct PXCAP {
+ uint8_t data[48];
+ struct {
+ uint16_t pxid; /* 0:7 cid
+ * 8:15 next
+ */
+ uint16_t pxcap; /* 0:3 ver;
+ * 4:7 dpt;
+ * 8 si;
+ * 9:13 imn;
+ * 14:15 reserved;
+ */
+ uint32_t pxdcap; /* 0:2 mps;
+ * 3:4 pfs;
+ * 5 etfs;
+ * 6:8 l0sl;
+ * 9:11 l1l;
+ * 12:14 reserved;
+ * 15 rer;
+ * 16:17 reserved;
+ * 18:25 csplv;
+ * 26:27 cspls;
+ * 28 flrc;
+ * 29:31 reserved;
+ */
+ uint16_t pxdc; /* 0 cere;
+ * 1 nfere;
+ * 2 fere;
+ * 3 urre;
+ * 4 ero;
+ * 5:7 mps;
+ * 8 ete;
+ * 9 pfe;
+ * 10 appme;
+ * 11 ens;
+ * 12:14 mrrs;
+ * 15 func_reset;
+ */
+ uint16_t pxds; /* 0 ced;
+ * 1 nfed;
+ * 2 fed;
+ * 3 urd;
+ * 4 apd;
+ * 5 tp;
+ * 6:15 reserved;
+ */
+ uint32_t pxlcap; /* 0:3 sls;
+ * 4:9 mlw;
+ * 10:11 aspms;
+ * 12:14 l0sel;
+ * 15:17 l1el;
+ * 18 cpm;
+ * 19 sderc;
+ * 20 dllla;
+ * 21 lbnc;
+ * 22:23 reserved;
+ * 24:31 pn;
+ */
+ uint16_t pxlc; /* 0:1 aspmc;
+ * 2 reserved;
+ * 3 rcb;
+ * 4:5 reserved;
+ * 6 ccc;
+ * 7 es;
+ * 8 ecpm;
+ * 9 hawd;
+ * 10:15 reserved;
+ */
+ uint16_t pxls; /* 0:3 cls;
+ * 4:9 nlw;
+ * 10:11 reserved;
+ * 12 slot_clk_config;
+ * 13:15 reserved;
+ */
+ uint8_t reserved[20];
+ uint32_t pxdcap2; /* 0:3 ctrs;
+ * 4 ctds;
+ * 5 arifs;
+ * 6 aors;
+ * 7 aocs32;
+ * 8 aocs64;
+ * 9 ccs128;
+ * 10 nprpr;
+ * 11 ltrs;
+ * 12:13 tphcs;
+ * 14:17 reserved;
+ * 18:19 obffs;
+ * 20 effs;
+ * 21 eetps;
+ * 22:23 meetp;
+ * 24:31 reserved;
+ */
+ uint32_t pxdc2; /* 0:3 ctv;
+ * 4 ctd;
+ * 5:9 reserved;
+ * 10 ltrme;
+ * 11:12 reserved;
+ * 13:14 obffe;
+ * 15:31 reserved;
+ */
+ };
+};
+#endif // __PCIREG_H__
+++ /dev/null
-/*
- * Copyright (c) 2013, 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.
- *
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
- * All rights reserved.
- *
- * 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: Ali Saidi
- * Andrew Schultz
- * Miguel Serrano
- */
-
-/* @file
- * A single PCI device configuration space entry.
- */
-
-#include <list>
-#include <string>
-#include <vector>
-
-#include "base/inifile.hh"
-#include "base/intmath.hh"
-#include "base/misc.hh"
-#include "base/str.hh"
-#include "base/trace.hh"
-#include "debug/PCIDEV.hh"
-#include "dev/pcidev.hh"
-#include "mem/packet.hh"
-#include "mem/packet_access.hh"
-#include "sim/byteswap.hh"
-#include "sim/core.hh"
-
-
-PciDevice::PciDevice(const PciDeviceParams *p)
- : DmaDevice(p),
- _busAddr(p->pci_bus, p->pci_dev, p->pci_func),
- PMCAP_BASE(p->PMCAPBaseOffset),
- PMCAP_ID_OFFSET(p->PMCAPBaseOffset+PMCAP_ID),
- PMCAP_PC_OFFSET(p->PMCAPBaseOffset+PMCAP_PC),
- PMCAP_PMCS_OFFSET(p->PMCAPBaseOffset+PMCAP_PMCS),
- MSICAP_BASE(p->MSICAPBaseOffset),
- MSIXCAP_BASE(p->MSIXCAPBaseOffset),
- MSIXCAP_ID_OFFSET(p->MSIXCAPBaseOffset+MSIXCAP_ID),
- MSIXCAP_MXC_OFFSET(p->MSIXCAPBaseOffset+MSIXCAP_MXC),
- MSIXCAP_MTAB_OFFSET(p->MSIXCAPBaseOffset+MSIXCAP_MTAB),
- MSIXCAP_MPBA_OFFSET(p->MSIXCAPBaseOffset+MSIXCAP_MPBA),
- PXCAP_BASE(p->PXCAPBaseOffset),
-
- hostInterface(p->host->registerDevice(this, _busAddr,
- (PciIntPin)p->InterruptPin)),
- pioDelay(p->pio_latency),
- configDelay(p->config_latency)
-{
- fatal_if(p->InterruptPin >= 5,
- "Invalid PCI interrupt '%i' specified.", p->InterruptPin);
-
- config.vendor = htole(p->VendorID);
- config.device = htole(p->DeviceID);
- config.command = htole(p->Command);
- config.status = htole(p->Status);
- config.revision = htole(p->Revision);
- config.progIF = htole(p->ProgIF);
- config.subClassCode = htole(p->SubClassCode);
- config.classCode = htole(p->ClassCode);
- config.cacheLineSize = htole(p->CacheLineSize);
- config.latencyTimer = htole(p->LatencyTimer);
- config.headerType = htole(p->HeaderType);
- config.bist = htole(p->BIST);
-
- config.baseAddr[0] = htole(p->BAR0);
- config.baseAddr[1] = htole(p->BAR1);
- config.baseAddr[2] = htole(p->BAR2);
- config.baseAddr[3] = htole(p->BAR3);
- config.baseAddr[4] = htole(p->BAR4);
- config.baseAddr[5] = htole(p->BAR5);
- config.cardbusCIS = htole(p->CardbusCIS);
- config.subsystemVendorID = htole(p->SubsystemVendorID);
- config.subsystemID = htole(p->SubsystemID);
- config.expansionROM = htole(p->ExpansionROM);
- config.capabilityPtr = htole(p->CapabilityPtr);
- // Zero out the 7 bytes of reserved space in the PCI Config space register.
- bzero(config.reserved, 7*sizeof(uint8_t));
- config.interruptLine = htole(p->InterruptLine);
- config.interruptPin = htole(p->InterruptPin);
- config.minimumGrant = htole(p->MinimumGrant);
- config.maximumLatency = htole(p->MaximumLatency);
-
- // Initialize the capability lists
- // These structs are bitunions, meaning the data is stored in host
- // endianess and must be converted to Little Endian when accessed
- // by the guest
- // PMCAP
- pmcap.pid = (uint16_t)p->PMCAPCapId; // pid.cid
- pmcap.pid |= (uint16_t)p->PMCAPNextCapability << 8; //pid.next
- pmcap.pc = p->PMCAPCapabilities;
- pmcap.pmcs = p->PMCAPCtrlStatus;
-
- // MSICAP
- msicap.mid = (uint16_t)p->MSICAPCapId; //mid.cid
- msicap.mid |= (uint16_t)p->MSICAPNextCapability << 8; //mid.next
- msicap.mc = p->MSICAPMsgCtrl;
- msicap.ma = p->MSICAPMsgAddr;
- msicap.mua = p->MSICAPMsgUpperAddr;
- msicap.md = p->MSICAPMsgData;
- msicap.mmask = p->MSICAPMaskBits;
- msicap.mpend = p->MSICAPPendingBits;
-
- // MSIXCAP
- msixcap.mxid = (uint16_t)p->MSIXCAPCapId; //mxid.cid
- msixcap.mxid |= (uint16_t)p->MSIXCAPNextCapability << 8; //mxid.next
- msixcap.mxc = p->MSIXMsgCtrl;
- msixcap.mtab = p->MSIXTableOffset;
- msixcap.mpba = p->MSIXPbaOffset;
-
- // allocate MSIX structures if MSIXCAP_BASE
- // indicates the MSIXCAP is being used by having a
- // non-zero base address.
- // The MSIX tables are stored by the guest in
- // little endian byte-order as according the
- // PCIe specification. Make sure to take the proper
- // actions when manipulating these tables on the host
- uint16_t msixcap_mxc_ts = msixcap.mxc & 0x07ff;
- if (MSIXCAP_BASE != 0x0) {
- int msix_vecs = msixcap_mxc_ts + 1;
- MSIXTable tmp1 = {{0UL,0UL,0UL,0UL}};
- msix_table.resize(msix_vecs, tmp1);
-
- MSIXPbaEntry tmp2 = {0};
- int pba_size = msix_vecs / MSIXVECS_PER_PBA;
- if ((msix_vecs % MSIXVECS_PER_PBA) > 0) {
- pba_size++;
- }
- msix_pba.resize(pba_size, tmp2);
- }
- MSIX_TABLE_OFFSET = msixcap.mtab & 0xfffffffc;
- MSIX_TABLE_END = MSIX_TABLE_OFFSET +
- (msixcap_mxc_ts + 1) * sizeof(MSIXTable);
- MSIX_PBA_OFFSET = msixcap.mpba & 0xfffffffc;
- MSIX_PBA_END = MSIX_PBA_OFFSET +
- ((msixcap_mxc_ts + 1) / MSIXVECS_PER_PBA)
- * sizeof(MSIXPbaEntry);
- if (((msixcap_mxc_ts + 1) % MSIXVECS_PER_PBA) > 0) {
- MSIX_PBA_END += sizeof(MSIXPbaEntry);
- }
-
- // PXCAP
- pxcap.pxid = (uint16_t)p->PXCAPCapId; //pxid.cid
- pxcap.pxid |= (uint16_t)p->PXCAPNextCapability << 8; //pxid.next
- pxcap.pxcap = p->PXCAPCapabilities;
- pxcap.pxdcap = p->PXCAPDevCapabilities;
- pxcap.pxdc = p->PXCAPDevCtrl;
- pxcap.pxds = p->PXCAPDevStatus;
- pxcap.pxlcap = p->PXCAPLinkCap;
- pxcap.pxlc = p->PXCAPLinkCtrl;
- pxcap.pxls = p->PXCAPLinkStatus;
- pxcap.pxdcap2 = p->PXCAPDevCap2;
- pxcap.pxdc2 = p->PXCAPDevCtrl2;
-
- BARSize[0] = p->BAR0Size;
- BARSize[1] = p->BAR1Size;
- BARSize[2] = p->BAR2Size;
- BARSize[3] = p->BAR3Size;
- BARSize[4] = p->BAR4Size;
- BARSize[5] = p->BAR5Size;
-
- legacyIO[0] = p->BAR0LegacyIO;
- legacyIO[1] = p->BAR1LegacyIO;
- legacyIO[2] = p->BAR2LegacyIO;
- legacyIO[3] = p->BAR3LegacyIO;
- legacyIO[4] = p->BAR4LegacyIO;
- legacyIO[5] = p->BAR5LegacyIO;
-
- for (int i = 0; i < 6; ++i) {
- if (legacyIO[i]) {
- BARAddrs[i] = p->LegacyIOBase + letoh(config.baseAddr[i]);
- config.baseAddr[i] = 0;
- } else {
- BARAddrs[i] = 0;
- uint32_t barsize = BARSize[i];
- if (barsize != 0 && !isPowerOf2(barsize)) {
- fatal("BAR %d size %d is not a power of 2\n", i, BARSize[i]);
- }
- }
- }
-}
-
-Tick
-PciDevice::readConfig(PacketPtr pkt)
-{
- int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
-
- /* Return 0 for accesses to unimplemented PCI configspace areas */
- if (offset >= PCI_DEVICE_SPECIFIC &&
- offset < PCI_CONFIG_SIZE) {
- warn_once("Device specific PCI config space "
- "not implemented for %s!\n", this->name());
- switch (pkt->getSize()) {
- case sizeof(uint8_t):
- pkt->set<uint8_t>(0);
- break;
- case sizeof(uint16_t):
- pkt->set<uint16_t>(0);
- break;
- case sizeof(uint32_t):
- pkt->set<uint32_t>(0);
- break;
- default:
- panic("invalid access size(?) for PCI configspace!\n");
- }
- } else if (offset > PCI_CONFIG_SIZE) {
- panic("Out-of-range access to PCI config space!\n");
- }
-
- switch (pkt->getSize()) {
- case sizeof(uint8_t):
- pkt->set<uint8_t>(config.data[offset]);
- DPRINTF(PCIDEV,
- "readConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
- _busAddr.dev, _busAddr.func, offset,
- (uint32_t)pkt->get<uint8_t>());
- break;
- case sizeof(uint16_t):
- pkt->set<uint16_t>(*(uint16_t*)&config.data[offset]);
- DPRINTF(PCIDEV,
- "readConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
- _busAddr.dev, _busAddr.func, offset,
- (uint32_t)pkt->get<uint16_t>());
- break;
- case sizeof(uint32_t):
- pkt->set<uint32_t>(*(uint32_t*)&config.data[offset]);
- DPRINTF(PCIDEV,
- "readConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
- _busAddr.dev, _busAddr.func, offset,
- (uint32_t)pkt->get<uint32_t>());
- break;
- default:
- panic("invalid access size(?) for PCI configspace!\n");
- }
- pkt->makeAtomicResponse();
- return configDelay;
-
-}
-
-AddrRangeList
-PciDevice::getAddrRanges() const
-{
- AddrRangeList ranges;
- int x = 0;
- for (x = 0; x < 6; x++)
- if (BARAddrs[x] != 0)
- ranges.push_back(RangeSize(BARAddrs[x],BARSize[x]));
- return ranges;
-}
-
-Tick
-PciDevice::writeConfig(PacketPtr pkt)
-{
- int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
-
- /* No effect if we write to config space that is not implemented*/
- if (offset >= PCI_DEVICE_SPECIFIC &&
- offset < PCI_CONFIG_SIZE) {
- warn_once("Device specific PCI config space "
- "not implemented for %s!\n", this->name());
- switch (pkt->getSize()) {
- case sizeof(uint8_t):
- case sizeof(uint16_t):
- case sizeof(uint32_t):
- break;
- default:
- panic("invalid access size(?) for PCI configspace!\n");
- }
- } else if (offset > PCI_CONFIG_SIZE) {
- panic("Out-of-range access to PCI config space!\n");
- }
-
- switch (pkt->getSize()) {
- case sizeof(uint8_t):
- switch (offset) {
- case PCI0_INTERRUPT_LINE:
- config.interruptLine = pkt->get<uint8_t>();
- break;
- case PCI_CACHE_LINE_SIZE:
- config.cacheLineSize = pkt->get<uint8_t>();
- break;
- case PCI_LATENCY_TIMER:
- config.latencyTimer = pkt->get<uint8_t>();
- break;
- /* Do nothing for these read-only registers */
- case PCI0_INTERRUPT_PIN:
- case PCI0_MINIMUM_GRANT:
- case PCI0_MAXIMUM_LATENCY:
- case PCI_CLASS_CODE:
- case PCI_REVISION_ID:
- break;
- default:
- panic("writing to a read only register");
- }
- DPRINTF(PCIDEV,
- "writeConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
- _busAddr.dev, _busAddr.func, offset,
- (uint32_t)pkt->get<uint8_t>());
- break;
- case sizeof(uint16_t):
- switch (offset) {
- case PCI_COMMAND:
- config.command = pkt->get<uint8_t>();
- break;
- case PCI_STATUS:
- config.status = pkt->get<uint8_t>();
- break;
- case PCI_CACHE_LINE_SIZE:
- config.cacheLineSize = pkt->get<uint8_t>();
- break;
- default:
- panic("writing to a read only register");
- }
- DPRINTF(PCIDEV,
- "writeConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
- _busAddr.dev, _busAddr.func, offset,
- (uint32_t)pkt->get<uint16_t>());
- break;
- case sizeof(uint32_t):
- switch (offset) {
- case PCI0_BASE_ADDR0:
- case PCI0_BASE_ADDR1:
- case PCI0_BASE_ADDR2:
- case PCI0_BASE_ADDR3:
- case PCI0_BASE_ADDR4:
- case PCI0_BASE_ADDR5:
- {
- int barnum = BAR_NUMBER(offset);
-
- if (!legacyIO[barnum]) {
- // convert BAR values to host endianness
- uint32_t he_old_bar = letoh(config.baseAddr[barnum]);
- uint32_t he_new_bar = letoh(pkt->get<uint32_t>());
-
- uint32_t bar_mask =
- BAR_IO_SPACE(he_old_bar) ? BAR_IO_MASK : BAR_MEM_MASK;
-
- // Writing 0xffffffff to a BAR tells the card to set the
- // value of the bar to a bitmask indicating the size of
- // memory it needs
- if (he_new_bar == 0xffffffff) {
- he_new_bar = ~(BARSize[barnum] - 1);
- } else {
- // does it mean something special to write 0 to a BAR?
- he_new_bar &= ~bar_mask;
- if (he_new_bar) {
- BARAddrs[barnum] = BAR_IO_SPACE(he_old_bar) ?
- hostInterface.pioAddr(he_new_bar) :
- hostInterface.memAddr(he_new_bar);
- pioPort.sendRangeChange();
- }
- }
- config.baseAddr[barnum] = htole((he_new_bar & ~bar_mask) |
- (he_old_bar & bar_mask));
- }
- }
- break;
-
- case PCI0_ROM_BASE_ADDR:
- if (letoh(pkt->get<uint32_t>()) == 0xfffffffe)
- config.expansionROM = htole((uint32_t)0xffffffff);
- else
- config.expansionROM = pkt->get<uint32_t>();
- break;
-
- case PCI_COMMAND:
- // This could also clear some of the error bits in the Status
- // register. However they should never get set, so lets ignore
- // it for now
- config.command = pkt->get<uint32_t>();
- break;
-
- default:
- DPRINTF(PCIDEV, "Writing to a read only register");
- }
- DPRINTF(PCIDEV,
- "writeConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
- _busAddr.dev, _busAddr.func, offset,
- (uint32_t)pkt->get<uint32_t>());
- break;
- default:
- panic("invalid access size(?) for PCI configspace!\n");
- }
- pkt->makeAtomicResponse();
- return configDelay;
-}
-
-void
-PciDevice::serialize(CheckpointOut &cp) const
-{
- SERIALIZE_ARRAY(BARSize, sizeof(BARSize) / sizeof(BARSize[0]));
- SERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0]));
- SERIALIZE_ARRAY(config.data, sizeof(config.data) / sizeof(config.data[0]));
-
- // serialize the capability list registers
- paramOut(cp, csprintf("pmcap.pid"), uint16_t(pmcap.pid));
- paramOut(cp, csprintf("pmcap.pc"), uint16_t(pmcap.pc));
- paramOut(cp, csprintf("pmcap.pmcs"), uint16_t(pmcap.pmcs));
-
- paramOut(cp, csprintf("msicap.mid"), uint16_t(msicap.mid));
- paramOut(cp, csprintf("msicap.mc"), uint16_t(msicap.mc));
- paramOut(cp, csprintf("msicap.ma"), uint32_t(msicap.ma));
- SERIALIZE_SCALAR(msicap.mua);
- paramOut(cp, csprintf("msicap.md"), uint16_t(msicap.md));
- SERIALIZE_SCALAR(msicap.mmask);
- SERIALIZE_SCALAR(msicap.mpend);
-
- paramOut(cp, csprintf("msixcap.mxid"), uint16_t(msixcap.mxid));
- paramOut(cp, csprintf("msixcap.mxc"), uint16_t(msixcap.mxc));
- paramOut(cp, csprintf("msixcap.mtab"), uint32_t(msixcap.mtab));
- paramOut(cp, csprintf("msixcap.mpba"), uint32_t(msixcap.mpba));
-
- // Only serialize if we have a non-zero base address
- if (MSIXCAP_BASE != 0x0) {
- uint16_t msixcap_mxc_ts = msixcap.mxc & 0x07ff;
- int msix_array_size = msixcap_mxc_ts + 1;
- int pba_array_size = msix_array_size/MSIXVECS_PER_PBA;
- if ((msix_array_size % MSIXVECS_PER_PBA) > 0) {
- pba_array_size++;
- }
-
- SERIALIZE_SCALAR(msix_array_size);
- SERIALIZE_SCALAR(pba_array_size);
-
- for (int i = 0; i < msix_array_size; i++) {
- paramOut(cp, csprintf("msix_table[%d].addr_lo", i),
- msix_table[i].fields.addr_lo);
- paramOut(cp, csprintf("msix_table[%d].addr_hi", i),
- msix_table[i].fields.addr_hi);
- paramOut(cp, csprintf("msix_table[%d].msg_data", i),
- msix_table[i].fields.msg_data);
- paramOut(cp, csprintf("msix_table[%d].vec_ctrl", i),
- msix_table[i].fields.vec_ctrl);
- }
- for (int i = 0; i < pba_array_size; i++) {
- paramOut(cp, csprintf("msix_pba[%d].bits", i),
- msix_pba[i].bits);
- }
- }
-
- paramOut(cp, csprintf("pxcap.pxid"), uint16_t(pxcap.pxid));
- paramOut(cp, csprintf("pxcap.pxcap"), uint16_t(pxcap.pxcap));
- paramOut(cp, csprintf("pxcap.pxdcap"), uint32_t(pxcap.pxdcap));
- paramOut(cp, csprintf("pxcap.pxdc"), uint16_t(pxcap.pxdc));
- paramOut(cp, csprintf("pxcap.pxds"), uint16_t(pxcap.pxds));
- paramOut(cp, csprintf("pxcap.pxlcap"), uint32_t(pxcap.pxlcap));
- paramOut(cp, csprintf("pxcap.pxlc"), uint16_t(pxcap.pxlc));
- paramOut(cp, csprintf("pxcap.pxls"), uint16_t(pxcap.pxls));
- paramOut(cp, csprintf("pxcap.pxdcap2"), uint32_t(pxcap.pxdcap2));
- paramOut(cp, csprintf("pxcap.pxdc2"), uint32_t(pxcap.pxdc2));
-}
-
-void
-PciDevice::unserialize(CheckpointIn &cp)
-{
- UNSERIALIZE_ARRAY(BARSize, sizeof(BARSize) / sizeof(BARSize[0]));
- UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0]));
- UNSERIALIZE_ARRAY(config.data,
- sizeof(config.data) / sizeof(config.data[0]));
-
- // unserialize the capability list registers
- uint16_t tmp16;
- uint32_t tmp32;
- paramIn(cp, csprintf("pmcap.pid"), tmp16);
- pmcap.pid = tmp16;
- paramIn(cp, csprintf("pmcap.pc"), tmp16);
- pmcap.pc = tmp16;
- paramIn(cp, csprintf("pmcap.pmcs"), tmp16);
- pmcap.pmcs = tmp16;
-
- paramIn(cp, csprintf("msicap.mid"), tmp16);
- msicap.mid = tmp16;
- paramIn(cp, csprintf("msicap.mc"), tmp16);
- msicap.mc = tmp16;
- paramIn(cp, csprintf("msicap.ma"), tmp32);
- msicap.ma = tmp32;
- UNSERIALIZE_SCALAR(msicap.mua);
- paramIn(cp, csprintf("msicap.md"), tmp16);;
- msicap.md = tmp16;
- UNSERIALIZE_SCALAR(msicap.mmask);
- UNSERIALIZE_SCALAR(msicap.mpend);
-
- paramIn(cp, csprintf("msixcap.mxid"), tmp16);
- msixcap.mxid = tmp16;
- paramIn(cp, csprintf("msixcap.mxc"), tmp16);
- msixcap.mxc = tmp16;
- paramIn(cp, csprintf("msixcap.mtab"), tmp32);
- msixcap.mtab = tmp32;
- paramIn(cp, csprintf("msixcap.mpba"), tmp32);
- msixcap.mpba = tmp32;
-
- // Only allocate if MSIXCAP_BASE is not 0x0
- if (MSIXCAP_BASE != 0x0) {
- int msix_array_size;
- int pba_array_size;
-
- UNSERIALIZE_SCALAR(msix_array_size);
- UNSERIALIZE_SCALAR(pba_array_size);
-
- MSIXTable tmp1 = {{0UL, 0UL, 0UL, 0UL}};
- msix_table.resize(msix_array_size, tmp1);
-
- MSIXPbaEntry tmp2 = {0};
- msix_pba.resize(pba_array_size, tmp2);
-
- for (int i = 0; i < msix_array_size; i++) {
- paramIn(cp, csprintf("msix_table[%d].addr_lo", i),
- msix_table[i].fields.addr_lo);
- paramIn(cp, csprintf("msix_table[%d].addr_hi", i),
- msix_table[i].fields.addr_hi);
- paramIn(cp, csprintf("msix_table[%d].msg_data", i),
- msix_table[i].fields.msg_data);
- paramIn(cp, csprintf("msix_table[%d].vec_ctrl", i),
- msix_table[i].fields.vec_ctrl);
- }
- for (int i = 0; i < pba_array_size; i++) {
- paramIn(cp, csprintf("msix_pba[%d].bits", i),
- msix_pba[i].bits);
- }
- }
-
- paramIn(cp, csprintf("pxcap.pxid"), tmp16);
- pxcap.pxid = tmp16;
- paramIn(cp, csprintf("pxcap.pxcap"), tmp16);
- pxcap.pxcap = tmp16;
- paramIn(cp, csprintf("pxcap.pxdcap"), tmp32);
- pxcap.pxdcap = tmp32;
- paramIn(cp, csprintf("pxcap.pxdc"), tmp16);
- pxcap.pxdc = tmp16;
- paramIn(cp, csprintf("pxcap.pxds"), tmp16);
- pxcap.pxds = tmp16;
- paramIn(cp, csprintf("pxcap.pxlcap"), tmp32);
- pxcap.pxlcap = tmp32;
- paramIn(cp, csprintf("pxcap.pxlc"), tmp16);
- pxcap.pxlc = tmp16;
- paramIn(cp, csprintf("pxcap.pxls"), tmp16);
- pxcap.pxls = tmp16;
- paramIn(cp, csprintf("pxcap.pxdcap2"), tmp32);
- pxcap.pxdcap2 = tmp32;
- paramIn(cp, csprintf("pxcap.pxdc2"), tmp32);
- pxcap.pxdc2 = tmp32;
- pioPort.sendRangeChange();
-}
-
+++ /dev/null
-/*
- * Copyright (c) 2013 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.
- *
- * Copyright (c) 2004-2005 The Regents of The University of Michigan
- * All rights reserved.
- *
- * 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: Ali Saidi
- * Andrew Schultz
- * Nathan Binkert
- */
-
-/* @file
- * Interface for devices using PCI configuration
- */
-
-#ifndef __DEV_PCIDEV_HH__
-#define __DEV_PCIDEV_HH__
-
-#include <cstring>
-#include <vector>
-
-#include "dev/dma_device.hh"
-#include "dev/pcireg.h"
-#include "dev/pci/host.hh"
-#include "params/PciDevice.hh"
-#include "sim/byteswap.hh"
-
-#define BAR_IO_MASK 0x3
-#define BAR_MEM_MASK 0xF
-#define BAR_IO_SPACE_BIT 0x1
-#define BAR_IO_SPACE(x) ((x) & BAR_IO_SPACE_BIT)
-#define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
-
-/**
- * PCI device, base implementation is only config space.
- */
-class PciDevice : public DmaDevice
-{
- protected:
- const PciBusAddr _busAddr;
-
- /** The current config space. */
- PCIConfig config;
-
- /** The capability list structures and base addresses
- * @{
- */
- const int PMCAP_BASE;
- const int PMCAP_ID_OFFSET;
- const int PMCAP_PC_OFFSET;
- const int PMCAP_PMCS_OFFSET;
- PMCAP pmcap;
-
- const int MSICAP_BASE;
- MSICAP msicap;
-
- const int MSIXCAP_BASE;
- const int MSIXCAP_ID_OFFSET;
- const int MSIXCAP_MXC_OFFSET;
- const int MSIXCAP_MTAB_OFFSET;
- const int MSIXCAP_MPBA_OFFSET;
- int MSIX_TABLE_OFFSET;
- int MSIX_TABLE_END;
- int MSIX_PBA_OFFSET;
- int MSIX_PBA_END;
- MSIXCAP msixcap;
-
- const int PXCAP_BASE;
- PXCAP pxcap;
- /** @} */
-
- /** MSIX Table and PBA Structures */
- std::vector<MSIXTable> msix_table;
- std::vector<MSIXPbaEntry> msix_pba;
-
- /** The size of the BARs */
- uint32_t BARSize[6];
-
- /** The current address mapping of the BARs */
- Addr BARAddrs[6];
-
- /** Whether the BARs are really hardwired legacy IO locations. */
- bool legacyIO[6];
-
- /**
- * Does the given address lie within the space mapped by the given
- * base address register?
- */
- bool
- isBAR(Addr addr, int bar) const
- {
- assert(bar >= 0 && bar < 6);
- return BARAddrs[bar] <= addr && addr < BARAddrs[bar] + BARSize[bar];
- }
-
- /**
- * Which base address register (if any) maps the given address?
- * @return The BAR number (0-5 inclusive), or -1 if none.
- */
- int
- getBAR(Addr addr)
- {
- for (int i = 0; i <= 5; ++i)
- if (isBAR(addr, i))
- return i;
-
- return -1;
- }
-
- /**
- * Which base address register (if any) maps the given address?
- * @param addr The address to check.
- * @retval bar The BAR number (0-5 inclusive),
- * only valid if return value is true.
- * @retval offs The offset from the base address,
- * only valid if return value is true.
- * @return True iff address maps to a base address register's region.
- */
- bool
- getBAR(Addr addr, int &bar, Addr &offs)
- {
- int b = getBAR(addr);
- if (b < 0)
- return false;
-
- offs = addr - BARAddrs[b];
- bar = b;
- return true;
- }
-
- public: // Host configuration interface
- /**
- * Write to the PCI config space data that is stored locally. This may be
- * overridden by the device but at some point it will eventually call this
- * for normal operations that it does not need to override.
- * @param pkt packet containing the write the offset into config space
- */
- virtual Tick writeConfig(PacketPtr pkt);
-
-
- /**
- * Read from the PCI config space data that is stored locally. This may be
- * overridden by the device but at some point it will eventually call this
- * for normal operations that it does not need to override.
- * @param pkt packet containing the write the offset into config space
- */
- virtual Tick readConfig(PacketPtr pkt);
-
- protected:
- PciHost::DeviceInterface hostInterface;
-
- Tick pioDelay;
- Tick configDelay;
-
- public:
- Addr pciToDma(Addr pci_addr) const {
- return hostInterface.dmaAddr(pci_addr);
- }
-
- void intrPost() { hostInterface.postInt(); }
- void intrClear() { hostInterface.clearInt(); }
-
- uint8_t interruptLine() const { return letoh(config.interruptLine); }
-
- /**
- * Determine the address ranges that this device responds to.
- *
- * @return a list of non-overlapping address ranges
- */
- AddrRangeList getAddrRanges() const override;
-
- /**
- * Constructor for PCI Dev. This function copies data from the
- * config file object PCIConfigData and registers the device with
- * a PciHost object.
- */
- PciDevice(const PciDeviceParams *params);
-
- /**
- * Serialize this object to the given output stream.
- * @param os The stream to serialize to.
- */
- void serialize(CheckpointOut &cp) const override;
-
- /**
- * Reconstruct the state of this object from a checkpoint.
- * @param cp The checkpoint use.
- * @param section The section name of this object
- */
- void unserialize(CheckpointIn &cp) override;
-
- const PciBusAddr &busAddr() const { return _busAddr; }
-};
-#endif // __DEV_PCIDEV_HH__
+++ /dev/null
-/*
- * Copyright (c) 2013 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.
- *
- * Copyright (c) 2001-2005 The Regents of The University of Michigan
- * All rights reserved.
- *
- * 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: Nathan Binkert
- * Miguel Serrano
- */
-
-/* @file
- * Device register definitions for a device's PCI config space
- */
-
-#ifndef __PCIREG_H__
-#define __PCIREG_H__
-
-#include <sys/types.h>
-
-#include "base/bitfield.hh"
-#include "base/bitunion.hh"
-
-union PCIConfig {
- uint8_t data[64];
-
- struct {
- uint16_t vendor;
- uint16_t device;
- uint16_t command;
- uint16_t status;
- uint8_t revision;
- uint8_t progIF;
- uint8_t subClassCode;
- uint8_t classCode;
- uint8_t cacheLineSize;
- uint8_t latencyTimer;
- uint8_t headerType;
- uint8_t bist;
- uint32_t baseAddr[6];
- uint32_t cardbusCIS;
- uint16_t subsystemVendorID;
- uint16_t subsystemID;
- uint32_t expansionROM;
- uint8_t capabilityPtr;
- // Was 8 bytes in the legacy PCI spec, but to support PCIe
- // this field is now 7 bytes with PCIe's addition of the
- // capability list pointer.
- uint8_t reserved[7];
- uint8_t interruptLine;
- uint8_t interruptPin;
- uint8_t minimumGrant;
- uint8_t maximumLatency;
- };
-};
-
-// Common PCI offsets
-#define PCI_VENDOR_ID 0x00 // Vendor ID ro
-#define PCI_DEVICE_ID 0x02 // Device ID ro
-#define PCI_COMMAND 0x04 // Command rw
-#define PCI_STATUS 0x06 // Status rw
-#define PCI_REVISION_ID 0x08 // Revision ID ro
-#define PCI_CLASS_CODE 0x09 // Class Code ro
-#define PCI_SUB_CLASS_CODE 0x0A // Sub Class Code ro
-#define PCI_BASE_CLASS_CODE 0x0B // Base Class Code ro
-#define PCI_CACHE_LINE_SIZE 0x0C // Cache Line Size ro+
-#define PCI_LATENCY_TIMER 0x0D // Latency Timer ro+
-#define PCI_HEADER_TYPE 0x0E // Header Type ro
-#define PCI_BIST 0x0F // Built in self test rw
-
-// some pci command reg bitfields
-#define PCI_CMD_BME 0x04 // Bus master function enable
-#define PCI_CMD_MSE 0x02 // Memory Space Access enable
-#define PCI_CMD_IOSE 0x01 // I/O space enable
-
-// Type 0 PCI offsets
-#define PCI0_BASE_ADDR0 0x10 // Base Address 0 rw
-#define PCI0_BASE_ADDR1 0x14 // Base Address 1 rw
-#define PCI0_BASE_ADDR2 0x18 // Base Address 2 rw
-#define PCI0_BASE_ADDR3 0x1C // Base Address 3 rw
-#define PCI0_BASE_ADDR4 0x20 // Base Address 4 rw
-#define PCI0_BASE_ADDR5 0x24 // Base Address 5 rw
-#define PCI0_CIS 0x28 // CardBus CIS Pointer ro
-#define PCI0_SUB_VENDOR_ID 0x2C // Sub-Vendor ID ro
-#define PCI0_SUB_SYSTEM_ID 0x2E // Sub-System ID ro
-#define PCI0_ROM_BASE_ADDR 0x30 // Expansion ROM Base Address rw
-#define PCI0_CAP_PTR 0x34 // Capability list pointer ro
-#define PCI0_RESERVED 0x35
-#define PCI0_INTERRUPT_LINE 0x3C // Interrupt Line rw
-#define PCI0_INTERRUPT_PIN 0x3D // Interrupt Pin ro
-#define PCI0_MINIMUM_GRANT 0x3E // Maximum Grant ro
-#define PCI0_MAXIMUM_LATENCY 0x3F // Maximum Latency ro
-
-// Type 1 PCI offsets
-#define PCI1_BASE_ADDR0 0x10 // Base Address 0 rw
-#define PCI1_BASE_ADDR1 0x14 // Base Address 1 rw
-#define PCI1_PRI_BUS_NUM 0x18 // Primary Bus Number rw
-#define PCI1_SEC_BUS_NUM 0x19 // Secondary Bus Number rw
-#define PCI1_SUB_BUS_NUM 0x1A // Subordinate Bus Number rw
-#define PCI1_SEC_LAT_TIMER 0x1B // Secondary Latency Timer ro+
-#define PCI1_IO_BASE 0x1C // I/O Base rw
-#define PCI1_IO_LIMIT 0x1D // I/O Limit rw
-#define PCI1_SECONDARY_STATUS 0x1E // Secondary Status rw
-#define PCI1_MEM_BASE 0x20 // Memory Base rw
-#define PCI1_MEM_LIMIT 0x22 // Memory Limit rw
-#define PCI1_PRF_MEM_BASE 0x24 // Prefetchable Memory Base rw
-#define PCI1_PRF_MEM_LIMIT 0x26 // Prefetchable Memory Limit rw
-#define PCI1_PRF_BASE_UPPER 0x28 // Prefetchable Base Upper 32 rw
-#define PCI1_PRF_LIMIT_UPPER 0x2C // Prefetchable Limit Upper 32 rw
-#define PCI1_IO_BASE_UPPER 0x30 // I/O Base Upper 16 bits rw
-#define PCI1_IO_LIMIT_UPPER 0x32 // I/O Limit Upper 16 bits rw
-#define PCI1_RESERVED 0x34 // Reserved ro
-#define PCI1_ROM_BASE_ADDR 0x38 // Expansion ROM Base Address rw
-#define PCI1_INTR_LINE 0x3C // Interrupt Line rw
-#define PCI1_INTR_PIN 0x3D // Interrupt Pin ro
-#define PCI1_BRIDGE_CTRL 0x3E // Bridge Control rw
-
-// Device specific offsets
-#define PCI_DEVICE_SPECIFIC 0x40 // 192 bytes
-#define PCI_CONFIG_SIZE 0xFF
-
-// Some Vendor IDs
-#define PCI_VENDOR_DEC 0x1011
-#define PCI_VENDOR_NCR 0x101A
-#define PCI_VENDOR_QLOGIC 0x1077
-#define PCI_VENDOR_SIMOS 0x1291
-
-// Some Product IDs
-#define PCI_PRODUCT_DEC_PZA 0x0008
-#define PCI_PRODUCT_NCR_810 0x0001
-#define PCI_PRODUCT_QLOGIC_ISP1020 0x1020
-#define PCI_PRODUCT_SIMOS_SIMOS 0x1291
-#define PCI_PRODUCT_SIMOS_ETHER 0x1292
-
-/**
- * PCIe capability list offsets internal to the entry.
- * Actual offsets in the PCI config space are defined in
- * the python files setting up the system.
- */
-#define PMCAP_ID 0x00
-#define PMCAP_PC 0x02
-#define PMCAP_PMCS 0x04
-#define PMCAP_SIZE 0x06
-
-#define MSICAP_ID 0x00
-#define MSICAP_MC 0x02
-#define MSICAP_MA 0x04
-#define MSICAP_MUA 0x08
-#define MSICAP_MD 0x0C
-#define MSICAP_MMASK 0x10
-#define MSICAP_MPEND 0x14
-#define MSICAP_SIZE 0x18
-
-#define MSIXCAP_ID 0x00
-#define MSIXCAP_MXC 0x02
-#define MSIXCAP_MTAB 0x04
-#define MSIXCAP_MPBA 0x08
-#define MSIXCAP_SIZE 0x0C
-
-#define PXCAP_ID 0x00
-#define PXCAP_PXCAP 0x02
-#define PXCAP_PXDCAP 0x04
-#define PXCAP_PXDC 0x08
-#define PXCAP_PXDS 0x0A
-#define PXCAP_PXLCAP 0x0C
-#define PXCAP_PXLC 0x10
-#define PXCAP_PXLS 0x12
-#define PXCAP_PXDCAP2 0x24
-#define PXCAP_PXDC2 0x28
-#define PXCAP_SIZE 0x30
-
-/** @struct PMCAP
- * Defines the Power Management capability register and all its associated
- * bitfields for a PCIe device.
- */
-union PMCAP {
- uint8_t data[6];
- struct {
- uint16_t pid; /* 0:7 cid
- * 8:15 next
- */
- uint16_t pc; /* 0:2 vs
- * 3 pmec
- * 4 reserved
- * 5 dsi
- * 6:8 auxc
- * 9 d1s
- * 10 d2s
- * 11:15 psup
- */
- uint16_t pmcs; /* 0:1 ps
- * 2 reserved
- * 3 nsfrst
- * 4:7 reserved
- * 8 pmee
- * 9:12 dse
- * 13:14 dsc
- * 15 pmes
- */
- };
-};
-
-/** @struct MSICAP
- * Defines the MSI Capability register and its associated bitfields for
- * the a PCI/PCIe device. Both the MSI capability and the MSIX capability
- * can be filled in if a device model supports both, but only 1 of
- * MSI/MSIX/INTx interrupt mode can be selected at a given time.
- */
-union MSICAP {
- uint8_t data[24];
- struct {
- uint16_t mid; /* 0:7 cid
- * 8:15 next
- */
- uint16_t mc; /* 0 msie;
- * 1:3 mmc;
- * 4:6 mme;
- * 7 c64;
- * 8 pvm;
- * 9:15 reserved;
- */
- uint32_t ma; /* 0:1 reserved
- * 2:31 addr
- */
- uint32_t mua;
- uint16_t md;
- uint32_t mmask;
- uint32_t mpend;
- };
-};
-
-/** @struct MSIX
- * Defines the MSI-X Capability register and its associated bitfields for
- * a PCIe device.
- */
-union MSIXCAP {
- uint8_t data[12];
- struct {
- uint16_t mxid; /* 0:7 cid
- * 8:15 next
- */
- uint16_t mxc; /* 0:10 ts;
- * 11:13 reserved;
- * 14 fm;
- * 15 mxe;
- */
- uint32_t mtab; /* 0:2 tbir;
- * 3:31 to;
- */
- uint32_t mpba; /* 0:2 pbir;
- * 3:31> pbao;
- */
- };
-};
-
-union MSIXTable {
- struct {
- uint32_t addr_lo;
- uint32_t addr_hi;
- uint32_t msg_data;
- uint32_t vec_ctrl;
- } fields;
- uint32_t data[4];
-};
-
-#define MSIXVECS_PER_PBA 64
-struct MSIXPbaEntry {
- uint64_t bits;
-};
-
-/** @struct PXCAP
- * Defines the PCI Express capability register and its associated bitfields
- * for a PCIe device.
- */
-struct PXCAP {
- uint8_t data[48];
- struct {
- uint16_t pxid; /* 0:7 cid
- * 8:15 next
- */
- uint16_t pxcap; /* 0:3 ver;
- * 4:7 dpt;
- * 8 si;
- * 9:13 imn;
- * 14:15 reserved;
- */
- uint32_t pxdcap; /* 0:2 mps;
- * 3:4 pfs;
- * 5 etfs;
- * 6:8 l0sl;
- * 9:11 l1l;
- * 12:14 reserved;
- * 15 rer;
- * 16:17 reserved;
- * 18:25 csplv;
- * 26:27 cspls;
- * 28 flrc;
- * 29:31 reserved;
- */
- uint16_t pxdc; /* 0 cere;
- * 1 nfere;
- * 2 fere;
- * 3 urre;
- * 4 ero;
- * 5:7 mps;
- * 8 ete;
- * 9 pfe;
- * 10 appme;
- * 11 ens;
- * 12:14 mrrs;
- * 15 func_reset;
- */
- uint16_t pxds; /* 0 ced;
- * 1 nfed;
- * 2 fed;
- * 3 urd;
- * 4 apd;
- * 5 tp;
- * 6:15 reserved;
- */
- uint32_t pxlcap; /* 0:3 sls;
- * 4:9 mlw;
- * 10:11 aspms;
- * 12:14 l0sel;
- * 15:17 l1el;
- * 18 cpm;
- * 19 sderc;
- * 20 dllla;
- * 21 lbnc;
- * 22:23 reserved;
- * 24:31 pn;
- */
- uint16_t pxlc; /* 0:1 aspmc;
- * 2 reserved;
- * 3 rcb;
- * 4:5 reserved;
- * 6 ccc;
- * 7 es;
- * 8 ecpm;
- * 9 hawd;
- * 10:15 reserved;
- */
- uint16_t pxls; /* 0:3 cls;
- * 4:9 nlw;
- * 10:11 reserved;
- * 12 slot_clk_config;
- * 13:15 reserved;
- */
- uint8_t reserved[20];
- uint32_t pxdcap2; /* 0:3 ctrs;
- * 4 ctds;
- * 5 arifs;
- * 6 aors;
- * 7 aocs32;
- * 8 aocs64;
- * 9 ccs128;
- * 10 nprpr;
- * 11 ltrs;
- * 12:13 tphcs;
- * 14:17 reserved;
- * 18:19 obffs;
- * 20 effs;
- * 21 eetps;
- * 22:23 meetp;
- * 24:31 reserved;
- */
- uint32_t pxdc2; /* 0:3 ctv;
- * 4 ctd;
- * 5:9 reserved;
- * 10 ltrme;
- * 11:12 reserved;
- * 13:14 obffe;
- * 15:31 reserved;
- */
- };
-};
-#endif // __PCIREG_H__
#include "dev/etherint.hh"
#include "dev/etherpkt.hh"
#include "dev/io_device.hh"
-#include "dev/pcidev.hh"
+#include "dev/pci/device.hh"
#include "dev/pktfifo.hh"
#include "dev/sinicreg.hh"
#include "params/Sinic.hh"
from m5.params import *
from m5.proxy import *
from Device import PioDevice
-from Pci import PciDevice
+from PciDevice import PciDevice
class VirtIODeviceBase(SimObject):
#include "base/statistics.hh"
#include "dev/virtio/base.hh"
-#include "dev/pcidev.hh"
+#include "dev/pci/device.hh"
struct PciVirtIOParams;