dev, arm: Add a device model that uses the NoMali model
Add a simple device shim that interfaces with the NoMali model library. The gem5 side of the interface supports Mali T60x/T62x/T760 GPUs. This device model pretends to be a Mali GPU, but doesn't render anything and executes in zero time.
This commit is contained in:
parent
c274057840
commit
a74c446e7d
4 changed files with 463 additions and 0 deletions
63
src/dev/arm/NoMali.py
Normal file
63
src/dev/arm/NoMali.py
Normal file
|
@ -0,0 +1,63 @@
|
|||
# Copyright (c) 2014-2015 ARM Limited
|
||||
# All rights reserved.
|
||||
#
|
||||
# The license below extends only to copyright in the software and shall
|
||||
# not be construed as granting a license to any other intellectual
|
||||
# property including but not limited to intellectual property relating
|
||||
# to a hardware implementation of the functionality of the software
|
||||
# licensed hereunder. You may use the software subject to the license
|
||||
# terms below provided that you ensure that this notice is replicated
|
||||
# unmodified and in its entirety in all distributions of the software,
|
||||
# modified or unmodified, in source code or in binary form.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions are
|
||||
# met: redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer;
|
||||
# redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in the
|
||||
# documentation and/or other materials provided with the distribution;
|
||||
# neither the name of the copyright holders nor the names of its
|
||||
# contributors may be used to endorse or promote products derived from
|
||||
# this software without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
# Authors: Andreas Sandberg
|
||||
|
||||
from m5.params import *
|
||||
from Device import BasicPioDevice
|
||||
from Gic import *
|
||||
|
||||
class NoMaliGpuType(Enum): vals = [
|
||||
'T60x',
|
||||
'T62x',
|
||||
'T760',
|
||||
]
|
||||
|
||||
class NoMaliGpu(PioDevice):
|
||||
type = 'NoMaliGpu'
|
||||
cxx_header = "dev/arm/gpu_nomali.hh"
|
||||
|
||||
pio_addr = Param.Addr("Device base address")
|
||||
|
||||
platform = Param.RealView(Parent.any, "Platform this device is part of.")
|
||||
|
||||
gpu_type = Param.NoMaliGpuType("T760", "GPU type")
|
||||
ver_maj = Param.UInt32(0, "GPU Version (Major)")
|
||||
ver_min = Param.UInt32(0, "GPU Version (Minor)")
|
||||
ver_status = Param.UInt32(0, "GPU Version (Status)")
|
||||
|
||||
int_gpu = Param.UInt32("Interrupt number for GPU interrupts")
|
||||
int_job = Param.UInt32("Interrupt number for JOB interrupts")
|
||||
int_mmu = Param.UInt32("Interrupt number for MMU interrupts")
|
|
@ -46,6 +46,7 @@ if env['TARGET_ISA'] == 'arm':
|
|||
SimObject('RealView.py')
|
||||
SimObject('UFSHostDevice.py')
|
||||
SimObject('EnergyCtrl.py')
|
||||
SimObject('NoMali.py')
|
||||
|
||||
Source('a9scu.cc')
|
||||
Source('amba_device.cc')
|
||||
|
@ -60,6 +61,7 @@ if env['TARGET_ISA'] == 'arm':
|
|||
Source('hdlcd.cc')
|
||||
Source('kmi.cc')
|
||||
Source('timer_sp804.cc')
|
||||
Source('gpu_nomali.cc')
|
||||
Source('rv_ctrl.cc')
|
||||
Source('realview.cc')
|
||||
Source('rtc_pl031.cc')
|
||||
|
@ -79,3 +81,4 @@ if env['TARGET_ISA'] == 'arm':
|
|||
DebugFlag('EnergyCtrl')
|
||||
DebugFlag('UFSHostDevice')
|
||||
DebugFlag('VGIC')
|
||||
DebugFlag('NoMali')
|
||||
|
|
267
src/dev/arm/gpu_nomali.cc
Normal file
267
src/dev/arm/gpu_nomali.cc
Normal file
|
@ -0,0 +1,267 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Andreas Sandberg
|
||||
*/
|
||||
|
||||
#include "dev/arm/gpu_nomali.hh"
|
||||
|
||||
#include "debug/NoMali.hh"
|
||||
#include "dev/arm/base_gic.hh"
|
||||
#include "dev/arm/realview.hh"
|
||||
#include "enums/MemoryMode.hh"
|
||||
#include "mem/packet_access.hh"
|
||||
#include "params/NoMaliGpu.hh"
|
||||
|
||||
NoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p)
|
||||
: PioDevice(p),
|
||||
pioAddr(p->pio_addr),
|
||||
platform(p->platform),
|
||||
interruptMap{
|
||||
{ NOMALI_INT_GPU, p->int_gpu },
|
||||
{ NOMALI_INT_JOB, p->int_job },
|
||||
{ NOMALI_INT_MMU, p->int_mmu },
|
||||
}
|
||||
{
|
||||
if (nomali_api_version() != NOMALI_API_VERSION)
|
||||
panic("NoMali library API mismatch!\n");
|
||||
|
||||
/* Setup the GPU configuration based on our param struct */
|
||||
nomali_config_t cfg;
|
||||
memset(&cfg, 0, sizeof(cfg));
|
||||
|
||||
switch (p->gpu_type) {
|
||||
case Enums::T60x:
|
||||
cfg.type = NOMALI_GPU_T60X;
|
||||
break;
|
||||
|
||||
case Enums::T62x:
|
||||
cfg.type = NOMALI_GPU_T62X;
|
||||
break;
|
||||
|
||||
case Enums::T760:
|
||||
cfg.type = NOMALI_GPU_T760;
|
||||
break;
|
||||
|
||||
default:
|
||||
fatal("Unknown GPU type\n");
|
||||
}
|
||||
|
||||
cfg.ver_maj = p->ver_maj;
|
||||
cfg.ver_min = p->ver_min;
|
||||
cfg.ver_status = p->ver_status;
|
||||
|
||||
panicOnErr(
|
||||
nomali_create(&nomali, &cfg),
|
||||
"Failed to instantiate NoMali");
|
||||
|
||||
|
||||
/* Setup an interrupt callback */
|
||||
nomali_callback_t cbk_int;
|
||||
cbk_int.type = NOMALI_CALLBACK_INT;
|
||||
cbk_int.usr = (void *)this;
|
||||
cbk_int.func.interrupt = NoMaliGpu::_interrupt;
|
||||
panicOnErr(
|
||||
nomali_set_callback(nomali, &cbk_int),
|
||||
"Failed to setup interrupt callback");
|
||||
|
||||
panicOnErr(
|
||||
nomali_get_info(nomali, &nomaliInfo),
|
||||
"Failed to get NoMali information struct");
|
||||
}
|
||||
|
||||
NoMaliGpu::~NoMaliGpu()
|
||||
{
|
||||
nomali_destroy(nomali);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NoMaliGpu::serialize(CheckpointOut &cp) const
|
||||
{
|
||||
std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2);
|
||||
|
||||
for (int i = 0; i < nomaliInfo.reg_size; i += 4)
|
||||
regs[i >> 2] = readRegRaw(i);
|
||||
|
||||
SERIALIZE_CONTAINER(regs);
|
||||
}
|
||||
|
||||
void
|
||||
NoMaliGpu::unserialize(CheckpointIn &cp)
|
||||
{
|
||||
std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2);
|
||||
|
||||
UNSERIALIZE_CONTAINER(regs);
|
||||
|
||||
for (int i = 0; i < nomaliInfo.reg_size; i += 4)
|
||||
writeRegRaw(i, regs[i >> 2]);
|
||||
}
|
||||
|
||||
Tick
|
||||
NoMaliGpu::read(PacketPtr pkt)
|
||||
{
|
||||
assert(pkt->getAddr() >= pioAddr);
|
||||
const Addr addr(pkt->getAddr() - pioAddr);
|
||||
const unsigned size(pkt->getSize());
|
||||
|
||||
if (addr + size >= nomaliInfo.reg_size)
|
||||
panic("GPU register '0x%x' out of range!\n", addr);
|
||||
|
||||
if (size != 4)
|
||||
panic("Unexpected GPU register read size: %i\n", size);
|
||||
else if (addr & 0x3)
|
||||
panic("Unaligned GPU read: %i\n", size);
|
||||
|
||||
pkt->set<uint32_t>(readReg(addr));
|
||||
pkt->makeResponse();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Tick
|
||||
NoMaliGpu::write(PacketPtr pkt)
|
||||
{
|
||||
assert(pkt->getAddr() >= pioAddr);
|
||||
const Addr addr(pkt->getAddr() - pioAddr);
|
||||
const unsigned size(pkt->getSize());
|
||||
|
||||
if (addr + size >= nomaliInfo.reg_size)
|
||||
panic("GPU register '0x%x' out of range!\n", addr);
|
||||
|
||||
if (size != 4)
|
||||
panic("Unexpected GPU register write size: %i\n", size);
|
||||
else if (addr & 0x3)
|
||||
panic("Unaligned GPU write: %i\n", size);
|
||||
|
||||
writeReg(addr, pkt->get<uint32_t>());
|
||||
pkt->makeAtomicResponse();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
AddrRangeList
|
||||
NoMaliGpu::getAddrRanges() const
|
||||
{
|
||||
return AddrRangeList({ RangeSize(pioAddr, nomaliInfo.reg_size) });
|
||||
}
|
||||
|
||||
uint32_t
|
||||
NoMaliGpu::readReg(nomali_addr_t reg)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
panicOnErr(
|
||||
nomali_reg_read(nomali, &value, reg),
|
||||
"GPU register read failed");
|
||||
|
||||
DPRINTF(NoMali, "readReg(0x%x): 0x%x\n",
|
||||
reg, value);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NoMaliGpu::writeReg(nomali_addr_t reg, uint32_t value)
|
||||
{
|
||||
DPRINTF(NoMali, "writeReg(0x%x, 0x%x)\n",
|
||||
reg, value);
|
||||
|
||||
panicOnErr(
|
||||
nomali_reg_write(nomali, reg, value),
|
||||
"GPU register write failed");
|
||||
}
|
||||
|
||||
uint32_t
|
||||
NoMaliGpu::readRegRaw(nomali_addr_t reg) const
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
panicOnErr(
|
||||
nomali_reg_read_raw(nomali, &value, reg),
|
||||
"GPU raw register read failed");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
NoMaliGpu::writeRegRaw(nomali_addr_t reg, uint32_t value)
|
||||
{
|
||||
panicOnErr(
|
||||
nomali_reg_write_raw(nomali, reg, value),
|
||||
"GPU raw register write failed");
|
||||
}
|
||||
|
||||
void
|
||||
NoMaliGpu::_interrupt(nomali_handle_t h, void *usr, nomali_int_t intno, int set)
|
||||
{
|
||||
NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr));
|
||||
|
||||
_this->onInterrupt(h, intno, !!set);
|
||||
}
|
||||
|
||||
void
|
||||
NoMaliGpu::onInterrupt(nomali_handle_t h, nomali_int_t intno, bool set)
|
||||
{
|
||||
const auto it_int(interruptMap.find(intno));
|
||||
if (it_int == interruptMap.end())
|
||||
panic("Unhandled interrupt from NoMali: %i\n", intno);
|
||||
|
||||
DPRINTF(NoMali, "Interrupt %i->%i: %i\n",
|
||||
intno, it_int->second, set);
|
||||
|
||||
assert(platform);
|
||||
assert(platform->gic);
|
||||
|
||||
if (set)
|
||||
platform->gic->sendInt(it_int->second);
|
||||
else
|
||||
platform->gic->clearInt(it_int->second);
|
||||
}
|
||||
|
||||
void
|
||||
NoMaliGpu::gpuPanic(nomali_error_t err, const char *msg)
|
||||
{
|
||||
panic("%s: %s\n", msg, nomali_errstr(err));
|
||||
}
|
||||
|
||||
NoMaliGpu *
|
||||
NoMaliGpuParams::create()
|
||||
{
|
||||
return new NoMaliGpu(this);
|
||||
}
|
130
src/dev/arm/gpu_nomali.hh
Normal file
130
src/dev/arm/gpu_nomali.hh
Normal file
|
@ -0,0 +1,130 @@
|
|||
/*
|
||||
* Copyright (c) 2014-2015 ARM Limited
|
||||
* All rights reserved
|
||||
*
|
||||
* The license below extends only to copyright in the software and shall
|
||||
* not be construed as granting a license to any other intellectual
|
||||
* property including but not limited to intellectual property relating
|
||||
* to a hardware implementation of the functionality of the software
|
||||
* licensed hereunder. You may use the software subject to the license
|
||||
* terms below provided that you ensure that this notice is replicated
|
||||
* unmodified and in its entirety in all distributions of the software,
|
||||
* modified or unmodified, in source code or in binary form.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are
|
||||
* met: redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer;
|
||||
* redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution;
|
||||
* neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
* Authors: Andreas Sandberg
|
||||
*/
|
||||
|
||||
#ifndef __DEV_ARM_NOMALI_GPU_HH__
|
||||
#define __DEV_ARM_NOMALI_GPU_HH__
|
||||
|
||||
#include <map>
|
||||
|
||||
#include "dev/io_device.hh"
|
||||
#include "libnomali/nomali.h"
|
||||
|
||||
class NoMaliGpuParams;
|
||||
class RealView;
|
||||
|
||||
class NoMaliGpu : public PioDevice
|
||||
{
|
||||
public:
|
||||
NoMaliGpu(const NoMaliGpuParams *p);
|
||||
virtual ~NoMaliGpu();
|
||||
|
||||
public: /* Checkpointing */
|
||||
void serialize(CheckpointOut &cp) const M5_ATTR_OVERRIDE;
|
||||
void unserialize(CheckpointIn &cp) M5_ATTR_OVERRIDE;
|
||||
|
||||
public: /* IO device interfaces */
|
||||
Tick read(PacketPtr pkt) M5_ATTR_OVERRIDE;
|
||||
Tick write(PacketPtr pkt) M5_ATTR_OVERRIDE;
|
||||
AddrRangeList getAddrRanges() const M5_ATTR_OVERRIDE;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Interrupt callback from the NoMali library.
|
||||
*
|
||||
* This method calls onInterrupt() on the NoMaliGpu owning this
|
||||
* device.
|
||||
*
|
||||
* @param h NoMali library handle.
|
||||
* @param usr Pointer to an instance of the NoMaliGpu
|
||||
* @param intno GPU interrupt type
|
||||
* @param set Was the interrupt raised (1) or lowered (0)?
|
||||
*/
|
||||
static void _interrupt(nomali_handle_t h, void *usr,
|
||||
nomali_int_t intno, int set);
|
||||
|
||||
void onInterrupt(nomali_handle_t h, nomali_int_t intno, bool set);
|
||||
|
||||
/** Wrapper around nomali_reg_read(). */
|
||||
uint32_t readReg(nomali_addr_t reg);
|
||||
/** Wrapper around nomali_reg_write(). */
|
||||
void writeReg(nomali_addr_t reg, uint32_t value);
|
||||
|
||||
/** Wrapper around nomali_reg_read_raw(). */
|
||||
uint32_t readRegRaw(nomali_addr_t reg) const;
|
||||
/** Wrapper around nomali_reg_write_raw(). */
|
||||
void writeRegRaw(nomali_addr_t reg, uint32_t value);
|
||||
|
||||
/**
|
||||
* Format a NoMali error into an error message and panic.
|
||||
*
|
||||
* @param err Error code from the NoMali library.
|
||||
* @param msg Message to print.
|
||||
*/
|
||||
static void gpuPanic(nomali_error_t err, const char *msg) M5_ATTR_NORETURN;
|
||||
/**
|
||||
* Panic if the NoMali returned an error, do nothing otherwise.
|
||||
*
|
||||
* @param err Error code from the NoMali library.
|
||||
* @param msg Message to print when panicking.
|
||||
*/
|
||||
static void panicOnErr(nomali_error_t err, const char *msg) {
|
||||
if (err != NOMALI_E_OK)
|
||||
gpuPanic(err, msg);
|
||||
}
|
||||
|
||||
/** Device base address */
|
||||
const Addr pioAddr;
|
||||
|
||||
/** Platform, used to discover GIC */
|
||||
RealView *const platform;
|
||||
|
||||
/** Map between NoMali interrupt types and actual GIC
|
||||
* interrupts */
|
||||
const std::map<nomali_int_t, uint32_t> interruptMap;
|
||||
|
||||
|
||||
/** Cached information struct from the NoMali library */
|
||||
nomali_info_t nomaliInfo;
|
||||
|
||||
/** Handle of a NoMali library instance */
|
||||
nomali_handle_t nomali;
|
||||
};
|
||||
|
||||
|
||||
#endif // __DEV_ARM_NOMALI_GPU_HH__
|
Loading…
Reference in a new issue