gem5  v21.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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 #include "sim/core.hh"
61 
62 PciDevice::PciDevice(const PciDeviceParams &p)
63  : DmaDevice(p),
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),
73  MSIXCAP_MTAB_OFFSET(p.MSIXCAPBaseOffset+MSIXCAP_MTAB),
74  MSIXCAP_MPBA_OFFSET(p.MSIXCAPBaseOffset+MSIXCAP_MPBA),
75  PXCAP_BASE(p.PXCAPBaseOffset),
76 
77  hostInterface(p.host->registerDevice(this, _busAddr,
78  (PciIntPin)p.InterruptPin)),
79  pioDelay(p.pio_latency),
80  configDelay(p.config_latency)
81 {
82  fatal_if(p.InterruptPin >= 5,
83  "Invalid PCI interrupt '%i' specified.", p.InterruptPin);
84 
85  BARs[0] = p.BAR0;
86  BARs[1] = p.BAR1;
87  BARs[2] = p.BAR2;
88  BARs[3] = p.BAR3;
89  BARs[4] = p.BAR4;
90  BARs[5] = p.BAR5;
91 
92  int idx = 0;
93  for (auto *bar: BARs) {
94  auto *mu = dynamic_cast<PciMemUpperBar *>(bar);
95  // If this is the upper 32 bits of a memory BAR, try to connect it to
96  // the lower 32 bits.
97  if (mu) {
98  fatal_if(idx == 0,
99  "First BAR in %s is upper 32 bits of a memory BAR.", idx);
100  auto *ml = dynamic_cast<PciMemBar *>(BARs[idx - 1]);
101  fatal_if(!ml, "Upper 32 bits of memory BAR in %s doesn't come "
102  "after the lower 32.");
103  mu->lower(ml);
104  }
105  idx++;
106  }
107 
108  config.vendor = htole(p.VendorID);
109  config.device = htole(p.DeviceID);
110  config.command = htole(p.Command);
111  config.status = htole(p.Status);
112  config.revision = htole(p.Revision);
113  config.progIF = htole(p.ProgIF);
114  config.subClassCode = htole(p.SubClassCode);
115  config.classCode = htole(p.ClassCode);
116  config.cacheLineSize = htole(p.CacheLineSize);
117  config.latencyTimer = htole(p.LatencyTimer);
118  config.headerType = htole(p.HeaderType);
119  config.bist = htole(p.BIST);
120 
121  idx = 0;
122  for (auto *bar: BARs)
123  config.baseAddr[idx++] = bar->write(hostInterface, 0);
124 
125  config.cardbusCIS = htole(p.CardbusCIS);
126  config.subsystemVendorID = htole(p.SubsystemVendorID);
127  config.subsystemID = htole(p.SubsystemID);
128  config.expansionROM = htole(p.ExpansionROM);
129  config.capabilityPtr = htole(p.CapabilityPtr);
130  // Zero out the 7 bytes of reserved space in the PCI Config space register.
131  bzero(config.reserved, 7*sizeof(uint8_t));
132  config.interruptLine = htole(p.InterruptLine);
133  config.interruptPin = htole(p.InterruptPin);
134  config.minimumGrant = htole(p.MinimumGrant);
135  config.maximumLatency = htole(p.MaximumLatency);
136 
137  // Initialize the capability lists
138  // These structs are bitunions, meaning the data is stored in host
139  // endianess and must be converted to Little Endian when accessed
140  // by the guest
141  // PMCAP
142  pmcap.pid = (uint16_t)p.PMCAPCapId; // pid.cid
143  pmcap.pid |= (uint16_t)p.PMCAPNextCapability << 8; //pid.next
144  pmcap.pc = p.PMCAPCapabilities;
145  pmcap.pmcs = p.PMCAPCtrlStatus;
146 
147  // MSICAP
148  msicap.mid = (uint16_t)p.MSICAPCapId; //mid.cid
149  msicap.mid |= (uint16_t)p.MSICAPNextCapability << 8; //mid.next
150  msicap.mc = p.MSICAPMsgCtrl;
151  msicap.ma = p.MSICAPMsgAddr;
152  msicap.mua = p.MSICAPMsgUpperAddr;
153  msicap.md = p.MSICAPMsgData;
154  msicap.mmask = p.MSICAPMaskBits;
155  msicap.mpend = p.MSICAPPendingBits;
156 
157  // MSIXCAP
158  msixcap.mxid = (uint16_t)p.MSIXCAPCapId; //mxid.cid
159  msixcap.mxid |= (uint16_t)p.MSIXCAPNextCapability << 8; //mxid.next
160  msixcap.mxc = p.MSIXMsgCtrl;
161  msixcap.mtab = p.MSIXTableOffset;
162  msixcap.mpba = p.MSIXPbaOffset;
163 
164  // allocate MSIX structures if MSIXCAP_BASE
165  // indicates the MSIXCAP is being used by having a
166  // non-zero base address.
167  // The MSIX tables are stored by the guest in
168  // little endian byte-order as according the
169  // PCIe specification. Make sure to take the proper
170  // actions when manipulating these tables on the host
171  uint16_t msixcap_mxc_ts = msixcap.mxc & 0x07ff;
172  if (MSIXCAP_BASE != 0x0) {
173  int msix_vecs = msixcap_mxc_ts + 1;
174  MSIXTable tmp1 = {{0UL,0UL,0UL,0UL}};
175  msix_table.resize(msix_vecs, tmp1);
176 
177  MSIXPbaEntry tmp2 = {0};
178  int pba_size = msix_vecs / MSIXVECS_PER_PBA;
179  if ((msix_vecs % MSIXVECS_PER_PBA) > 0) {
180  pba_size++;
181  }
182  msix_pba.resize(pba_size, tmp2);
183  }
184  MSIX_TABLE_OFFSET = msixcap.mtab & 0xfffffffc;
186  (msixcap_mxc_ts + 1) * sizeof(MSIXTable);
187  MSIX_PBA_OFFSET = msixcap.mpba & 0xfffffffc;
189  ((msixcap_mxc_ts + 1) / MSIXVECS_PER_PBA)
190  * sizeof(MSIXPbaEntry);
191  if (((msixcap_mxc_ts + 1) % MSIXVECS_PER_PBA) > 0) {
192  MSIX_PBA_END += sizeof(MSIXPbaEntry);
193  }
194 
195  // PXCAP
196  pxcap.pxid = (uint16_t)p.PXCAPCapId; //pxid.cid
197  pxcap.pxid |= (uint16_t)p.PXCAPNextCapability << 8; //pxid.next
198  pxcap.pxcap = p.PXCAPCapabilities;
199  pxcap.pxdcap = p.PXCAPDevCapabilities;
200  pxcap.pxdc = p.PXCAPDevCtrl;
201  pxcap.pxds = p.PXCAPDevStatus;
202  pxcap.pxlcap = p.PXCAPLinkCap;
203  pxcap.pxlc = p.PXCAPLinkCtrl;
204  pxcap.pxls = p.PXCAPLinkStatus;
205  pxcap.pxdcap2 = p.PXCAPDevCap2;
206  pxcap.pxdc2 = p.PXCAPDevCtrl2;
207 }
208 
209 Tick
211 {
212  int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
213 
214  /* Return 0 for accesses to unimplemented PCI configspace areas */
215  if (offset >= PCI_DEVICE_SPECIFIC &&
217  warn_once("Device specific PCI config space "
218  "not implemented for %s!\n", this->name());
219  switch (pkt->getSize()) {
220  case sizeof(uint8_t):
221  pkt->setLE<uint8_t>(0);
222  break;
223  case sizeof(uint16_t):
224  pkt->setLE<uint16_t>(0);
225  break;
226  case sizeof(uint32_t):
227  pkt->setLE<uint32_t>(0);
228  break;
229  default:
230  panic("invalid access size(?) for PCI configspace!\n");
231  }
232  } else if (offset > PCI_CONFIG_SIZE) {
233  panic("Out-of-range access to PCI config space!\n");
234  }
235 
236  switch (pkt->getSize()) {
237  case sizeof(uint8_t):
238  pkt->setLE<uint8_t>(config.data[offset]);
240  "readConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
242  (uint32_t)pkt->getLE<uint8_t>());
243  break;
244  case sizeof(uint16_t):
245  pkt->setLE<uint16_t>(*(uint16_t*)&config.data[offset]);
247  "readConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
249  (uint32_t)pkt->getLE<uint16_t>());
250  break;
251  case sizeof(uint32_t):
252  pkt->setLE<uint32_t>(*(uint32_t*)&config.data[offset]);
254  "readConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
256  (uint32_t)pkt->getLE<uint32_t>());
257  break;
258  default:
259  panic("invalid access size(?) for PCI configspace!\n");
260  }
261  pkt->makeAtomicResponse();
262  return configDelay;
263 
264 }
265 
268 {
269  AddrRangeList ranges;
270  PciCommandRegister command = letoh(config.command);
271  for (auto *bar: BARs) {
272  if (command.ioSpace && bar->isIo())
273  ranges.push_back(bar->range());
274  if (command.memorySpace && bar->isMem())
275  ranges.push_back(bar->range());
276  }
277  return ranges;
278 }
279 
280 Tick
282 {
283  int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
284 
285  /* No effect if we write to config space that is not implemented*/
286  if (offset >= PCI_DEVICE_SPECIFIC &&
288  warn_once("Device specific PCI config space "
289  "not implemented for %s!\n", this->name());
290  switch (pkt->getSize()) {
291  case sizeof(uint8_t):
292  case sizeof(uint16_t):
293  case sizeof(uint32_t):
294  break;
295  default:
296  panic("invalid access size(?) for PCI configspace!\n");
297  }
298  } else if (offset > PCI_CONFIG_SIZE) {
299  panic("Out-of-range access to PCI config space!\n");
300  }
301 
302  switch (pkt->getSize()) {
303  case sizeof(uint8_t):
304  switch (offset) {
305  case PCI0_INTERRUPT_LINE:
306  config.interruptLine = pkt->getLE<uint8_t>();
307  break;
308  case PCI_CACHE_LINE_SIZE:
309  config.cacheLineSize = pkt->getLE<uint8_t>();
310  break;
311  case PCI_LATENCY_TIMER:
312  config.latencyTimer = pkt->getLE<uint8_t>();
313  break;
314  /* Do nothing for these read-only registers */
315  case PCI0_INTERRUPT_PIN:
316  case PCI0_MINIMUM_GRANT:
318  case PCI_CLASS_CODE:
319  case PCI_REVISION_ID:
320  break;
321  default:
322  panic("writing to a read only register");
323  }
325  "writeConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
327  (uint32_t)pkt->getLE<uint8_t>());
328  break;
329  case sizeof(uint16_t):
330  switch (offset) {
331  case PCI_COMMAND:
332  config.command = pkt->getLE<uint8_t>();
333  // IO or memory space may have been enabled/disabled.
335  break;
336  case PCI_STATUS:
337  config.status = pkt->getLE<uint8_t>();
338  break;
339  case PCI_CACHE_LINE_SIZE:
340  config.cacheLineSize = pkt->getLE<uint8_t>();
341  break;
342  default:
343  panic("writing to a read only register");
344  }
346  "writeConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
348  (uint32_t)pkt->getLE<uint16_t>());
349  break;
350  case sizeof(uint32_t):
351  switch (offset) {
352  case PCI0_BASE_ADDR0:
353  case PCI0_BASE_ADDR1:
354  case PCI0_BASE_ADDR2:
355  case PCI0_BASE_ADDR3:
356  case PCI0_BASE_ADDR4:
357  case PCI0_BASE_ADDR5:
358  {
359  int num = BAR_NUMBER(offset);
360  auto *bar = BARs[num];
361  config.baseAddr[num] =
362  htole(bar->write(hostInterface, pkt->getLE<uint32_t>()));
364  }
365  break;
366 
367  case PCI0_ROM_BASE_ADDR:
368  if (letoh(pkt->getLE<uint32_t>()) == 0xfffffffe)
369  config.expansionROM = htole((uint32_t)0xffffffff);
370  else
371  config.expansionROM = pkt->getLE<uint32_t>();
372  break;
373 
374  case PCI_COMMAND:
375  // This could also clear some of the error bits in the Status
376  // register. However they should never get set, so lets ignore
377  // it for now
378  config.command = pkt->getLE<uint32_t>();
379  // IO or memory space may have been enabled/disabled.
381  break;
382 
383  default:
384  DPRINTF(PciDevice, "Writing to a read only register");
385  }
387  "writeConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
389  (uint32_t)pkt->getLE<uint32_t>());
390  break;
391  default:
392  panic("invalid access size(?) for PCI configspace!\n");
393  }
394  pkt->makeAtomicResponse();
395  return configDelay;
396 }
397 
398 void
400 {
401  SERIALIZE_ARRAY(config.data, sizeof(config.data) / sizeof(config.data[0]));
402 
403  // serialize the capability list registers
404  paramOut(cp, csprintf("pmcap.pid"), uint16_t(pmcap.pid));
405  paramOut(cp, csprintf("pmcap.pc"), uint16_t(pmcap.pc));
406  paramOut(cp, csprintf("pmcap.pmcs"), uint16_t(pmcap.pmcs));
407 
408  paramOut(cp, csprintf("msicap.mid"), uint16_t(msicap.mid));
409  paramOut(cp, csprintf("msicap.mc"), uint16_t(msicap.mc));
410  paramOut(cp, csprintf("msicap.ma"), uint32_t(msicap.ma));
412  paramOut(cp, csprintf("msicap.md"), uint16_t(msicap.md));
415 
416  paramOut(cp, csprintf("msixcap.mxid"), uint16_t(msixcap.mxid));
417  paramOut(cp, csprintf("msixcap.mxc"), uint16_t(msixcap.mxc));
418  paramOut(cp, csprintf("msixcap.mtab"), uint32_t(msixcap.mtab));
419  paramOut(cp, csprintf("msixcap.mpba"), uint32_t(msixcap.mpba));
420 
421  // Only serialize if we have a non-zero base address
422  if (MSIXCAP_BASE != 0x0) {
423  uint16_t msixcap_mxc_ts = msixcap.mxc & 0x07ff;
424  int msix_array_size = msixcap_mxc_ts + 1;
425  int pba_array_size = msix_array_size/MSIXVECS_PER_PBA;
426  if ((msix_array_size % MSIXVECS_PER_PBA) > 0) {
427  pba_array_size++;
428  }
429 
430  SERIALIZE_SCALAR(msix_array_size);
431  SERIALIZE_SCALAR(pba_array_size);
432 
433  for (int i = 0; i < msix_array_size; i++) {
434  paramOut(cp, csprintf("msix_table[%d].addr_lo", i),
435  msix_table[i].fields.addr_lo);
436  paramOut(cp, csprintf("msix_table[%d].addr_hi", i),
437  msix_table[i].fields.addr_hi);
438  paramOut(cp, csprintf("msix_table[%d].msg_data", i),
439  msix_table[i].fields.msg_data);
440  paramOut(cp, csprintf("msix_table[%d].vec_ctrl", i),
441  msix_table[i].fields.vec_ctrl);
442  }
443  for (int i = 0; i < pba_array_size; i++) {
444  paramOut(cp, csprintf("msix_pba[%d].bits", i),
445  msix_pba[i].bits);
446  }
447  }
448 
449  paramOut(cp, csprintf("pxcap.pxid"), uint16_t(pxcap.pxid));
450  paramOut(cp, csprintf("pxcap.pxcap"), uint16_t(pxcap.pxcap));
451  paramOut(cp, csprintf("pxcap.pxdcap"), uint32_t(pxcap.pxdcap));
452  paramOut(cp, csprintf("pxcap.pxdc"), uint16_t(pxcap.pxdc));
453  paramOut(cp, csprintf("pxcap.pxds"), uint16_t(pxcap.pxds));
454  paramOut(cp, csprintf("pxcap.pxlcap"), uint32_t(pxcap.pxlcap));
455  paramOut(cp, csprintf("pxcap.pxlc"), uint16_t(pxcap.pxlc));
456  paramOut(cp, csprintf("pxcap.pxls"), uint16_t(pxcap.pxls));
457  paramOut(cp, csprintf("pxcap.pxdcap2"), uint32_t(pxcap.pxdcap2));
458  paramOut(cp, csprintf("pxcap.pxdc2"), uint32_t(pxcap.pxdc2));
459 }
460 
461 void
463 {
465  sizeof(config.data) / sizeof(config.data[0]));
466 
467  for (int idx = 0; idx < BARs.size(); idx++)
468  BARs[idx]->write(hostInterface, config.baseAddr[idx]);
469 
470  // unserialize the capability list registers
471  uint16_t tmp16;
472  uint32_t tmp32;
473  paramIn(cp, csprintf("pmcap.pid"), tmp16);
474  pmcap.pid = tmp16;
475  paramIn(cp, csprintf("pmcap.pc"), tmp16);
476  pmcap.pc = tmp16;
477  paramIn(cp, csprintf("pmcap.pmcs"), tmp16);
478  pmcap.pmcs = tmp16;
479 
480  paramIn(cp, csprintf("msicap.mid"), tmp16);
481  msicap.mid = tmp16;
482  paramIn(cp, csprintf("msicap.mc"), tmp16);
483  msicap.mc = tmp16;
484  paramIn(cp, csprintf("msicap.ma"), tmp32);
485  msicap.ma = tmp32;
487  paramIn(cp, csprintf("msicap.md"), tmp16);;
488  msicap.md = tmp16;
491 
492  paramIn(cp, csprintf("msixcap.mxid"), tmp16);
493  msixcap.mxid = tmp16;
494  paramIn(cp, csprintf("msixcap.mxc"), tmp16);
495  msixcap.mxc = tmp16;
496  paramIn(cp, csprintf("msixcap.mtab"), tmp32);
497  msixcap.mtab = tmp32;
498  paramIn(cp, csprintf("msixcap.mpba"), tmp32);
499  msixcap.mpba = tmp32;
500 
501  // Only allocate if MSIXCAP_BASE is not 0x0
502  if (MSIXCAP_BASE != 0x0) {
503  int msix_array_size;
504  int pba_array_size;
505 
506  UNSERIALIZE_SCALAR(msix_array_size);
507  UNSERIALIZE_SCALAR(pba_array_size);
508 
509  MSIXTable tmp1 = {{0UL, 0UL, 0UL, 0UL}};
510  msix_table.resize(msix_array_size, tmp1);
511 
512  MSIXPbaEntry tmp2 = {0};
513  msix_pba.resize(pba_array_size, tmp2);
514 
515  for (int i = 0; i < msix_array_size; i++) {
516  paramIn(cp, csprintf("msix_table[%d].addr_lo", i),
517  msix_table[i].fields.addr_lo);
518  paramIn(cp, csprintf("msix_table[%d].addr_hi", i),
519  msix_table[i].fields.addr_hi);
520  paramIn(cp, csprintf("msix_table[%d].msg_data", i),
521  msix_table[i].fields.msg_data);
522  paramIn(cp, csprintf("msix_table[%d].vec_ctrl", i),
523  msix_table[i].fields.vec_ctrl);
524  }
525  for (int i = 0; i < pba_array_size; i++) {
526  paramIn(cp, csprintf("msix_pba[%d].bits", i),
527  msix_pba[i].bits);
528  }
529  }
530 
531  paramIn(cp, csprintf("pxcap.pxid"), tmp16);
532  pxcap.pxid = tmp16;
533  paramIn(cp, csprintf("pxcap.pxcap"), tmp16);
534  pxcap.pxcap = tmp16;
535  paramIn(cp, csprintf("pxcap.pxdcap"), tmp32);
536  pxcap.pxdcap = tmp32;
537  paramIn(cp, csprintf("pxcap.pxdc"), tmp16);
538  pxcap.pxdc = tmp16;
539  paramIn(cp, csprintf("pxcap.pxds"), tmp16);
540  pxcap.pxds = tmp16;
541  paramIn(cp, csprintf("pxcap.pxlcap"), tmp32);
542  pxcap.pxlcap = tmp32;
543  paramIn(cp, csprintf("pxcap.pxlc"), tmp16);
544  pxcap.pxlc = tmp16;
545  paramIn(cp, csprintf("pxcap.pxls"), tmp16);
546  pxcap.pxls = tmp16;
547  paramIn(cp, csprintf("pxcap.pxdcap2"), tmp32);
548  pxcap.pxdcap2 = tmp32;
549  paramIn(cp, csprintf("pxcap.pxdc2"), tmp32);
550  pxcap.pxdc2 = tmp32;
552 }
MSIXCAP::mtab
uint32_t mtab
Definition: pcireg.h:290
PciIntPin
PciIntPin
Definition: types.hh:63
PciMemBar
Definition: device.hh:168
Packet::makeAtomicResponse
void makeAtomicResponse()
Definition: packet.hh:1017
PCI_STATUS
#define PCI_STATUS
Definition: pcireg.h:104
PXCAP::pxdc2
uint32_t pxdc2
Definition: pcireg.h:410
PciDevice::getAddrRanges
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
Definition: device.cc:267
PCI0_MINIMUM_GRANT
#define PCI0_MINIMUM_GRANT
Definition: pcireg.h:134
MSIXVECS_PER_PBA
#define MSIXVECS_PER_PBA
Definition: pcireg.h:309
PCI_REVISION_ID
#define PCI_REVISION_ID
Definition: pcireg.h:105
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:591
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:755
PciDevice::BARs
std::array< PciBar *, 6 > BARs
Definition: device.hh:305
PMCAP::pc
uint16_t pc
Definition: pcireg.h:225
warn_once
#define warn_once(...)
Definition: logging.hh:243
ArmISA::i
Bitfield< 7 > i
Definition: miscregs_types.hh:63
PciDevice::writeConfig
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
Definition: device.cc:281
htole
T htole(T value)
Definition: byteswap.hh:141
PciDevice::readConfig
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
Definition: device.cc:210
MSIXCAP_MXC
#define MSIXCAP_MXC
Definition: pcireg.h:198
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:59
PXCAP::pxlcap
uint32_t pxlcap
Definition: pcireg.h:364
PCI0_BASE_ADDR4
#define PCI0_BASE_ADDR4
Definition: pcireg.h:124
PciDevice::pxcap
PXCAP pxcap
Definition: device.hh:298
PciDevice::config
PCIConfig config
The current config space.
Definition: device.hh:272
PciDevice::_busAddr
const PciBusAddr _busAddr
Definition: device.hh:269
Packet::getSize
unsigned getSize() const
Definition: packet.hh:765
PCI_COMMAND
#define PCI_COMMAND
Definition: pcireg.h:103
PciDevice::msixcap
MSIXCAP msixcap
Definition: device.hh:295
PCI_LATENCY_TIMER
#define PCI_LATENCY_TIMER
Definition: pcireg.h:110
device.hh
PciDevice::msix_pba
std::vector< MSIXPbaEntry > msix_pba
Definition: device.hh:303
MSIXCAP_MPBA
#define MSIXCAP_MPBA
Definition: pcireg.h:200
PXCAP::pxds
uint16_t pxds
Definition: pcireg.h:356
PCI_DEVICE_SPECIFIC
#define PCI_DEVICE_SPECIFIC
Definition: pcireg.h:162
packet.hh
MSICAP::mmask
uint32_t mmask
Definition: pcireg.h:270
PCI0_INTERRUPT_LINE
#define PCI0_INTERRUPT_LINE
Definition: pcireg.h:132
MSIXTable
Definition: pcireg.h:299
str.hh
PCI0_ROM_BASE_ADDR
#define PCI0_ROM_BASE_ADDR
Definition: pcireg.h:129
letoh
T letoh(T value)
Definition: byteswap.hh:142
PciDevice::hostInterface
PciHost::DeviceInterface hostInterface
Definition: device.hh:349
cp
Definition: cprintf.cc:37
PCI0_BASE_ADDR0
#define PCI0_BASE_ADDR0
Definition: pcireg.h:120
PCI0_BASE_ADDR5
#define PCI0_BASE_ADDR5
Definition: pcireg.h:125
MSIXCAP::mxc
uint16_t mxc
Definition: pcireg.h:285
MSIXPbaEntry
Definition: pcireg.h:310
PciDevice::msicap
MSICAP msicap
Definition: device.hh:284
PciDevice::MSIX_TABLE_OFFSET
int MSIX_TABLE_OFFSET
Definition: device.hh:291
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:237
PciDevice::serialize
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition: device.cc:399
MSICAP::mc
uint16_t mc
Definition: pcireg.h:258
MSIXCAP::mpba
uint32_t mpba
Definition: pcireg.h:293
PciDevice::MSIXCAP_BASE
const int MSIXCAP_BASE
Definition: device.hh:286
PXCAP::pxid
uint16_t pxid
Definition: pcireg.h:321
MSICAP::md
uint16_t md
Definition: pcireg.h:269
PXCAP::pxdcap
uint32_t pxdcap
Definition: pcireg.h:330
PciDevice::MSIX_TABLE_END
int MSIX_TABLE_END
Definition: device.hh:292
PXCAP::pxdcap2
uint32_t pxdcap2
Definition: pcireg.h:393
PioDevice::write
virtual Tick write(PacketPtr pkt)=0
Pure virtual function that the device must implement.
MSIXCAP::mxid
uint16_t mxid
Definition: pcireg.h:282
PXCAP::pxls
uint16_t pxls
Definition: pcireg.h:386
PciDevice::unserialize
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition: device.cc:462
inifile.hh
SERIALIZE_ARRAY
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:626
PXCAP::pxcap
uint16_t pxcap
Definition: pcireg.h:324
PciBusAddr::func
uint8_t func
Definition: types.hh:55
core.hh
BAR_NUMBER
#define BAR_NUMBER(x)
Definition: device.hh:64
PCI0_MAXIMUM_LATENCY
#define PCI0_MAXIMUM_LATENCY
Definition: pcireg.h:135
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:584
paramOut
void paramOut(CheckpointOut &cp, const std::string &name, ExtMachInst const &machInst)
Definition: types.cc:37
packet_access.hh
PciDevice::PciDevice
PciDevice(const PciDeviceParams &params)
Constructor for PCI Dev.
Definition: device.cc:62
PciDevice::configDelay
Tick configDelay
Definition: device.hh:352
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:182
PMCAP::pid
uint16_t pid
Definition: pcireg.h:222
PCI_CLASS_CODE
#define PCI_CLASS_CODE
Definition: pcireg.h:106
DmaDevice
Definition: dma_device.hh:200
Packet::getLE
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Definition: packet_access.hh:75
PciDevice::msix_table
std::vector< MSIXTable > msix_table
MSIX Table and PBA Structures.
Definition: device.hh:302
UNSERIALIZE_ARRAY
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:634
MSICAP::mid
uint16_t mid
Definition: pcireg.h:255
MSICAP::mpend
uint32_t mpend
Definition: pcireg.h:271
MSICAP::mua
uint32_t mua
Definition: pcireg.h:268
PCI_CACHE_LINE_SIZE
#define PCI_CACHE_LINE_SIZE
Definition: pcireg.h:109
MSIXCAP_MTAB
#define MSIXCAP_MTAB
Definition: pcireg.h:199
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:258
PciDevice::MSIX_PBA_OFFSET
int MSIX_PBA_OFFSET
Definition: device.hh:293
PMCAP_PMCS
#define PMCAP_PMCS
Definition: pcireg.h:185
PMCAP_PC
#define PMCAP_PC
Definition: pcireg.h:184
MSICAP::ma
uint32_t ma
Definition: pcireg.h:265
PciDevice::pmcap
PMCAP pmcap
Definition: device.hh:281
MSIXCAP_ID
#define MSIXCAP_ID
Definition: pcireg.h:197
logging.hh
Packet::setLE
void setLE(T v)
Set the value in the data pointer to v as little endian.
Definition: packet_access.hh:105
PCI0_BASE_ADDR1
#define PCI0_BASE_ADDR1
Definition: pcireg.h:121
bits
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:73
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:64
PXCAP::pxdc
uint16_t pxdc
Definition: pcireg.h:343
trace.hh
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
std::list< AddrRange >
intmath.hh
PciDevice::MSIX_PBA_END
int MSIX_PBA_END
Definition: device.hh:294
PCI_CONFIG_SIZE
#define PCI_CONFIG_SIZE
Definition: pcireg.h:163
fatal_if
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:219
paramIn
void paramIn(CheckpointIn &cp, const std::string &name, ExtMachInst &machInst)
Definition: types.cc:69
CheckpointIn
Definition: serialize.hh:68
ResponsePort::sendRangeChange
void sendRangeChange() const
Called by the owner to send a range change.
Definition: port.hh:293
PCI0_BASE_ADDR3
#define PCI0_BASE_ADDR3
Definition: pcireg.h:123
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
PciBusAddr::dev
uint8_t dev
Definition: types.hh:54
PMCAP::pmcs
uint16_t pmcs
Definition: pcireg.h:234
PciDevice
PCI device, base implementation is only config space.
Definition: device.hh:266
PXCAP::pxlc
uint16_t pxlc
Definition: pcireg.h:376
byteswap.hh
PciMemUpperBar
Definition: device.hh:231
PMCAP_ID
#define PMCAP_ID
PCIe capability list offsets internal to the entry.
Definition: pcireg.h:183
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:171
PioDevice::pioPort
PioPort< PioDevice > pioPort
The pioPort that handles the requests for us and provides us requests that it sees.
Definition: io_device.hh:106
ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:153
PCI0_INTERRUPT_PIN
#define PCI0_INTERRUPT_PIN
Definition: pcireg.h:133
PCI0_BASE_ADDR2
#define PCI0_BASE_ADDR2
Definition: pcireg.h:122

Generated on Tue Mar 23 2021 19:41:24 for gem5 by doxygen 1.8.17