gem5  v22.1.0.0
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 
49 namespace gem5
50 {
51 
52 static 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 
58 NoMaliGpu::NoMaliGpu(const NoMaliGpuParams &p)
59  : PioDevice(p),
60  pioAddr(p.pio_addr),
61  platform(p.platform),
62  interruptMap{
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 
110 NoMaliGpu::~NoMaliGpu()
111 {
112  nomali_destroy(nomali);
113 }
114 
115 
116 void
118 {
119  PioDevice::init();
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 
127 void
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 
135  SERIALIZE_CONTAINER(regs);
136 }
137 
138 void
140 {
141  std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2);
142 
143  UNSERIALIZE_CONTAINER(regs);
144 
145  for (int i = 0; i < nomaliInfo.reg_size; i += 4)
146  writeRegRaw(i, regs[i >> 2]);
147 }
148 
149 Tick
150 NoMaliGpu::read(PacketPtr pkt)
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 
170 Tick
171 NoMaliGpu::write(PacketPtr pkt)
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 
192 NoMaliGpu::getAddrRanges() const
193 {
194  return AddrRangeList({ RangeSize(pioAddr, nomaliInfo.reg_size) });
195 }
196 
197 void
199 {
200  DPRINTF(NoMali, "reset()\n");
201 
202  panicOnErr(
203  nomali_reset(nomali),
204  "Failed to reset GPU");
205 }
206 
207 uint32_t
208 NoMaliGpu::readReg(nomali_addr_t reg)
209 {
210  uint32_t value;
211 
212  panicOnErr(
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 
223 void
224 NoMaliGpu::writeReg(nomali_addr_t reg, uint32_t value)
225 {
226  DPRINTF(NoMali, "writeReg(0x%x, 0x%x)\n",
227  reg, value);
228 
229  panicOnErr(
230  nomali_reg_write(nomali, reg, value),
231  "GPU register write failed");
232 }
233 
234 uint32_t
235 NoMaliGpu::readRegRaw(nomali_addr_t reg) const
236 {
237  uint32_t value;
238 
239  panicOnErr(
240  nomali_reg_read_raw(nomali, &value, reg),
241  "GPU raw register read failed");
242 
243  return value;
244 }
245 
246 
247 void
248 NoMaliGpu::writeRegRaw(nomali_addr_t reg, uint32_t value)
249 {
250  panicOnErr(
251  nomali_reg_write_raw(nomali, reg, value),
252  "GPU raw register write failed");
253 }
254 
255 bool
256 NoMaliGpu::intState(nomali_int_t intno)
257 {
258  int state = 0;
259  panicOnErr(
260  nomali_int_state(nomali, &state, intno),
261  "Failed to get interrupt state");
262 
263  return !!state;
264 }
265 
266 void
267 NoMaliGpu::gpuPanic(nomali_error_t err, const char *msg)
268 {
269  panic("%s: %s\n", msg, nomali_errstr(err));
270 }
271 
272 
273 void
274 NoMaliGpu::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 
292 void
293 NoMaliGpu::onReset()
294 {
295  DPRINTF(NoMali, "Reset\n");
296 }
297 
298 void
299 NoMaliGpu::setCallback(const nomali_callback_t &callback)
300 {
301  DPRINTF(NoMali, "Registering callback %i\n",
302  callback.type);
303 
304  panicOnErr(
305  nomali_set_callback(nomali, &callback),
306  "Failed to register callback");
307 }
308 
309 void
310 NoMaliGpu::_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 
318 void
319 NoMaliGpu::_reset(nomali_handle_t h, void *usr)
320 {
321  NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr));
322 
323  _this->onReset();
324 }
325 
326 
327 CustomNoMaliGpu::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 
369 {
370 }
371 
372 void
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:186
Base class for ARM GIC implementations.
std::map< nomali_addr_t, uint32_t > idRegs
Map between GPU registers and their custom reset values.
Definition: gpu_nomali.hh:202
void onReset() override
Reset callback from the NoMali library.
Definition: gpu_nomali.cc:373
virtual ~CustomNoMaliGpu()
Definition: gpu_nomali.cc:368
NoMaliGpu(const NoMaliGpuParams &p)
Definition: gpu_nomali.cc:58
virtual void onInterrupt(nomali_int_t intno, bool set)
Interrupt callback from the NoMali library.
Definition: gpu_nomali.cc:274
void writeRegRaw(nomali_addr_t reg, uint32_t value)
Wrapper around nomali_reg_write_raw().
Definition: gpu_nomali.cc:248
virtual void onReset()
Reset callback from the NoMali library.
Definition: gpu_nomali.cc:293
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:294
Addr getAddr() const
Definition: packet.hh:805
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:1059
unsigned getSize() const
Definition: packet.hh:815
void makeAtomicResponse()
Definition: packet.hh:1071
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
This device is the base class which all devices senstive to an address range inherit from.
Definition: io_device.hh:103
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:815
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
Definition: addr_range.hh:57
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 panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:178
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:226
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:190
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:634
#define SERIALIZE_CONTAINER(member)
Definition: serialize.hh:626
atomic_var_t state
Definition: helpers.cc:188
Bitfield< 6 > err
Definition: misc_types.hh:809
Bitfield< 7 > i
Definition: misc_types.hh:67
Bitfield< 12, 11 > set
Definition: misc_types.hh:709
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:809
const FlagsType init
This Stat is Initialized.
Definition: info.hh:56
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
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
void unserialize(ThreadContext &tc, CheckpointIn &cp)
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
void serialize(const ThreadContext &tc, CheckpointOut &cp)
Thread context serialization helpers.
Declaration of top level class for the RealView platform chips.

Generated on Wed Dec 21 2022 10:22:33 for gem5 by doxygen 1.9.1