60 #include "debug/PciDevice.hh" 68 _busAddr(p->pci_bus, p->pci_dev, p->pci_func),
69 PMCAP_BASE(p->PMCAPBaseOffset),
70 PMCAP_ID_OFFSET(p->PMCAPBaseOffset+
PMCAP_ID),
71 PMCAP_PC_OFFSET(p->PMCAPBaseOffset+
PMCAP_PC),
72 PMCAP_PMCS_OFFSET(p->PMCAPBaseOffset+
PMCAP_PMCS),
73 MSICAP_BASE(p->MSICAPBaseOffset),
74 MSIXCAP_BASE(p->MSIXCAPBaseOffset),
75 MSIXCAP_ID_OFFSET(p->MSIXCAPBaseOffset+
MSIXCAP_ID),
76 MSIXCAP_MXC_OFFSET(p->MSIXCAPBaseOffset+
MSIXCAP_MXC),
79 PXCAP_BASE(p->PXCAPBaseOffset),
81 hostInterface(p->host->registerDevice(this, _busAddr,
83 pioDelay(p->pio_latency),
84 configDelay(p->config_latency)
87 "Invalid PCI interrupt '%i' specified.", p->InterruptPin);
125 pmcap.
pid = (uint16_t)p->PMCAPCapId;
126 pmcap.
pid |= (uint16_t)p->PMCAPNextCapability << 8;
127 pmcap.
pc = p->PMCAPCapabilities;
132 msicap.
mid |= (uint16_t)p->MSICAPNextCapability << 8;
142 msixcap.
mxid |= (uint16_t)p->MSIXCAPNextCapability << 8;
154 uint16_t msixcap_mxc_ts =
msixcap.
mxc & 0x07ff;
156 int msix_vecs = msixcap_mxc_ts + 1;
169 (msixcap_mxc_ts + 1) *
sizeof(
MSIXTable);
180 pxcap.
pxid |= (uint16_t)p->PXCAPNextCapability << 8;
205 for (
int i = 0;
i < 6; ++
i) {
213 fatal(
"BAR %d size %d is not a power of 2\n", i,
BARSize[i]);
227 warn_once(
"Device specific PCI config space " 228 "not implemented for %s!\n", this->
name());
230 case sizeof(uint8_t):
231 pkt->
setLE<uint8_t>(0);
233 case sizeof(uint16_t):
234 pkt->
setLE<uint16_t>(0);
236 case sizeof(uint32_t):
237 pkt->
setLE<uint32_t>(0);
240 panic(
"invalid access size(?) for PCI configspace!\n");
243 panic(
"Out-of-range access to PCI config space!\n");
247 case sizeof(uint8_t):
250 "readConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
252 (uint32_t)pkt->
getLE<uint8_t>());
254 case sizeof(uint16_t):
257 "readConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
259 (uint32_t)pkt->
getLE<uint16_t>());
261 case sizeof(uint32_t):
264 "readConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
266 (uint32_t)pkt->
getLE<uint32_t>());
269 panic(
"invalid access size(?) for PCI configspace!\n");
281 for (x = 0; x < 6; x++)
295 warn_once(
"Device specific PCI config space " 296 "not implemented for %s!\n", this->
name());
298 case sizeof(uint8_t):
299 case sizeof(uint16_t):
300 case sizeof(uint32_t):
303 panic(
"invalid access size(?) for PCI configspace!\n");
306 panic(
"Out-of-range access to PCI config space!\n");
310 case sizeof(uint8_t):
329 panic(
"writing to a read only register");
332 "writeConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
334 (uint32_t)pkt->
getLE<uint8_t>());
336 case sizeof(uint16_t):
348 panic(
"writing to a read only register");
351 "writeConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
353 (uint32_t)pkt->
getLE<uint16_t>());
355 case sizeof(uint32_t):
369 uint32_t he_new_bar =
letoh(pkt->
getLE<uint32_t>());
377 if (he_new_bar == 0xffffffff) {
378 he_new_bar = ~(
BARSize[barnum] - 1);
381 he_new_bar &= ~bar_mask;
385 warn(
"IO BARs can't be set as large BAR");
386 uint64_t he_large_bar =
388 he_large_bar = he_large_bar << 32;
389 he_large_bar += he_new_bar;
394 uint64_t he_large_bar = he_new_bar;
395 he_large_bar = he_large_bar << 32;
411 (he_old_bar & bar_mask));
417 if (
letoh(pkt->
getLE<uint32_t>()) == 0xfffffffe)
434 "writeConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
436 (uint32_t)pkt->
getLE<uint32_t>());
439 panic(
"invalid access size(?) for PCI configspace!\n");
472 uint16_t msixcap_mxc_ts =
msixcap.
mxc & 0x07ff;
473 int msix_array_size = msixcap_mxc_ts + 1;
482 for (
int i = 0;
i < msix_array_size;
i++) {
492 for (
int i = 0;
i < pba_array_size;
i++) {
561 msix_pba.resize(pba_array_size, tmp2);
563 for (
int i = 0;
i < msix_array_size;
i++) {
573 for (
int i = 0;
i < pba_array_size;
i++) {
#define panic(...)
This implements a cprintf based panic() function.
AddrRange RangeSize(Addr start, Addr size)
void sendRangeChange() const
Called by the owner to send a range change.
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
#define fatal(...)
This implements a cprintf based fatal() function.
PCI device, base implementation is only config space.
const PciBusAddr _busAddr
#define PCI0_MINIMUM_GRANT
#define PCI_CACHE_LINE_SIZE
PciDevice(const PciDeviceParams *params)
Constructor for PCI Dev.
void setLE(T v)
Set the value in the data pointer to v as little endian.
PioPort< PioDevice > pioPort
The pioPort that handles the requests for us and provides us requests that it sees.
bool isLargeBAR(int bar) const
Does the given BAR represent 32 lower bits of a 64-bit address?
#define PCI0_MAXIMUM_LATENCY
#define UNSERIALIZE_SCALAR(scalar)
Addr memAddr(Addr addr) const
Calculate the physical address of a non-prefetchable memory location in the PCI address space...
std::string csprintf(const char *format, const Args &...args)
bool legacyIO[6]
Whether the BARs are really hardwired legacy IO locations.
void makeAtomicResponse()
uint64_t Tick
Tick count type.
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
#define SERIALIZE_ARRAY(member, size)
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
bool isPowerOf2(const T &n)
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
#define PCI_DEVICE_SPECIFIC
Declaration of IniFile object.
virtual const std::string name() const
std::vector< MSIXTable > msix_table
MSIX Table and PBA Structures.
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Addr BARAddrs[6]
The current address mapping of the BARs.
#define PCI0_ROM_BASE_ADDR
#define SERIALIZE_SCALAR(scalar)
uint16_t subsystemVendorID
#define UNSERIALIZE_ARRAY(member, size)
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
#define PCI0_INTERRUPT_LINE
#define PMCAP_ID
PCIe capability list offsets internal to the entry.
#define PCI_LATENCY_TIMER
#define PCI0_INTERRUPT_PIN
Declaration of the Packet class.
std::ostream CheckpointOut
std::vector< MSIXPbaEntry > msix_pba
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Addr pioAddr(Addr addr) const
Calculate the physical address of an IO location on the PCI bus.
PciHost::DeviceInterface hostInterface
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it...
PCIConfig config
The current config space.
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
uint32_t BARSize[6]
The size of the BARs.