gem5  v21.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
device.hh
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2013 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  * Interface for devices using PCI configuration
43  */
44 
45 #ifndef __DEV_PCI_DEVICE_HH__
46 #define __DEV_PCI_DEVICE_HH__
47 
48 #include <array>
49 #include <cstring>
50 #include <vector>
51 
52 #include "dev/dma_device.hh"
53 #include "dev/pci/host.hh"
54 #include "dev/pci/pcireg.h"
55 #include "params/PciBar.hh"
56 #include "params/PciBarNone.hh"
57 #include "params/PciDevice.hh"
58 #include "params/PciIoBar.hh"
59 #include "params/PciLegacyIoBar.hh"
60 #include "params/PciMemBar.hh"
61 #include "params/PciMemUpperBar.hh"
62 #include "sim/byteswap.hh"
63 
64 #define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
65 
66 class PciBar : public SimObject
67 {
68  protected:
69  // The address and size of the region this decoder recognizes.
70  Addr _addr = 0;
71  Addr _size = 0;
72 
73  public:
74  PciBar(const PciBarParams &p) : SimObject(p) {}
75 
76  virtual bool isMem() const { return false; }
77  virtual bool isIo() const { return false; }
78 
79  // Accepts a value written to config space, consumes it, and returns what
80  // value config space should actually be set to. Both should be in host
81  // endian format.
82  virtual uint32_t write(const PciHost::DeviceInterface &host,
83  uint32_t val) = 0;
84 
85  AddrRange range() const { return AddrRange(_addr, _addr + _size); }
86  Addr addr() const { return _addr; }
87  Addr size() const { return _size; }
88 
89  // Hack for devices that don't know their BAR sizes ahead of time :-o.
90  // Don't use unless you have to, since this may not propogate properly
91  // outside of a small window.
92  void size(Addr value) { _size = value; }
93 };
94 
95 class PciBarNone : public PciBar
96 {
97  public:
98  PciBarNone(const PciBarNoneParams &p) : PciBar(p) {}
99 
100  uint32_t
101  write(const PciHost::DeviceInterface &host, uint32_t val) override
102  {
103  return 0;
104  }
105 };
106 
107 class PciIoBar : public PciBar
108 {
109  protected:
110  BitUnion32(Bar)
111  Bitfield<31, 2> addr;
112  Bitfield<1> reserved;
113  Bitfield<0> io;
115 
116  public:
117  PciIoBar(const PciIoBarParams &p, bool legacy=false) : PciBar(p)
118  {
119  _size = p.size;
120  if (!legacy) {
121  Bar bar = _size;
122  fatal_if(!_size || !isPowerOf2(_size) || bar.io || bar.reserved,
123  "Illegal size %d for bar %s.", _size, name());
124  }
125  }
126 
127  bool isIo() const override { return true; }
128 
129  uint32_t
130  write(const PciHost::DeviceInterface &host, uint32_t val) override
131  {
132  // Mask away the bits fixed by hardware.
133  Bar bar = val & ~(_size - 1);
134  // Set the fixed bits to their correct values.
135  bar.reserved = 0;
136  bar.io = 1;
137 
138  // Update our address.
139  _addr = host.pioAddr(bar.addr << 2);
140 
141  // Return what should go into config space.
142  return bar;
143  }
144 };
145 
146 class PciLegacyIoBar : public PciIoBar
147 {
148  protected:
150 
151  public:
152  PciLegacyIoBar(const PciLegacyIoBarParams &p) : PciIoBar(p, true)
153  {
154  // Save the address until we get a host to translate it.
155  fixedAddr = p.addr;
156  }
157 
158  uint32_t
159  write(const PciHost::DeviceInterface &host, uint32_t val) override
160  {
161  // Update the address now that we have a host to translate it.
162  _addr = host.pioAddr(fixedAddr);
163  // Ignore writes.
164  return 0;
165  }
166 };
167 
168 class PciMemBar : public PciBar
169 {
170  private:
171  BitUnion32(Bar)
172  Bitfield<31, 3> addr;
173  SubBitUnion(type, 2, 1)
174  Bitfield<2> wide;
175  Bitfield<1> reserved;
177  Bitfield<0> io;
178  EndBitUnion(Bar)
179 
180  bool _wide = false;
181  uint64_t _lower = 0;
182  uint64_t _upper = 0;
183 
184  public:
185  PciMemBar(const PciMemBarParams &p) : PciBar(p)
186  {
187  _size = p.size;
188  Bar bar = _size;
189  fatal_if(!_size || !isPowerOf2(_size) || bar.io || bar.type,
190  "Illegal size %d for bar %s.", _size, name());
191  }
192 
193  bool isMem() const override { return true; }
194 
195  uint32_t
196  write(const PciHost::DeviceInterface &host, uint32_t val) override
197  {
198  // Mask away the bits fixed by hardware.
199  Bar bar = val & ~(_size - 1);
200  // Set the fixed bits to their correct values.
201  bar.type.wide = wide() ? 1 : 0;
202  bar.type.reserved = 0;
203  bar.io = 0;
204 
205  // Keep track of our lower 32 bits.
206  _lower = bar.addr << 3;
207 
208  // Update our address.
209  _addr = host.memAddr(upper() + lower());
210 
211  // Return what should go into config space.
212  return bar;
213  }
214 
215  bool wide() const { return _wide; }
216  void wide(bool val) { _wide = val; }
217 
218  uint64_t upper() const { return _upper; }
219  void
220  upper(const PciHost::DeviceInterface &host, uint32_t val)
221  {
222  _upper = (uint64_t)val << 32;
223 
224  // Update our address.
225  _addr = host.memAddr(upper() + lower());
226  }
227 
228  uint64_t lower() const { return _lower; }
229 };
230 
231 class PciMemUpperBar : public PciBar
232 {
233  private:
234  PciMemBar *_lower = nullptr;
235 
236  public:
237  PciMemUpperBar(const PciMemUpperBarParams &p) : PciBar(p)
238  {}
239 
240  void
242  {
243  _lower = val;
244  // Let our lower half know we're up here.
245  _lower->wide(true);
246  }
247 
248  uint32_t
249  write(const PciHost::DeviceInterface &host, uint32_t val) override
250  {
251  assert(_lower);
252 
253  // Mask away bits fixed by hardware, if any.
254  Addr upper = val & ~((_lower->size() - 1) >> 32);
255 
256  // Let our lower half know about the update.
257  _lower->upper(host, upper);
258 
259  return upper;
260  }
261 };
262 
266 class PciDevice : public DmaDevice
267 {
268  protected:
270 
272  PCIConfig config;
273 
277  const int PMCAP_BASE;
278  const int PMCAP_ID_OFFSET;
279  const int PMCAP_PC_OFFSET;
280  const int PMCAP_PMCS_OFFSET;
282 
283  const int MSICAP_BASE;
285 
286  const int MSIXCAP_BASE;
287  const int MSIXCAP_ID_OFFSET;
296 
297  const int PXCAP_BASE;
304 
305  std::array<PciBar *, 6> BARs{};
306 
316  bool
317  getBAR(Addr addr, int &num, Addr &offs)
318  {
319  for (int i = 0; i < BARs.size(); i++) {
320  auto *bar = BARs[i];
321  if (!bar || !bar->range().contains(addr))
322  continue;
323  num = i;
324  offs = addr - bar->addr();
325  return true;
326  }
327  return false;
328  }
329 
330  public: // Host configuration interface
337  virtual Tick writeConfig(PacketPtr pkt);
338 
339 
346  virtual Tick readConfig(PacketPtr pkt);
347 
348  protected:
350 
353 
354  public:
355  Addr
356  pciToDma(Addr pci_addr) const
357  {
358  return hostInterface.dmaAddr(pci_addr);
359  }
360 
363 
364  uint8_t interruptLine() const { return letoh(config.interruptLine); }
365 
371  AddrRangeList getAddrRanges() const override;
372 
378  PciDevice(const PciDeviceParams &params);
379 
384  void serialize(CheckpointOut &cp) const override;
385 
391  void unserialize(CheckpointIn &cp) override;
392 
393  const PciBusAddr &busAddr() const { return _busAddr; }
394 };
395 #endif // __DEV_PCI_DEVICE_HH__
PciMemBar
Definition: device.hh:168
PciDevice::getAddrRanges
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
Definition: device.cc:267
PciDevice::MSICAP_BASE
const int MSICAP_BASE
Definition: device.hh:283
PciMemBar::write
uint32_t write(const PciHost::DeviceInterface &host, uint32_t val) override
Definition: device.hh:196
PciIoBar::reserved
Bitfield< 1 > reserved
Definition: device.hh:112
PciHost::DeviceInterface::postInt
void postInt()
Post a PCI interrupt to the CPU.
Definition: host.cc:102
PciBar::size
void size(Addr value)
Definition: device.hh:92
PciDevice::BARs
std::array< PciBar *, 6 > BARs
Definition: device.hh:305
PciMemBar::wide
void wide(bool val)
Definition: device.hh:216
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
PciIoBar::isIo
bool isIo() const override
Definition: device.hh:127
PciMemBar::wide
bool wide() const
Definition: device.hh:215
PciMemBar::EndSubBitUnion
EndSubBitUnion(type) Bitfield< 0 > io
PciBar::range
AddrRange range() const
Definition: device.hh:85
PciDevice::PMCAP_PC_OFFSET
const int PMCAP_PC_OFFSET
Definition: device.hh:279
PciMemBar::upper
uint64_t upper() const
Definition: device.hh:218
PciBar::_addr
Addr _addr
Definition: device.hh:70
PciDevice::readConfig
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
Definition: device.cc:210
PciHost::DeviceInterface
Callback interface from PCI devices to the host.
Definition: host.hh:91
PciMemBar::BitUnion32
BitUnion32(Bar) Bitfield< 31
PciDevice::interruptLine
uint8_t interruptLine() const
Definition: device.hh:364
PciBar
Definition: device.hh:66
Tick
uint64_t Tick
Tick count type.
Definition: types.hh:59
PciMemUpperBar::PciMemUpperBar
PciMemUpperBar(const PciMemUpperBarParams &p)
Definition: device.hh:237
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
std::vector< MSIXTable >
PciDevice::intrClear
void intrClear()
Definition: device.hh:362
PciLegacyIoBar::PciLegacyIoBar
PciLegacyIoBar(const PciLegacyIoBarParams &p)
Definition: device.hh:152
PciDevice::msixcap
MSIXCAP msixcap
Definition: device.hh:295
PciBarNone
Definition: device.hh:95
PciMemBar::SubBitUnion
SubBitUnion(type, 2, 1) Bitfield< 2 > wide
PciDevice::msix_pba
std::vector< MSIXPbaEntry > msix_pba
Definition: device.hh:303
PciMemBar::_upper
uint64_t _upper
Definition: device.hh:182
PciIoBar
Definition: device.hh:107
PciMemUpperBar::write
uint32_t write(const PciHost::DeviceInterface &host, uint32_t val) override
Definition: device.hh:249
MipsISA::io
Bitfield< 26 > io
Definition: dt_constants.hh:75
PciDevice::MSIXCAP_MTAB_OFFSET
const int MSIXCAP_MTAB_OFFSET
Definition: device.hh:289
PciMemBar::reserved
Bitfield< 1 > reserved
Definition: device.hh:175
PciDevice::PMCAP_PMCS_OFFSET
const int PMCAP_PMCS_OFFSET
Definition: device.hh:280
PciMemUpperBar::_lower
PciMemBar * _lower
Definition: device.hh:234
PciLegacyIoBar::fixedAddr
Addr fixedAddr
Definition: device.hh:149
letoh
T letoh(T value)
Definition: byteswap.hh:142
PciDevice::hostInterface
PciHost::DeviceInterface hostInterface
Definition: device.hh:349
cp
Definition: cprintf.cc:37
PciIoBar::write
uint32_t write(const PciHost::DeviceInterface &host, uint32_t val) override
Definition: device.hh:130
dma_device.hh
PciHost::DeviceInterface::clearInt
void clearInt()
Clear a posted PCI interrupt.
Definition: host.cc:110
PciBusAddr
Definition: types.hh:41
PciDevice::busAddr
const PciBusAddr & busAddr() const
Definition: device.hh:393
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
PciHost::DeviceInterface::pioAddr
Addr pioAddr(Addr addr) const
Calculate the physical address of an IO location on the PCI bus.
Definition: host.hh:128
AddrRange
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition: addr_range.hh:68
PciIoBar::EndBitUnion
EndBitUnion(Bar) public
Definition: device.hh:114
PMCAP
Definition: pcireg.h:219
PciDevice::msicap
MSICAP msicap
Definition: device.hh:284
PciDevice::MSIX_TABLE_OFFSET
int MSIX_TABLE_OFFSET
Definition: device.hh:291
PciMemBar::EndBitUnion
EndBitUnion(Bar) bool _wide
PciDevice::serialize
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition: device.cc:399
PciDevice::PMCAP_BASE
const int PMCAP_BASE
The capability list structures and base addresses.
Definition: device.hh:277
PciBar::isIo
virtual bool isIo() const
Definition: device.hh:77
PciDevice::MSIXCAP_BASE
const int MSIXCAP_BASE
Definition: device.hh:286
PciMemBar::isMem
bool isMem() const override
Definition: device.hh:193
PciDevice::MSIX_TABLE_END
int MSIX_TABLE_END
Definition: device.hh:292
PXCAP
Definition: pcireg.h:318
pcireg.h
PciDevice::unserialize
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition: device.cc:462
PciBarNone::write
uint32_t write(const PciHost::DeviceInterface &host, uint32_t val) override
Definition: device.hh:101
X86ISA::val
Bitfield< 63 > val
Definition: misc.hh:769
Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:148
PciDevice::MSIXCAP_MXC_OFFSET
const int MSIXCAP_MXC_OFFSET
Definition: device.hh:288
host.hh
PciDevice::PciDevice
PciDevice(const PciDeviceParams &params)
Constructor for PCI Dev.
Definition: device.cc:62
PciMemBar::upper
void upper(const PciHost::DeviceInterface &host, uint32_t val)
Definition: device.hh:220
PciIoBar::addr
addr
Definition: device.hh:111
PciDevice::configDelay
Tick configDelay
Definition: device.hh:352
X86ISA::legacy
legacy
Definition: misc.hh:609
X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:80
SimObject::name
virtual const std::string name() const
Definition: sim_object.hh:182
PciBar::addr
Addr addr() const
Definition: device.hh:86
MSIXCAP
Definition: pcireg.h:279
PciBarNone::PciBarNone
PciBarNone(const PciBarNoneParams &p)
Definition: device.hh:98
PciLegacyIoBar::write
uint32_t write(const PciHost::DeviceInterface &host, uint32_t val) override
Definition: device.hh:159
DmaDevice
Definition: dma_device.hh:200
PciMemBar::lower
uint64_t lower() const
Definition: device.hh:228
PciDevice::msix_table
std::vector< MSIXTable > msix_table
MSIX Table and PBA Structures.
Definition: device.hh:302
MSICAP
Definition: pcireg.h:252
PciMemBar::addr
addr
Definition: device.hh:172
PciBar::PciBar
PciBar(const PciBarParams &p)
Definition: device.hh:74
PciDevice::PXCAP_BASE
const int PXCAP_BASE
Definition: device.hh:297
PciBar::write
virtual uint32_t write(const PciHost::DeviceInterface &host, uint32_t val)=0
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
PciIoBar::BitUnion32
BitUnion32(Bar) Bitfield< 31
PciDevice::pmcap
PMCAP pmcap
Definition: device.hh:281
PciDevice::pioDelay
Tick pioDelay
Definition: device.hh:351
PciBar::isMem
virtual bool isMem() const
Definition: device.hh:76
CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:64
PciLegacyIoBar
Definition: device.hh:146
PciDevice::intrPost
void intrPost()
Definition: device.hh:361
X86ISA::type
type
Definition: misc.hh:727
PciDevice::MSIXCAP_MPBA_OFFSET
const int MSIXCAP_MPBA_OFFSET
Definition: device.hh:290
SimObject::params
const Params & params() const
Definition: sim_object.hh:168
MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:323
std::list< AddrRange >
PciDevice::PMCAP_ID_OFFSET
const int PMCAP_ID_OFFSET
Definition: device.hh:278
PciDevice::MSIX_PBA_END
int MSIX_PBA_END
Definition: device.hh:294
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
CheckpointIn
Definition: serialize.hh:68
PciDevice::MSIXCAP_ID_OFFSET
const int MSIXCAP_ID_OFFSET
Definition: device.hh:287
isPowerOf2
bool isPowerOf2(const T &n)
Definition: intmath.hh:102
PciBar::size
Addr size() const
Definition: device.hh:87
PciHost::DeviceInterface::dmaAddr
Addr dmaAddr(Addr addr) const
Calculate the physical address of a prefetchable memory location in the PCI address space.
Definition: host.hh:146
PciIoBar::io
Bitfield< 0 > io
Definition: device.hh:113
PciDevice
PCI device, base implementation is only config space.
Definition: device.hh:266
PciBar::_size
Addr _size
Definition: device.hh:71
PciDevice::pciToDma
Addr pciToDma(Addr pci_addr) const
Definition: device.hh:356
byteswap.hh
PciMemUpperBar
Definition: device.hh:231
PciMemUpperBar::lower
void lower(PciMemBar *val)
Definition: device.hh:241
PciDevice::getBAR
bool getBAR(Addr addr, int &num, Addr &offs)
Which base address register (if any) maps the given address?
Definition: device.hh:317
PciMemBar::_lower
uint64_t _lower
Definition: device.hh:181
SimObject
Abstract superclass for simulation objects.
Definition: sim_object.hh:141

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