gem5  v22.0.0.1
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
interrupt_handler.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  */
32 
34 
35 #include "debug/AMDGPUDevice.hh"
36 #include "dev/amdgpu/ih_mmio.hh"
37 #include "mem/packet_access.hh"
38 
39 // For generating interrupts, the object causing interrupt communicates with
40 // the Interrupt Handler (IH), which submits a 256-bit Interrupt packet to the
41 // system memory. The location where the IH submits the packet is the
42 // IH Ring buffer in the system memory. The IH updates the Write Pointer
43 // and the host consumes the ring buffer and once done, updates the Read
44 // Pointer through the doorbell.
45 
46 // IH_RB_BaseAddr, IH_RB_WptrAddr (Lo/Hi), IH_RB_RptrAddr (Lo/Hi), etc. are
47 // not GART addresses but system dma addresses and thus don't require
48 // translations through the GART table.
49 
50 namespace gem5
51 {
52 
54  const AMDGPUInterruptHandlerParams &p)
55  : DmaDevice(p)
56 {
57  memset(&regs, 0, sizeof(AMDGPUIHRegs));
58 }
59 
62 {
63  AddrRangeList ranges;
64  return ranges;
65 }
66 
67 void
69 {
70  if (gpuDevice)
72 }
73 
74 void
76  uint32_t ring_id,
77  uint32_t client_id,
78  uint32_t source_id)
79 {
90  memset(cookie, 0, sizeof(AMDGPUInterruptCookie));
91  cookie->timestamp_Lo = 0x40;
92  cookie->clientId = client_id;
93  cookie->sourceId = source_id;
94  cookie->ringId = ring_id;
95  cookie->source_data_dw1 = cntxt_id;
96  interruptQueue.push(cookie);
97 }
98 
99 void
101 {
102  if (data == 1) {
103  DPRINTF(AMDGPUDevice, "Completed interrupt cookie write\n");
105  } else if (data == 2) {
106  DPRINTF(AMDGPUDevice, "Completed interrupt write pointer update\n");
107  deviceIh->intrPost();
108  } else {
109  fatal("Interrupt Handler DMA event returned bad value: %d\n", data);
110  }
111 }
112 
113 void
115 {
116  uint8_t *dataPtr = new uint8_t[sizeof(uint32_t)];
118  Addr paddr = regs.WptrAddr;
119  std::memcpy(dataPtr, &regs.IH_Wptr, sizeof(uint32_t));
120 
122  dmaWrite(paddr, sizeof(uint32_t), dmaEvent, dataPtr);
123 }
124 
125 void
127 {
128  assert(!interruptQueue.empty());
129  auto cookie = interruptQueue.front();
130  size_t cookieSize = sizeof(AMDGPUInterruptCookie);
131 
132  uint8_t *dataPtr = new uint8_t[cookieSize];
133  std::memcpy(dataPtr, cookie, cookieSize);
134  Addr paddr = regs.baseAddr + regs.IH_Wptr;
135 
136  DPRINTF(AMDGPUDevice, "InterruptHandler rptr: 0x%x wptr: 0x%x\n",
139  dmaWrite(paddr, cookieSize, dmaEvent, dataPtr);
140 
141  interruptQueue.pop();
142 }
143 
144 void
146 {
147  switch (mmio_offset) {
148  case mmIH_RB_CNTL:
149  setCntl(pkt->getLE<uint32_t>());
150  break;
151  case mmIH_RB_BASE:
152  setBase(pkt->getLE<uint32_t>());
153  break;
154  case mmIH_RB_BASE_HI:
155  setBaseHi(pkt->getLE<uint32_t>());
156  break;
157  case mmIH_RB_RPTR:
158  setRptr(pkt->getLE<uint32_t>());
159  break;
160  case mmIH_RB_WPTR:
161  setWptr(pkt->getLE<uint32_t>());
162  break;
164  setWptrAddrLo(pkt->getLE<uint32_t>());
165  break;
167  setWptrAddrHi(pkt->getLE<uint32_t>());
168  break;
169  case mmIH_DOORBELL_RPTR:
170  setDoorbellOffset(pkt->getLE<uint32_t>());
171  if (bits(pkt->getLE<uint32_t>(), 28, 28)) {
174  }
175  break;
176  default:
177  DPRINTF(AMDGPUDevice, "IH Unknown MMIO %#x\n", mmio_offset);
178  break;
179  }
180 }
181 
182 void
184 {
185  regs.IH_Cntl = data;
186 }
187 
188 void
190 {
191  regs.IH_Base = data << 8;
193 }
194 
195 void
197 {
198  regs.IH_Base_Hi = data;
199  regs.baseAddr |= ((uint64_t)regs.IH_Base_Hi) << 32;
200 }
201 
202 void
204 {
205  regs.IH_Rptr = data;
206 }
207 
208 void
210 {
211  regs.IH_Wptr = data;
212 }
213 
214 void
216 {
219 }
220 
221 void
223 {
225  regs.WptrAddr |= ((uint64_t)regs.IH_Wptr_Addr_Hi) << 32;
226 }
227 
228 void
230 {
231  regs.IH_Doorbell = data & 0x3ffffff;
232 }
233 
234 void
236 {
237  regs.IH_Rptr = data; // update ring buffer rptr offset
238 }
239 
240 void
242 {
243  uint32_t ih_cntl = regs.IH_Cntl;
244  uint32_t ih_base = regs.IH_Base;
245  uint32_t ih_base_hi = regs.IH_Base_Hi;
246  Addr ih_baseAddr = regs.baseAddr;
247  uint32_t ih_rptr = regs.IH_Rptr;
248  uint32_t ih_wptr = regs.IH_Wptr;
249  uint32_t ih_wptr_addr_lo = regs.IH_Wptr_Addr_Lo;
250  uint32_t ih_wptr_addr_hi = regs.IH_Wptr_Addr_Hi;
251  Addr ih_wptrAddr = regs.WptrAddr;
252  uint32_t ih_doorbellOffset = regs.IH_Doorbell;
253 
254  SERIALIZE_SCALAR(ih_cntl);
255  SERIALIZE_SCALAR(ih_base);
256  SERIALIZE_SCALAR(ih_base_hi);
257  SERIALIZE_SCALAR(ih_baseAddr);
258  SERIALIZE_SCALAR(ih_rptr);
259  SERIALIZE_SCALAR(ih_wptr);
260  SERIALIZE_SCALAR(ih_wptr_addr_lo);
261  SERIALIZE_SCALAR(ih_wptr_addr_hi);
262  SERIALIZE_SCALAR(ih_wptrAddr);
263  SERIALIZE_SCALAR(ih_doorbellOffset);
264 }
265 
266 void
268 {
269  uint32_t ih_cntl;
270  uint32_t ih_base;
271  uint32_t ih_base_hi;
272  Addr ih_baseAddr;
273  uint32_t ih_rptr;
274  uint32_t ih_wptr;
275  uint32_t ih_wptr_addr_lo;
276  uint32_t ih_wptr_addr_hi;
277  Addr ih_wptrAddr;
278  uint32_t ih_doorbellOffset;
279 
280  UNSERIALIZE_SCALAR(ih_cntl);
281  UNSERIALIZE_SCALAR(ih_base);
282  UNSERIALIZE_SCALAR(ih_base_hi);
283  UNSERIALIZE_SCALAR(ih_baseAddr);
284  UNSERIALIZE_SCALAR(ih_rptr);
285  UNSERIALIZE_SCALAR(ih_wptr);
286  UNSERIALIZE_SCALAR(ih_wptr_addr_lo);
287  UNSERIALIZE_SCALAR(ih_wptr_addr_hi);
288  UNSERIALIZE_SCALAR(ih_wptrAddr);
289  UNSERIALIZE_SCALAR(ih_doorbellOffset);
290 
291  regs.IH_Cntl = ih_cntl;
292  regs.IH_Base = ih_base;
293  regs.IH_Base_Hi = ih_base_hi;
294  regs.baseAddr = ih_baseAddr;
295  regs.IH_Rptr = ih_rptr;
296  regs.IH_Wptr = ih_wptr;
297  regs.IH_Wptr_Addr_Lo = ih_wptr_addr_lo;
298  regs.IH_Wptr_Addr_Hi = ih_wptr_addr_hi;
299  regs.WptrAddr = ih_wptrAddr;
300  regs.IH_Doorbell = ih_doorbellOffset;
301 }
302 
303 } // namespace gem5
gem5::AMDGPUIHRegs::IH_Wptr
uint32_t IH_Wptr
Definition: interrupt_handler.hh:115
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
mmIH_DOORBELL_RPTR
#define mmIH_DOORBELL_RPTR
Definition: ih_mmio.hh:49
mmIH_RB_BASE_HI
#define mmIH_RB_BASE_HI
Definition: ih_mmio.hh:44
data
const char data[]
Definition: circlebuf.test.cc:48
gem5::AMDGPUInterruptHandler::setBase
void setBase(const uint32_t &data)
Definition: interrupt_handler.cc:189
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
gem5::AMDGPUInterruptCookie::sourceId
uint32_t sourceId
Definition: interrupt_handler.hh:86
gem5::AMDGPUInterruptCookie::timestamp_Lo
uint32_t timestamp_Lo
Definition: interrupt_handler.hh:91
gem5::AMDGPUDevice::setDoorbellType
void setDoorbellType(uint32_t offset, QueueType qt)
Set handles to GPU blocks.
Definition: amdgpu_device.cc:424
mmIH_RB_RPTR
#define mmIH_RB_RPTR
Definition: ih_mmio.hh:45
gem5::AMDGPUInterruptHandler::gpuDevice
AMDGPUDevice * gpuDevice
Definition: interrupt_handler.hh:188
gem5::AMDGPUInterruptHandler::writeMMIO
void writeMMIO(PacketPtr pkt, Addr mmio_offset)
Methods for setting the values of interrupt handler MMIO registers.
Definition: interrupt_handler.cc:145
gem5::AMDGPUDevice::intrPost
void intrPost()
Methods inherited from PciDevice.
Definition: amdgpu_device.cc:465
gem5::CheckpointIn
Definition: serialize.hh:68
gem5::AMDGPUInterruptHandler::getDoorbellOffset
uint32_t getDoorbellOffset() const
Definition: interrupt_handler.hh:176
gem5::AMDGPUIHRegs::IH_Base_Hi
uint32_t IH_Base_Hi
Definition: interrupt_handler.hh:112
gem5::AMDGPUIHRegs::IH_Doorbell
uint32_t IH_Doorbell
Definition: interrupt_handler.hh:119
gem5::AMDGPUIHRegs::IH_Cntl
uint32_t IH_Cntl
Definition: interrupt_handler.hh:110
gem5::AMDGPUInterruptHandler::submitInterruptCookie
void submitInterruptCookie()
Definition: interrupt_handler.cc:126
gem5::AMDGPUInterruptHandler::getAddrRanges
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
Definition: interrupt_handler.cc:61
interrupt_handler.hh
gem5::AMDGPUInterruptHandler::setWptrAddrHi
void setWptrAddrHi(const uint32_t &data)
Definition: interrupt_handler.cc:222
gem5::AMDGPUInterruptHandler::DmaEvent::data
uint32_t data
Definition: interrupt_handler.hh:129
gem5::AMDGPUIHRegs::IH_Rptr
uint32_t IH_Rptr
Definition: interrupt_handler.hh:114
gem5::AMDGPUInterruptHandler::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: interrupt_handler.cc:267
gem5::AMDGPUInterruptHandler::updateRptr
void updateRptr(const uint32_t &data)
Definition: interrupt_handler.cc:235
gem5::AMDGPUInterruptHandler::DmaEvent
Definition: interrupt_handler.hh:125
ih_mmio.hh
gem5::VegaISA::p
Bitfield< 54 > p
Definition: pagetable.hh:70
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:291
gem5::AMDGPUInterruptHandler::regs
AMDGPUIHRegs regs
Definition: interrupt_handler.hh:189
gem5::AMDGPUIHRegs::IH_Wptr_Addr_Hi
uint32_t IH_Wptr_Addr_Hi
Definition: interrupt_handler.hh:117
gem5::AMDGPUInterruptCookie::ringId
uint32_t ringId
Definition: interrupt_handler.hh:87
gem5::DmaDevice
Definition: dma_device.hh:203
gem5::AMDGPUInterruptHandler::DmaEvent::deviceIh
AMDGPUInterruptHandler * deviceIh
Definition: interrupt_handler.hh:128
gem5::AMDGPUInterruptCookie::source_data_dw1
uint32_t source_data_dw1
Definition: interrupt_handler.hh:98
gem5::AMDGPUDevice
Device model for an AMD GPU.
Definition: amdgpu_device.hh:60
gem5::AMDGPUInterruptHandler::setWptrAddrLo
void setWptrAddrLo(const uint32_t &data)
Definition: interrupt_handler.cc:215
gem5::DmaDevice::dmaWrite
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
Definition: dma_device.hh:214
gem5::bits
constexpr T bits(T val, unsigned first, unsigned last)
Extract the bitfield from position 'first' to 'last' (inclusive) from 'val' and right justify it.
Definition: bitfield.hh:76
gem5::AMDGPUInterruptHandler::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: interrupt_handler.cc:241
gem5::AMDGPUInterruptHandler::setCntl
void setCntl(const uint32_t &data)
Definition: interrupt_handler.cc:183
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
SERIALIZE_SCALAR
#define SERIALIZE_SCALAR(scalar)
Definition: serialize.hh:568
packet_access.hh
mmIH_RB_WPTR_ADDR_HI
#define mmIH_RB_WPTR_ADDR_HI
Definition: ih_mmio.hh:47
gem5::AMDGPUIHRegs
Struct to contain all interrupt handler related registers.
Definition: interrupt_handler.hh:108
gem5::AMDGPUInterruptHandler::AMDGPUInterruptHandler
AMDGPUInterruptHandler(const AMDGPUInterruptHandlerParams &p)
Definition: interrupt_handler.cc:53
gem5::AMDGPUIHRegs::baseAddr
Addr baseAddr
Definition: interrupt_handler.hh:113
gem5::AMDGPUIHRegs::WptrAddr
Addr WptrAddr
Definition: interrupt_handler.hh:118
mmIH_RB_WPTR_ADDR_LO
#define mmIH_RB_WPTR_ADDR_LO
Definition: ih_mmio.hh:48
mmIH_RB_CNTL
#define mmIH_RB_CNTL
MMIO offsets for interrupt handler.
Definition: ih_mmio.hh:42
mmIH_RB_WPTR
#define mmIH_RB_WPTR
Definition: ih_mmio.hh:46
gem5::AMDGPUInterruptHandler::submitWritePointer
void submitWritePointer()
Definition: interrupt_handler.cc:114
gem5::AMDGPUInterruptHandler::dmaEvent
AMDGPUInterruptHandler::DmaEvent * dmaEvent
Definition: interrupt_handler.hh:191
gem5::ContextID
int ContextID
Globally unique thread context ID.
Definition: types.hh:239
gem5::AMDGPUInterruptHandler::setWptr
void setWptr(const uint32_t &data)
Definition: interrupt_handler.cc:209
mmIH_RB_BASE
#define mmIH_RB_BASE
Definition: ih_mmio.hh:43
gem5::AMDGPUInterruptHandler::setRptr
void setRptr(const uint32_t &data)
Definition: interrupt_handler.cc:203
gem5::Packet::getLE
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Definition: packet_access.hh:78
gem5::AMDGPUInterruptHandler::intrPost
void intrPost()
Definition: interrupt_handler.cc:68
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::AMDGPUInterruptCookie::clientId
uint32_t clientId
Definition: interrupt_handler.hh:85
gem5::InterruptHandler
@ InterruptHandler
Definition: amdgpu_defines.hh:48
gem5::AMDGPUIHRegs::IH_Base
uint32_t IH_Base
Definition: interrupt_handler.hh:111
std::list< AddrRange >
gem5::AMDGPUInterruptCookie
Definition: interrupt_handler.hh:83
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: gpu_translation_state.hh:37
gem5::AMDGPUInterruptHandler::interruptQueue
std::queue< AMDGPUInterruptCookie * > interruptQueue
Definition: interrupt_handler.hh:190
gem5::AMDGPUInterruptHandler::prepareInterruptCookie
void prepareInterruptCookie(ContextID cntxtId, uint32_t ring_id, uint32_t client_id, uint32_t source_id)
Definition: interrupt_handler.cc:75
gem5::AMDGPUIHRegs::IH_Wptr_Addr_Lo
uint32_t IH_Wptr_Addr_Lo
Definition: interrupt_handler.hh:116
gem5::AMDGPUInterruptHandler::setDoorbellOffset
void setDoorbellOffset(const uint32_t &data)
Definition: interrupt_handler.cc:229
gem5::AMDGPUInterruptHandler::DmaEvent::process
void process()
Definition: interrupt_handler.cc:100
gem5::AMDGPUInterruptHandler::setBaseHi
void setBaseHi(const uint32_t &data)
Definition: interrupt_handler.cc:196

Generated on Wed Jul 13 2022 10:39:18 for gem5 by doxygen 1.8.17