gem5 v24.0.0.0
Loading...
Searching...
No Matches
device.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2013, 2015 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Copyright (c) 2004-2005 The Regents of The University of Michigan
15 * All rights reserved.
16 *
17 * Redistribution and use in source and binary forms, with or without
18 * modification, are permitted provided that the following conditions are
19 * met: redistributions of source code must retain the above copyright
20 * notice, this list of conditions and the following disclaimer;
21 * redistributions in binary form must reproduce the above copyright
22 * notice, this list of conditions and the following disclaimer in the
23 * documentation and/or other materials provided with the distribution;
24 * neither the name of the copyright holders nor the names of its
25 * contributors may be used to endorse or promote products derived from
26 * this software without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 */
40
41/* @file
42 * A single PCI device configuration space entry.
43 */
44
45#include "dev/pci/device.hh"
46
47#include <list>
48#include <string>
49#include <vector>
50
51#include "base/inifile.hh"
52#include "base/intmath.hh"
53#include "base/logging.hh"
54#include "base/str.hh"
55#include "base/trace.hh"
56#include "debug/PciDevice.hh"
57#include "mem/packet.hh"
58#include "mem/packet_access.hh"
59#include "sim/byteswap.hh"
60
61namespace gem5
62{
63
64PciDevice::PciDevice(const PciDeviceParams &p)
65 : DmaDevice(p),
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),
70 PMCAP_PMCS_OFFSET(p.PMCAPBaseOffset+PMCAP_PMCS),
71 MSICAP_BASE(p.MSICAPBaseOffset),
72 MSIXCAP_BASE(p.MSIXCAPBaseOffset),
73 MSIXCAP_ID_OFFSET(p.MSIXCAPBaseOffset+MSIXCAP_ID),
74 MSIXCAP_MXC_OFFSET(p.MSIXCAPBaseOffset+MSIXCAP_MXC),
75 MSIXCAP_MTAB_OFFSET(p.MSIXCAPBaseOffset+MSIXCAP_MTAB),
76 MSIXCAP_MPBA_OFFSET(p.MSIXCAPBaseOffset+MSIXCAP_MPBA),
77 PXCAP_BASE(p.PXCAPBaseOffset),
78
79 hostInterface(p.host->registerDevice(this, _busAddr,
80 (PciIntPin)p.InterruptPin)),
81 pioDelay(p.pio_latency),
82 configDelay(p.config_latency)
83{
84 fatal_if(p.InterruptPin >= 5,
85 "Invalid PCI interrupt '%i' specified.", p.InterruptPin);
86
87 BARs[0] = p.BAR0;
88 BARs[1] = p.BAR1;
89 BARs[2] = p.BAR2;
90 BARs[3] = p.BAR3;
91 BARs[4] = p.BAR4;
92 BARs[5] = p.BAR5;
93
94 int idx = 0;
95 for (auto *bar: BARs) {
96 auto *mu = dynamic_cast<PciMemUpperBar *>(bar);
97 // If this is the upper 32 bits of a memory BAR, try to connect it to
98 // the lower 32 bits.
99 if (mu) {
100 fatal_if(idx == 0,
101 "First BAR in %s is upper 32 bits of a memory BAR.", idx);
102 auto *ml = dynamic_cast<PciMemBar *>(BARs[idx - 1]);
103 fatal_if(!ml, "Upper 32 bits of memory BAR in %s doesn't come "
104 "after the lower 32.");
105 mu->lower(ml);
106 }
107 idx++;
108 }
109
110 config.vendor = htole(p.VendorID);
111 config.device = htole(p.DeviceID);
112 config.command = htole(p.Command);
113 config.status = htole(p.Status);
114 config.revision = htole(p.Revision);
115 config.progIF = htole(p.ProgIF);
116 config.subClassCode = htole(p.SubClassCode);
117 config.classCode = htole(p.ClassCode);
118 config.cacheLineSize = htole(p.CacheLineSize);
119 config.latencyTimer = htole(p.LatencyTimer);
120 config.headerType = htole(p.HeaderType);
121 config.bist = htole(p.BIST);
122
123 idx = 0;
124 for (auto *bar: BARs)
125 config.baseAddr[idx++] = bar->write(hostInterface, 0);
126
127 config.cardbusCIS = htole(p.CardbusCIS);
128 config.subsystemVendorID = htole(p.SubsystemVendorID);
129 config.subsystemID = htole(p.SubsystemID);
130 config.expansionROM = htole(p.ExpansionROM);
131 config.capabilityPtr = htole(p.CapabilityPtr);
132 // Zero out the 7 bytes of reserved space in the PCI Config space register.
133 bzero(config.reserved, 7*sizeof(uint8_t));
134 config.interruptLine = htole(p.InterruptLine);
135 config.interruptPin = htole(p.InterruptPin);
136 config.minimumGrant = htole(p.MinimumGrant);
137 config.maximumLatency = htole(p.MaximumLatency);
138
139 // Initialize the capability lists
140 // These structs are bitunions, meaning the data is stored in host
141 // endianess and must be converted to Little Endian when accessed
142 // by the guest
143 // PMCAP
144 pmcap.pid = (uint16_t)p.PMCAPCapId; // pid.cid
145 pmcap.pid |= (uint16_t)p.PMCAPNextCapability << 8; //pid.next
146 pmcap.pc = p.PMCAPCapabilities;
147 pmcap.pmcs = p.PMCAPCtrlStatus;
148
149 // MSICAP
150 msicap.mid = (uint16_t)p.MSICAPCapId; //mid.cid
151 msicap.mid |= (uint16_t)p.MSICAPNextCapability << 8; //mid.next
152 msicap.mc = p.MSICAPMsgCtrl;
153 msicap.ma = p.MSICAPMsgAddr;
154 msicap.mua = p.MSICAPMsgUpperAddr;
155 msicap.md = p.MSICAPMsgData;
156 msicap.mmask = p.MSICAPMaskBits;
157 msicap.mpend = p.MSICAPPendingBits;
158
159 // MSIXCAP
160 msixcap.mxid = (uint16_t)p.MSIXCAPCapId; //mxid.cid
161 msixcap.mxid |= (uint16_t)p.MSIXCAPNextCapability << 8; //mxid.next
162 msixcap.mxc = p.MSIXMsgCtrl;
163 msixcap.mtab = p.MSIXTableOffset;
164 msixcap.mpba = p.MSIXPbaOffset;
165
166 // allocate MSIX structures if MSIXCAP_BASE
167 // indicates the MSIXCAP is being used by having a
168 // non-zero base address.
169 // The MSIX tables are stored by the guest in
170 // little endian byte-order as according the
171 // PCIe specification. Make sure to take the proper
172 // actions when manipulating these tables on the host
173 uint16_t msixcap_mxc_ts = msixcap.mxc & 0x07ff;
174 if (MSIXCAP_BASE != 0x0) {
175 int msix_vecs = msixcap_mxc_ts + 1;
176 MSIXTable tmp1 = {{0UL,0UL,0UL,0UL}};
177 msix_table.resize(msix_vecs, tmp1);
178
179 MSIXPbaEntry tmp2 = {0};
180 int pba_size = msix_vecs / MSIXVECS_PER_PBA;
181 if ((msix_vecs % MSIXVECS_PER_PBA) > 0) {
182 pba_size++;
183 }
184 msix_pba.resize(pba_size, tmp2);
185 }
186 MSIX_TABLE_OFFSET = msixcap.mtab & 0xfffffffc;
188 (msixcap_mxc_ts + 1) * sizeof(MSIXTable);
189 MSIX_PBA_OFFSET = msixcap.mpba & 0xfffffffc;
191 ((msixcap_mxc_ts + 1) / MSIXVECS_PER_PBA)
192 * sizeof(MSIXPbaEntry);
193 if (((msixcap_mxc_ts + 1) % MSIXVECS_PER_PBA) > 0) {
194 MSIX_PBA_END += sizeof(MSIXPbaEntry);
195 }
196
197 // PXCAP
198 pxcap.pxid = (uint16_t)p.PXCAPCapId; //pxid.cid
199 pxcap.pxid |= (uint16_t)p.PXCAPNextCapability << 8; //pxid.next
200 pxcap.pxcap = p.PXCAPCapabilities;
201 pxcap.pxdcap = p.PXCAPDevCapabilities;
202 pxcap.pxdc = p.PXCAPDevCtrl;
203 pxcap.pxds = p.PXCAPDevStatus;
204 pxcap.pxlcap = p.PXCAPLinkCap;
205 pxcap.pxlc = p.PXCAPLinkCtrl;
206 pxcap.pxls = p.PXCAPLinkStatus;
207 pxcap.pxdcap2 = p.PXCAPDevCap2;
208 pxcap.pxdc2 = p.PXCAPDevCtrl2;
209}
210
211Tick
213{
214 int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
215
216 /* Return 0 for accesses to unimplemented PCI configspace areas */
219 warn_once("Device specific PCI config space "
220 "not implemented for %s!\n", this->name());
221 switch (pkt->getSize()) {
222 case sizeof(uint8_t):
223 pkt->setLE<uint8_t>(0);
224 break;
225 case sizeof(uint16_t):
226 pkt->setLE<uint16_t>(0);
227 break;
228 case sizeof(uint32_t):
229 pkt->setLE<uint32_t>(0);
230 break;
231 default:
232 panic("invalid access size(?) for PCI configspace!\n");
233 }
234 } else if (offset > PCI_CONFIG_SIZE) {
235 panic("Out-of-range access to PCI config space!\n");
236 }
237
238 switch (pkt->getSize()) {
239 case sizeof(uint8_t):
240 pkt->setLE<uint8_t>(config.data[offset]);
242 "readConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
244 (uint32_t)pkt->getLE<uint8_t>());
245 break;
246 case sizeof(uint16_t):
247 pkt->setLE<uint16_t>(*(uint16_t*)&config.data[offset]);
249 "readConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
251 (uint32_t)pkt->getLE<uint16_t>());
252 break;
253 case sizeof(uint32_t):
254 pkt->setLE<uint32_t>(*(uint32_t*)&config.data[offset]);
256 "readConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
258 (uint32_t)pkt->getLE<uint32_t>());
259 break;
260 default:
261 panic("invalid access size(?) for PCI configspace!\n");
262 }
263 pkt->makeAtomicResponse();
264 return configDelay;
265
266}
267
270{
271 AddrRangeList ranges;
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());
278 }
279 return ranges;
280}
281
282Tick
284{
285 int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
286
287 /* No effect if we write to config space that is not implemented*/
290 warn_once("Device specific PCI config space "
291 "not implemented for %s!\n", this->name());
292 switch (pkt->getSize()) {
293 case sizeof(uint8_t):
294 case sizeof(uint16_t):
295 case sizeof(uint32_t):
296 break;
297 default:
298 panic("invalid access size(?) for PCI configspace!\n");
299 }
300 } else if (offset > PCI_CONFIG_SIZE) {
301 panic("Out-of-range access to PCI config space!\n");
302 }
303
304 switch (pkt->getSize()) {
305 case sizeof(uint8_t):
306 switch (offset) {
308 config.interruptLine = pkt->getLE<uint8_t>();
309 break;
311 config.cacheLineSize = pkt->getLE<uint8_t>();
312 break;
314 config.latencyTimer = pkt->getLE<uint8_t>();
315 break;
316 /* Do nothing for these read-only registers */
320 case PCI_CLASS_CODE:
321 case PCI_REVISION_ID:
322 break;
323 default:
324 panic("writing to a read only register");
325 }
327 "writeConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
329 (uint32_t)pkt->getLE<uint8_t>());
330 break;
331 case sizeof(uint16_t):
332 switch (offset) {
333 case PCI_COMMAND:
334 config.command = pkt->getLE<uint8_t>();
335 // IO or memory space may have been enabled/disabled.
336 pioPort.sendRangeChange();
337 break;
338 case PCI_STATUS:
339 config.status = pkt->getLE<uint8_t>();
340 break;
342 config.cacheLineSize = pkt->getLE<uint8_t>();
343 break;
344 default:
345 panic("writing to a read only register");
346 }
348 "writeConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
350 (uint32_t)pkt->getLE<uint16_t>());
351 break;
352 case sizeof(uint32_t):
353 switch (offset) {
354 case PCI0_BASE_ADDR0:
355 case PCI0_BASE_ADDR1:
356 case PCI0_BASE_ADDR2:
357 case PCI0_BASE_ADDR3:
358 case PCI0_BASE_ADDR4:
359 case PCI0_BASE_ADDR5:
360 {
361 int num = BAR_NUMBER(offset);
362 auto *bar = BARs[num];
363 config.baseAddr[num] =
364 htole(bar->write(hostInterface, pkt->getLE<uint32_t>()));
365 pioPort.sendRangeChange();
366 }
367 break;
368
370 if (letoh(pkt->getLE<uint32_t>()) == 0xfffffffe)
371 config.expansionROM = htole((uint32_t)0xffffffff);
372 else
373 config.expansionROM = pkt->getLE<uint32_t>();
374 break;
375
376 case PCI_COMMAND:
377 // This could also clear some of the error bits in the Status
378 // register. However they should never get set, so lets ignore
379 // it for now
380 config.command = pkt->getLE<uint32_t>();
381 // IO or memory space may have been enabled/disabled.
382 pioPort.sendRangeChange();
383 break;
384
385 default:
386 DPRINTF(PciDevice, "Writing to a read only register");
387 }
389 "writeConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
391 (uint32_t)pkt->getLE<uint32_t>());
392 break;
393 default:
394 panic("invalid access size(?) for PCI configspace!\n");
395 }
396 pkt->makeAtomicResponse();
397 return configDelay;
398}
399
400void
402{
403 SERIALIZE_ARRAY(config.data, sizeof(config.data) / sizeof(config.data[0]));
404
405 // serialize the capability list registers
406 paramOut(cp, csprintf("pmcap.pid"), uint16_t(pmcap.pid));
407 paramOut(cp, csprintf("pmcap.pc"), uint16_t(pmcap.pc));
408 paramOut(cp, csprintf("pmcap.pmcs"), uint16_t(pmcap.pmcs));
409
410 paramOut(cp, csprintf("msicap.mid"), uint16_t(msicap.mid));
411 paramOut(cp, csprintf("msicap.mc"), uint16_t(msicap.mc));
412 paramOut(cp, csprintf("msicap.ma"), uint32_t(msicap.ma));
414 paramOut(cp, csprintf("msicap.md"), uint16_t(msicap.md));
417
418 paramOut(cp, csprintf("msixcap.mxid"), uint16_t(msixcap.mxid));
419 paramOut(cp, csprintf("msixcap.mxc"), uint16_t(msixcap.mxc));
420 paramOut(cp, csprintf("msixcap.mtab"), uint32_t(msixcap.mtab));
421 paramOut(cp, csprintf("msixcap.mpba"), uint32_t(msixcap.mpba));
422
423 // Only serialize if we have a non-zero base address
424 if (MSIXCAP_BASE != 0x0) {
425 uint16_t msixcap_mxc_ts = msixcap.mxc & 0x07ff;
426 int msix_array_size = msixcap_mxc_ts + 1;
427 int pba_array_size = msix_array_size/MSIXVECS_PER_PBA;
428 if ((msix_array_size % MSIXVECS_PER_PBA) > 0) {
429 pba_array_size++;
430 }
431
432 SERIALIZE_SCALAR(msix_array_size);
433 SERIALIZE_SCALAR(pba_array_size);
434
435 for (int i = 0; i < msix_array_size; i++) {
436 paramOut(cp, csprintf("msix_table[%d].addr_lo", i),
437 msix_table[i].fields.addr_lo);
438 paramOut(cp, csprintf("msix_table[%d].addr_hi", i),
439 msix_table[i].fields.addr_hi);
440 paramOut(cp, csprintf("msix_table[%d].msg_data", i),
441 msix_table[i].fields.msg_data);
442 paramOut(cp, csprintf("msix_table[%d].vec_ctrl", i),
443 msix_table[i].fields.vec_ctrl);
444 }
445 for (int i = 0; i < pba_array_size; i++) {
446 paramOut(cp, csprintf("msix_pba[%d].bits", i),
447 msix_pba[i].bits);
448 }
449 }
450
451 paramOut(cp, csprintf("pxcap.pxid"), uint16_t(pxcap.pxid));
452 paramOut(cp, csprintf("pxcap.pxcap"), uint16_t(pxcap.pxcap));
453 paramOut(cp, csprintf("pxcap.pxdcap"), uint32_t(pxcap.pxdcap));
454 paramOut(cp, csprintf("pxcap.pxdc"), uint16_t(pxcap.pxdc));
455 paramOut(cp, csprintf("pxcap.pxds"), uint16_t(pxcap.pxds));
456 paramOut(cp, csprintf("pxcap.pxlcap"), uint32_t(pxcap.pxlcap));
457 paramOut(cp, csprintf("pxcap.pxlc"), uint16_t(pxcap.pxlc));
458 paramOut(cp, csprintf("pxcap.pxls"), uint16_t(pxcap.pxls));
459 paramOut(cp, csprintf("pxcap.pxdcap2"), uint32_t(pxcap.pxdcap2));
460 paramOut(cp, csprintf("pxcap.pxdc2"), uint32_t(pxcap.pxdc2));
461}
462
463void
465{
467 sizeof(config.data) / sizeof(config.data[0]));
468
469 for (int idx = 0; idx < BARs.size(); idx++)
470 BARs[idx]->write(hostInterface, config.baseAddr[idx]);
471
472 // unserialize the capability list registers
473 uint16_t tmp16;
474 uint32_t tmp32;
475 paramIn(cp, csprintf("pmcap.pid"), tmp16);
476 pmcap.pid = tmp16;
477 paramIn(cp, csprintf("pmcap.pc"), tmp16);
478 pmcap.pc = tmp16;
479 paramIn(cp, csprintf("pmcap.pmcs"), tmp16);
480 pmcap.pmcs = tmp16;
481
482 paramIn(cp, csprintf("msicap.mid"), tmp16);
483 msicap.mid = tmp16;
484 paramIn(cp, csprintf("msicap.mc"), tmp16);
485 msicap.mc = tmp16;
486 paramIn(cp, csprintf("msicap.ma"), tmp32);
487 msicap.ma = tmp32;
489 paramIn(cp, csprintf("msicap.md"), tmp16);;
490 msicap.md = tmp16;
493
494 paramIn(cp, csprintf("msixcap.mxid"), tmp16);
495 msixcap.mxid = tmp16;
496 paramIn(cp, csprintf("msixcap.mxc"), tmp16);
497 msixcap.mxc = tmp16;
498 paramIn(cp, csprintf("msixcap.mtab"), tmp32);
499 msixcap.mtab = tmp32;
500 paramIn(cp, csprintf("msixcap.mpba"), tmp32);
501 msixcap.mpba = tmp32;
502
503 // Only allocate if MSIXCAP_BASE is not 0x0
504 if (MSIXCAP_BASE != 0x0) {
505 int msix_array_size;
506 int pba_array_size;
507
508 UNSERIALIZE_SCALAR(msix_array_size);
509 UNSERIALIZE_SCALAR(pba_array_size);
510
511 MSIXTable tmp1 = {{0UL, 0UL, 0UL, 0UL}};
512 msix_table.resize(msix_array_size, tmp1);
513
514 MSIXPbaEntry tmp2 = {0};
515 msix_pba.resize(pba_array_size, tmp2);
516
517 for (int i = 0; i < msix_array_size; i++) {
518 paramIn(cp, csprintf("msix_table[%d].addr_lo", i),
519 msix_table[i].fields.addr_lo);
520 paramIn(cp, csprintf("msix_table[%d].addr_hi", i),
521 msix_table[i].fields.addr_hi);
522 paramIn(cp, csprintf("msix_table[%d].msg_data", i),
523 msix_table[i].fields.msg_data);
524 paramIn(cp, csprintf("msix_table[%d].vec_ctrl", i),
525 msix_table[i].fields.vec_ctrl);
526 }
527 for (int i = 0; i < pba_array_size; i++) {
528 paramIn(cp, csprintf("msix_pba[%d].bits", i),
529 msix_pba[i].bits);
530 }
531 }
532
533 paramIn(cp, csprintf("pxcap.pxid"), tmp16);
534 pxcap.pxid = tmp16;
535 paramIn(cp, csprintf("pxcap.pxcap"), tmp16);
536 pxcap.pxcap = tmp16;
537 paramIn(cp, csprintf("pxcap.pxdcap"), tmp32);
538 pxcap.pxdcap = tmp32;
539 paramIn(cp, csprintf("pxcap.pxdc"), tmp16);
540 pxcap.pxdc = tmp16;
541 paramIn(cp, csprintf("pxcap.pxds"), tmp16);
542 pxcap.pxds = tmp16;
543 paramIn(cp, csprintf("pxcap.pxlcap"), tmp32);
544 pxcap.pxlcap = tmp32;
545 paramIn(cp, csprintf("pxcap.pxlc"), tmp16);
546 pxcap.pxlc = tmp16;
547 paramIn(cp, csprintf("pxcap.pxls"), tmp16);
548 pxcap.pxls = tmp16;
549 paramIn(cp, csprintf("pxcap.pxdcap2"), tmp32);
550 pxcap.pxdcap2 = tmp32;
551 paramIn(cp, csprintf("pxcap.pxdc2"), tmp32);
552 pxcap.pxdc2 = tmp32;
553 pioPort.sendRangeChange();
554}
555
556} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:210
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
Addr getAddr() const
Definition packet.hh:807
void setLE(T v)
Set the value in the data pointer to v as little endian.
unsigned getSize() const
Definition packet.hh:817
void makeAtomicResponse()
Definition packet.hh:1074
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
PCI device, base implementation is only config space.
Definition device.hh:270
PciHost::DeviceInterface hostInterface
Definition device.hh:352
PCIConfig config
The current config space.
Definition device.hh:275
MSICAP msicap
Definition device.hh:287
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition device.cc:464
std::vector< MSIXTable > msix_table
MSIX Table and PBA Structures.
Definition device.hh:305
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition device.cc:401
const int MSIXCAP_BASE
Definition device.hh:289
std::array< PciBar *, 6 > BARs
Definition device.hh:308
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
Definition device.cc:269
int MSIX_PBA_OFFSET
Definition device.hh:296
const PciBusAddr _busAddr
Definition device.hh:272
std::vector< MSIXPbaEntry > msix_pba
Definition device.hh:306
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
Definition device.cc:212
MSIXCAP msixcap
Definition device.hh:298
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
Definition device.cc:283
int MSIX_TABLE_OFFSET
Definition device.hh:294
PciDevice(const PciDeviceParams &params)
Constructor for PCI Dev.
Definition device.cc:64
PioPort< PioDevice > pioPort
The pioPort that handles the requests for us and provides us requests that it sees.
Definition io_device.hh:109
virtual Tick write(PacketPtr pkt)=0
Pure virtual function that the device must implement.
#define BAR_NUMBER(x)
Definition device.hh:64
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition bitfield.hh:79
#define panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:188
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
#define UNSERIALIZE_ARRAY(member, size)
Definition serialize.hh:618
#define SERIALIZE_ARRAY(member, size)
Definition serialize.hh:610
Declaration of IniFile object.
#define warn_once(...)
Definition logging.hh:260
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 23, 0 > offset
Definition types.hh:144
Bitfield< 0 > p
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
T letoh(T value)
Definition byteswap.hh:173
PciIntPin
Definition types.hh:67
std::ostream CheckpointOut
Definition serialize.hh:66
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition types.cc:40
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition types.cc:72
uint64_t Tick
Tick count type.
Definition types.hh:58
T htole(T value)
Definition byteswap.hh:172
std::string csprintf(const char *format, const Args &...args)
Definition cprintf.hh:161
Declaration of the Packet class.
#define PCI0_INTERRUPT_PIN
Definition pcireg.h:135
#define PCI0_MINIMUM_GRANT
Definition pcireg.h:136
#define PMCAP_PMCS
Definition pcireg.h:187
#define PCI_STATUS
Definition pcireg.h:106
#define PCI0_INTERRUPT_LINE
Definition pcireg.h:134
#define PCI0_BASE_ADDR4
Definition pcireg.h:126
#define PCI0_MAXIMUM_LATENCY
Definition pcireg.h:137
#define PCI0_BASE_ADDR0
Definition pcireg.h:122
#define PCI0_BASE_ADDR5
Definition pcireg.h:127
#define PCI0_ROM_BASE_ADDR
Definition pcireg.h:131
#define PCI0_BASE_ADDR1
Definition pcireg.h:123
#define PCI0_BASE_ADDR2
Definition pcireg.h:124
#define MSIXVECS_PER_PBA
Definition pcireg.h:319
#define PCI0_BASE_ADDR3
Definition pcireg.h:125
#define MSIXCAP_MPBA
Definition pcireg.h:202
#define PMCAP_ID
PCIe capability list offsets internal to the entry.
Definition pcireg.h:185
#define MSIXCAP_MXC
Definition pcireg.h:200
#define PCI_CACHE_LINE_SIZE
Definition pcireg.h:111
#define PMCAP_PC
Definition pcireg.h:186
#define PCI_DEVICE_SPECIFIC
Definition pcireg.h:164
#define PCI_COMMAND
Definition pcireg.h:105
#define PCI_REVISION_ID
Definition pcireg.h:107
#define MSIXCAP_ID
Definition pcireg.h:199
#define PCI_CONFIG_SIZE
Definition pcireg.h:165
#define PCI_LATENCY_TIMER
Definition pcireg.h:112
#define PCI_CLASS_CODE
Definition pcireg.h:108
#define MSIXCAP_MTAB
Definition pcireg.h:201
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
uint8_t func
Definition types.hh:58
uint8_t dev
Definition types.hh:57
const std::string & name()
Definition trace.cc:48
uint32_t mpend
Definition pcireg.h:277
uint32_t mmask
Definition pcireg.h:276
uint32_t mua
Definition pcireg.h:274
uint16_t md
Definition pcireg.h:275
uint16_t mc
Definition pcireg.h:264
uint32_t ma
Definition pcireg.h:271
uint16_t mid
Definition pcireg.h:261
uint32_t mpba
Definition pcireg.h:301
uint16_t mxc
Definition pcireg.h:293
uint32_t mtab
Definition pcireg.h:298
uint16_t mxid
Definition pcireg.h:290
uint16_t pmcs
Definition pcireg.h:238
uint16_t pc
Definition pcireg.h:229
uint16_t pid
Definition pcireg.h:226
uint16_t pxlc
Definition pcireg.h:389
uint32_t pxdcap
Definition pcireg.h:343
uint32_t pxdc2
Definition pcireg.h:423
uint32_t pxlcap
Definition pcireg.h:377
uint16_t pxcap
Definition pcireg.h:337
uint16_t pxls
Definition pcireg.h:399
uint16_t pxdc
Definition pcireg.h:356
uint16_t pxid
Definition pcireg.h:334
uint16_t pxds
Definition pcireg.h:369
uint32_t pxdcap2
Definition pcireg.h:406

Generated on Tue Jun 18 2024 16:24:01 for gem5 by doxygen 1.11.0