gem5 [DEVELOP-FOR-25.1]
Loading...
Searching...
No Matches
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 <cstring>
49#include <vector>
50
51#include "dev/dma_device.hh"
52#include "dev/pci/pcireg.h"
53#include "dev/pci/types.hh"
54#include "dev/pci/upstream.hh"
55#include "params/PciBar.hh"
56#include "params/PciBarNone.hh"
57#include "params/PciDevice.hh"
58#include "params/PciEndpoint.hh"
59#include "params/PciIoBar.hh"
60#include "params/PciLegacyIoBar.hh"
61#include "params/PciMemBar.hh"
62#include "params/PciMemUpperBar.hh"
63#include "params/PciType1Device.hh"
64#include "sim/byteswap.hh"
65
66#define PCI0_BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2);
67#define PCI1_BAR_NUMBER(x) (((x) - PCI1_BASE_ADDR0) >> 0x2);
68
69namespace gem5
70{
71
72class PciBar : public SimObject
73{
74 protected:
75 // The address and size of the region this decoder recognizes.
78
79 public:
80 PciBar(const PciBarParams &p) : SimObject(p) {}
81
82 virtual bool isMem() const { return false; }
83 virtual bool isIo() const { return false; }
84
85 // Accepts a value written to config space, consumes it, and returns what
86 // value config space should actually be set to. Both should be in host
87 // endian format.
88 virtual uint32_t write(const PciUpstream::DeviceInterface &interface,
89 uint32_t val) = 0;
90
91 AddrRange range() const { return AddrRange(_addr, _addr + _size); }
92 Addr addr() const { return _addr; }
93 Addr size() const { return _size; }
94
95 // Hack for devices that don't know their BAR sizes ahead of time :-o.
96 // Don't use unless you have to, since this may not propogate properly
97 // outside of a small window.
98 void size(Addr value) { _size = value; }
99};
100
101class PciBarNone : public PciBar
102{
103 public:
104 PciBarNone(const PciBarNoneParams &p) : PciBar(p) {}
105
106 uint32_t
107 write(const PciUpstream::DeviceInterface &interface, uint32_t val) override
108 {
109 return 0;
110 }
111};
112
113class PciIoBar : public PciBar
114{
115 protected:
117 Bitfield<31, 2> addr;
118 Bitfield<1> reserved;
119 Bitfield<0> io;
121
122 public:
123 PciIoBar(const PciIoBarParams &p, bool legacy=false) : PciBar(p)
124 {
125 _size = p.size;
126 if (!legacy) {
127 Bar bar = _size;
128 fatal_if(!_size || !isPowerOf2(_size) || bar.io || bar.reserved,
129 "Illegal size %d for bar %s.", _size, name());
130 }
131 }
132
133 bool isIo() const override { return true; }
134
135 uint32_t
136 write(const PciUpstream::DeviceInterface &interface, uint32_t val) override
137 {
138 // Mask away the bits fixed by hardware.
139 Bar bar = val & ~(_size - 1);
140 // Set the fixed bits to their correct values.
141 bar.reserved = 0;
142 bar.io = 1;
143
144 // Update our address.
145 _addr = interface.pioAddr(bar.addr << 2);
146
147 // Return what should go into config space.
148 return bar;
149 }
150};
151
153{
154 protected:
156
157 public:
158 PciLegacyIoBar(const PciLegacyIoBarParams &p) : PciIoBar(p, true)
159 {
160 // Save the address until we get a host to translate it.
161 fixedAddr = p.addr;
162 }
163
164 uint32_t
165 write(const PciUpstream::DeviceInterface &interface, uint32_t val) override
166 {
167 // Update the address now that we have a host to translate it.
168 _addr = interface.pioAddr(fixedAddr);
169 // Ignore writes.
170 return 0;
171 }
172};
173
174class PciMemBar : public PciBar
175{
176 private:
178 Bitfield<31, 3> addr;
179 SubBitUnion(type, 2, 1)
180 Bitfield<2> wide;
181 Bitfield<1> reserved;
183 Bitfield<0> io;
185
186 bool _wide = false;
187 uint64_t _lower = 0;
188 uint64_t _upper = 0;
189
190 public:
191 PciMemBar(const PciMemBarParams &p) : PciBar(p)
192 {
193 _size = p.size;
194 Bar bar = _size;
195 fatal_if(!_size || !isPowerOf2(_size) || bar.io || bar.type,
196 "Illegal size %d for bar %s.", _size, name());
197 }
198
199 bool isMem() const override { return true; }
200
201 uint32_t
202 write(const PciUpstream::DeviceInterface &interface, uint32_t val) override
203 {
204 // Mask away the bits fixed by hardware.
205 Bar bar = val & ~(_size - 1);
206 // Set the fixed bits to their correct values.
207 bar.type.wide = wide() ? 1 : 0;
208 bar.type.reserved = 0;
209 bar.io = 0;
210
211 // Keep track of our lower 32 bits.
212 _lower = bar.addr << 3;
213
214 // Update our address.
215 _addr = interface.memAddr(upper() + lower());
216
217 // Return what should go into config space.
218 return bar;
219 }
220
221 bool wide() const { return _wide; }
222 void wide(bool val) { _wide = val; }
223
224 uint64_t upper() const { return _upper; }
225
226 void
227 upper(const PciUpstream::DeviceInterface &interface, uint32_t val)
228 {
229 _upper = (uint64_t)val << 32;
230
231 // Update our address.
232 _addr = interface.memAddr(upper() + lower());
233 }
234
235 uint64_t lower() const { return _lower; }
236};
237
238class PciMemUpperBar : public PciBar
239{
240 private:
241 PciMemBar *_lower = nullptr;
242
243 public:
244 PciMemUpperBar(const PciMemUpperBarParams &p) : PciBar(p)
245 {}
246
247 void
249 {
250 _lower = val;
251 // Let our lower half know we're up here.
252 _lower->wide(true);
253 }
254
255 uint32_t
256 write(const PciUpstream::DeviceInterface &interface, uint32_t val) override
257 {
258 assert(_lower);
259
260 // Mask away bits fixed by hardware, if any.
261 Addr upper = val & ~((_lower->size() - 1) >> 32);
262
263 // Let our lower half know about the update.
264 _lower->upper(interface, upper);
265
266 return upper;
267 }
268};
269
270class PciEndpoint;
271class PciType1Device;
272
296class PciDevice : public DmaDevice
297{
300
301 private:
304
305 bool
307 {
308 return (offs <= PCI_BIST) || (offs == PCI_CAP_PTR) ||
309 (offs == PCI_INTERRUPT_LINE) || (offs == PCI_INTERRUPT_PIN);
310 }
311
312 protected:
314
318 const int PMCAP_BASE;
323
324 const int MSICAP_BASE;
326
327 const int MSIXCAP_BASE;
337
338 const int PXCAP_BASE;
341
345
347
357 bool
358 getBAR(Addr addr, int &num, Addr &offs)
359 {
360 for (int i = 0; i < BARs.size(); i++) {
361 auto *bar = BARs[i];
362 if (!bar || !bar->range().contains(addr))
363 continue;
364 num = i;
365 offs = addr - bar->addr();
366 return true;
367 }
368 return false;
369 }
370
371 public:
379 Tick write(PacketPtr pkt) final;
380
388 Tick read(PacketPtr pkt) final;
389
390 protected:
397 virtual Tick writeConfig(PacketPtr pkt);
398
405 virtual Tick readConfig(PacketPtr pkt);
406
412 virtual Tick writeDevice(PacketPtr pkt) = 0;
413
419 virtual Tick readDevice(PacketPtr pkt) = 0;
420
421 protected:
423
426
427 public:
428 Addr
429 pciToDma(Addr pci_addr) const
430 {
431 return upstreamInterface.dmaAddr(pci_addr);
432 }
433
434 void
436 {
437 upstreamInterface.postInt();
438 }
439
440 void
442 {
443 upstreamInterface.clearInt();
444 }
445
446 uint8_t
448 {
449 return letoh(_config.common.interruptLine);
450 }
451
457 AddrRangeList getAddrRanges() const override;
458
464 PciDevice(const PciDeviceParams &params,
465 std::initializer_list<PciBar *> BARs_init);
466
471 void serialize(CheckpointOut &cp) const override;
472
478 void unserialize(CheckpointIn &cp) override;
479
480 const PciDevAddr &
481 devAddr() const
482 {
483 return _devAddr;
484 }
485
492 void recvBusChange();
493};
494
501class PciEndpoint : public PciDevice
502{
503 protected:
506 {
507 return _config.type0;
508 }
509
516 Tick writeConfig(PacketPtr pkt) override;
517
518 public:
524 PciEndpoint(const PciEndpointParams &params);
525
531 void unserialize(CheckpointIn &cp) override;
532};
533
542{
543 protected:
546 {
547 return _config.type1;
548 }
549
556 Tick writeConfig(PacketPtr pkt) override;
557
558 public:
564 PciType1Device(const PciType1DeviceParams &params);
565
571 void unserialize(CheckpointIn &cp) override;
572};
573
574} // namespace gem5
575
576#endif // __DEV_PCI_DEVICE_HH__
The AddrRange class encapsulates an address range, and supports a number of tests to check if two ran...
Definition addr_range.hh:82
DmaDevice(const Params &p)
virtual std::string name() const
Definition named.hh:60
PciBarNone(const PciBarNoneParams &p)
Definition device.hh:104
uint32_t write(const PciUpstream::DeviceInterface &interface, uint32_t val) override
Definition device.hh:107
virtual bool isIo() const
Definition device.hh:83
PciBar(const PciBarParams &p)
Definition device.hh:80
Addr _addr
Definition device.hh:76
Addr size() const
Definition device.hh:93
Addr _size
Definition device.hh:77
AddrRange range() const
Definition device.hh:91
Addr addr() const
Definition device.hh:92
virtual uint32_t write(const PciUpstream::DeviceInterface &interface, uint32_t val)=0
void size(Addr value)
Definition device.hh:98
virtual bool isMem() const
Definition device.hh:82
const int PMCAP_PC_OFFSET
Definition device.hh:320
Tick write(PacketPtr pkt) final
Final implementation of write access from DmaDevice.
Definition device.cc:396
const int MSIXCAP_MTAB_OFFSET
Definition device.hh:330
MSICAP msicap
Definition device.hh:325
PciDevice(const PciDeviceParams &params, std::initializer_list< PciBar * > BARs_init)
Constructor for PCI Dev.
Definition device.cc:65
void intrClear()
Definition device.hh:441
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition device.cc:489
friend PciEndpoint
Definition device.hh:298
std::vector< MSIXTable > msix_table
MSIX Table and PBA Structures.
Definition device.hh:343
const PciDevAddr & devAddr() const
Definition device.hh:481
PciUpstream::DeviceInterface upstreamInterface
Definition device.hh:422
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition device.cc:412
void recvBusChange()
Called to receive a bus number change from the PCI upstream.
Definition device.cc:406
Tick read(PacketPtr pkt) final
Final implementation of read access from PioDevice.
Definition device.cc:264
bool getBAR(Addr addr, int &num, Addr &offs)
Which base address register (if any) maps the given address?
Definition device.hh:358
const int MSIXCAP_BASE
Definition device.hh:327
const int PMCAP_BASE
The capability list structures and base addresses.
Definition device.hh:318
Addr pciToDma(Addr pci_addr) const
Definition device.hh:429
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
Definition device.cc:274
int MSIX_PBA_OFFSET
Definition device.hh:334
const int PMCAP_PMCS_OFFSET
Definition device.hh:321
virtual Tick writeDevice(PacketPtr pkt)=0
Write to the PCI device.
std::vector< MSIXPbaEntry > msix_pba
Definition device.hh:344
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
Definition device.cc:207
PCIConfig _config
The current config space.
Definition device.hh:303
virtual Tick readDevice(PacketPtr pkt)=0
Read from the PCI device.
MSIXCAP msixcap
Definition device.hh:336
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
Definition device.cc:291
int MSIX_TABLE_OFFSET
Definition device.hh:332
const int MSIXCAP_ID_OFFSET
Definition device.hh:328
const int MSIXCAP_MPBA_OFFSET
Definition device.hh:331
friend PciType1Device
Definition device.hh:299
std::vector< PciBar * > BARs
Definition device.hh:346
void intrPost()
Definition device.hh:435
bool isCommonConfig(Addr offs)
Definition device.hh:306
uint8_t interruptLine() const
Definition device.hh:447
const int PMCAP_ID_OFFSET
Definition device.hh:319
const int MSIXCAP_MXC_OFFSET
Definition device.hh:329
const int PXCAP_BASE
Definition device.hh:338
const PciDevAddr _devAddr
Definition device.hh:313
const int MSICAP_BASE
Definition device.hh:324
PCIConfigType0 & config()
Definition device.hh:505
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition device.cc:703
PciEndpoint(const PciEndpointParams &params)
Constructor for PCI Dev.
Definition device.cc:603
Tick writeConfig(PacketPtr pkt) override
Write to the PCI config space data that is stored locally.
Definition device.cc:625
Bitfield< 1 > reserved
Definition device.hh:118
EndBitUnion(Bar) public
Definition device.hh:120
uint32_t write(const PciUpstream::DeviceInterface &interface, uint32_t val) override
Definition device.hh:136
BitUnion32(Bar) Bitfield< 31
Bitfield< 0 > io
Definition device.hh:119
bool isIo() const override
Definition device.hh:133
uint32_t write(const PciUpstream::DeviceInterface &interface, uint32_t val) override
Definition device.hh:165
PciLegacyIoBar(const PciLegacyIoBarParams &p)
Definition device.hh:158
PciMemBar(const PciMemBarParams &p)
Definition device.hh:191
bool isMem() const override
Definition device.hh:199
uint64_t lower() const
Definition device.hh:235
SubBitUnion(type, 2, 1) Bitfield< 2 > wide
uint64_t _upper
Definition device.hh:188
void wide(bool val)
Definition device.hh:222
uint64_t _lower
Definition device.hh:187
EndSubBitUnion(type) Bitfield< 0 > io
uint32_t write(const PciUpstream::DeviceInterface &interface, uint32_t val) override
Definition device.hh:202
void upper(const PciUpstream::DeviceInterface &interface, uint32_t val)
Definition device.hh:227
EndBitUnion(Bar) bool _wide
Bitfield< 1 > reserved
Definition device.hh:181
uint64_t upper() const
Definition device.hh:224
BitUnion32(Bar) Bitfield< 31
bool wide() const
Definition device.hh:221
uint32_t write(const PciUpstream::DeviceInterface &interface, uint32_t val) override
Definition device.hh:256
PciMemBar * _lower
Definition device.hh:241
PciMemUpperBar(const PciMemUpperBarParams &p)
Definition device.hh:244
void lower(PciMemBar *val)
Definition device.hh:248
Tick writeConfig(PacketPtr pkt) override
Write to the PCI config space data that is stored locally.
Definition device.cc:742
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition device.cc:866
PciType1Device(const PciType1DeviceParams &params)
Constructor for PCI Dev.
Definition device.cc:713
PCIConfigType1 & config()
Definition device.hh:545
Callback interface from PCI devices to the upstream.
Definition upstream.hh:112
Addr memAddr(Addr addr) const
Calculate the physical address of a non-prefetchable memory location in the PCI address space.
Definition upstream.hh:175
Addr pioAddr(Addr addr) const
Calculate the physical address of an IO location on the PCI bus.
Definition upstream.hh:162
STL vector class.
Definition stl.hh:37
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
Definition addr_range.hh:64
static constexpr bool isPowerOf2(const T &n)
Definition intmath.hh:98
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:268
const Params & params() const
SimObject(const Params &p)
Definition sim_object.cc:58
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 26 > io
Bitfield< 0 > p
Bitfield< 63 > val
Definition misc.hh:804
Bitfield< 3 > addr
Definition types.hh:84
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
T letoh(T value)
Definition byteswap.hh:173
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint64_t Tick
Tick count type.
Definition types.hh:58
Packet * PacketPtr
#define PCI_INTERRUPT_PIN
Definition pcireg.h:190
#define PCI_BIST
Definition pcireg.h:187
#define PCI_INTERRUPT_LINE
Definition pcireg.h:189
#define PCI_CAP_PTR
Definition pcireg.h:188
Defines the MSI Capability register and its associated bitfields for the a PCI/PCIe device.
Definition pcireg.h:337
Defines the Power Management capability register and all its associated bitfields for a PCIe device.
Definition pcireg.h:302
Defines the PCI Express capability register and its associated bitfields for a PCIe device.
Definition pcireg.h:410

Generated on Mon Oct 27 2025 04:13:00 for gem5 by doxygen 1.14.0