gem5 v24.0.0.0
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 <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
66namespace gem5
67{
68
69class PciBar : public SimObject
70{
71 protected:
72 // The address and size of the region this decoder recognizes.
75
76 public:
77 PciBar(const PciBarParams &p) : SimObject(p) {}
78
79 virtual bool isMem() const { return false; }
80 virtual bool isIo() const { return false; }
81
82 // Accepts a value written to config space, consumes it, and returns what
83 // value config space should actually be set to. Both should be in host
84 // endian format.
85 virtual uint32_t write(const PciHost::DeviceInterface &host,
86 uint32_t val) = 0;
87
88 AddrRange range() const { return AddrRange(_addr, _addr + _size); }
89 Addr addr() const { return _addr; }
90 Addr size() const { return _size; }
91
92 // Hack for devices that don't know their BAR sizes ahead of time :-o.
93 // Don't use unless you have to, since this may not propogate properly
94 // outside of a small window.
95 void size(Addr value) { _size = value; }
96};
97
98class PciBarNone : public PciBar
99{
100 public:
101 PciBarNone(const PciBarNoneParams &p) : PciBar(p) {}
102
103 uint32_t
104 write(const PciHost::DeviceInterface &host, uint32_t val) override
105 {
106 return 0;
107 }
108};
109
110class PciIoBar : public PciBar
111{
112 protected:
114 Bitfield<31, 2> addr;
115 Bitfield<1> reserved;
116 Bitfield<0> io;
118
119 public:
120 PciIoBar(const PciIoBarParams &p, bool legacy=false) : PciBar(p)
121 {
122 _size = p.size;
123 if (!legacy) {
124 Bar bar = _size;
125 fatal_if(!_size || !isPowerOf2(_size) || bar.io || bar.reserved,
126 "Illegal size %d for bar %s.", _size, name());
127 }
128 }
129
130 bool isIo() const override { return true; }
131
132 uint32_t
133 write(const PciHost::DeviceInterface &host, uint32_t val) override
134 {
135 // Mask away the bits fixed by hardware.
136 Bar bar = val & ~(_size - 1);
137 // Set the fixed bits to their correct values.
138 bar.reserved = 0;
139 bar.io = 1;
140
141 // Update our address.
142 _addr = host.pioAddr(bar.addr << 2);
143
144 // Return what should go into config space.
145 return bar;
146 }
147};
148
150{
151 protected:
153
154 public:
155 PciLegacyIoBar(const PciLegacyIoBarParams &p) : PciIoBar(p, true)
156 {
157 // Save the address until we get a host to translate it.
158 fixedAddr = p.addr;
159 }
160
161 uint32_t
162 write(const PciHost::DeviceInterface &host, uint32_t val) override
163 {
164 // Update the address now that we have a host to translate it.
165 _addr = host.pioAddr(fixedAddr);
166 // Ignore writes.
167 return 0;
168 }
169};
170
171class PciMemBar : public PciBar
172{
173 private:
175 Bitfield<31, 3> addr;
177 Bitfield<2> wide;
178 Bitfield<1> reserved;
180 Bitfield<0> io;
182
183 bool _wide = false;
184 uint64_t _lower = 0;
185 uint64_t _upper = 0;
186
187 public:
188 PciMemBar(const PciMemBarParams &p) : PciBar(p)
189 {
190 _size = p.size;
191 Bar bar = _size;
192 fatal_if(!_size || !isPowerOf2(_size) || bar.io || bar.type,
193 "Illegal size %d for bar %s.", _size, name());
194 }
195
196 bool isMem() const override { return true; }
197
198 uint32_t
199 write(const PciHost::DeviceInterface &host, uint32_t val) override
200 {
201 // Mask away the bits fixed by hardware.
202 Bar bar = val & ~(_size - 1);
203 // Set the fixed bits to their correct values.
204 bar.type.wide = wide() ? 1 : 0;
205 bar.type.reserved = 0;
206 bar.io = 0;
207
208 // Keep track of our lower 32 bits.
209 _lower = bar.addr << 3;
210
211 // Update our address.
212 _addr = host.memAddr(upper() + lower());
213
214 // Return what should go into config space.
215 return bar;
216 }
217
218 bool wide() const { return _wide; }
219 void wide(bool val) { _wide = val; }
220
221 uint64_t upper() const { return _upper; }
222 void
223 upper(const PciHost::DeviceInterface &host, uint32_t val)
224 {
225 _upper = (uint64_t)val << 32;
226
227 // Update our address.
228 _addr = host.memAddr(upper() + lower());
229 }
230
231 uint64_t lower() const { return _lower; }
232};
233
234class PciMemUpperBar : public PciBar
235{
236 private:
237 PciMemBar *_lower = nullptr;
238
239 public:
240 PciMemUpperBar(const PciMemUpperBarParams &p) : PciBar(p)
241 {}
242
243 void
245 {
246 _lower = val;
247 // Let our lower half know we're up here.
248 _lower->wide(true);
249 }
250
251 uint32_t
252 write(const PciHost::DeviceInterface &host, uint32_t val) override
253 {
254 assert(_lower);
255
256 // Mask away bits fixed by hardware, if any.
257 Addr upper = val & ~((_lower->size() - 1) >> 32);
258
259 // Let our lower half know about the update.
260 _lower->upper(host, upper);
261
262 return upper;
263 }
264};
265
269class PciDevice : public DmaDevice
270{
271 protected:
273
275 PCIConfig config;
276
280 const int PMCAP_BASE;
285
286 const int MSICAP_BASE;
288
289 const int MSIXCAP_BASE;
299
300 const int PXCAP_BASE;
307
308 std::array<PciBar *, 6> BARs{};
309
319 bool
320 getBAR(Addr addr, int &num, Addr &offs)
321 {
322 for (int i = 0; i < BARs.size(); i++) {
323 auto *bar = BARs[i];
324 if (!bar || !bar->range().contains(addr))
325 continue;
326 num = i;
327 offs = addr - bar->addr();
328 return true;
329 }
330 return false;
331 }
332
333 public: // Host configuration interface
340 virtual Tick writeConfig(PacketPtr pkt);
341
342
349 virtual Tick readConfig(PacketPtr pkt);
350
351 protected:
353
356
357 public:
358 Addr
359 pciToDma(Addr pci_addr) const
360 {
361 return hostInterface.dmaAddr(pci_addr);
362 }
363
366
367 uint8_t interruptLine() const { return letoh(config.interruptLine); }
368
374 AddrRangeList getAddrRanges() const override;
375
381 PciDevice(const PciDeviceParams &params);
382
387 void serialize(CheckpointOut &cp) const override;
388
394 void unserialize(CheckpointIn &cp) override;
395
396 const PciBusAddr &busAddr() const { return _busAddr; }
397};
398
399} // namespace gem5
400
401#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
virtual std::string name() const
Definition named.hh:47
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
PciBarNone(const PciBarNoneParams &p)
Definition device.hh:101
uint32_t write(const PciHost::DeviceInterface &host, uint32_t val) override
Definition device.hh:104
virtual bool isIo() const
Definition device.hh:80
PciBar(const PciBarParams &p)
Definition device.hh:77
Addr _addr
Definition device.hh:73
Addr size() const
Definition device.hh:90
virtual uint32_t write(const PciHost::DeviceInterface &host, uint32_t val)=0
Addr _size
Definition device.hh:74
AddrRange range() const
Definition device.hh:88
Addr addr() const
Definition device.hh:89
void size(Addr value)
Definition device.hh:95
virtual bool isMem() const
Definition device.hh:79
PCI device, base implementation is only config space.
Definition device.hh:270
const int PMCAP_PC_OFFSET
Definition device.hh:282
PciHost::DeviceInterface hostInterface
Definition device.hh:352
PCIConfig config
The current config space.
Definition device.hh:275
const int MSIXCAP_MTAB_OFFSET
Definition device.hh:292
MSICAP msicap
Definition device.hh:287
void intrClear()
Definition device.hh:365
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition device.cc:464
std::vector< MSIXTable > msix_table
MSIX Table and PBA Structures.
Definition device.hh:305
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition device.cc:401
bool getBAR(Addr addr, int &num, Addr &offs)
Which base address register (if any) maps the given address?
Definition device.hh:320
const int MSIXCAP_BASE
Definition device.hh:289
const int PMCAP_BASE
The capability list structures and base addresses.
Definition device.hh:280
Addr pciToDma(Addr pci_addr) const
Definition device.hh:359
std::array< PciBar *, 6 > BARs
Definition device.hh:308
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
Definition device.cc:269
int MSIX_PBA_OFFSET
Definition device.hh:296
const int PMCAP_PMCS_OFFSET
Definition device.hh:283
const PciBusAddr _busAddr
Definition device.hh:272
std::vector< MSIXPbaEntry > msix_pba
Definition device.hh:306
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
Definition device.cc:212
MSIXCAP msixcap
Definition device.hh:298
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
Definition device.cc:283
int MSIX_TABLE_OFFSET
Definition device.hh:294
const int MSIXCAP_ID_OFFSET
Definition device.hh:290
const int MSIXCAP_MPBA_OFFSET
Definition device.hh:293
void intrPost()
Definition device.hh:364
PciDevice(const PciDeviceParams &params)
Constructor for PCI Dev.
Definition device.cc:64
uint8_t interruptLine() const
Definition device.hh:367
const int PMCAP_ID_OFFSET
Definition device.hh:281
const PciBusAddr & busAddr() const
Definition device.hh:396
const int MSIXCAP_MXC_OFFSET
Definition device.hh:291
const int PXCAP_BASE
Definition device.hh:300
const int MSICAP_BASE
Definition device.hh:286
Callback interface from PCI devices to the host.
Definition host.hh:95
void postInt()
Post a PCI interrupt to the CPU.
Definition host.cc:105
Addr pioAddr(Addr addr) const
Calculate the physical address of an IO location on the PCI bus.
Definition host.hh:131
Addr dmaAddr(Addr addr) const
Calculate the physical address of a prefetchable memory location in the PCI address space.
Definition host.hh:149
Addr memAddr(Addr addr) const
Calculate the physical address of a non-prefetchable memory location in the PCI address space.
Definition host.hh:140
void clearInt()
Clear a posted PCI interrupt.
Definition host.cc:113
Bitfield< 1 > reserved
Definition device.hh:115
BitUnion32(Bar) Bitfield< 31
Bitfield< 0 > io
Definition device.hh:116
bool isIo() const override
Definition device.hh:130
uint32_t write(const PciHost::DeviceInterface &host, uint32_t val) override
Definition device.hh:133
PciLegacyIoBar(const PciLegacyIoBarParams &p)
Definition device.hh:155
uint32_t write(const PciHost::DeviceInterface &host, uint32_t val) override
Definition device.hh:162
bool isMem() const override
Definition device.hh:196
uint64_t lower() const
Definition device.hh:231
uint32_t write(const PciHost::DeviceInterface &host, uint32_t val) override
Definition device.hh:199
uint64_t _upper
Definition device.hh:185
void wide(bool val)
Definition device.hh:219
uint64_t _lower
Definition device.hh:184
Bitfield< 1 > reserved
Definition device.hh:178
void upper(const PciHost::DeviceInterface &host, uint32_t val)
Definition device.hh:223
uint64_t upper() const
Definition device.hh:221
BitUnion32(Bar) Bitfield< 31
bool wide() const
Definition device.hh:218
PciMemBar * _lower
Definition device.hh:237
PciMemUpperBar(const PciMemUpperBarParams &p)
Definition device.hh:240
void lower(PciMemBar *val)
Definition device.hh:244
uint32_t write(const PciHost::DeviceInterface &host, uint32_t val) override
Definition device.hh:252
Abstract superclass for simulation objects.
STL vector class.
Definition stl.hh:37
static constexpr bool isPowerOf2(const T &n)
Definition intmath.hh:98
#define EndBitUnion(name)
This closes off the class and union started by the above macro.
Definition bitunion.hh:428
#define SubBitUnion(name, first, last)
Regular bitfields These define macros for read/write regular bitfield based subbitfields.
Definition bitunion.hh:470
#define EndSubBitUnion(name)
This closes off the union created above and gives it a name.
Definition bitunion.hh:455
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:236
const Params & params() const
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 - Pranith Kumar Copyright (c) 2020 Inria 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
Defines the MSI Capability register and its associated bitfields for the a PCI/PCIe device.
Definition pcireg.h:257
Defines the Power Management capability register and all its associated bitfields for a PCIe device.
Definition pcireg.h:222
Defines the PCI Express capability register and its associated bitfields for a PCIe device.
Definition pcireg.h:330

Generated on Tue Jun 18 2024 16:24:01 for gem5 by doxygen 1.11.0