gem5 [DEVELOP-FOR-25.0]
Loading...
Searching...
No Matches
gpu_nomali.cc
Go to the documentation of this file.
1/*
2 * Copyright (c) 2014-2016 ARM Limited
3 * All rights reserved
4 *
5 * The license below extends only to copyright in the software and shall
6 * not be construed as granting a license to any other intellectual
7 * property including but not limited to intellectual property relating
8 * to a hardware implementation of the functionality of the software
9 * licensed hereunder. You may use the software subject to the license
10 * terms below provided that you ensure that this notice is replicated
11 * unmodified and in its entirety in all distributions of the software,
12 * modified or unmodified, in source code or in binary form.
13 *
14 * Redistribution and use in source and binary forms, with or without
15 * modification, are permitted provided that the following conditions are
16 * met: redistributions of source code must retain the above copyright
17 * notice, this list of conditions and the following disclaimer;
18 * redistributions in binary form must reproduce the above copyright
19 * notice, this list of conditions and the following disclaimer in the
20 * documentation and/or other materials provided with the distribution;
21 * neither the name of the copyright holders nor the names of its
22 * contributors may be used to endorse or promote products derived from
23 * this software without specific prior written permission.
24 *
25 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
28 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
29 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
30 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
31 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
32 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
33 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
35 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38#include "dev/arm/gpu_nomali.hh"
39
40#include "debug/NoMali.hh"
41#include "dev/arm/base_gic.hh"
42#include "dev/arm/realview.hh"
43#include "enums/MemoryMode.hh"
44#include "mem/packet_access.hh"
45#include "nomali/lib/mali_midg_regmap.h"
46#include "params/CustomNoMaliGpu.hh"
47#include "params/NoMaliGpu.hh"
48
49namespace gem5
50{
51
52static const std::map<enums::NoMaliGpuType, nomali_gpu_type_t> gpuTypeMap{
53 { enums::T60x, NOMALI_GPU_T60X },
54 { enums::T62x, NOMALI_GPU_T62X },
55 { enums::T760, NOMALI_GPU_T760 },
56};
57
58NoMaliGpu::NoMaliGpu(const NoMaliGpuParams &p)
59 : PioDevice(p),
60 pioAddr(p.pio_addr),
63 { NOMALI_INT_GPU, p.int_gpu },
64 { NOMALI_INT_JOB, p.int_job },
65 { NOMALI_INT_MMU, p.int_mmu },
66 }
67{
68 if (nomali_api_version() != NOMALI_API_VERSION)
69 panic("NoMali library API mismatch!\n");
70
71 /* Setup the GPU configuration based on our param struct */
72 nomali_config_t cfg;
73 memset(&cfg, 0, sizeof(cfg));
74
75 const auto it_gpu(gpuTypeMap.find(p.gpu_type));
76 if (it_gpu == gpuTypeMap.end()) {
77 fatal("Unrecognized GPU type: %s (%i)\n",
78 enums::NoMaliGpuTypeStrings[p.gpu_type], p.gpu_type);
79 }
80 cfg.type = it_gpu->second;
81
82 cfg.ver_maj = p.ver_maj;
83 cfg.ver_min = p.ver_min;
84 cfg.ver_status = p.ver_status;
85
86 panicOnErr(
87 nomali_create(&nomali, &cfg),
88 "Failed to instantiate NoMali");
89
90
91 /* Setup an interrupt callback */
92 nomali_callback_t cbk_int;
93 cbk_int.type = NOMALI_CALLBACK_INT;
94 cbk_int.usr = (void *)this;
95 cbk_int.func.interrupt = NoMaliGpu::_interrupt;
96 setCallback(cbk_int);
97
98 /* Setup a reset callback */
99 nomali_callback_t cbk_rst;
100 cbk_rst.type = NOMALI_CALLBACK_RESET;
101 cbk_rst.usr = (void *)this;
102 cbk_rst.func.reset = NoMaliGpu::_reset;
103 setCallback(cbk_rst);
104
105 panicOnErr(
106 nomali_get_info(nomali, &nomaliInfo),
107 "Failed to get NoMali information struct");
108}
109
111{
112 nomali_destroy(nomali);
113}
114
115
116void
118{
120
121 /* Reset the GPU here since the reset callback won't have been
122 * installed when the GPU was reset at instantiation time.
123 */
124 reset();
125}
126
127void
129{
130 std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2);
131
132 for (int i = 0; i < nomaliInfo.reg_size; i += 4)
133 regs[i >> 2] = readRegRaw(i);
134
136}
137
138void
140{
141 std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2);
142
144
145 for (int i = 0; i < nomaliInfo.reg_size; i += 4)
146 writeRegRaw(i, regs[i >> 2]);
147}
148
149Tick
151{
152 assert(pkt->getAddr() >= pioAddr);
153 const Addr addr(pkt->getAddr() - pioAddr);
154 const unsigned size(pkt->getSize());
155
156 if (addr + size >= nomaliInfo.reg_size)
157 panic("GPU register '0x%x' out of range!\n", addr);
158
159 if (size != 4)
160 panic("Unexpected GPU register read size: %i\n", size);
161 else if (addr & 0x3)
162 panic("Unaligned GPU read: %i\n", size);
163
164 pkt->setLE<uint32_t>(readReg(addr));
165 pkt->makeResponse();
166
167 return 0;
168}
169
170Tick
172{
173 assert(pkt->getAddr() >= pioAddr);
174 const Addr addr(pkt->getAddr() - pioAddr);
175 const unsigned size(pkt->getSize());
176
177 if (addr + size >= nomaliInfo.reg_size)
178 panic("GPU register '0x%x' out of range!\n", addr);
179
180 if (size != 4)
181 panic("Unexpected GPU register write size: %i\n", size);
182 else if (addr & 0x3)
183 panic("Unaligned GPU write: %i\n", size);
184
185 writeReg(addr, pkt->getLE<uint32_t>());
186 pkt->makeAtomicResponse();
187
188 return 0;
189}
190
193{
194 return AddrRangeList({ RangeSize(pioAddr, nomaliInfo.reg_size) });
195}
196
197void
199{
200 DPRINTF(NoMali, "reset()\n");
201
203 nomali_reset(nomali),
204 "Failed to reset GPU");
205}
206
207uint32_t
209{
210 uint32_t value;
211
213 nomali_reg_read(nomali, &value, reg),
214 "GPU register read failed");
215
216 DPRINTF(NoMali, "readReg(0x%x): 0x%x\n",
217 reg, value);
218
219 return value;
220}
221
222
223void
224NoMaliGpu::writeReg(nomali_addr_t reg, uint32_t value)
225{
226 DPRINTF(NoMali, "writeReg(0x%x, 0x%x)\n",
227 reg, value);
228
230 nomali_reg_write(nomali, reg, value),
231 "GPU register write failed");
232}
233
234uint32_t
235NoMaliGpu::readRegRaw(nomali_addr_t reg) const
236{
237 uint32_t value;
238
240 nomali_reg_read_raw(nomali, &value, reg),
241 "GPU raw register read failed");
242
243 return value;
244}
245
246
247void
248NoMaliGpu::writeRegRaw(nomali_addr_t reg, uint32_t value)
249{
251 nomali_reg_write_raw(nomali, reg, value),
252 "GPU raw register write failed");
253}
254
255bool
256NoMaliGpu::intState(nomali_int_t intno)
257{
258 int state = 0;
260 nomali_int_state(nomali, &state, intno),
261 "Failed to get interrupt state");
262
263 return !!state;
264}
265
266void
267NoMaliGpu::gpuPanic(nomali_error_t err, const char *msg)
268{
269 panic("%s: %s\n", msg, nomali_errstr(err));
270}
271
272
273void
274NoMaliGpu::onInterrupt(nomali_int_t intno, bool set)
275{
276 const auto it_int(interruptMap.find(intno));
277 if (it_int == interruptMap.end())
278 panic("Unhandled interrupt from NoMali: %i\n", intno);
279
280 DPRINTF(NoMali, "Interrupt %i->%i: %i\n",
281 intno, it_int->second, set);
282
283 assert(platform);
284 assert(platform->gic);
285
286 if (set)
287 platform->gic->sendInt(it_int->second);
288 else
289 platform->gic->clearInt(it_int->second);
290}
291
292void
294{
295 DPRINTF(NoMali, "Reset\n");
296}
297
298void
299NoMaliGpu::setCallback(const nomali_callback_t &callback)
300{
301 DPRINTF(NoMali, "Registering callback %i\n",
302 callback.type);
303
305 nomali_set_callback(nomali, &callback),
306 "Failed to register callback");
307}
308
309void
310NoMaliGpu::_interrupt(nomali_handle_t h, void *usr,
311 nomali_int_t intno, int set)
312{
313 NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr));
314
315 _this->onInterrupt(intno, !!set);
316}
317
318void
319NoMaliGpu::_reset(nomali_handle_t h, void *usr)
320{
321 NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr));
322
323 _this->onReset();
324}
325
326
327CustomNoMaliGpu::CustomNoMaliGpu(const CustomNoMaliGpuParams &p)
328 : NoMaliGpu(p),
329 idRegs{
330 { GPU_CONTROL_REG(GPU_ID), p.gpu_id },
331 { GPU_CONTROL_REG(L2_FEATURES), p.l2_features },
332 { GPU_CONTROL_REG(TILER_FEATURES), p.tiler_features },
333 { GPU_CONTROL_REG(MEM_FEATURES), p.mem_features },
334 { GPU_CONTROL_REG(MMU_FEATURES), p.mmu_features },
335 { GPU_CONTROL_REG(AS_PRESENT), p.as_present },
336 { GPU_CONTROL_REG(JS_PRESENT), p.js_present },
337
338 { GPU_CONTROL_REG(THREAD_MAX_THREADS), p.thread_max_threads },
339 { GPU_CONTROL_REG(THREAD_MAX_WORKGROUP_SIZE),
340 p.thread_max_workgroup_size },
341 { GPU_CONTROL_REG(THREAD_MAX_BARRIER_SIZE),
342 p.thread_max_barrier_size },
343 { GPU_CONTROL_REG(THREAD_FEATURES), p.thread_features },
344
345 { GPU_CONTROL_REG(SHADER_PRESENT_LO), bits(p.shader_present, 31, 0) },
346 { GPU_CONTROL_REG(SHADER_PRESENT_HI), bits(p.shader_present, 63, 32) },
347 { GPU_CONTROL_REG(TILER_PRESENT_LO), bits(p.tiler_present, 31, 0) },
348 { GPU_CONTROL_REG(TILER_PRESENT_HI), bits(p.tiler_present, 63, 32) },
349 { GPU_CONTROL_REG(L2_PRESENT_LO), bits(p.l2_present, 31, 0) },
350 { GPU_CONTROL_REG(L2_PRESENT_HI), bits(p.l2_present, 63, 32) },
351 }
352{
353 fatal_if(p.texture_features.size() > 3,
354 "Too many texture feature registers specified (%i)\n",
355 p.texture_features.size());
356
357 fatal_if(p.js_features.size() > 16,
358 "Too many job slot feature registers specified (%i)\n",
359 p.js_features.size());
360
361 for (int i = 0; i < p.texture_features.size(); i++)
362 idRegs[TEXTURE_FEATURES_REG(i)] = p.texture_features[i];
363
364 for (int i = 0; i < p.js_features.size(); i++)
365 idRegs[JS_FEATURES_REG(i)] = p.js_features[i];
366}
367
371
372void
374{
376
377 for (const auto &reg : idRegs)
378 writeRegRaw(reg.first, reg.second);
379}
380
381} // namespace gem5
#define DPRINTF(x,...)
Definition trace.hh:209
Base class for ARM GIC implementations.
std::map< nomali_addr_t, uint32_t > idRegs
Map between GPU registers and their custom reset values.
void onReset() override
Reset callback from the NoMali library.
CustomNoMaliGpu(const CustomNoMaliGpuParams &p)
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
static void _interrupt(nomali_handle_t h, void *usr, nomali_int_t intno, int set)
Interrupt callback from the NoMali library.
void unserialize(CheckpointIn &cp) override
Unserialize an object.
void setCallback(const nomali_callback_t &callback)
Wrapper around nomali_set_callback()
RealView *const platform
Platform, used to discover GIC.
uint32_t readReg(nomali_addr_t reg)
Wrapper around nomali_reg_read().
virtual ~NoMaliGpu()
static void _reset(nomali_handle_t h, void *usr)
Reset callback from the NoMali library.
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
static void panicOnErr(nomali_error_t err, const char *msg)
Panic if the NoMali returned an error, do nothing otherwise.
const Addr pioAddr
Device base address.
static void gpuPanic(nomali_error_t err, const char *msg)
Format a NoMali error into an error message and panic.
uint32_t readRegRaw(nomali_addr_t reg) const
Wrapper around nomali_reg_read_raw().
const std::map< nomali_int_t, uint32_t > interruptMap
Map between NoMali interrupt types and actual GIC interrupts.
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
NoMaliGpu(const NoMaliGpuParams &p)
Definition gpu_nomali.cc:58
bool intState(nomali_int_t intno)
Wrapper around nomali_int_state()
nomali_info_t nomaliInfo
Cached information struct from the NoMali library.
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
virtual void onInterrupt(nomali_int_t intno, bool set)
Interrupt callback from the NoMali library.
void reset()
Wrapper around nomali_reset().
void writeReg(nomali_addr_t reg, uint32_t value)
Wrapper around nomali_reg_write().
nomali_handle_t nomali
Handle of a NoMali library instance.
void serialize(CheckpointOut &cp) const override
Serialize an object.
void writeRegRaw(nomali_addr_t reg, uint32_t value)
Wrapper around nomali_reg_write_raw().
virtual void onReset()
Reset callback from the NoMali library.
Addr getAddr() const
Definition packet.hh:807
void setLE(T v)
Set the value in the data pointer to v as little endian.
void makeResponse()
Take a request packet and modify it in place to be suitable for returning as a response to that reque...
Definition packet.hh:1062
unsigned getSize() const
Definition packet.hh:817
void makeAtomicResponse()
Definition packet.hh:1074
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
PioDevice(const Params &p)
Definition io_device.cc:50
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition io_device.cc:59
STL vector class.
Definition stl.hh:37
AddrRange RangeSize(Addr start, Addr size)
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
Definition addr_range.hh:64
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 panic(...)
This implements a cprintf based panic() function.
Definition logging.hh:220
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition logging.hh:268
#define fatal(...)
This implements a cprintf based fatal() function.
Definition logging.hh:232
#define UNSERIALIZE_CONTAINER(member)
Definition serialize.hh:651
#define SERIALIZE_CONTAINER(member)
Definition serialize.hh:643
Bitfield< 6 > err
Bitfield< 7 > i
Definition misc_types.hh:67
Bitfield< 12, 11 > set
Bitfield< 0 > p
Bitfield< 54 > p
Definition pagetable.hh:70
Bitfield< 5, 3 > reg
Definition types.hh:92
Bitfield< 3 > addr
Definition types.hh:84
Bitfield< 16 > usr
Definition misc.hh:837
Copyright (c) 2024 Arm Limited All rights reserved.
Definition binary32.hh:36
std::ostream CheckpointOut
Definition serialize.hh:66
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition types.hh:147
uint64_t Tick
Tick count type.
Definition types.hh:58
static const std::map< enums::NoMaliGpuType, nomali_gpu_type_t > gpuTypeMap
Definition gpu_nomali.cc:52
Packet * PacketPtr
Declaration of top level class for the RealView platform chips.

Generated on Mon May 26 2025 09:19:09 for gem5 by doxygen 1.13.2