gem5  v22.1.0.0
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 
61 namespace gem5
62 {
63 
64 PciDevice::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 
211 Tick
213 {
214  int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
215 
216  /* Return 0 for accesses to unimplemented PCI configspace areas */
217  if (offset >= PCI_DEVICE_SPECIFIC &&
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 
282 Tick
284 {
285  int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
286 
287  /* No effect if we write to config space that is not implemented*/
288  if (offset >= PCI_DEVICE_SPECIFIC &&
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) {
307  case PCI0_INTERRUPT_LINE:
308  config.interruptLine = pkt->getLE<uint8_t>();
309  break;
310  case PCI_CACHE_LINE_SIZE:
311  config.cacheLineSize = pkt->getLE<uint8_t>();
312  break;
313  case PCI_LATENCY_TIMER:
314  config.latencyTimer = pkt->getLE<uint8_t>();
315  break;
316  /* Do nothing for these read-only registers */
317  case PCI0_INTERRUPT_PIN:
318  case PCI0_MINIMUM_GRANT:
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;
341  case PCI_CACHE_LINE_SIZE:
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 
369  case PCI0_ROM_BASE_ADDR:
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 
400 void
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 
463 void
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:186
virtual std::string name() const
Definition: named.hh:47
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
Addr getAddr() const
Definition: packet.hh:805
void setLE(T v)
Set the value in the data pointer to v as little endian.
unsigned getSize() const
Definition: packet.hh:815
void makeAtomicResponse()
Definition: packet.hh:1071
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
int MSIX_PBA_END
Definition: device.hh:297
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
Tick configDelay
Definition: device.hh:355
int MSIX_TABLE_END
Definition: device.hh:295
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:76
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:226
#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:250
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 23, 0 > offset
Definition: types.hh:144
Bitfield< 54 > p
Definition: pagetable.hh:70
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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
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
uint8_t func
Definition: types.hh:58
uint8_t dev
Definition: types.hh:57
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

Generated on Wed Dec 21 2022 10:22:30 for gem5 by doxygen 1.9.1