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:
Andreas Sandberg 2015-07-07 10:03:14 +01:00
parent c274057840
commit a74c446e7d
4 changed files with 463 additions and 0 deletions

63
src/dev/arm/NoMali.py Normal file
View 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")

View file

@ -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
View 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
View 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__