Go to the documentation of this file.
56 #include "debug/PciDevice.hh"
66 _busAddr(
p.pci_bus,
p.pci_dev,
p.pci_func),
67 PMCAP_BASE(
p.PMCAPBaseOffset),
68 PMCAP_ID_OFFSET(
p.PMCAPBaseOffset+
PMCAP_ID),
69 PMCAP_PC_OFFSET(
p.PMCAPBaseOffset+
PMCAP_PC),
71 MSICAP_BASE(
p.MSICAPBaseOffset),
72 MSIXCAP_BASE(
p.MSIXCAPBaseOffset),
77 PXCAP_BASE(
p.PXCAPBaseOffset),
79 hostInterface(
p.host->registerDevice(this, _busAddr,
81 pioDelay(
p.pio_latency),
82 configDelay(
p.config_latency)
85 "Invalid PCI interrupt '%i' specified.",
p.InterruptPin);
95 for (
auto *bar:
BARs) {
101 "First BAR in %s is upper 32 bits of a memory BAR.", idx);
103 fatal_if(!ml,
"Upper 32 bits of memory BAR in %s doesn't come "
104 "after the lower 32.");
124 for (
auto *bar:
BARs)
133 bzero(
config.reserved, 7*
sizeof(uint8_t));
145 pmcap.
pid |= (uint16_t)
p.PMCAPNextCapability << 8;
151 msicap.
mid |= (uint16_t)
p.MSICAPNextCapability << 8;
173 uint16_t msixcap_mxc_ts =
msixcap.
mxc & 0x07ff;
175 int msix_vecs = msixcap_mxc_ts + 1;
188 (msixcap_mxc_ts + 1) *
sizeof(
MSIXTable);
199 pxcap.
pxid |= (uint16_t)
p.PXCAPNextCapability << 8;
219 warn_once(
"Device specific PCI config space "
220 "not implemented for %s!\n", this->
name());
222 case sizeof(uint8_t):
223 pkt->
setLE<uint8_t>(0);
225 case sizeof(uint16_t):
226 pkt->
setLE<uint16_t>(0);
228 case sizeof(uint32_t):
229 pkt->
setLE<uint32_t>(0);
232 panic(
"invalid access size(?) for PCI configspace!\n");
235 panic(
"Out-of-range access to PCI config space!\n");
239 case sizeof(uint8_t):
242 "readConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
244 (uint32_t)pkt->
getLE<uint8_t>());
246 case sizeof(uint16_t):
249 "readConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
251 (uint32_t)pkt->
getLE<uint16_t>());
253 case sizeof(uint32_t):
256 "readConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
258 (uint32_t)pkt->
getLE<uint32_t>());
261 panic(
"invalid access size(?) for PCI configspace!\n");
272 PciCommandRegister command =
letoh(
config.command);
273 for (
auto *bar:
BARs) {
274 if (command.ioSpace && bar->isIo())
275 ranges.push_back(bar->range());
276 if (command.memorySpace && bar->isMem())
277 ranges.push_back(bar->range());
290 warn_once(
"Device specific PCI config space "
291 "not implemented for %s!\n", this->
name());
293 case sizeof(uint8_t):
294 case sizeof(uint16_t):
295 case sizeof(uint32_t):
298 panic(
"invalid access size(?) for PCI configspace!\n");
301 panic(
"Out-of-range access to PCI config space!\n");
305 case sizeof(uint8_t):
324 panic(
"writing to a read only register");
327 "writeConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
329 (uint32_t)pkt->
getLE<uint8_t>());
331 case sizeof(uint16_t):
345 panic(
"writing to a read only register");
348 "writeConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
350 (uint32_t)pkt->
getLE<uint16_t>());
352 case sizeof(uint32_t):
362 auto *bar =
BARs[num];
370 if (
letoh(pkt->
getLE<uint32_t>()) == 0xfffffffe)
389 "writeConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
391 (uint32_t)pkt->
getLE<uint32_t>());
394 panic(
"invalid access size(?) for PCI configspace!\n");
425 uint16_t msixcap_mxc_ts =
msixcap.
mxc & 0x07ff;
426 int msix_array_size = msixcap_mxc_ts + 1;
435 for (
int i = 0;
i < msix_array_size;
i++) {
445 for (
int i = 0;
i < pba_array_size;
i++) {
469 for (
int idx = 0; idx <
BARs.size(); idx++)
515 msix_pba.resize(pba_array_size, tmp2);
517 for (
int i = 0;
i < msix_array_size;
i++) {
527 for (
int i = 0;
i < pba_array_size;
i++) {
PCIConfig config
The current config space.
#define PCI0_MINIMUM_GRANT
#define UNSERIALIZE_SCALAR(scalar)
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
PioPort< PioDevice > pioPort
The pioPort that handles the requests for us and provides us requests that it sees.
std::vector< MSIXPbaEntry > msix_pba
std::string csprintf(const char *format, const Args &...args)
void makeAtomicResponse()
#define PCI_LATENCY_TIMER
#define PCI_DEVICE_SPECIFIC
#define PCI0_INTERRUPT_LINE
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
#define PCI0_ROM_BASE_ADDR
virtual std::string name() const
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
uint64_t Tick
Tick count type.
std::array< PciBar *, 6 > BARs
PCI device, base implementation is only config space.
PciHost::DeviceInterface hostInterface
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
#define SERIALIZE_ARRAY(member, size)
#define PCI0_MAXIMUM_LATENCY
#define SERIALIZE_SCALAR(scalar)
const PciBusAddr _busAddr
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
#define UNSERIALIZE_ARRAY(member, size)
#define PCI_CACHE_LINE_SIZE
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
virtual Tick write(PacketPtr pkt)=0
Pure virtual function that the device must implement.
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
std::ostream CheckpointOut
void setLE(T v)
Set the value in the data pointer to v as little endian.
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
std::vector< MSIXTable > msix_table
MSIX Table and PBA Structures.
#define PMCAP_ID
PCIe capability list offsets internal to the entry.
#define panic(...)
This implements a cprintf based panic() function.
PciDevice(const PciDeviceParams ¶ms)
Constructor for PCI Dev.
#define PCI0_INTERRUPT_PIN
Generated on Sun Jul 30 2023 01:56:52 for gem5 by doxygen 1.8.17