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

Generated on Wed Sep 30 2020 14:02:10 for gem5 by doxygen 1.8.17