gem5  v20.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 #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  config.vendor = htole(p->VendorID);
86  config.device = htole(p->DeviceID);
87  config.command = htole(p->Command);
88  config.status = htole(p->Status);
89  config.revision = htole(p->Revision);
90  config.progIF = htole(p->ProgIF);
91  config.subClassCode = htole(p->SubClassCode);
92  config.classCode = htole(p->ClassCode);
93  config.cacheLineSize = htole(p->CacheLineSize);
94  config.latencyTimer = htole(p->LatencyTimer);
95  config.headerType = htole(p->HeaderType);
96  config.bist = htole(p->BIST);
97 
98  config.baseAddr[0] = htole(p->BAR0);
99  config.baseAddr[1] = htole(p->BAR1);
100  config.baseAddr[2] = htole(p->BAR2);
101  config.baseAddr[3] = htole(p->BAR3);
102  config.baseAddr[4] = htole(p->BAR4);
103  config.baseAddr[5] = htole(p->BAR5);
104  config.cardbusCIS = htole(p->CardbusCIS);
105  config.subsystemVendorID = htole(p->SubsystemVendorID);
106  config.subsystemID = htole(p->SubsystemID);
107  config.expansionROM = htole(p->ExpansionROM);
108  config.capabilityPtr = htole(p->CapabilityPtr);
109  // Zero out the 7 bytes of reserved space in the PCI Config space register.
110  bzero(config.reserved, 7*sizeof(uint8_t));
111  config.interruptLine = htole(p->InterruptLine);
112  config.interruptPin = htole(p->InterruptPin);
113  config.minimumGrant = htole(p->MinimumGrant);
114  config.maximumLatency = htole(p->MaximumLatency);
115 
116  // Initialize the capability lists
117  // These structs are bitunions, meaning the data is stored in host
118  // endianess and must be converted to Little Endian when accessed
119  // by the guest
120  // PMCAP
121  pmcap.pid = (uint16_t)p->PMCAPCapId; // pid.cid
122  pmcap.pid |= (uint16_t)p->PMCAPNextCapability << 8; //pid.next
123  pmcap.pc = p->PMCAPCapabilities;
124  pmcap.pmcs = p->PMCAPCtrlStatus;
125 
126  // MSICAP
127  msicap.mid = (uint16_t)p->MSICAPCapId; //mid.cid
128  msicap.mid |= (uint16_t)p->MSICAPNextCapability << 8; //mid.next
129  msicap.mc = p->MSICAPMsgCtrl;
130  msicap.ma = p->MSICAPMsgAddr;
131  msicap.mua = p->MSICAPMsgUpperAddr;
132  msicap.md = p->MSICAPMsgData;
133  msicap.mmask = p->MSICAPMaskBits;
134  msicap.mpend = p->MSICAPPendingBits;
135 
136  // MSIXCAP
137  msixcap.mxid = (uint16_t)p->MSIXCAPCapId; //mxid.cid
138  msixcap.mxid |= (uint16_t)p->MSIXCAPNextCapability << 8; //mxid.next
139  msixcap.mxc = p->MSIXMsgCtrl;
140  msixcap.mtab = p->MSIXTableOffset;
141  msixcap.mpba = p->MSIXPbaOffset;
142 
143  // allocate MSIX structures if MSIXCAP_BASE
144  // indicates the MSIXCAP is being used by having a
145  // non-zero base address.
146  // The MSIX tables are stored by the guest in
147  // little endian byte-order as according the
148  // PCIe specification. Make sure to take the proper
149  // actions when manipulating these tables on the host
150  uint16_t msixcap_mxc_ts = msixcap.mxc & 0x07ff;
151  if (MSIXCAP_BASE != 0x0) {
152  int msix_vecs = msixcap_mxc_ts + 1;
153  MSIXTable tmp1 = {{0UL,0UL,0UL,0UL}};
154  msix_table.resize(msix_vecs, tmp1);
155 
156  MSIXPbaEntry tmp2 = {0};
157  int pba_size = msix_vecs / MSIXVECS_PER_PBA;
158  if ((msix_vecs % MSIXVECS_PER_PBA) > 0) {
159  pba_size++;
160  }
161  msix_pba.resize(pba_size, tmp2);
162  }
163  MSIX_TABLE_OFFSET = msixcap.mtab & 0xfffffffc;
165  (msixcap_mxc_ts + 1) * sizeof(MSIXTable);
166  MSIX_PBA_OFFSET = msixcap.mpba & 0xfffffffc;
168  ((msixcap_mxc_ts + 1) / MSIXVECS_PER_PBA)
169  * sizeof(MSIXPbaEntry);
170  if (((msixcap_mxc_ts + 1) % MSIXVECS_PER_PBA) > 0) {
171  MSIX_PBA_END += sizeof(MSIXPbaEntry);
172  }
173 
174  // PXCAP
175  pxcap.pxid = (uint16_t)p->PXCAPCapId; //pxid.cid
176  pxcap.pxid |= (uint16_t)p->PXCAPNextCapability << 8; //pxid.next
177  pxcap.pxcap = p->PXCAPCapabilities;
178  pxcap.pxdcap = p->PXCAPDevCapabilities;
179  pxcap.pxdc = p->PXCAPDevCtrl;
180  pxcap.pxds = p->PXCAPDevStatus;
181  pxcap.pxlcap = p->PXCAPLinkCap;
182  pxcap.pxlc = p->PXCAPLinkCtrl;
183  pxcap.pxls = p->PXCAPLinkStatus;
184  pxcap.pxdcap2 = p->PXCAPDevCap2;
185  pxcap.pxdc2 = p->PXCAPDevCtrl2;
186 
187  BARSize[0] = p->BAR0Size;
188  BARSize[1] = p->BAR1Size;
189  BARSize[2] = p->BAR2Size;
190  BARSize[3] = p->BAR3Size;
191  BARSize[4] = p->BAR4Size;
192  BARSize[5] = p->BAR5Size;
193 
194  legacyIO[0] = p->BAR0LegacyIO;
195  legacyIO[1] = p->BAR1LegacyIO;
196  legacyIO[2] = p->BAR2LegacyIO;
197  legacyIO[3] = p->BAR3LegacyIO;
198  legacyIO[4] = p->BAR4LegacyIO;
199  legacyIO[5] = p->BAR5LegacyIO;
200 
201  for (int i = 0; i < 6; ++i) {
202  if (legacyIO[i]) {
203  BARAddrs[i] = p->LegacyIOBase + letoh(config.baseAddr[i]);
204  config.baseAddr[i] = 0;
205  } else {
206  BARAddrs[i] = 0;
207  uint32_t barsize = BARSize[i];
208  if (barsize != 0 && !isPowerOf2(barsize)) {
209  fatal("BAR %d size %d is not a power of 2\n", i, BARSize[i]);
210  }
211  }
212  }
213 }
214 
215 Tick
217 {
218  int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
219 
220  /* Return 0 for accesses to unimplemented PCI configspace areas */
221  if (offset >= PCI_DEVICE_SPECIFIC &&
223  warn_once("Device specific PCI config space "
224  "not implemented for %s!\n", this->name());
225  switch (pkt->getSize()) {
226  case sizeof(uint8_t):
227  pkt->setLE<uint8_t>(0);
228  break;
229  case sizeof(uint16_t):
230  pkt->setLE<uint16_t>(0);
231  break;
232  case sizeof(uint32_t):
233  pkt->setLE<uint32_t>(0);
234  break;
235  default:
236  panic("invalid access size(?) for PCI configspace!\n");
237  }
238  } else if (offset > PCI_CONFIG_SIZE) {
239  panic("Out-of-range access to PCI config space!\n");
240  }
241 
242  switch (pkt->getSize()) {
243  case sizeof(uint8_t):
244  pkt->setLE<uint8_t>(config.data[offset]);
246  "readConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
248  (uint32_t)pkt->getLE<uint8_t>());
249  break;
250  case sizeof(uint16_t):
251  pkt->setLE<uint16_t>(*(uint16_t*)&config.data[offset]);
253  "readConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
255  (uint32_t)pkt->getLE<uint16_t>());
256  break;
257  case sizeof(uint32_t):
258  pkt->setLE<uint32_t>(*(uint32_t*)&config.data[offset]);
260  "readConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
262  (uint32_t)pkt->getLE<uint32_t>());
263  break;
264  default:
265  panic("invalid access size(?) for PCI configspace!\n");
266  }
267  pkt->makeAtomicResponse();
268  return configDelay;
269 
270 }
271 
274 {
275  AddrRangeList ranges;
276  int x = 0;
277  for (x = 0; x < 6; x++)
278  if (BARAddrs[x] != 0)
279  ranges.push_back(RangeSize(BARAddrs[x],BARSize[x]));
280  return ranges;
281 }
282 
283 Tick
285 {
286  int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
287 
288  /* No effect if we write to config space that is not implemented*/
289  if (offset >= PCI_DEVICE_SPECIFIC &&
291  warn_once("Device specific PCI config space "
292  "not implemented for %s!\n", this->name());
293  switch (pkt->getSize()) {
294  case sizeof(uint8_t):
295  case sizeof(uint16_t):
296  case sizeof(uint32_t):
297  break;
298  default:
299  panic("invalid access size(?) for PCI configspace!\n");
300  }
301  } else if (offset > PCI_CONFIG_SIZE) {
302  panic("Out-of-range access to PCI config space!\n");
303  }
304 
305  switch (pkt->getSize()) {
306  case sizeof(uint8_t):
307  switch (offset) {
308  case PCI0_INTERRUPT_LINE:
309  config.interruptLine = pkt->getLE<uint8_t>();
310  break;
311  case PCI_CACHE_LINE_SIZE:
312  config.cacheLineSize = pkt->getLE<uint8_t>();
313  break;
314  case PCI_LATENCY_TIMER:
315  config.latencyTimer = pkt->getLE<uint8_t>();
316  break;
317  /* Do nothing for these read-only registers */
318  case PCI0_INTERRUPT_PIN:
319  case PCI0_MINIMUM_GRANT:
321  case PCI_CLASS_CODE:
322  case PCI_REVISION_ID:
323  break;
324  default:
325  panic("writing to a read only register");
326  }
328  "writeConfig: dev %#x func %#x reg %#x 1 bytes: data = %#x\n",
330  (uint32_t)pkt->getLE<uint8_t>());
331  break;
332  case sizeof(uint16_t):
333  switch (offset) {
334  case PCI_COMMAND:
335  config.command = pkt->getLE<uint8_t>();
336  break;
337  case PCI_STATUS:
338  config.status = pkt->getLE<uint8_t>();
339  break;
340  case PCI_CACHE_LINE_SIZE:
341  config.cacheLineSize = pkt->getLE<uint8_t>();
342  break;
343  default:
344  panic("writing to a read only register");
345  }
347  "writeConfig: dev %#x func %#x reg %#x 2 bytes: data = %#x\n",
349  (uint32_t)pkt->getLE<uint16_t>());
350  break;
351  case sizeof(uint32_t):
352  switch (offset) {
353  case PCI0_BASE_ADDR0:
354  case PCI0_BASE_ADDR1:
355  case PCI0_BASE_ADDR2:
356  case PCI0_BASE_ADDR3:
357  case PCI0_BASE_ADDR4:
358  case PCI0_BASE_ADDR5:
359  {
360  int barnum = BAR_NUMBER(offset);
361 
362  if (!legacyIO[barnum]) {
363  // convert BAR values to host endianness
364  uint32_t he_old_bar = letoh(config.baseAddr[barnum]);
365  uint32_t he_new_bar = letoh(pkt->getLE<uint32_t>());
366 
367  uint32_t bar_mask =
368  BAR_IO_SPACE(he_old_bar) ? BAR_IO_MASK : BAR_MEM_MASK;
369 
370  // Writing 0xffffffff to a BAR tells the card to set the
371  // value of the bar to a bitmask indicating the size of
372  // memory it needs
373  if (he_new_bar == 0xffffffff) {
374  he_new_bar = ~(BARSize[barnum] - 1);
375  } else {
376  // does it mean something special to write 0 to a BAR?
377  he_new_bar &= ~bar_mask;
378  if (he_new_bar) {
379  if (isLargeBAR(barnum)) {
380  if (BAR_IO_SPACE(he_old_bar))
381  warn("IO BARs can't be set as large BAR");
382  uint64_t he_large_bar =
383  letoh(config.baseAddr[barnum + 1]);
384  he_large_bar = he_large_bar << 32;
385  he_large_bar += he_new_bar;
386  BARAddrs[barnum] =
387  hostInterface.memAddr(he_large_bar);
388  } else if (isLargeBAR(barnum - 1)) {
389  BARAddrs[barnum] = 0;
390  uint64_t he_large_bar = he_new_bar;
391  he_large_bar = he_large_bar << 32;
392  // We need to apply mask to lower bits
393  he_large_bar +=
394  letoh(config.baseAddr[barnum - 1]
395  & ~bar_mask);
396  BARAddrs[barnum - 1] =
397  hostInterface.memAddr(he_large_bar);
398  } else {
399  BARAddrs[barnum] = BAR_IO_SPACE(he_old_bar) ?
400  hostInterface.pioAddr(he_new_bar) :
401  hostInterface.memAddr(he_new_bar);
402  }
404  }
405  }
406  config.baseAddr[barnum] = htole((he_new_bar & ~bar_mask) |
407  (he_old_bar & bar_mask));
408  }
409  }
410  break;
411 
412  case PCI0_ROM_BASE_ADDR:
413  if (letoh(pkt->getLE<uint32_t>()) == 0xfffffffe)
414  config.expansionROM = htole((uint32_t)0xffffffff);
415  else
416  config.expansionROM = pkt->getLE<uint32_t>();
417  break;
418 
419  case PCI_COMMAND:
420  // This could also clear some of the error bits in the Status
421  // register. However they should never get set, so lets ignore
422  // it for now
423  config.command = pkt->getLE<uint32_t>();
424  break;
425 
426  default:
427  DPRINTF(PciDevice, "Writing to a read only register");
428  }
430  "writeConfig: dev %#x func %#x reg %#x 4 bytes: data = %#x\n",
432  (uint32_t)pkt->getLE<uint32_t>());
433  break;
434  default:
435  panic("invalid access size(?) for PCI configspace!\n");
436  }
437  pkt->makeAtomicResponse();
438  return configDelay;
439 }
440 
441 void
443 {
444  SERIALIZE_ARRAY(BARSize, sizeof(BARSize) / sizeof(BARSize[0]));
445  SERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0]));
446  SERIALIZE_ARRAY(config.data, sizeof(config.data) / sizeof(config.data[0]));
447 
448  // serialize the capability list registers
449  paramOut(cp, csprintf("pmcap.pid"), uint16_t(pmcap.pid));
450  paramOut(cp, csprintf("pmcap.pc"), uint16_t(pmcap.pc));
451  paramOut(cp, csprintf("pmcap.pmcs"), uint16_t(pmcap.pmcs));
452 
453  paramOut(cp, csprintf("msicap.mid"), uint16_t(msicap.mid));
454  paramOut(cp, csprintf("msicap.mc"), uint16_t(msicap.mc));
455  paramOut(cp, csprintf("msicap.ma"), uint32_t(msicap.ma));
457  paramOut(cp, csprintf("msicap.md"), uint16_t(msicap.md));
460 
461  paramOut(cp, csprintf("msixcap.mxid"), uint16_t(msixcap.mxid));
462  paramOut(cp, csprintf("msixcap.mxc"), uint16_t(msixcap.mxc));
463  paramOut(cp, csprintf("msixcap.mtab"), uint32_t(msixcap.mtab));
464  paramOut(cp, csprintf("msixcap.mpba"), uint32_t(msixcap.mpba));
465 
466  // Only serialize if we have a non-zero base address
467  if (MSIXCAP_BASE != 0x0) {
468  uint16_t msixcap_mxc_ts = msixcap.mxc & 0x07ff;
469  int msix_array_size = msixcap_mxc_ts + 1;
470  int pba_array_size = msix_array_size/MSIXVECS_PER_PBA;
471  if ((msix_array_size % MSIXVECS_PER_PBA) > 0) {
472  pba_array_size++;
473  }
474 
475  SERIALIZE_SCALAR(msix_array_size);
476  SERIALIZE_SCALAR(pba_array_size);
477 
478  for (int i = 0; i < msix_array_size; i++) {
479  paramOut(cp, csprintf("msix_table[%d].addr_lo", i),
480  msix_table[i].fields.addr_lo);
481  paramOut(cp, csprintf("msix_table[%d].addr_hi", i),
482  msix_table[i].fields.addr_hi);
483  paramOut(cp, csprintf("msix_table[%d].msg_data", i),
484  msix_table[i].fields.msg_data);
485  paramOut(cp, csprintf("msix_table[%d].vec_ctrl", i),
486  msix_table[i].fields.vec_ctrl);
487  }
488  for (int i = 0; i < pba_array_size; i++) {
489  paramOut(cp, csprintf("msix_pba[%d].bits", i),
490  msix_pba[i].bits);
491  }
492  }
493 
494  paramOut(cp, csprintf("pxcap.pxid"), uint16_t(pxcap.pxid));
495  paramOut(cp, csprintf("pxcap.pxcap"), uint16_t(pxcap.pxcap));
496  paramOut(cp, csprintf("pxcap.pxdcap"), uint32_t(pxcap.pxdcap));
497  paramOut(cp, csprintf("pxcap.pxdc"), uint16_t(pxcap.pxdc));
498  paramOut(cp, csprintf("pxcap.pxds"), uint16_t(pxcap.pxds));
499  paramOut(cp, csprintf("pxcap.pxlcap"), uint32_t(pxcap.pxlcap));
500  paramOut(cp, csprintf("pxcap.pxlc"), uint16_t(pxcap.pxlc));
501  paramOut(cp, csprintf("pxcap.pxls"), uint16_t(pxcap.pxls));
502  paramOut(cp, csprintf("pxcap.pxdcap2"), uint32_t(pxcap.pxdcap2));
503  paramOut(cp, csprintf("pxcap.pxdc2"), uint32_t(pxcap.pxdc2));
504 }
505 
506 void
508 {
509  UNSERIALIZE_ARRAY(BARSize, sizeof(BARSize) / sizeof(BARSize[0]));
510  UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0]));
512  sizeof(config.data) / sizeof(config.data[0]));
513 
514  // unserialize the capability list registers
515  uint16_t tmp16;
516  uint32_t tmp32;
517  paramIn(cp, csprintf("pmcap.pid"), tmp16);
518  pmcap.pid = tmp16;
519  paramIn(cp, csprintf("pmcap.pc"), tmp16);
520  pmcap.pc = tmp16;
521  paramIn(cp, csprintf("pmcap.pmcs"), tmp16);
522  pmcap.pmcs = tmp16;
523 
524  paramIn(cp, csprintf("msicap.mid"), tmp16);
525  msicap.mid = tmp16;
526  paramIn(cp, csprintf("msicap.mc"), tmp16);
527  msicap.mc = tmp16;
528  paramIn(cp, csprintf("msicap.ma"), tmp32);
529  msicap.ma = tmp32;
531  paramIn(cp, csprintf("msicap.md"), tmp16);;
532  msicap.md = tmp16;
535 
536  paramIn(cp, csprintf("msixcap.mxid"), tmp16);
537  msixcap.mxid = tmp16;
538  paramIn(cp, csprintf("msixcap.mxc"), tmp16);
539  msixcap.mxc = tmp16;
540  paramIn(cp, csprintf("msixcap.mtab"), tmp32);
541  msixcap.mtab = tmp32;
542  paramIn(cp, csprintf("msixcap.mpba"), tmp32);
543  msixcap.mpba = tmp32;
544 
545  // Only allocate if MSIXCAP_BASE is not 0x0
546  if (MSIXCAP_BASE != 0x0) {
547  int msix_array_size;
548  int pba_array_size;
549 
550  UNSERIALIZE_SCALAR(msix_array_size);
551  UNSERIALIZE_SCALAR(pba_array_size);
552 
553  MSIXTable tmp1 = {{0UL, 0UL, 0UL, 0UL}};
554  msix_table.resize(msix_array_size, tmp1);
555 
556  MSIXPbaEntry tmp2 = {0};
557  msix_pba.resize(pba_array_size, tmp2);
558 
559  for (int i = 0; i < msix_array_size; i++) {
560  paramIn(cp, csprintf("msix_table[%d].addr_lo", i),
561  msix_table[i].fields.addr_lo);
562  paramIn(cp, csprintf("msix_table[%d].addr_hi", i),
563  msix_table[i].fields.addr_hi);
564  paramIn(cp, csprintf("msix_table[%d].msg_data", i),
565  msix_table[i].fields.msg_data);
566  paramIn(cp, csprintf("msix_table[%d].vec_ctrl", i),
567  msix_table[i].fields.vec_ctrl);
568  }
569  for (int i = 0; i < pba_array_size; i++) {
570  paramIn(cp, csprintf("msix_pba[%d].bits", i),
571  msix_pba[i].bits);
572  }
573  }
574 
575  paramIn(cp, csprintf("pxcap.pxid"), tmp16);
576  pxcap.pxid = tmp16;
577  paramIn(cp, csprintf("pxcap.pxcap"), tmp16);
578  pxcap.pxcap = tmp16;
579  paramIn(cp, csprintf("pxcap.pxdcap"), tmp32);
580  pxcap.pxdcap = tmp32;
581  paramIn(cp, csprintf("pxcap.pxdc"), tmp16);
582  pxcap.pxdc = tmp16;
583  paramIn(cp, csprintf("pxcap.pxds"), tmp16);
584  pxcap.pxds = tmp16;
585  paramIn(cp, csprintf("pxcap.pxlcap"), tmp32);
586  pxcap.pxlcap = tmp32;
587  paramIn(cp, csprintf("pxcap.pxlc"), tmp16);
588  pxcap.pxlc = tmp16;
589  paramIn(cp, csprintf("pxcap.pxls"), tmp16);
590  pxcap.pxls = tmp16;
591  paramIn(cp, csprintf("pxcap.pxdcap2"), tmp32);
592  pxcap.pxdcap2 = tmp32;
593  paramIn(cp, csprintf("pxcap.pxdc2"), tmp32);
594  pxcap.pxdc2 = tmp32;
596 }
597 
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:183
MSIXCAP::mtab
uint32_t mtab
Definition: pcireg.h:276
PciIntPin
PciIntPin
Definition: types.hh:63
Packet::makeAtomicResponse
void makeAtomicResponse()
Definition: packet.hh:1016
PCI_STATUS
#define PCI_STATUS
Definition: pcireg.h:90
PXCAP::pxdc2
uint32_t pxdc2
Definition: pcireg.h:396
PciDevice::getAddrRanges
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
Definition: device.cc:273
warn
#define warn(...)
Definition: logging.hh:239
BAR_IO_SPACE
#define BAR_IO_SPACE(x)
Definition: device.hh:60
PCIConfig::capabilityPtr
uint8_t capabilityPtr
Definition: pcireg.h:74
PCI0_MINIMUM_GRANT
#define PCI0_MINIMUM_GRANT
Definition: pcireg.h:120
MSIXVECS_PER_PBA
#define MSIXVECS_PER_PBA
Definition: pcireg.h:295
PCI_REVISION_ID
#define PCI_REVISION_ID
Definition: pcireg.h:91
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:797
Packet::getAddr
Addr getAddr() const
Definition: packet.hh:754
PMCAP::pc
uint16_t pc
Definition: pcireg.h:211
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:284
PCIConfig::headerType
uint8_t headerType
Definition: pcireg.h:67
PCIConfig::subClassCode
uint8_t subClassCode
Definition: pcireg.h:63
htole
T htole(T value)
Definition: byteswap.hh:140
PciDevice::readConfig
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
Definition: device.cc:216
BAR_MEM_MASK
#define BAR_MEM_MASK
Definition: device.hh:58
MSIXCAP_MXC
#define MSIXCAP_MXC
Definition: pcireg.h:184
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:63
PXCAP::pxlcap
uint32_t pxlcap
Definition: pcireg.h:350
PCI0_BASE_ADDR4
#define PCI0_BASE_ADDR4
Definition: pcireg.h:110
PciDevice::pxcap
PXCAP pxcap
Definition: device.hh:98
PciDevice::config
PCIConfig config
The current config space.
Definition: device.hh:72
PciDevice::_busAddr
const PciBusAddr _busAddr
Definition: device.hh:69
Packet::getSize
unsigned getSize() const
Definition: packet.hh:764
PCI_COMMAND
#define PCI_COMMAND
Definition: pcireg.h:89
PciDevice::msixcap
MSIXCAP msixcap
Definition: device.hh:95
PCI_LATENCY_TIMER
#define PCI_LATENCY_TIMER
Definition: pcireg.h:96
PCIConfig::minimumGrant
uint8_t minimumGrant
Definition: pcireg.h:81
PCIConfig::interruptLine
uint8_t interruptLine
Definition: pcireg.h:79
PCIConfig::status
uint16_t status
Definition: pcireg.h:60
device.hh
PciDevice::msix_pba
std::vector< MSIXPbaEntry > msix_pba
Definition: device.hh:103
MSIXCAP_MPBA
#define MSIXCAP_MPBA
Definition: pcireg.h:186
paramOut
void paramOut(CheckpointOut &cp, const string &name, ExtMachInst const &machInst)
Definition: types.cc:38
PXCAP::pxds
uint16_t pxds
Definition: pcireg.h:342
PCI_DEVICE_SPECIFIC
#define PCI_DEVICE_SPECIFIC
Definition: pcireg.h:148
PCIConfig::latencyTimer
uint8_t latencyTimer
Definition: pcireg.h:66
packet.hh
MSICAP::mmask
uint32_t mmask
Definition: pcireg.h:256
PCI0_INTERRUPT_LINE
#define PCI0_INTERRUPT_LINE
Definition: pcireg.h:118
MSIXTable
Definition: pcireg.h:285
PCIConfig::device
uint16_t device
Definition: pcireg.h:58
str.hh
PCIConfig::maximumLatency
uint8_t maximumLatency
Definition: pcireg.h:82
PCI0_ROM_BASE_ADDR
#define PCI0_ROM_BASE_ADDR
Definition: pcireg.h:115
letoh
T letoh(T value)
Definition: byteswap.hh:141
PciDevice::PciDevice
PciDevice(const PciDeviceParams *params)
Constructor for PCI Dev.
Definition: device.cc:62
PciDevice::hostInterface
PciHost::DeviceInterface hostInterface
Definition: device.hh:188
cp
Definition: cprintf.cc:40
PCI0_BASE_ADDR0
#define PCI0_BASE_ADDR0
Definition: pcireg.h:106
PCI0_BASE_ADDR5
#define PCI0_BASE_ADDR5
Definition: pcireg.h:111
MSIXCAP::mxc
uint16_t mxc
Definition: pcireg.h:271
PciDevice::BARSize
uint32_t BARSize[6]
The size of the BARs.
Definition: device.hh:106
PCIConfig::bist
uint8_t bist
Definition: pcireg.h:68
MSIXPbaEntry
Definition: pcireg.h:296
PciHost::DeviceInterface::memAddr
Addr memAddr(Addr addr) const
Calculate the physical address of a non-prefetchable memory location in the PCI address space.
Definition: host.hh:137
PCIConfig::subsystemID
uint16_t subsystemID
Definition: pcireg.h:72
PciHost::DeviceInterface::pioAddr
Addr pioAddr(Addr addr) const
Calculate the physical address of an IO location on the PCI bus.
Definition: host.hh:128
PciDevice::msicap
MSICAP msicap
Definition: device.hh:84
PciDevice::MSIX_TABLE_OFFSET
int MSIX_TABLE_OFFSET
Definition: device.hh:91
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:234
PCIConfig::cacheLineSize
uint8_t cacheLineSize
Definition: pcireg.h:65
PciDevice::serialize
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition: device.cc:442
MSICAP::mc
uint16_t mc
Definition: pcireg.h:244
MSIXCAP::mpba
uint32_t mpba
Definition: pcireg.h:279
PciDevice::MSIXCAP_BASE
const int MSIXCAP_BASE
Definition: device.hh:86
PXCAP::pxid
uint16_t pxid
Definition: pcireg.h:307
MSICAP::md
uint16_t md
Definition: pcireg.h:255
PCIConfig::interruptPin
uint8_t interruptPin
Definition: pcireg.h:80
PXCAP::pxdcap
uint32_t pxdcap
Definition: pcireg.h:316
RangeSize
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:638
PCIConfig::baseAddr
uint32_t baseAddr[6]
Definition: pcireg.h:69
PciDevice::MSIX_TABLE_END
int MSIX_TABLE_END
Definition: device.hh:92
PXCAP::pxdcap2
uint32_t pxdcap2
Definition: pcireg.h:379
MSIXCAP::mxid
uint16_t mxid
Definition: pcireg.h:268
PXCAP::pxls
uint16_t pxls
Definition: pcireg.h:372
PciDevice::unserialize
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition: device.cc:507
inifile.hh
SERIALIZE_ARRAY
#define SERIALIZE_ARRAY(member, size)
Definition: serialize.hh:832
RiscvISA::x
Bitfield< 3 > x
Definition: pagetable.hh:69
PXCAP::pxcap
uint16_t pxcap
Definition: pcireg.h:310
PciBusAddr::func
uint8_t func
Definition: types.hh:55
PCIConfig::expansionROM
uint32_t expansionROM
Definition: pcireg.h:73
PciDevice::isLargeBAR
bool isLargeBAR(int bar) const
Does the given BAR represent 32 lower bits of a 64-bit address?
Definition: device.hh:118
core.hh
PCIConfig::subsystemVendorID
uint16_t subsystemVendorID
Definition: pcireg.h:71
BAR_NUMBER
#define BAR_NUMBER(x)
Definition: device.hh:61
PCI0_MAXIMUM_LATENCY
#define PCI0_MAXIMUM_LATENCY
Definition: pcireg.h:121
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:790
packet_access.hh
PciDevice::configDelay
Tick configDelay
Definition: device.hh:191
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:133
PMCAP::pid
uint16_t pid
Definition: pcireg.h:208
PCI_CLASS_CODE
#define PCI_CLASS_CODE
Definition: pcireg.h:92
PCIConfig::reserved
uint8_t reserved[7]
Definition: pcireg.h:78
DmaDevice
Definition: dma_device.hh:165
Packet::getLE
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Definition: packet_access.hh:75
PCIConfig::data
uint8_t data[64]
Definition: pcireg.h:54
PciDevice::msix_table
std::vector< MSIXTable > msix_table
MSIX Table and PBA Structures.
Definition: device.hh:102
PCIConfig::progIF
uint8_t progIF
Definition: pcireg.h:62
UNSERIALIZE_ARRAY
#define UNSERIALIZE_ARRAY(member, size)
Definition: serialize.hh:840
MSICAP::mid
uint16_t mid
Definition: pcireg.h:241
PCIConfig::classCode
uint8_t classCode
Definition: pcireg.h:64
MSICAP::mpend
uint32_t mpend
Definition: pcireg.h:257
MSICAP::mua
uint32_t mua
Definition: pcireg.h:254
PCI_CACHE_LINE_SIZE
#define PCI_CACHE_LINE_SIZE
Definition: pcireg.h:95
MSIXCAP_MTAB
#define MSIXCAP_MTAB
Definition: pcireg.h:185
Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:257
PciDevice::MSIX_PBA_OFFSET
int MSIX_PBA_OFFSET
Definition: device.hh:93
PMCAP_PMCS
#define PMCAP_PMCS
Definition: pcireg.h:171
BAR_IO_MASK
#define BAR_IO_MASK
Definition: device.hh:57
PMCAP_PC
#define PMCAP_PC
Definition: pcireg.h:170
MSICAP::ma
uint32_t ma
Definition: pcireg.h:251
PCIConfig::vendor
uint16_t vendor
Definition: pcireg.h:57
PCIConfig::command
uint16_t command
Definition: pcireg.h:59
paramIn
void paramIn(CheckpointIn &cp, const string &name, ExtMachInst &machInst)
Definition: types.cc:69
PciDevice::pmcap
PMCAP pmcap
Definition: device.hh:81
MSIXCAP_ID
#define MSIXCAP_ID
Definition: pcireg.h:183
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:107
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:63
PXCAP::pxdc
uint16_t pxdc
Definition: pcireg.h:329
PCIConfig::revision
uint8_t revision
Definition: pcireg.h:61
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:94
PCI_CONFIG_SIZE
#define PCI_CONFIG_SIZE
Definition: pcireg.h:149
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
PciDevice::BARAddrs
Addr BARAddrs[6]
The current address mapping of the BARs.
Definition: device.hh:109
CheckpointIn
Definition: serialize.hh:67
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:109
isPowerOf2
bool isPowerOf2(const T &n)
Definition: intmath.hh:102
PciDevice::legacyIO
bool legacyIO[6]
Whether the BARs are really hardwired legacy IO locations.
Definition: device.hh:112
csprintf
std::string csprintf(const char *format, const Args &...args)
Definition: cprintf.hh:158
PciBusAddr::dev
uint8_t dev
Definition: types.hh:54
PCIConfig::cardbusCIS
uint32_t cardbusCIS
Definition: pcireg.h:70
PMCAP::pmcs
uint16_t pmcs
Definition: pcireg.h:220
PciDevice
PCI device, base implementation is only config space.
Definition: device.hh:66
PXCAP::pxlc
uint16_t pxlc
Definition: pcireg.h:362
byteswap.hh
PMCAP_ID
#define PMCAP_ID
PCIe capability list offsets internal to the entry.
Definition: pcireg.h:169
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
bits
T bits(T val, int first, int last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:75
PCI0_INTERRUPT_PIN
#define PCI0_INTERRUPT_PIN
Definition: pcireg.h:119
PCI0_BASE_ADDR2
#define PCI0_BASE_ADDR2
Definition: pcireg.h:108

Generated on Wed Sep 30 2020 14:02:08 for gem5 by doxygen 1.8.17