56 #include "debug/PciDevice.hh" 64 _busAddr(p->pci_bus, p->pci_dev, p->pci_func),
65 PMCAP_BASE(p->PMCAPBaseOffset),
66 PMCAP_ID_OFFSET(p->PMCAPBaseOffset+
PMCAP_ID),
67 PMCAP_PC_OFFSET(p->PMCAPBaseOffset+
PMCAP_PC),
68 PMCAP_PMCS_OFFSET(p->PMCAPBaseOffset+
PMCAP_PMCS),
69 MSICAP_BASE(p->MSICAPBaseOffset),
70 MSIXCAP_BASE(p->MSIXCAPBaseOffset),
71 MSIXCAP_ID_OFFSET(p->MSIXCAPBaseOffset+
MSIXCAP_ID),
72 MSIXCAP_MXC_OFFSET(p->MSIXCAPBaseOffset+
MSIXCAP_MXC),
75 PXCAP_BASE(p->PXCAPBaseOffset),
77 hostInterface(p->host->registerDevice(this, _busAddr,
79 pioDelay(p->pio_latency),
80 configDelay(p->config_latency)
83 "Invalid PCI interrupt '%i' specified.", p->InterruptPin);
121 pmcap.
pid = (uint16_t)p->PMCAPCapId;
122 pmcap.
pid |= (uint16_t)p->PMCAPNextCapability << 8;
123 pmcap.
pc = p->PMCAPCapabilities;
128 msicap.
mid |= (uint16_t)p->MSICAPNextCapability << 8;
138 msixcap.
mxid |= (uint16_t)p->MSIXCAPNextCapability << 8;
150 uint16_t msixcap_mxc_ts =
msixcap.
mxc & 0x07ff;
152 int msix_vecs = msixcap_mxc_ts + 1;
165 (msixcap_mxc_ts + 1) *
sizeof(
MSIXTable);
176 pxcap.
pxid |= (uint16_t)p->PXCAPNextCapability << 8;
201 for (
int i = 0;
i < 6; ++
i) {
209 fatal(
"BAR %d size %d is not a power of 2\n", i,
BARSize[i]);
223 warn_once(
"Device specific PCI config space " 224 "not implemented for %s!\n", this->
name());
226 case sizeof(uint8_t):
227 pkt->
setLE<uint8_t>(0);
229 case sizeof(uint16_t):
230 pkt->
setLE<uint16_t>(0);
232 case sizeof(uint32_t):
233 pkt->
setLE<uint32_t>(0);
236 panic(
"invalid access size(?) for PCI configspace!\n");
239 panic(
"Out-of-range access to PCI config space!\n");
243 case sizeof(uint8_t):
246 "readConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
248 (uint32_t)pkt->
getLE<uint8_t>());
250 case sizeof(uint16_t):
253 "readConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
255 (uint32_t)pkt->
getLE<uint16_t>());
257 case sizeof(uint32_t):
260 "readConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
262 (uint32_t)pkt->
getLE<uint32_t>());
265 panic(
"invalid access size(?) for PCI configspace!\n");
277 for (x = 0; x < 6; x++)
291 warn_once(
"Device specific PCI config space " 292 "not implemented for %s!\n", this->
name());
294 case sizeof(uint8_t):
295 case sizeof(uint16_t):
296 case sizeof(uint32_t):
299 panic(
"invalid access size(?) for PCI configspace!\n");
302 panic(
"Out-of-range access to PCI config space!\n");
306 case sizeof(uint8_t):
325 panic(
"writing to a read only register");
328 "writeConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
330 (uint32_t)pkt->
getLE<uint8_t>());
332 case sizeof(uint16_t):
344 panic(
"writing to a read only register");
347 "writeConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
349 (uint32_t)pkt->
getLE<uint16_t>());
351 case sizeof(uint32_t):
365 uint32_t he_new_bar =
letoh(pkt->
getLE<uint32_t>());
373 if (he_new_bar == 0xffffffff) {
374 he_new_bar = ~(
BARSize[barnum] - 1);
377 he_new_bar &= ~bar_mask;
381 warn(
"IO BARs can't be set as large BAR");
382 uint64_t he_large_bar =
384 he_large_bar = he_large_bar << 32;
385 he_large_bar += he_new_bar;
390 uint64_t he_large_bar = he_new_bar;
391 he_large_bar = he_large_bar << 32;
407 (he_old_bar & bar_mask));
413 if (
letoh(pkt->
getLE<uint32_t>()) == 0xfffffffe)
430 "writeConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
432 (uint32_t)pkt->
getLE<uint32_t>());
435 panic(
"invalid access size(?) for PCI configspace!\n");
468 uint16_t msixcap_mxc_ts =
msixcap.
mxc & 0x07ff;
469 int msix_array_size = msixcap_mxc_ts + 1;
478 for (
int i = 0;
i < msix_array_size;
i++) {
488 for (
int i = 0;
i < pba_array_size;
i++) {
557 msix_pba.resize(pba_array_size, tmp2);
559 for (
int i = 0;
i < msix_array_size;
i++) {
569 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)
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.
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...
#define SERIALIZE_ARRAY(member, size)
Addr BARAddrs[6]
The current address mapping of the BARs.
#define PCI0_ROM_BASE_ADDR
#define SERIALIZE_SCALAR(scalar)
uint16_t subsystemVendorID
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
virtual const std::string name() const
#define UNSERIALIZE_ARRAY(member, size)
#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.