gem5  [DEVELOP-FOR-23.0]
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 {
80  assert(client_id == SOC15_IH_CLIENTID_RLC ||
81  client_id == SOC15_IH_CLIENTID_SDMA0 ||
82  client_id == SOC15_IH_CLIENTID_SDMA1 ||
83  client_id == SOC15_IH_CLIENTID_SDMA2 ||
84  client_id == SOC15_IH_CLIENTID_SDMA3 ||
85  client_id == SOC15_IH_CLIENTID_SDMA4 ||
86  client_id == SOC15_IH_CLIENTID_SDMA5 ||
87  client_id == SOC15_IH_CLIENTID_SDMA6 ||
88  client_id == SOC15_IH_CLIENTID_SDMA7 ||
89  client_id == SOC15_IH_CLIENTID_GRBM_CP);
90  assert(source_id == CP_EOP || source_id == TRAP_ID);
91 
102  memset(cookie, 0, sizeof(AMDGPUInterruptCookie));
103 
104  // Currently only one process is supported and the first pasid from driver
105  // is always 0x8000. In the future this can be obtained from the PM4
106  // MAP_PROCESS packet and may need to be passed to this function.
107  //
108  // On a related note, leave vmid fields alone as they are only used for
109  // memory exceptions. Memory exceptions are not supported on gfx900.
110  cookie->pasid = 0x8000;
111  cookie->timestamp_Lo = 0x40;
112  cookie->clientId = client_id;
113  cookie->sourceId = source_id;
114  cookie->ringId = ring_id;
115  cookie->source_data_dw1 = cntxt_id;
116  interruptQueue.push(cookie);
117 }
118 
119 void
121 {
122  if (data == 1) {
123  DPRINTF(AMDGPUDevice, "Completed interrupt cookie write\n");
125  } else if (data == 2) {
126  DPRINTF(AMDGPUDevice, "Completed interrupt write pointer update\n");
127  deviceIh->intrPost();
128  } else {
129  fatal("Interrupt Handler DMA event returned bad value: %d\n", data);
130  }
131 }
132 
133 void
135 {
136  uint8_t *dataPtr = new uint8_t[sizeof(uint32_t)];
138  Addr paddr = regs.WptrAddr;
139  std::memcpy(dataPtr, &regs.IH_Wptr, sizeof(uint32_t));
140 
142  dmaWrite(paddr, sizeof(uint32_t), dmaEvent, dataPtr);
143 }
144 
145 void
147 {
148  assert(!interruptQueue.empty());
149  auto cookie = interruptQueue.front();
150  size_t cookieSize = sizeof(AMDGPUInterruptCookie);
151 
152  uint8_t *dataPtr = new uint8_t[cookieSize];
153  std::memcpy(dataPtr, cookie, cookieSize);
154  Addr paddr = regs.baseAddr + regs.IH_Wptr;
155 
156  DPRINTF(AMDGPUDevice, "InterruptHandler rptr: 0x%x wptr: 0x%x\n",
159  dmaWrite(paddr, cookieSize, dmaEvent, dataPtr);
160 
161  interruptQueue.pop();
162 }
163 
164 void
166 {
167  switch (mmio_offset) {
168  case mmIH_RB_CNTL:
169  setCntl(pkt->getLE<uint32_t>());
170  break;
171  case mmIH_RB_BASE:
172  setBase(pkt->getLE<uint32_t>());
173  break;
174  case mmIH_RB_BASE_HI:
175  setBaseHi(pkt->getLE<uint32_t>());
176  break;
177  case mmIH_RB_RPTR:
178  setRptr(pkt->getLE<uint32_t>());
179  break;
180  case mmIH_RB_WPTR:
181  setWptr(pkt->getLE<uint32_t>());
182  break;
184  setWptrAddrLo(pkt->getLE<uint32_t>());
185  break;
187  setWptrAddrHi(pkt->getLE<uint32_t>());
188  break;
189  case mmIH_DOORBELL_RPTR:
190  setDoorbellOffset(pkt->getLE<uint32_t>());
191  if (bits(pkt->getLE<uint32_t>(), 28, 28)) {
194  }
195  break;
196  default:
197  DPRINTF(AMDGPUDevice, "IH Unknown MMIO %#x\n", mmio_offset);
198  break;
199  }
200 }
201 
202 void
204 {
205  regs.IH_Cntl = data;
206 }
207 
208 void
210 {
211  regs.baseAddr = data;
212  regs.baseAddr <<= 8;
213 }
214 
215 void
217 {
218  regs.baseAddr |= static_cast<uint64_t>(data) << 40;
219 }
220 
221 void
223 {
224  regs.IH_Rptr = data;
225 }
226 
227 void
229 {
230  regs.IH_Wptr = data;
231 }
232 
233 void
235 {
238 }
239 
240 void
242 {
244  regs.WptrAddr |= ((uint64_t)regs.IH_Wptr_Addr_Hi) << 32;
245 }
246 
247 void
249 {
250  regs.IH_Doorbell = data & 0x3ffffff;
251 }
252 
253 void
255 {
256  regs.IH_Rptr = data; // update ring buffer rptr offset
257 }
258 
259 void
261 {
262  uint32_t ih_cntl = regs.IH_Cntl;
263  uint32_t ih_base = regs.IH_Base;
264  uint32_t ih_base_hi = regs.IH_Base_Hi;
265  Addr ih_baseAddr = regs.baseAddr;
266  uint32_t ih_rptr = regs.IH_Rptr;
267  uint32_t ih_wptr = regs.IH_Wptr;
268  uint32_t ih_wptr_addr_lo = regs.IH_Wptr_Addr_Lo;
269  uint32_t ih_wptr_addr_hi = regs.IH_Wptr_Addr_Hi;
270  Addr ih_wptrAddr = regs.WptrAddr;
271  uint32_t ih_doorbellOffset = regs.IH_Doorbell;
272 
273  SERIALIZE_SCALAR(ih_cntl);
274  SERIALIZE_SCALAR(ih_base);
275  SERIALIZE_SCALAR(ih_base_hi);
276  SERIALIZE_SCALAR(ih_baseAddr);
277  SERIALIZE_SCALAR(ih_rptr);
278  SERIALIZE_SCALAR(ih_wptr);
279  SERIALIZE_SCALAR(ih_wptr_addr_lo);
280  SERIALIZE_SCALAR(ih_wptr_addr_hi);
281  SERIALIZE_SCALAR(ih_wptrAddr);
282  SERIALIZE_SCALAR(ih_doorbellOffset);
283 }
284 
285 void
287 {
288  uint32_t ih_cntl;
289  uint32_t ih_base;
290  uint32_t ih_base_hi;
291  Addr ih_baseAddr;
292  uint32_t ih_rptr;
293  uint32_t ih_wptr;
294  uint32_t ih_wptr_addr_lo;
295  uint32_t ih_wptr_addr_hi;
296  Addr ih_wptrAddr;
297  uint32_t ih_doorbellOffset;
298 
299  UNSERIALIZE_SCALAR(ih_cntl);
300  UNSERIALIZE_SCALAR(ih_base);
301  UNSERIALIZE_SCALAR(ih_base_hi);
302  UNSERIALIZE_SCALAR(ih_baseAddr);
303  UNSERIALIZE_SCALAR(ih_rptr);
304  UNSERIALIZE_SCALAR(ih_wptr);
305  UNSERIALIZE_SCALAR(ih_wptr_addr_lo);
306  UNSERIALIZE_SCALAR(ih_wptr_addr_hi);
307  UNSERIALIZE_SCALAR(ih_wptrAddr);
308  UNSERIALIZE_SCALAR(ih_doorbellOffset);
309 
310  regs.IH_Cntl = ih_cntl;
311  regs.IH_Base = ih_base;
312  regs.IH_Base_Hi = ih_base_hi;
313  regs.baseAddr = ih_baseAddr;
314  regs.IH_Rptr = ih_rptr;
315  regs.IH_Wptr = ih_wptr;
316  regs.IH_Wptr_Addr_Lo = ih_wptr_addr_lo;
317  regs.IH_Wptr_Addr_Hi = ih_wptr_addr_hi;
318  regs.WptrAddr = ih_wptrAddr;
319  regs.IH_Doorbell = ih_doorbellOffset;
320 }
321 
322 } // namespace gem5
gem5::AMDGPUIHRegs::IH_Wptr
uint32_t IH_Wptr
Definition: interrupt_handler.hh:123
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:200
mmIH_DOORBELL_RPTR
#define mmIH_DOORBELL_RPTR
Definition: ih_mmio.hh:49
gem5::TRAP_ID
@ TRAP_ID
Definition: interrupt_handler.hh:73
gem5::SOC15_IH_CLIENTID_SDMA6
@ SOC15_IH_CLIENTID_SDMA6
Definition: interrupt_handler.hh:65
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:209
UNSERIALIZE_SCALAR
#define UNSERIALIZE_SCALAR(scalar)
Definition: serialize.hh:575
gem5::AMDGPUInterruptCookie::sourceId
uint32_t sourceId
Definition: interrupt_handler.hh:94
gem5::AMDGPUInterruptCookie::timestamp_Lo
uint32_t timestamp_Lo
Definition: interrupt_handler.hh:99
gem5::AMDGPUDevice::setDoorbellType
void setDoorbellType(uint32_t offset, QueueType qt)
Set handles to GPU blocks.
Definition: amdgpu_device.cc:555
mmIH_RB_RPTR
#define mmIH_RB_RPTR
Definition: ih_mmio.hh:45
gem5::AMDGPUInterruptHandler::gpuDevice
AMDGPUDevice * gpuDevice
Definition: interrupt_handler.hh:196
gem5::AMDGPUInterruptHandler::writeMMIO
void writeMMIO(PacketPtr pkt, Addr mmio_offset)
Methods for setting the values of interrupt handler MMIO registers.
Definition: interrupt_handler.cc:165
gem5::AMDGPUDevice::intrPost
void intrPost()
Methods inherited from PciDevice.
Definition: amdgpu_device.cc:586
gem5::CheckpointIn
Definition: serialize.hh:68
gem5::AMDGPUInterruptHandler::getDoorbellOffset
uint32_t getDoorbellOffset() const
Definition: interrupt_handler.hh:184
gem5::AMDGPUIHRegs::IH_Base_Hi
uint32_t IH_Base_Hi
Definition: interrupt_handler.hh:120
gem5::SOC15_IH_CLIENTID_SDMA0
@ SOC15_IH_CLIENTID_SDMA0
Definition: interrupt_handler.hh:59
gem5::SOC15_IH_CLIENTID_SDMA1
@ SOC15_IH_CLIENTID_SDMA1
Definition: interrupt_handler.hh:60
gem5::AMDGPUIHRegs::IH_Doorbell
uint32_t IH_Doorbell
Definition: interrupt_handler.hh:127
gem5::AMDGPUIHRegs::IH_Cntl
uint32_t IH_Cntl
Definition: interrupt_handler.hh:118
gem5::AMDGPUInterruptHandler::submitInterruptCookie
void submitInterruptCookie()
Definition: interrupt_handler.cc:146
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:241
gem5::AMDGPUInterruptHandler::DmaEvent::data
uint32_t data
Definition: interrupt_handler.hh:137
gem5::AMDGPUIHRegs::IH_Rptr
uint32_t IH_Rptr
Definition: interrupt_handler.hh:122
gem5::AMDGPUInterruptHandler::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: interrupt_handler.cc:286
gem5::AMDGPUInterruptHandler::updateRptr
void updateRptr(const uint32_t &data)
Definition: interrupt_handler.cc:254
gem5::AMDGPUInterruptHandler::DmaEvent
Definition: interrupt_handler.hh:133
ih_mmio.hh
gem5::VegaISA::p
Bitfield< 54 > p
Definition: pagetable.hh:70
gem5::AMDGPUInterruptCookie::pasid
uint32_t pasid
Definition: interrupt_handler.hh:103
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:210
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
gem5::AMDGPUInterruptHandler::regs
AMDGPUIHRegs regs
Definition: interrupt_handler.hh:197
gem5::SOC15_IH_CLIENTID_SDMA4
@ SOC15_IH_CLIENTID_SDMA4
Definition: interrupt_handler.hh:63
gem5::AMDGPUIHRegs::IH_Wptr_Addr_Hi
uint32_t IH_Wptr_Addr_Hi
Definition: interrupt_handler.hh:125
gem5::AMDGPUInterruptCookie::ringId
uint32_t ringId
Definition: interrupt_handler.hh:95
gem5::DmaDevice
Definition: dma_device.hh:218
gem5::AMDGPUInterruptHandler::DmaEvent::deviceIh
AMDGPUInterruptHandler * deviceIh
Definition: interrupt_handler.hh:136
gem5::AMDGPUInterruptCookie::source_data_dw1
uint32_t source_data_dw1
Definition: interrupt_handler.hh:106
gem5::AMDGPUDevice
Device model for an AMD GPU.
Definition: amdgpu_device.hh:62
gem5::AMDGPUInterruptHandler::setWptrAddrLo
void setWptrAddrLo(const uint32_t &data)
Definition: interrupt_handler.cc:234
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:229
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:260
gem5::AMDGPUInterruptHandler::setCntl
void setCntl(const uint32_t &data)
Definition: interrupt_handler.cc:203
gem5::SOC15_IH_CLIENTID_SDMA2
@ SOC15_IH_CLIENTID_SDMA2
Definition: interrupt_handler.hh:61
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::SOC15_IH_CLIENTID_RLC
@ SOC15_IH_CLIENTID_RLC
Definition: interrupt_handler.hh:58
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:116
gem5::AMDGPUInterruptHandler::AMDGPUInterruptHandler
AMDGPUInterruptHandler(const AMDGPUInterruptHandlerParams &p)
Definition: interrupt_handler.cc:53
gem5::CP_EOP
@ CP_EOP
Definition: interrupt_handler.hh:72
gem5::AMDGPUIHRegs::baseAddr
Addr baseAddr
Definition: interrupt_handler.hh:121
gem5::SOC15_IH_CLIENTID_SDMA3
@ SOC15_IH_CLIENTID_SDMA3
Definition: interrupt_handler.hh:62
gem5::AMDGPUIHRegs::WptrAddr
Addr WptrAddr
Definition: interrupt_handler.hh:126
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:134
gem5::AMDGPUInterruptHandler::dmaEvent
AMDGPUInterruptHandler::DmaEvent * dmaEvent
Definition: interrupt_handler.hh:199
gem5::ContextID
int ContextID
Globally unique thread context ID.
Definition: types.hh:239
gem5::SOC15_IH_CLIENTID_SDMA5
@ SOC15_IH_CLIENTID_SDMA5
Definition: interrupt_handler.hh:64
gem5::AMDGPUInterruptHandler::setWptr
void setWptr(const uint32_t &data)
Definition: interrupt_handler.cc:228
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:222
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:93
gem5::InterruptHandler
@ InterruptHandler
Definition: amdgpu_defines.hh:48
gem5::AMDGPUIHRegs::IH_Base
uint32_t IH_Base
Definition: interrupt_handler.hh:119
std::list< AddrRange >
gem5::AMDGPUInterruptCookie
Definition: interrupt_handler.hh:91
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:198
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:124
gem5::AMDGPUInterruptHandler::setDoorbellOffset
void setDoorbellOffset(const uint32_t &data)
Definition: interrupt_handler.cc:248
gem5::SOC15_IH_CLIENTID_SDMA7
@ SOC15_IH_CLIENTID_SDMA7
Definition: interrupt_handler.hh:66
gem5::AMDGPUInterruptHandler::DmaEvent::process
void process()
Definition: interrupt_handler.cc:120
gem5::SOC15_IH_CLIENTID_GRBM_CP
@ SOC15_IH_CLIENTID_GRBM_CP
Definition: interrupt_handler.hh:67
gem5::AMDGPUInterruptHandler::setBaseHi
void setBaseHi(const uint32_t &data)
Definition: interrupt_handler.cc:216

Generated on Sun Jul 30 2023 01:56:54 for gem5 by doxygen 1.8.17