2 * Copyright (c) 2014-2015 ARM Limited
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.
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.
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.
37 * Authors: Andreas Sandberg
40 #include "dev/arm/gpu_nomali.hh"
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 "params/NoMaliGpu.hh"
49 NoMaliGpu::NoMaliGpu(const NoMaliGpuParams
*p
)
52 platform(p
->platform
),
54 { NOMALI_INT_GPU
, p
->int_gpu
},
55 { NOMALI_INT_JOB
, p
->int_job
},
56 { NOMALI_INT_MMU
, p
->int_mmu
},
59 if (nomali_api_version() != NOMALI_API_VERSION
)
60 panic("NoMali library API mismatch!\n");
62 /* Setup the GPU configuration based on our param struct */
64 memset(&cfg
, 0, sizeof(cfg
));
66 switch (p
->gpu_type
) {
68 cfg
.type
= NOMALI_GPU_T60X
;
72 cfg
.type
= NOMALI_GPU_T62X
;
76 cfg
.type
= NOMALI_GPU_T760
;
80 fatal("Unknown GPU type\n");
83 cfg
.ver_maj
= p
->ver_maj
;
84 cfg
.ver_min
= p
->ver_min
;
85 cfg
.ver_status
= p
->ver_status
;
88 nomali_create(&nomali
, &cfg
),
89 "Failed to instantiate NoMali");
92 /* Setup an interrupt callback */
93 nomali_callback_t cbk_int
;
94 cbk_int
.type
= NOMALI_CALLBACK_INT
;
95 cbk_int
.usr
= (void *)this;
96 cbk_int
.func
.interrupt
= NoMaliGpu::_interrupt
;
98 nomali_set_callback(nomali
, &cbk_int
),
99 "Failed to setup interrupt callback");
102 nomali_get_info(nomali
, &nomaliInfo
),
103 "Failed to get NoMali information struct");
106 NoMaliGpu::~NoMaliGpu()
108 nomali_destroy(nomali
);
113 NoMaliGpu::serialize(CheckpointOut
&cp
) const
115 std::vector
<uint32_t> regs(nomaliInfo
.reg_size
>> 2);
117 for (int i
= 0; i
< nomaliInfo
.reg_size
; i
+= 4)
118 regs
[i
>> 2] = readRegRaw(i
);
120 SERIALIZE_CONTAINER(regs
);
124 NoMaliGpu::unserialize(CheckpointIn
&cp
)
126 std::vector
<uint32_t> regs(nomaliInfo
.reg_size
>> 2);
128 UNSERIALIZE_CONTAINER(regs
);
130 for (int i
= 0; i
< nomaliInfo
.reg_size
; i
+= 4)
131 writeRegRaw(i
, regs
[i
>> 2]);
135 NoMaliGpu::read(PacketPtr pkt
)
137 assert(pkt
->getAddr() >= pioAddr
);
138 const Addr
addr(pkt
->getAddr() - pioAddr
);
139 const unsigned size(pkt
->getSize());
141 if (addr
+ size
>= nomaliInfo
.reg_size
)
142 panic("GPU register '0x%x' out of range!\n", addr
);
145 panic("Unexpected GPU register read size: %i\n", size
);
147 panic("Unaligned GPU read: %i\n", size
);
149 pkt
->set
<uint32_t>(readReg(addr
));
156 NoMaliGpu::write(PacketPtr pkt
)
158 assert(pkt
->getAddr() >= pioAddr
);
159 const Addr
addr(pkt
->getAddr() - pioAddr
);
160 const unsigned size(pkt
->getSize());
162 if (addr
+ size
>= nomaliInfo
.reg_size
)
163 panic("GPU register '0x%x' out of range!\n", addr
);
166 panic("Unexpected GPU register write size: %i\n", size
);
168 panic("Unaligned GPU write: %i\n", size
);
170 writeReg(addr
, pkt
->get
<uint32_t>());
171 pkt
->makeAtomicResponse();
177 NoMaliGpu::getAddrRanges() const
179 return AddrRangeList({ RangeSize(pioAddr
, nomaliInfo
.reg_size
) });
183 NoMaliGpu::readReg(nomali_addr_t reg
)
188 nomali_reg_read(nomali
, &value
, reg
),
189 "GPU register read failed");
191 DPRINTF(NoMali
, "readReg(0x%x): 0x%x\n",
199 NoMaliGpu::writeReg(nomali_addr_t reg
, uint32_t value
)
201 DPRINTF(NoMali
, "writeReg(0x%x, 0x%x)\n",
205 nomali_reg_write(nomali
, reg
, value
),
206 "GPU register write failed");
210 NoMaliGpu::readRegRaw(nomali_addr_t reg
) const
215 nomali_reg_read_raw(nomali
, &value
, reg
),
216 "GPU raw register read failed");
223 NoMaliGpu::writeRegRaw(nomali_addr_t reg
, uint32_t value
)
226 nomali_reg_write_raw(nomali
, reg
, value
),
227 "GPU raw register write failed");
231 NoMaliGpu::_interrupt(nomali_handle_t h
, void *usr
, nomali_int_t intno
, int set
)
233 NoMaliGpu
*_this(static_cast<NoMaliGpu
*>(usr
));
235 _this
->onInterrupt(h
, intno
, !!set
);
239 NoMaliGpu::onInterrupt(nomali_handle_t h
, nomali_int_t intno
, bool set
)
241 const auto it_int(interruptMap
.find(intno
));
242 if (it_int
== interruptMap
.end())
243 panic("Unhandled interrupt from NoMali: %i\n", intno
);
245 DPRINTF(NoMali
, "Interrupt %i->%i: %i\n",
246 intno
, it_int
->second
, set
);
249 assert(platform
->gic
);
252 platform
->gic
->sendInt(it_int
->second
);
254 platform
->gic
->clearInt(it_int
->second
);
258 NoMaliGpu::gpuPanic(nomali_error_t err
, const char *msg
)
260 panic("%s: %s\n", msg
, nomali_errstr(err
));
264 NoMaliGpuParams::create()
266 return new NoMaliGpu(this);