gem5 v24.0.0.0
Loading...
Searching...
No Matches
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
73
74void
76 uint32_t ring_id,
77 uint32_t client_id,
78 uint32_t source_id,
79 unsigned node_id)
80{
81 assert(client_id == SOC15_IH_CLIENTID_RLC ||
82 client_id == SOC15_IH_CLIENTID_SDMA0 ||
83 client_id == SOC15_IH_CLIENTID_SDMA1 ||
84 client_id == SOC15_IH_CLIENTID_SDMA2 ||
85 client_id == SOC15_IH_CLIENTID_SDMA3 ||
86 client_id == SOC15_IH_CLIENTID_SDMA4 ||
87 client_id == SOC15_IH_CLIENTID_SDMA5 ||
88 client_id == SOC15_IH_CLIENTID_SDMA6 ||
89 client_id == SOC15_IH_CLIENTID_SDMA7 ||
90 client_id == SOC15_IH_CLIENTID_GRBM_CP);
91 assert(source_id == CP_EOP || source_id == TRAP_ID);
92
103 memset(cookie, 0, sizeof(AMDGPUInterruptCookie));
104
105 // Currently only one process is supported and the first pasid from driver
106 // is always 0x8000. In the future this can be obtained from the PM4
107 // MAP_PROCESS packet and may need to be passed to this function.
108 //
109 // On a related note, leave vmid fields alone as they are only used for
110 // memory exceptions. Memory exceptions are not supported on gfx900.
111 cookie->pasid = 0x8000;
112 cookie->timestamp_Lo = 0x40;
113 cookie->clientId = client_id;
114 cookie->sourceId = source_id;
115 cookie->ringId = ring_id;
116 cookie->nodeId = node_id;
117 cookie->source_data_dw1 = cntxt_id;
118 interruptQueue.push(cookie);
119}
120
121void
123{
124 if (data == 1) {
125 DPRINTF(AMDGPUDevice, "Completed interrupt cookie write\n");
127 } else if (data == 2) {
128 DPRINTF(AMDGPUDevice, "Completed interrupt write pointer update\n");
130 } else {
131 fatal("Interrupt Handler DMA event returned bad value: %d\n", data);
132 }
133
134 if (dataPtr) {
135 delete [] dataPtr;
136 }
137}
138
139void
141{
142 uint8_t *dataPtr = new uint8_t[sizeof(uint32_t)];
144 Addr paddr = regs.WptrAddr;
145 std::memcpy(dataPtr, &regs.IH_Wptr, sizeof(uint32_t));
146
147 dmaEvent = new AMDGPUInterruptHandler::DmaEvent(this, 2, dataPtr);
148 dmaWrite(paddr, sizeof(uint32_t), dmaEvent, dataPtr);
149}
150
151void
153{
154 assert(!interruptQueue.empty());
155 auto cookie = interruptQueue.front();
156 size_t cookieSize = sizeof(AMDGPUInterruptCookie);
157
158 uint8_t *dataPtr = new uint8_t[cookieSize];
159 std::memcpy(dataPtr, cookie, cookieSize);
160 Addr paddr = regs.baseAddr + regs.IH_Wptr;
161
162 DPRINTF(AMDGPUDevice, "InterruptHandler rptr: 0x%x wptr: 0x%x\n",
164 dmaEvent = new AMDGPUInterruptHandler::DmaEvent(this, 1, dataPtr);
165 dmaWrite(paddr, cookieSize, dmaEvent, dataPtr);
166
167 interruptQueue.pop();
168}
169
170void
172{
173 switch (mmio_offset) {
174 case mmIH_RB_CNTL:
175 setCntl(pkt->getLE<uint32_t>());
176 break;
177 case mmIH_RB_BASE:
178 setBase(pkt->getLE<uint32_t>());
179 break;
180 case mmIH_RB_BASE_HI:
181 setBaseHi(pkt->getLE<uint32_t>());
182 break;
183 case mmIH_RB_RPTR:
184 setRptr(pkt->getLE<uint32_t>());
185 break;
186 case mmIH_RB_WPTR:
187 setWptr(pkt->getLE<uint32_t>());
188 break;
190 setWptrAddrLo(pkt->getLE<uint32_t>());
191 break;
193 setWptrAddrHi(pkt->getLE<uint32_t>());
194 break;
196 setDoorbellOffset(pkt->getLE<uint32_t>());
197 if (bits(pkt->getLE<uint32_t>(), 28, 28)) {
200 }
201 break;
202 default:
203 DPRINTF(AMDGPUDevice, "IH Unknown MMIO %#x\n", mmio_offset);
204 break;
205 }
206}
207
208void
210{
211 regs.IH_Cntl = data;
212}
213
214void
216{
218 regs.baseAddr <<= 8;
219}
220
221void
223{
224 regs.baseAddr |= static_cast<uint64_t>(data) << 40;
225}
226
227void
229{
230 regs.IH_Rptr = data;
231}
232
233void
235{
236 regs.IH_Wptr = data;
237}
238
239void
245
246void
248{
250 regs.WptrAddr |= ((uint64_t)regs.IH_Wptr_Addr_Hi) << 32;
251}
252
253void
255{
256 regs.IH_Doorbell = data & 0x3ffffff;
257}
258
259void
261{
262 regs.IH_Rptr = data; // update ring buffer rptr offset
263}
264
265void
267{
268 uint32_t ih_cntl = regs.IH_Cntl;
269 uint32_t ih_base = regs.IH_Base;
270 uint32_t ih_base_hi = regs.IH_Base_Hi;
271 Addr ih_baseAddr = regs.baseAddr;
272 uint32_t ih_rptr = regs.IH_Rptr;
273 uint32_t ih_wptr = regs.IH_Wptr;
274 uint32_t ih_wptr_addr_lo = regs.IH_Wptr_Addr_Lo;
275 uint32_t ih_wptr_addr_hi = regs.IH_Wptr_Addr_Hi;
276 Addr ih_wptrAddr = regs.WptrAddr;
277 uint32_t ih_doorbellOffset = regs.IH_Doorbell;
278
279 SERIALIZE_SCALAR(ih_cntl);
280 SERIALIZE_SCALAR(ih_base);
281 SERIALIZE_SCALAR(ih_base_hi);
282 SERIALIZE_SCALAR(ih_baseAddr);
283 SERIALIZE_SCALAR(ih_rptr);
284 SERIALIZE_SCALAR(ih_wptr);
285 SERIALIZE_SCALAR(ih_wptr_addr_lo);
286 SERIALIZE_SCALAR(ih_wptr_addr_hi);
287 SERIALIZE_SCALAR(ih_wptrAddr);
288 SERIALIZE_SCALAR(ih_doorbellOffset);
289}
290
291void
293{
294 uint32_t ih_cntl;
295 uint32_t ih_base;
296 uint32_t ih_base_hi;
297 Addr ih_baseAddr;
298 uint32_t ih_rptr;
299 uint32_t ih_wptr;
300 uint32_t ih_wptr_addr_lo;
301 uint32_t ih_wptr_addr_hi;
302 Addr ih_wptrAddr;
303 uint32_t ih_doorbellOffset;
304
305 UNSERIALIZE_SCALAR(ih_cntl);
306 UNSERIALIZE_SCALAR(ih_base);
307 UNSERIALIZE_SCALAR(ih_base_hi);
308 UNSERIALIZE_SCALAR(ih_baseAddr);
309 UNSERIALIZE_SCALAR(ih_rptr);
310 UNSERIALIZE_SCALAR(ih_wptr);
311 UNSERIALIZE_SCALAR(ih_wptr_addr_lo);
312 UNSERIALIZE_SCALAR(ih_wptr_addr_hi);
313 UNSERIALIZE_SCALAR(ih_wptrAddr);
314 UNSERIALIZE_SCALAR(ih_doorbellOffset);
315
316 regs.IH_Cntl = ih_cntl;
317 regs.IH_Base = ih_base;
318 regs.IH_Base_Hi = ih_base_hi;
319 regs.baseAddr = ih_baseAddr;
320 regs.IH_Rptr = ih_rptr;
321 regs.IH_Wptr = ih_wptr;
322 regs.IH_Wptr_Addr_Lo = ih_wptr_addr_lo;
323 regs.IH_Wptr_Addr_Hi = ih_wptr_addr_hi;
324 regs.WptrAddr = ih_wptrAddr;
325 regs.IH_Doorbell = ih_doorbellOffset;
326}
327
328} // 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, int ip_id=0)
Set handles to GPU blocks.
void intrPost()
Methods inherited from PciDevice.
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 prepareInterruptCookie(ContextID cntxtId, uint32_t ring_id, uint32_t client_id, uint32_t source_id, unsigned node_id)
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:79
#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
Copyright (c) 2024 - Pranith Kumar Copyright (c) 2020 Inria All rights reserved.
Definition binary32.hh:36
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 Tue Jun 18 2024 16:24:02 for gem5 by doxygen 1.11.0