gem5  v21.1.0.2
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  * For use for simulation and test purposes only
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright notice,
11  * this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright notice,
14  * this list of conditions and the following disclaimer in the documentation
15  * and/or other materials provided with the distribution.
16  *
17  * 3. Neither the name of the copyright holder nor the names of its
18  * contributors may be used to endorse or promote products derived from this
19  * software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31  * POSSIBILITY OF SUCH DAMAGE.
32  */
33 
35 
36 #include <fstream>
37 
38 #include "debug/AMDGPUDevice.hh"
39 #include "mem/packet.hh"
40 #include "mem/packet_access.hh"
41 #include "params/AMDGPUDevice.hh"
42 #include "sim/byteswap.hh"
43 #include "sim/sim_exit.hh"
44 
45 namespace gem5
46 {
47 
48 AMDGPUDevice::AMDGPUDevice(const AMDGPUDeviceParams &p)
49  : PciDevice(p), checkpoint_before_mmios(p.checkpoint_before_mmios),
50  init_interrupt_count(0)
51 {
52  // Loading the rom binary dumped from hardware.
53  std::ifstream romBin;
54  romBin.open(p.rom_binary, std::ios::binary);
55  romBin.read((char *)rom.data(), ROM_SIZE);
56  romBin.close();
57 
58  if (config.expansionROM) {
59  romRange = RangeSize(config.expansionROM, ROM_SIZE);
60  } else {
62  }
63 
64  if (p.trace_file != "") {
65  mmioReader.readMMIOTrace(p.trace_file);
66  }
67 }
68 
69 void
71 {
72  Addr rom_offset = pkt->getAddr() & (ROM_SIZE - 1);
73  uint64_t rom_data = 0;
74 
75  memcpy(&rom_data, rom.data() + rom_offset, pkt->getSize());
76  pkt->setUintX(rom_data, ByteOrder::little);
77 
78  DPRINTF(AMDGPUDevice, "Read from addr %#x on ROM offset %#x data: %#x\n",
79  pkt->getAddr(), rom_offset, rom_data);
80 }
81 
84 {
86  AddrRangeList ret_ranges;
87  ret_ranges.push_back(romRange);
88 
89  // If the range starts at zero assume OS hasn't assigned it yet. Do not
90  // return ranges starting with zero as they will surely overlap with
91  // another range causing the I/O crossbar to fatal.
92  for (auto & r : ranges) {
93  if (r.start() != 0) {
94  ret_ranges.push_back(r);
95  }
96  }
97 
98  return ret_ranges;
99 }
100 
101 Tick
103 {
104  GEM5_VAR_USED int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
105  DPRINTF(AMDGPUDevice, "Read Config: from offset: %#x size: %#x "
106  "data: %#x\n", offset, pkt->getSize(), config.data[offset]);
107 
108  Tick delay = PciDevice::readConfig(pkt);
109 
110  // Before sending MMIOs the driver sends three interrupts in a row.
111  // Use this to trigger creating a checkpoint to restore in timing mode.
112  // This is only necessary until we can create a "hole" in the KVM VM
113  // around the VGA ROM region such that KVM exits and sends requests to
114  // this device rather than the KVM VM.
116  if (offset == PCI0_INTERRUPT_PIN) {
117  if (++init_interrupt_count == 3) {
118  DPRINTF(AMDGPUDevice, "Checkpointing before first MMIO\n");
119  exitSimLoop("checkpoint", 0, curTick() + delay + 1);
120  }
121  } else {
123  }
124  }
125 
126  return delay;
127 }
128 
129 Tick
131 {
132  GEM5_VAR_USED int offset = pkt->getAddr() & PCI_CONFIG_SIZE;
133  DPRINTF(AMDGPUDevice, "Write Config: from offset: %#x size: %#x "
134  "data: %#x\n", offset, pkt->getSize(),
135  pkt->getUintX(ByteOrder::little));
136 
137  return PciDevice::writeConfig(pkt);
138 }
139 
140 void
142 {
143  DPRINTF(AMDGPUDevice, "%s from addr %#x size: %#x data: %#x\n",
144  read ? "Read" : "Write", pkt->getAddr(), pkt->getSize(),
145  pkt->getUintX(ByteOrder::little));
146 
147  pkt->makeAtomicResponse();
148 }
149 
150 void
152 {
153  DPRINTF(AMDGPUDevice, "Read framebuffer address %#lx\n", offset);
154 
156 
157  /* Handle special counter addresses in framebuffer. */
158  if (offset == 0xa28000) {
159  /* Counter addresses expect the read to return previous value + 1. */
160  if (regs.find(pkt->getAddr()) == regs.end()) {
161  regs[pkt->getAddr()] = 1;
162  } else {
163  regs[pkt->getAddr()]++;
164  }
165 
166  pkt->setUintX(regs[pkt->getAddr()], ByteOrder::little);
167  }
168 }
169 
170 void
172 {
173  DPRINTF(AMDGPUDevice, "Read doorbell %#lx\n", offset);
175 }
176 
177 void
179 {
180  DPRINTF(AMDGPUDevice, "Read MMIO %#lx\n", offset);
182 }
183 
184 void
186 {
187  DPRINTF(AMDGPUDevice, "Wrote framebuffer address %#lx\n", offset);
189 }
190 
191 void
193 {
194  DPRINTF(AMDGPUDevice, "Wrote doorbell %#lx\n", offset);
196 }
197 
198 void
200 {
201  DPRINTF(AMDGPUDevice, "Wrote MMIO %#lx\n", offset);
203 }
204 
205 Tick
207 {
208  if (isROM(pkt->getAddr())) {
209  readROM(pkt);
210  } else {
211  int barnum = -1;
212  Addr offset = 0;
213  getBAR(pkt->getAddr(), barnum, offset);
214 
215  switch (barnum) {
216  case FRAMEBUFFER_BAR:
217  readFrame(pkt, offset);
218  break;
219  case DOORBELL_BAR:
220  readDoorbell(pkt, offset);
221  break;
222  case MMIO_BAR:
223  readMMIO(pkt, offset);
224  break;
225  default:
226  panic("Request with address out of mapped range!");
227  }
228  }
229 
230  dispatchAccess(pkt, true);
231  return pioDelay;
232 }
233 
234 Tick
236 {
237  int barnum = -1;
238  Addr offset = 0;
239  getBAR(pkt->getAddr(), barnum, offset);
240 
241  switch (barnum) {
242  case FRAMEBUFFER_BAR:
243  writeFrame(pkt, offset);
244  break;
245  case DOORBELL_BAR:
246  writeDoorbell(pkt, offset);
247  break;
248  case MMIO_BAR:
249  writeMMIO(pkt, offset);
250  break;
251  default:
252  panic("Request with address out of mapped range!");
253  }
254 
255  // Record only if there is non-zero value, or a value to be overwritten.
256  // Reads return 0 by default.
257  uint64_t data = pkt->getUintX(ByteOrder::little);
258 
259  if (data || regs.find(pkt->getAddr()) != regs.end())
260  regs[pkt->getAddr()] = data;
261 
262  dispatchAccess(pkt, false);
263 
264  return pioDelay;
265 }
266 
267 void
269 {
270  // Serialize the PciDevice base class
272 }
273 
274 void
276 {
277  // Unserialize the PciDevice base class
279 }
280 
281 } // 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:206
gem5::AMDGPUDevice::regs
std::unordered_map< uint32_t, uint64_t > regs
Device registers - Maps register address to register value.
Definition: amdgpu_device.hh:106
gem5::AMDGPUDevice::isROM
bool isROM(Addr addr) const
Definition: amdgpu_device.hh:93
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:83
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:661
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:50
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:104
gem5::FRAMEBUFFER_BAR
constexpr int FRAMEBUFFER_BAR
Definition: amdgpu_device.hh:49
gem5::AMDGPUDevice::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: amdgpu_device.cc:275
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:46
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:102
sim_exit.hh
gem5::AMDGPUDevice::writeMMIO
void writeMMIO(PacketPtr pkt, Addr offset)
Definition: amdgpu_device.cc:199
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:48
gem5::AMDGPUDevice::writeConfig
Tick writeConfig(PacketPtr pkt) override
Write to the PCI config space data that is stored locally.
Definition: amdgpu_device.cc:130
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:101
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:108
gem5::MMIO_BAR
constexpr int MMIO_BAR
Definition: amdgpu_device.hh:51
gem5::AMDGPUDevice::readROM
void readROM(PacketPtr pkt)
Definition: amdgpu_device.cc:70
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:65
gem5::AMDGPUDevice::serialize
void serialize(CheckpointOut &cp) const override
Checkpoint support.
Definition: amdgpu_device.cc:268
gem5::AMDGPUDevice::dispatchAccess
void dispatchAccess(PacketPtr pkt, bool read)
Convert a PCI packet into a response.
Definition: amdgpu_device.cc:141
gem5::AMDGPUDevice::readFrame
void readFrame(PacketPtr pkt, Addr offset)
Helper methods to handle specific BAR read/writes.
Definition: amdgpu_device.cc:151
gem5::AMDGPUDevice::readDoorbell
void readDoorbell(PacketPtr pkt, Addr offset)
Definition: amdgpu_device.cc:171
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:55
gem5::AMDGPUDevice::write
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: amdgpu_device.cc:235
gem5::VGA_ROM_DEFAULT
constexpr uint32_t VGA_ROM_DEFAULT
Definition: amdgpu_device.hh:54
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:78
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:178
gem5::AMDGPUDevice::init_interrupt_count
int init_interrupt_count
Definition: amdgpu_device.hh:109
gem5::AMDGPUDevice::romRange
AddrRange romRange
VGA ROM methods.
Definition: amdgpu_device.hh:92
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:96
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:185
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: decoder.cc:40
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:177
PCI0_INTERRUPT_PIN
#define PCI0_INTERRUPT_PIN
Definition: pcireg.h:135
gem5::AMDGPUDevice::writeDoorbell
void writeDoorbell(PacketPtr pkt, Addr offset)
Definition: amdgpu_device.cc:192

Generated on Tue Sep 21 2021 12:25:09 for gem5 by doxygen 1.8.17