gem5  v21.2.1.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
amdgpu_device.cc
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2021 Advanced Micro Devices, Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  *
8  * 1. Redistributions of source code must retain the above copyright notice,
9  * this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * 3. Neither the name of the copyright holder nor the names of its
16  * contributors may be used to endorse or promote products derived from this
17  * software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31 
33 
34 #include <fstream>
35 
36 #include "debug/AMDGPUDevice.hh"
37 #include "mem/packet.hh"
38 #include "mem/packet_access.hh"
39 #include "params/AMDGPUDevice.hh"
40 #include "sim/byteswap.hh"
41 #include "sim/sim_exit.hh"
42 
43 namespace gem5
44 {
45 
46 AMDGPUDevice::AMDGPUDevice(const AMDGPUDeviceParams &p)
47  : PciDevice(p), checkpoint_before_mmios(p.checkpoint_before_mmios),
48  init_interrupt_count(0)
49 {
50  // Loading the rom binary dumped from hardware.
51  std::ifstream romBin;
52  romBin.open(p.rom_binary, std::ios::binary);
53  romBin.read((char *)rom.data(), ROM_SIZE);
54  romBin.close();
55 
56  if (config.expansionROM) {
57  romRange = RangeSize(config.expansionROM, ROM_SIZE);
58  } else {
60  }
61 
62  if (p.trace_file != "") {
63  mmioReader.readMMIOTrace(p.trace_file);
64  }
65 }
66 
67 void
69 {
70  Addr rom_offset = pkt->getAddr() & (ROM_SIZE - 1);
71  uint64_t rom_data = 0;
72 
73  memcpy(&rom_data, rom.data() + rom_offset, pkt->getSize());
74  pkt->setUintX(rom_data, ByteOrder::little);
75 
76  DPRINTF(AMDGPUDevice, "Read from addr %#x on ROM offset %#x data: %#x\n",
77  pkt->getAddr(), rom_offset, rom_data);
78 }
79 
82 {
84  AddrRangeList ret_ranges;
85  ret_ranges.push_back(romRange);
86 
87  // If the range starts at zero assume OS hasn't assigned it yet. Do not
88  // return ranges starting with zero as they will surely overlap with
89  // another range causing the I/O crossbar to fatal.
90  for (auto & r : ranges) {
91  if (r.start() != 0) {
92  ret_ranges.push_back(r);
93  }
94  }
95 
96  return ret_ranges;
97 }
98 
99 Tick
101 {
102  [[maybe_unused]] int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
103  DPRINTF(AMDGPUDevice, "Read Config: from offset: %#x size: %#x "
104  "data: %#x\n", offset, pkt->getSize(), config.data[offset]);
105 
106  Tick delay = PciDevice::readConfig(pkt);
107 
108  // Before sending MMIOs the driver sends three interrupts in a row.
109  // Use this to trigger creating a checkpoint to restore in timing mode.
110  // This is only necessary until we can create a "hole" in the KVM VM
111  // around the VGA ROM region such that KVM exits and sends requests to
112  // this device rather than the KVM VM.
114  if (offset == PCI0_INTERRUPT_PIN) {
115  if (++init_interrupt_count == 3) {
116  DPRINTF(AMDGPUDevice, "Checkpointing before first MMIO\n");
117  exitSimLoop("checkpoint", 0, curTick() + delay + 1);
118  }
119  } else {
121  }
122  }
123 
124  return delay;
125 }
126 
127 Tick
129 {
130  [[maybe_unused]] int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
131  DPRINTF(AMDGPUDevice, "Write Config: from offset: %#x size: %#x "
132  "data: %#x\n", offset, pkt->getSize(),
133  pkt->getUintX(ByteOrder::little));
134 
135  return PciDevice::writeConfig(pkt);
136 }
137 
138 void
140 {
141  DPRINTF(AMDGPUDevice, "%s from addr %#x size: %#x data: %#x\n",
142  read ? "Read" : "Write", pkt->getAddr(), pkt->getSize(),
143  pkt->getUintX(ByteOrder::little));
144 
145  pkt->makeAtomicResponse();
146 }
147 
148 void
150 {
151  DPRINTF(AMDGPUDevice, "Read framebuffer address %#lx\n", offset);
152 
154 
155  /* Handle special counter addresses in framebuffer. */
156  if (offset == 0xa28000) {
157  /* Counter addresses expect the read to return previous value + 1. */
158  if (regs.find(pkt->getAddr()) == regs.end()) {
159  regs[pkt->getAddr()] = 1;
160  } else {
161  regs[pkt->getAddr()]++;
162  }
163 
164  pkt->setUintX(regs[pkt->getAddr()], ByteOrder::little);
165  }
166 }
167 
168 void
170 {
171  DPRINTF(AMDGPUDevice, "Read doorbell %#lx\n", offset);
173 }
174 
175 void
177 {
178  DPRINTF(AMDGPUDevice, "Read MMIO %#lx\n", offset);
180 }
181 
182 void
184 {
185  DPRINTF(AMDGPUDevice, "Wrote framebuffer address %#lx\n", offset);
187 }
188 
189 void
191 {
192  DPRINTF(AMDGPUDevice, "Wrote doorbell %#lx\n", offset);
194 }
195 
196 void
198 {
199  DPRINTF(AMDGPUDevice, "Wrote MMIO %#lx\n", offset);
201 }
202 
203 Tick
205 {
206  if (isROM(pkt->getAddr())) {
207  readROM(pkt);
208  } else {
209  int barnum = -1;
210  Addr offset = 0;
211  getBAR(pkt->getAddr(), barnum, offset);
212 
213  switch (barnum) {
214  case FRAMEBUFFER_BAR:
215  readFrame(pkt, offset);
216  break;
217  case DOORBELL_BAR:
218  readDoorbell(pkt, offset);
219  break;
220  case MMIO_BAR:
221  readMMIO(pkt, offset);
222  break;
223  default:
224  panic("Request with address out of mapped range!");
225  }
226  }
227 
228  dispatchAccess(pkt, true);
229  return pioDelay;
230 }
231 
232 Tick
234 {
235  int barnum = -1;
236  Addr offset = 0;
237  getBAR(pkt->getAddr(), barnum, offset);
238 
239  switch (barnum) {
240  case FRAMEBUFFER_BAR:
241  writeFrame(pkt, offset);
242  break;
243  case DOORBELL_BAR:
244  writeDoorbell(pkt, offset);
245  break;
246  case MMIO_BAR:
247  writeMMIO(pkt, offset);
248  break;
249  default:
250  panic("Request with address out of mapped range!");
251  }
252 
253  // Record only if there is non-zero value, or a value to be overwritten.
254  // Reads return 0 by default.
255  uint64_t data = pkt->getUintX(ByteOrder::little);
256 
257  if (data || regs.find(pkt->getAddr()) != regs.end())
258  regs[pkt->getAddr()] = data;
259 
260  dispatchAccess(pkt, false);
261 
262  return pioDelay;
263 }
264 
265 void
267 {
268  // Serialize the PciDevice base class
270 }
271 
272 void
274 {
275  // Unserialize the PciDevice base class
277 }
278 
279 } // namespace gem5
gem5::curTick
Tick curTick()
The universal simulation clock.
Definition: cur_tick.hh:46
gem5::AMDGPUDevice::read
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: amdgpu_device.cc:204
gem5::AMDGPUDevice::regs
std::unordered_map< uint32_t, uint64_t > regs
Device registers - Maps register address to register value.
Definition: amdgpu_device.hh:104
gem5::AMDGPUDevice::isROM
bool isROM(Addr addr) const
Definition: amdgpu_device.hh:91
gem5::AMDGPUDevice::getAddrRanges
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
Definition: amdgpu_device.cc:81
gem5::PciDevice::config
PCIConfig config
The current config space.
Definition: device.hh:275
gem5::Packet::getUintX
uint64_t getUintX(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness and zero-extended to 64 bits.
Definition: packet.cc:334
data
const char data[]
Definition: circlebuf.test.cc:48
gem5::PciDevice::serialize
void serialize(CheckpointOut &cp) const override
Serialize this object to the given output stream.
Definition: device.cc:401
gem5::RangeSize
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:815
gem5::PciDevice::unserialize
void unserialize(CheckpointIn &cp) override
Reconstruct the state of this object from a checkpoint.
Definition: device.cc:464
gem5::CheckpointIn
Definition: serialize.hh:68
gem5::PciDevice::pioDelay
Tick pioDelay
Definition: device.hh:354
gem5::DOORBELL_BAR
constexpr int DOORBELL_BAR
Definition: amdgpu_device.hh:48
gem5::AMDMMIOReader::writeFromTrace
void writeFromTrace(PacketPtr pkt, int barnum, Addr offset)
Get the next MMIO write from the trace file to an offset in a BAR and compare the value with the data...
Definition: mmio_reader.cc:102
gem5::FRAMEBUFFER_BAR
constexpr int FRAMEBUFFER_BAR
Definition: amdgpu_device.hh:47
gem5::AMDGPUDevice::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: amdgpu_device.cc:273
gem5::AMDMMIOReader::readMMIOTrace
void readMMIOTrace(std::string trace_file)
Read an MMIO trace gathered from a real system and place the MMIO values read and written into the MM...
Definition: mmio_reader.cc:44
gem5::Packet::makeAtomicResponse
void makeAtomicResponse()
Definition: packet.hh:1043
gem5::AMDGPUDevice::readConfig
Tick readConfig(PacketPtr pkt) override
Read from the PCI config space data that is stored locally.
Definition: amdgpu_device.cc:100
sim_exit.hh
gem5::AMDGPUDevice::writeMMIO
void writeMMIO(PacketPtr pkt, Addr offset)
Definition: amdgpu_device.cc:197
gem5::exitSimLoop
void exitSimLoop(const std::string &message, int exit_code, Tick when, Tick repeat, bool serialize)
Schedule an event to exit the simulation loop (returning to Python) at the end of the current cycle (...
Definition: sim_events.cc:88
packet.hh
gem5::PciDevice::writeConfig
virtual Tick writeConfig(PacketPtr pkt)
Write to the PCI config space data that is stored locally.
Definition: device.cc:283
gem5::AMDGPUDevice::AMDGPUDevice
AMDGPUDevice(const AMDGPUDeviceParams &p)
Definition: amdgpu_device.cc:46
gem5::AMDGPUDevice::writeConfig
Tick writeConfig(PacketPtr pkt) override
Write to the PCI config space data that is stored locally.
Definition: amdgpu_device.cc:128
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
amdgpu_device.hh
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:283
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::AMDGPUDevice::mmioReader
AMDMMIOReader mmioReader
MMIO reader to populate device registers map.
Definition: amdgpu_device.hh:99
gem5::PciDevice
PCI device, base implementation is only config space.
Definition: device.hh:269
gem5::AMDGPUDevice::checkpoint_before_mmios
bool checkpoint_before_mmios
Definition: amdgpu_device.hh:106
gem5::MMIO_BAR
constexpr int MMIO_BAR
Definition: amdgpu_device.hh:49
gem5::AMDGPUDevice::readROM
void readROM(PacketPtr pkt)
Definition: amdgpu_device.cc:68
gem5::PciDevice::getBAR
bool getBAR(Addr addr, int &num, Addr &offs)
Which base address register (if any) maps the given address?
Definition: device.hh:320
gem5::ArmISA::offset
Bitfield< 23, 0 > offset
Definition: types.hh:144
gem5::AMDGPUDevice
Device model for an AMD GPU.
Definition: amdgpu_device.hh:63
gem5::AMDGPUDevice::serialize
void serialize(CheckpointOut &cp) const override
Checkpoint support.
Definition: amdgpu_device.cc:266
gem5::AMDGPUDevice::dispatchAccess
void dispatchAccess(PacketPtr pkt, bool read)
Convert a PCI packet into a response.
Definition: amdgpu_device.cc:139
gem5::AMDGPUDevice::readFrame
void readFrame(PacketPtr pkt, Addr offset)
Helper methods to handle specific BAR read/writes.
Definition: amdgpu_device.cc:149
gem5::AMDGPUDevice::readDoorbell
void readDoorbell(PacketPtr pkt, Addr offset)
Definition: amdgpu_device.cc:169
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::ROM_SIZE
constexpr uint32_t ROM_SIZE
Definition: amdgpu_device.hh:53
gem5::AMDGPUDevice::write
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: amdgpu_device.cc:233
gem5::VGA_ROM_DEFAULT
constexpr uint32_t VGA_ROM_DEFAULT
Definition: amdgpu_device.hh:52
packet_access.hh
gem5::AMDMMIOReader::readFromTrace
void readFromTrace(PacketPtr pkt, int barnum, Addr offset)
Get the next MMIO read from the trace file to an offset in a BAR and write the value to the packet pr...
Definition: mmio_reader.cc:76
gem5::PciDevice::readConfig
virtual Tick readConfig(PacketPtr pkt)
Read from the PCI config space data that is stored locally.
Definition: device.cc:212
gem5::AMDGPUDevice::readMMIO
void readMMIO(PacketPtr pkt, Addr offset)
Definition: amdgpu_device.cc:176
gem5::AMDGPUDevice::init_interrupt_count
int init_interrupt_count
Definition: amdgpu_device.hh:107
gem5::AMDGPUDevice::romRange
AddrRange romRange
VGA ROM methods.
Definition: amdgpu_device.hh:90
gem5::PioDevice::read
virtual Tick read(PacketPtr pkt)=0
Pure virtual function that the device must implement.
gem5::AMDGPUDevice::rom
std::array< uint8_t, ROM_SIZE > rom
Definition: amdgpu_device.hh:94
gem5::MipsISA::r
r
Definition: pra_constants.hh:98
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::AMDGPUDevice::writeFrame
void writeFrame(PacketPtr pkt, Addr offset)
Definition: amdgpu_device.cc:183
std::list< AddrRange >
gem5::Packet::getAddr
Addr getAddr() const
Definition: packet.hh:781
PCI_CONFIG_SIZE
#define PCI_CONFIG_SIZE
Definition: pcireg.h:165
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: tlb.cc:60
gem5::Packet::setUintX
void setUintX(uint64_t w, ByteOrder endian)
Set the value in the word w after truncating it to the length of the packet and then byteswapping it ...
Definition: packet.cc:351
gem5::PciDevice::getAddrRanges
AddrRangeList getAddrRanges() const override
Determine the address ranges that this device responds to.
Definition: device.cc:269
gem5::Packet::getSize
unsigned getSize() const
Definition: packet.hh:791
byteswap.hh
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
PCI0_INTERRUPT_PIN
#define PCI0_INTERRUPT_PIN
Definition: pcireg.h:135
gem5::AMDGPUDevice::writeDoorbell
void writeDoorbell(PacketPtr pkt, Addr offset)
Definition: amdgpu_device.cc:190

Generated on Tue Feb 8 2022 11:47:05 for gem5 by doxygen 1.8.17