From a74c446e7d034cebe01babb92f448a145b4ba77d Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Tue, 7 Jul 2015 10:03:14 +0100 Subject: [PATCH] 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. --- src/dev/arm/NoMali.py | 63 +++++++++ src/dev/arm/SConscript | 3 + src/dev/arm/gpu_nomali.cc | 267 ++++++++++++++++++++++++++++++++++++++ src/dev/arm/gpu_nomali.hh | 130 +++++++++++++++++++ 4 files changed, 463 insertions(+) create mode 100644 src/dev/arm/NoMali.py create mode 100644 src/dev/arm/gpu_nomali.cc create mode 100644 src/dev/arm/gpu_nomali.hh diff --git a/src/dev/arm/NoMali.py b/src/dev/arm/NoMali.py new file mode 100644 index 000000000..c4465c37a --- /dev/null +++ b/src/dev/arm/NoMali.py @@ -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") diff --git a/src/dev/arm/SConscript b/src/dev/arm/SConscript index 06398ed15..804c11b24 100644 --- a/src/dev/arm/SConscript +++ b/src/dev/arm/SConscript @@ -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') diff --git a/src/dev/arm/gpu_nomali.cc b/src/dev/arm/gpu_nomali.cc new file mode 100644 index 000000000..5aba13e4f --- /dev/null +++ b/src/dev/arm/gpu_nomali.cc @@ -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 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 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(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()); + 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(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); +} diff --git a/src/dev/arm/gpu_nomali.hh b/src/dev/arm/gpu_nomali.hh new file mode 100644 index 000000000..bc687c264 --- /dev/null +++ b/src/dev/arm/gpu_nomali.hh @@ -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 + +#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 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__ -- 2.30.2