gem5 v23.0.0.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
50namespace 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
67void
69{
70 if (gpuDevice)
72}
73
74void
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
119void
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");
128 } else {
129 fatal("Interrupt Handler DMA event returned bad value: %d\n", data);
130 }
131}
132
133void
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
145void
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
164void
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;
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
202void
204{
205 regs.IH_Cntl = data;
206}
207
208void
210{
212 regs.baseAddr <<= 8;
213}
214
215void
217{
218 regs.baseAddr |= static_cast<uint64_t>(data) << 40;
219}
220
221void
223{
224 regs.IH_Rptr = data;
225}
226
227void
229{
230 regs.IH_Wptr = data;
231}
232
233void
235{
238}
239
240void
242{
244 regs.WptrAddr |= ((uint64_t)regs.IH_Wptr_Addr_Hi) << 32;
245}
246
247void
249{
250 regs.IH_Doorbell = data & 0x3ffffff;
251}
252
253void
255{
256 regs.IH_Rptr = data; // update ring buffer rptr offset
257}
258
259void
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
285void
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
#define DPRINTF(x,...)
Definition trace.hh:210
const char data[]
Device model for an AMD GPU.
void setDoorbellType(uint32_t offset, QueueType qt)
Set handles to GPU blocks.
void intrPost()
Methods inherited from PciDevice.
void prepareInterruptCookie(ContextID cntxtId, uint32_t ring_id, uint32_t client_id, uint32_t source_id)
void setCntl(const uint32_t &data)
void setRptr(const uint32_t &data)
void setWptrAddrLo(const uint32_t &data)
AMDGPUInterruptHandler::DmaEvent * dmaEvent
AMDGPUInterruptHandler(const AMDGPUInterruptHandlerParams &p)
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void setWptrAddrHi(const uint32_t &data)
void setBase(const uint32_t &data)
void serialize(CheckpointOut &cp) const override
Serialize an object.
void setDoorbellOffset(const uint32_t &data)
void updateRptr(const uint32_t &data)
void setBaseHi(const uint32_t &data)
void setWptr(const uint32_t &data)
std::queue< AMDGPUInterruptCookie * > interruptQueue
void writeMMIO(PacketPtr pkt, Addr mmio_offset)
Methods for setting the values of interrupt handler MMIO registers.
void dmaWrite(Addr addr, int size, Event *event, uint8_t *data, uint32_t sid, uint32_t ssid, Tick delay=0)
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition packet.hh:295
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
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
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:200
#define mmIH_RB_CNTL
MMIO offsets for interrupt handler.
Definition ih_mmio.hh:42
#define mmIH_RB_WPTR_ADDR_LO
Definition ih_mmio.hh:48
#define mmIH_RB_WPTR
Definition ih_mmio.hh:46
#define mmIH_RB_RPTR
Definition ih_mmio.hh:45
#define mmIH_DOORBELL_RPTR
Definition ih_mmio.hh:49
#define mmIH_RB_BASE_HI
Definition ih_mmio.hh:44
#define mmIH_RB_BASE
Definition ih_mmio.hh:43
#define mmIH_RB_WPTR_ADDR_HI
Definition ih_mmio.hh:47
Bitfield< 0 > p
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
std::ostream CheckpointOut
Definition serialize.hh:66
@ InterruptHandler
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
@ SOC15_IH_CLIENTID_SDMA3
@ SOC15_IH_CLIENTID_SDMA4
@ SOC15_IH_CLIENTID_SDMA0
@ SOC15_IH_CLIENTID_GRBM_CP
@ SOC15_IH_CLIENTID_SDMA1
@ SOC15_IH_CLIENTID_SDMA5
@ SOC15_IH_CLIENTID_SDMA2
@ SOC15_IH_CLIENTID_RLC
@ SOC15_IH_CLIENTID_SDMA6
@ SOC15_IH_CLIENTID_SDMA7
int ContextID
Globally unique thread context ID.
Definition types.hh:239
#define UNSERIALIZE_SCALAR(scalar)
Definition serialize.hh:575
#define SERIALIZE_SCALAR(scalar)
Definition serialize.hh:568
Struct to contain all interrupt handler related registers.

Generated on Mon Jul 10 2023 14:24:30 for gem5 by doxygen 1.9.7