gem5  v21.1.0.2
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 
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
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
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 
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
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
fatal
#define fatal(...)
This implements a cprintf based fatal() function.
Definition: logging.hh:189
gem5::NoMaliGpu::NoMaliGpu
NoMaliGpu(const NoMaliGpuParams &p)
Definition: gpu_nomali.cc:58
gem5::RealView::gic
BaseGic * gic
Definition: realview.hh:62
gem5::NoMaliGpu::writeRegRaw
void writeRegRaw(nomali_addr_t reg, uint32_t value)
Wrapper around nomali_reg_write_raw().
Definition: gpu_nomali.cc:248
gem5::NoMaliGpu::intState
bool intState(nomali_int_t intno)
Wrapper around nomali_int_state()
Definition: gpu_nomali.cc:256
gem5::PioDevice
This device is the base class which all devices senstive to an address range inherit from.
Definition: io_device.hh:102
gem5::gpuTypeMap
static const std::map< enums::NoMaliGpuType, nomali_gpu_type_t > gpuTypeMap
Definition: gpu_nomali.cc:52
gem5::RangeSize
AddrRange RangeSize(Addr start, Addr size)
Definition: addr_range.hh:661
UNSERIALIZE_CONTAINER
#define UNSERIALIZE_CONTAINER(member)
Definition: serialize.hh:634
gem5::AddrRangeList
std::list< AddrRange > AddrRangeList
Convenience typedef for a collection of address ranges.
Definition: addr_range.hh:641
gem5::CheckpointIn
Definition: serialize.hh:68
gem5::NoMaliGpu::onInterrupt
virtual void onInterrupt(nomali_int_t intno, bool set)
Interrupt callback from the NoMali library.
Definition: gpu_nomali.cc:274
base_gic.hh
gem5::ArmISA::err
Bitfield< 6 > err
Definition: misc_types.hh:750
gem5::NoMaliGpu::readReg
uint32_t readReg(nomali_addr_t reg)
Wrapper around nomali_reg_read().
Definition: gpu_nomali.cc:208
gem5::NoMaliGpu::_reset
static void _reset(nomali_handle_t h, void *usr)
Reset callback from the NoMali library.
Definition: gpu_nomali.cc:319
std::vector< uint32_t >
gem5::NoMaliGpu::reset
void reset()
Wrapper around nomali_reset().
Definition: gpu_nomali.cc:198
gem5::NoMaliGpu::read
Tick read(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: gpu_nomali.cc:150
gem5::Packet::makeAtomicResponse
void makeAtomicResponse()
Definition: packet.hh:1043
gem5::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:192
realview.hh
gem5::ArmISA::i
Bitfield< 7 > i
Definition: misc_types.hh:66
gem5::NoMaliGpu::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: gpu_nomali.cc:117
gem5::NoMaliGpu::setCallback
void setCallback(const nomali_callback_t &callback)
Wrapper around nomali_set_callback()
Definition: gpu_nomali.cc:299
gpu_nomali.hh
gem5::PioDevice::init
void init() override
init() is called after all C++ SimObjects have been created and all ports are connected.
Definition: io_device.cc:59
gem5::NoMaliGpu
Definition: gpu_nomali.hh:53
gem5::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:310
gem5::NoMaliGpu::~NoMaliGpu
virtual ~NoMaliGpu()
Definition: gpu_nomali.cc:110
DPRINTF
#define DPRINTF(x,...)
Definition: trace.hh:186
gem5::Packet
A Packet is used to encapsulate a transfer between two objects in the memory system (e....
Definition: packet.hh:283
gem5::MipsISA::p
Bitfield< 0 > p
Definition: pra_constants.hh:326
gem5::Tick
uint64_t Tick
Tick count type.
Definition: types.hh:58
gem5::NoMaliGpu::gpuPanic
static void gpuPanic(nomali_error_t err, const char *msg)
Format a NoMali error into an error message and panic.
Definition: gpu_nomali.cc:267
gem5::NoMaliGpu::onReset
virtual void onReset()
Reset callback from the NoMali library.
Definition: gpu_nomali.cc:293
gem5::bits
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
gem5::BaseGic::sendInt
virtual void sendInt(uint32_t num)=0
Post an interrupt from a device that is connected to the GIC.
gem5::NoMaliGpu::interruptMap
const std::map< nomali_int_t, uint32_t > interruptMap
Map between NoMali interrupt types and actual GIC interrupts.
Definition: gpu_nomali.hh:181
gem5::NoMaliGpu::unserialize
void unserialize(CheckpointIn &cp) override
Unserialize an object.
Definition: gpu_nomali.cc:139
gem5::X86ISA::usr
Bitfield< 16 > usr
Definition: misc.hh:808
gem5::Addr
uint64_t Addr
Address type This will probably be moved somewhere else in the near future.
Definition: types.hh:147
gem5::CustomNoMaliGpu::~CustomNoMaliGpu
virtual ~CustomNoMaliGpu()
Definition: gpu_nomali.cc:368
gem5::CustomNoMaliGpu::onReset
void onReset() override
Reset callback from the NoMali library.
Definition: gpu_nomali.cc:373
packet_access.hh
gem5::CustomNoMaliGpu::CustomNoMaliGpu
CustomNoMaliGpu(const CustomNoMaliGpuParams &p)
Definition: gpu_nomali.cc:327
gem5::X86ISA::reg
Bitfield< 5, 3 > reg
Definition: types.hh:92
gem5::NoMaliGpu::platform
RealView *const platform
Platform, used to discover GIC.
Definition: gpu_nomali.hh:177
gem5::BaseGic::clearInt
virtual void clearInt(uint32_t num)=0
Clear an interrupt from a device that is connected to the GIC.
SERIALIZE_CONTAINER
#define SERIALIZE_CONTAINER(member)
Definition: serialize.hh:626
gem5::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:1031
gem5::NoMaliGpu::pioAddr
const Addr pioAddr
Device base address.
Definition: gpu_nomali.hh:174
gem5::Packet::getLE
T getLE() const
Get the data in the packet byte swapped from little endian to host endian.
Definition: packet_access.hh:78
gem5::CheckpointOut
std::ostream CheckpointOut
Definition: serialize.hh:66
gem5::Packet::setLE
void setLE(T v)
Set the value in the data pointer to v as little endian.
Definition: packet_access.hh:108
std::list< AddrRange >
gem5::Packet::getAddr
Addr getAddr() const
Definition: packet.hh:781
gem5::NoMaliGpu::writeReg
void writeReg(nomali_addr_t reg, uint32_t value)
Wrapper around nomali_reg_write().
Definition: gpu_nomali.cc:224
gem5::NoMaliGpu::serialize
void serialize(CheckpointOut &cp) const override
Serialize an object.
Definition: gpu_nomali.cc:128
gem5::NoMaliGpu::nomaliInfo
nomali_info_t nomaliInfo
Cached information struct from the NoMali library.
Definition: gpu_nomali.hh:184
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:225
gem5
Reference material can be found at the JEDEC website: UFS standard http://www.jedec....
Definition: decoder.cc:40
gem5::NoMaliGpu::write
Tick write(PacketPtr pkt) override
Pure virtual function that the device must implement.
Definition: gpu_nomali.cc:171
gem5::CustomNoMaliGpu::idRegs
std::map< nomali_addr_t, uint32_t > idRegs
Map between GPU registers and their custom reset values.
Definition: gpu_nomali.hh:202
gem5::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:112
gem5::Packet::getSize
unsigned getSize() const
Definition: packet.hh:791
panic
#define panic(...)
This implements a cprintf based panic() function.
Definition: logging.hh:177
gem5::NoMaliGpu::nomali
nomali_handle_t nomali
Handle of a NoMali library instance.
Definition: gpu_nomali.hh:187
gem5::NoMaliGpu::readRegRaw
uint32_t readRegRaw(nomali_addr_t reg) const
Wrapper around nomali_reg_read_raw().
Definition: gpu_nomali.cc:235
gem5::X86ISA::addr
Bitfield< 3 > addr
Definition: types.hh:84

Generated on Tue Sep 21 2021 12:25:13 for gem5 by doxygen 1.8.17