gem5
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups 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->set<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->get<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 DPRINTF(x,...)
Definition: trace.hh:212
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:398
void set(T v, ByteOrder endian)
Set the value in the data pointer to v using the specified endianness.
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
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
Definition: miscregs.hh:1378
nomali_handle_t nomali
Handle of a NoMali library instance.
Definition: gpu_nomali.hh:186
#define panic(...)
Definition: misc.hh:153
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
Definition: addr_range.hh:387
setCallback(cbk_int)
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gpu_nomali.cc:127
ip6_addr_t addr
Definition: inet.hh:335
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.
virtual ~CustomNoMaliGpu()
Definition: gpu_nomali.cc:367
T get(ByteOrder endian) const
Get the data in the packet byte swapped from the specified endianness.
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
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
nomali_callback_t cbk_rst
Definition: gpu_nomali.cc:98
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:164
cbk_int usr
Definition: gpu_nomali.cc:93
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:857
void writeReg(nomali_addr_t reg, uint32_t value)
Wrapper around nomali_reg_write().
Definition: gpu_nomali.cc:223
panicOnErr(nomali_create(&nomali,&cfg),"Failed to instantiate NoMali")
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
#define fatal(...)
Definition: misc.hh:163
const std::map< nomali_int_t, uint32_t > interruptMap
Map between NoMali interrupt types and actual GIC interrupts.
Definition: gpu_nomali.hh:180
This device is the base class which all devices senstive to an address range inherit from...
Definition: io_device.hh:84
void onReset() override
Reset callback from the NoMali library.
Definition: gpu_nomali.cc:372
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:167
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:245
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
virtual void init()
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: io_device.cc:83
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:845
nomali_callback_t cbk_int
Definition: gpu_nomali.cc:91
int size()
Definition: pagetable.hh:146
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:67
uint32_t readRegRaw(nomali_addr_t reg) const
Wrapper around nomali_reg_read_raw().
Definition: gpu_nomali.cc:234
nomali_config_t cfg
Definition: gpu_nomali.cc:66
const auto it_gpu(gpuTypeMap.find(p->gpu_type))
unsigned getSize() const
Definition: packet.hh:649
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
fatal_if(p->js_features.size() > 16,"Too many job slot feature registers specified (%i)\n", p->js_features.size())
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:67
static const std::map< Enums::NoMaliGpuType, nomali_gpu_type_t > gpuTypeMap
Definition: gpu_nomali.cc:51
Bitfield< 0 > p
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: gpu_nomali.cc:149
Addr getAddr() const
Definition: packet.hh:639

Generated on Fri Jun 9 2017 13:03:45 for gem5 by doxygen 1.8.6