gem5  v19.0.0.0
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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  * Authors: Andreas Sandberg
38  */
39 
40 #include "dev/arm/gpu_nomali.hh"
41 
42 #include "debug/NoMali.hh"
43 #include "dev/arm/base_gic.hh"
44 #include "dev/arm/realview.hh"
45 #include "enums/MemoryMode.hh"
46 #include "mem/packet_access.hh"
47 #include "nomali/lib/mali_midg_regmap.h"
48 #include "params/CustomNoMaliGpu.hh"
49 #include "params/NoMaliGpu.hh"
50 
51 static const std::map<Enums::NoMaliGpuType, nomali_gpu_type_t> gpuTypeMap{
52  { Enums::T60x, NOMALI_GPU_T60X },
53  { Enums::T62x, NOMALI_GPU_T62X },
54  { Enums::T760, NOMALI_GPU_T760 },
55 };
56 
57 NoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p)
58  : PioDevice(p),
59  pioAddr(p->pio_addr),
60  platform(p->platform),
61  interruptMap{
62  { NOMALI_INT_GPU, p->int_gpu },
63  { NOMALI_INT_JOB, p->int_job },
64  { NOMALI_INT_MMU, p->int_mmu },
65  }
66 {
67  if (nomali_api_version() != NOMALI_API_VERSION)
68  panic("NoMali library API mismatch!\n");
69 
70  /* Setup the GPU configuration based on our param struct */
71  nomali_config_t cfg;
72  memset(&cfg, 0, sizeof(cfg));
73 
74  const auto it_gpu(gpuTypeMap.find(p->gpu_type));
75  if (it_gpu == gpuTypeMap.end()) {
76  fatal("Unrecognized GPU type: %s (%i)\n",
77  Enums::NoMaliGpuTypeStrings[p->gpu_type], p->gpu_type);
78  }
79  cfg.type = it_gpu->second;
80 
81  cfg.ver_maj = p->ver_maj;
82  cfg.ver_min = p->ver_min;
83  cfg.ver_status = p->ver_status;
84 
85  panicOnErr(
86  nomali_create(&nomali, &cfg),
87  "Failed to instantiate NoMali");
88 
89 
90  /* Setup an interrupt callback */
91  nomali_callback_t cbk_int;
92  cbk_int.type = NOMALI_CALLBACK_INT;
93  cbk_int.usr = (void *)this;
94  cbk_int.func.interrupt = NoMaliGpu::_interrupt;
95  setCallback(cbk_int);
96 
97  /* Setup a reset callback */
98  nomali_callback_t cbk_rst;
99  cbk_rst.type = NOMALI_CALLBACK_RESET;
100  cbk_rst.usr = (void *)this;
101  cbk_rst.func.reset = NoMaliGpu::_reset;
102  setCallback(cbk_rst);
103 
104  panicOnErr(
105  nomali_get_info(nomali, &nomaliInfo),
106  "Failed to get NoMali information struct");
107 }
108 
110 {
111  nomali_destroy(nomali);
112 }
113 
114 
115 void
117 {
118  PioDevice::init();
119 
120  /* Reset the GPU here since the reset callback won't have been
121  * installed when the GPU was reset at instantiation time.
122  */
123  reset();
124 }
125 
126 void
128 {
129  std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2);
130 
131  for (int i = 0; i < nomaliInfo.reg_size; i += 4)
132  regs[i >> 2] = readRegRaw(i);
133 
134  SERIALIZE_CONTAINER(regs);
135 }
136 
137 void
139 {
140  std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2);
141 
142  UNSERIALIZE_CONTAINER(regs);
143 
144  for (int i = 0; i < nomaliInfo.reg_size; i += 4)
145  writeRegRaw(i, regs[i >> 2]);
146 }
147 
148 Tick
150 {
151  assert(pkt->getAddr() >= pioAddr);
152  const Addr addr(pkt->getAddr() - pioAddr);
153  const unsigned size(pkt->getSize());
154 
155  if (addr + size >= nomaliInfo.reg_size)
156  panic("GPU register '0x%x' out of range!\n", addr);
157 
158  if (size != 4)
159  panic("Unexpected GPU register read size: %i\n", size);
160  else if (addr & 0x3)
161  panic("Unaligned GPU read: %i\n", size);
162 
163  pkt->setLE<uint32_t>(readReg(addr));
164  pkt->makeResponse();
165 
166  return 0;
167 }
168 
169 Tick
171 {
172  assert(pkt->getAddr() >= pioAddr);
173  const Addr addr(pkt->getAddr() - pioAddr);
174  const unsigned size(pkt->getSize());
175 
176  if (addr + size >= nomaliInfo.reg_size)
177  panic("GPU register '0x%x' out of range!\n", addr);
178 
179  if (size != 4)
180  panic("Unexpected GPU register write size: %i\n", size);
181  else if (addr & 0x3)
182  panic("Unaligned GPU write: %i\n", size);
183 
184  writeReg(addr, pkt->getLE<uint32_t>());
185  pkt->makeAtomicResponse();
186 
187  return 0;
188 }
189 
192 {
193  return AddrRangeList({ RangeSize(pioAddr, nomaliInfo.reg_size) });
194 }
195 
196 void
198 {
199  DPRINTF(NoMali, "reset()\n");
200 
201  panicOnErr(
202  nomali_reset(nomali),
203  "Failed to reset GPU");
204 }
205 
206 uint32_t
207 NoMaliGpu::readReg(nomali_addr_t reg)
208 {
209  uint32_t value;
210 
211  panicOnErr(
212  nomali_reg_read(nomali, &value, reg),
213  "GPU register read failed");
214 
215  DPRINTF(NoMali, "readReg(0x%x): 0x%x\n",
216  reg, value);
217 
218  return value;
219 }
220 
221 
222 void
223 NoMaliGpu::writeReg(nomali_addr_t reg, uint32_t value)
224 {
225  DPRINTF(NoMali, "writeReg(0x%x, 0x%x)\n",
226  reg, value);
227 
228  panicOnErr(
229  nomali_reg_write(nomali, reg, value),
230  "GPU register write failed");
231 }
232 
233 uint32_t
234 NoMaliGpu::readRegRaw(nomali_addr_t reg) const
235 {
236  uint32_t value;
237 
238  panicOnErr(
239  nomali_reg_read_raw(nomali, &value, reg),
240  "GPU raw register read failed");
241 
242  return value;
243 }
244 
245 
246 void
247 NoMaliGpu::writeRegRaw(nomali_addr_t reg, uint32_t value)
248 {
249  panicOnErr(
250  nomali_reg_write_raw(nomali, reg, value),
251  "GPU raw register write failed");
252 }
253 
254 bool
255 NoMaliGpu::intState(nomali_int_t intno)
256 {
257  int state = 0;
258  panicOnErr(
259  nomali_int_state(nomali, &state, intno),
260  "Failed to get interrupt state");
261 
262  return !!state;
263 }
264 
265 void
266 NoMaliGpu::gpuPanic(nomali_error_t err, const char *msg)
267 {
268  panic("%s: %s\n", msg, nomali_errstr(err));
269 }
270 
271 
272 void
273 NoMaliGpu::onInterrupt(nomali_int_t intno, bool set)
274 {
275  const auto it_int(interruptMap.find(intno));
276  if (it_int == interruptMap.end())
277  panic("Unhandled interrupt from NoMali: %i\n", intno);
278 
279  DPRINTF(NoMali, "Interrupt %i->%i: %i\n",
280  intno, it_int->second, set);
281 
282  assert(platform);
283  assert(platform->gic);
284 
285  if (set)
286  platform->gic->sendInt(it_int->second);
287  else
288  platform->gic->clearInt(it_int->second);
289 }
290 
291 void
293 {
294  DPRINTF(NoMali, "Reset\n");
295 }
296 
297 void
298 NoMaliGpu::setCallback(const nomali_callback_t &callback)
299 {
300  DPRINTF(NoMali, "Registering callback %i\n",
301  callback.type);
302 
303  panicOnErr(
304  nomali_set_callback(nomali, &callback),
305  "Failed to register callback");
306 }
307 
308 void
309 NoMaliGpu::_interrupt(nomali_handle_t h, void *usr,
310  nomali_int_t intno, int set)
311 {
312  NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr));
313 
314  _this->onInterrupt(intno, !!set);
315 }
316 
317 void
318 NoMaliGpu::_reset(nomali_handle_t h, void *usr)
319 {
320  NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr));
321 
322  _this->onReset();
323 }
324 
325 
326 CustomNoMaliGpu::CustomNoMaliGpu(const CustomNoMaliGpuParams *p)
327  : NoMaliGpu(p),
328  idRegs{
329  { GPU_CONTROL_REG(GPU_ID), p->gpu_id },
330  { GPU_CONTROL_REG(L2_FEATURES), p->l2_features },
331  { GPU_CONTROL_REG(TILER_FEATURES), p->tiler_features },
332  { GPU_CONTROL_REG(MEM_FEATURES), p->mem_features },
333  { GPU_CONTROL_REG(MMU_FEATURES), p->mmu_features },
334  { GPU_CONTROL_REG(AS_PRESENT), p->as_present },
335  { GPU_CONTROL_REG(JS_PRESENT), p->js_present },
336 
337  { GPU_CONTROL_REG(THREAD_MAX_THREADS), p->thread_max_threads },
338  { GPU_CONTROL_REG(THREAD_MAX_WORKGROUP_SIZE),
339  p->thread_max_workgroup_size },
340  { GPU_CONTROL_REG(THREAD_MAX_BARRIER_SIZE),
341  p->thread_max_barrier_size },
342  { GPU_CONTROL_REG(THREAD_FEATURES), p->thread_features },
343 
344  { GPU_CONTROL_REG(SHADER_PRESENT_LO), bits(p->shader_present, 31, 0) },
345  { GPU_CONTROL_REG(SHADER_PRESENT_HI), bits(p->shader_present, 63, 32) },
346  { GPU_CONTROL_REG(TILER_PRESENT_LO), bits(p->tiler_present, 31, 0) },
347  { GPU_CONTROL_REG(TILER_PRESENT_HI), bits(p->tiler_present, 63, 32) },
348  { GPU_CONTROL_REG(L2_PRESENT_LO), bits(p->l2_present, 31, 0) },
349  { GPU_CONTROL_REG(L2_PRESENT_HI), bits(p->l2_present, 63, 32) },
350  }
351 {
352  fatal_if(p->texture_features.size() > 3,
353  "Too many texture feature registers specified (%i)\n",
354  p->texture_features.size());
355 
356  fatal_if(p->js_features.size() > 16,
357  "Too many job slot feature registers specified (%i)\n",
358  p->js_features.size());
359 
360  for (int i = 0; i < p->texture_features.size(); i++)
361  idRegs[TEXTURE_FEATURES_REG(i)] = p->texture_features[i];
362 
363  for (int i = 0; i < p->js_features.size(); i++)
364  idRegs[JS_FEATURES_REG(i)] = p->js_features[i];
365 }
366 
368 {
369 }
370 
371 void
373 {
375 
376  for (const auto &reg : idRegs)
377  writeRegRaw(reg.first, reg.second);
378 }
379 
380 
381 
382 NoMaliGpu *
383 NoMaliGpuParams::create()
384 {
385  return new NoMaliGpu(this);
386 }
387 
389 CustomNoMaliGpuParams::create()
390 {
391  return new CustomNoMaliGpu(this);
392 }
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:167
#define DPRINTF(x,...)
Definition: trace.hh:229
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:584
RealView *const platform
Platform, used to discover GIC.
Definition: gpu_nomali.hh:176
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: gpu_nomali.cc:170
Bitfield< 5, 3 > reg
Definition: types.hh:89
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:175
bool intState(nomali_int_t intno)
Wrapper around nomali_int_state()
Definition: gpu_nomali.cc:255
virtual void clearInt(uint32_t num)=0
Clear an interrupt from a device that is connected to the GIC.
Bitfield< 7 > i
nomali_handle_t nomali
Handle of a NoMali library instance.
Definition: gpu_nomali.hh:186
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
Definition: addr_range.hh:573
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gpu_nomali.cc:127
Bitfield< 7, 0 > size
Definition: gic_v3_its.hh:182
ip6_addr_t addr
Definition: inet.hh:335
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: io_device.cc:59
static void _interrupt(nomali_handle_t h, void *usr, nomali_int_t intno, int set)
Interrupt callback from the NoMali library.
Definition: gpu_nomali.cc:309
virtual ~NoMaliGpu()
Definition: gpu_nomali.cc:109
virtual void onInterrupt(nomali_int_t intno, bool set)
Interrupt callback from the NoMali library.
Definition: gpu_nomali.cc:273
Declaration of top level class for the RealView platform chips.
Definition: cprintf.cc:42
virtual ~CustomNoMaliGpu()
Definition: gpu_nomali.cc:367
AddrRangeList getAddrRanges() const override
Every PIO device is obliged to provide an implementation that returns the address ranges the device r...
Definition: gpu_nomali.cc:191
void setLE(T v)
Set the value in the data pointer to v as little endian.
nomali_info_t nomaliInfo
Cached information struct from the NoMali library.
Definition: gpu_nomali.hh:183
NoMaliGpu(const NoMaliGpuParams *p)
Definition: gpu_nomali.cc:57
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: gpu_nomali.cc:138
unsigned getSize() const
Definition: packet.hh:736
static void _reset(nomali_handle_t h, void *usr)
Reset callback from the NoMali library.
Definition: gpu_nomali.cc:318
CustomNoMaliGpu(const CustomNoMaliGpuParams *p)
Definition: gpu_nomali.cc:326
#define SERIALIZE_CONTAINER(member)
Definition: serialize.hh:664
std::map< nomali_addr_t, uint32_t > idRegs
Map between GPU registers and their custom reset values.
Definition: gpu_nomali.hh:201
static void panicOnErr(nomali_error_t err, const char *msg)
Panic if the NoMali returned an error, do nothing otherwise.
Definition: gpu_nomali.hh:111
virtual void sendInt(uint32_t num)=0
Post an interrupt from a device that is connected to the GIC.
void makeAtomicResponse()
Definition: packet.hh:949
void writeReg(nomali_addr_t reg, uint32_t value)
Wrapper around nomali_reg_write().
Definition: gpu_nomali.cc:223
uint64_t Tick
Tick count type.
Definition: types.hh:63
void setCallback(const nomali_callback_t &callback)
Wrapper around nomali_set_callback()
Definition: gpu_nomali.cc:298
BaseGic * gic
Definition: realview.hh:65
const Addr pioAddr
Device base address.
Definition: gpu_nomali.hh:173
const std::map< nomali_int_t, uint32_t > interruptMap
Map between NoMali interrupt types and actual GIC interrupts.
Definition: gpu_nomali.hh:180
Addr getAddr() const
Definition: packet.hh:726
#define fatal_if(cond,...)
Conditional fatal macro that checks the supplied condition and only causes a fatal error if the condi...
Definition: logging.hh:203
This device is the base class which all devices senstive to an address range inherit from...
Definition: io_device.hh:102
void onReset() override
Reset callback from the NoMali library.
Definition: gpu_nomali.cc:372
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:667
Bitfield< 16 > usr
Definition: misc.hh:804
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:142
void writeRegRaw(nomali_addr_t reg, uint32_t value)
Wrapper around nomali_reg_write_raw().
Definition: gpu_nomali.cc:247
A Packet is used to encapsulate a transfer between two objects in the memory system (e...
Definition: packet.hh:255
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: gpu_nomali.cc:116
void reset()
Wrapper around nomali_reset().
Definition: gpu_nomali.cc:197
uint32_t readReg(nomali_addr_t reg)
Wrapper around nomali_reg_read().
Definition: gpu_nomali.cc:207
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:937
virtual void onReset()
Reset callback from the NoMali library.
Definition: gpu_nomali.cc:292
Base class for ARM GIC implementations.
std::ostream CheckpointOut
Definition: serialize.hh:68
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
uint32_t readRegRaw(nomali_addr_t reg) const
Wrapper around nomali_reg_read_raw().
Definition: gpu_nomali.cc:234
static void gpuPanic(nomali_error_t err, const char *msg) M5_ATTR_NORETURN
Format a NoMali error into an error message and panic.
Definition: gpu_nomali.cc:266
T bits(T val, int first, int last)
Extract the bitfield from position &#39;first&#39; to &#39;last&#39; (inclusive) from &#39;val&#39; and right justify it...
Definition: bitfield.hh:72
static const std::map< Enums::NoMaliGpuType, nomali_gpu_type_t > gpuTypeMap
Definition: gpu_nomali.cc:51
Bitfield< 0 > p
Addr pioAddr
Address that the device listens to.
Definition: io_device.hh:157
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: gpu_nomali.cc:149

Generated on Fri Feb 28 2020 16:27:00 for gem5 by doxygen 1.8.13