From 81a8ce356460c020bcab12801d91726ea886f7c2 Mon Sep 17 00:00:00 2001 From: Andreas Sandberg Date: Tue, 23 Feb 2016 11:49:34 +0000 Subject: dev, arm: Refactor the NoMali GPU Refactor and cleanup the NoMaliGpu class: * Use a std::map instead of a switch block to map the parameter enum describing the GPU type to a NoMali type. * Remove redundant NoMali handle from the interrupt callback. * Make callbacks and API wrappers protected instead of private to enable future extensions. * Wrap remaining NoMali API calls. --- src/dev/arm/gpu_nomali.cc | 81 +++++++++++++++++++++++++++++++---------------- src/dev/arm/gpu_nomali.hh | 67 ++++++++++++++++++++++++++++++--------- 2 files changed, 106 insertions(+), 42 deletions(-) (limited to 'src/dev') diff --git a/src/dev/arm/gpu_nomali.cc b/src/dev/arm/gpu_nomali.cc index 5aba13e4f..3f074b595 100644 --- a/src/dev/arm/gpu_nomali.cc +++ b/src/dev/arm/gpu_nomali.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 ARM Limited + * Copyright (c) 2014-2016 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -46,6 +46,12 @@ #include "mem/packet_access.hh" #include "params/NoMaliGpu.hh" +static const std::map gpuTypeMap{ + { Enums::T60x, NOMALI_GPU_T60X }, + { Enums::T62x, NOMALI_GPU_T62X }, + { Enums::T760, NOMALI_GPU_T760 }, +}; + NoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p) : PioDevice(p), pioAddr(p->pio_addr), @@ -63,22 +69,12 @@ NoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p) 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"); + const auto it_gpu(gpuTypeMap.find(p->gpu_type)); + if (it_gpu == gpuTypeMap.end()) { + fatal("Unrecognized GPU type: %s (%i)\n", + Enums::NoMaliGpuTypeStrings[p->gpu_type], p->gpu_type); } + cfg.type = it_gpu->second; cfg.ver_maj = p->ver_maj; cfg.ver_min = p->ver_min; @@ -94,9 +90,7 @@ NoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p) 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"); + setCallback(cbk_int); panicOnErr( nomali_get_info(nomali, &nomaliInfo), @@ -108,7 +102,6 @@ NoMaliGpu::~NoMaliGpu() nomali_destroy(nomali); } - void NoMaliGpu::serialize(CheckpointOut &cp) const { @@ -179,6 +172,16 @@ NoMaliGpu::getAddrRanges() const return AddrRangeList({ RangeSize(pioAddr, nomaliInfo.reg_size) }); } +void +NoMaliGpu::reset() +{ + DPRINTF(NoMali, "reset()\n"); + + panicOnErr( + nomali_reset(nomali), + "Failed to reset GPU"); +} + uint32_t NoMaliGpu::readReg(nomali_addr_t reg) { @@ -227,16 +230,26 @@ NoMaliGpu::writeRegRaw(nomali_addr_t reg, uint32_t value) "GPU raw register write failed"); } -void -NoMaliGpu::_interrupt(nomali_handle_t h, void *usr, nomali_int_t intno, int set) +bool +NoMaliGpu::intState(nomali_int_t intno) { - NoMaliGpu *_this(static_cast(usr)); + int state = 0; + panicOnErr( + nomali_int_state(nomali, &state, intno), + "Failed to get interrupt state"); + + return !!state; +} - _this->onInterrupt(h, intno, !!set); +void +NoMaliGpu::gpuPanic(nomali_error_t err, const char *msg) +{ + panic("%s: %s\n", msg, nomali_errstr(err)); } + void -NoMaliGpu::onInterrupt(nomali_handle_t h, nomali_int_t intno, bool set) +NoMaliGpu::onInterrupt(nomali_int_t intno, bool set) { const auto it_int(interruptMap.find(intno)); if (it_int == interruptMap.end()) @@ -255,9 +268,23 @@ NoMaliGpu::onInterrupt(nomali_handle_t h, nomali_int_t intno, bool set) } void -NoMaliGpu::gpuPanic(nomali_error_t err, const char *msg) +NoMaliGpu::setCallback(const nomali_callback_t &callback) { - panic("%s: %s\n", msg, nomali_errstr(err)); + DPRINTF(NoMali, "Registering callback %i\n", + callback.type); + + panicOnErr( + nomali_set_callback(nomali, &callback), + "Failed to register callback"); +} + +void +NoMaliGpu::_interrupt(nomali_handle_t h, void *usr, + nomali_int_t intno, int set) +{ + NoMaliGpu *_this(static_cast(usr)); + + _this->onInterrupt(intno, !!set); } NoMaliGpu * diff --git a/src/dev/arm/gpu_nomali.hh b/src/dev/arm/gpu_nomali.hh index 4e4f9dbcb..eaf7f37cb 100644 --- a/src/dev/arm/gpu_nomali.hh +++ b/src/dev/arm/gpu_nomali.hh @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2015 ARM Limited + * Copyright (c) 2014-2016 ARM Limited * All rights reserved * * The license below extends only to copyright in the software and shall @@ -63,22 +63,14 @@ class NoMaliGpu : public PioDevice Tick write(PacketPtr pkt) override; AddrRangeList getAddrRanges() const override; - private: + protected: /* API wrappers/helpers */ /** - * 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)? + * @{ + * @name API wrappers */ - 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_reset(). */ + void reset(); /** Wrapper around nomali_reg_read(). */ uint32_t readReg(nomali_addr_t reg); @@ -90,6 +82,16 @@ class NoMaliGpu : public PioDevice /** Wrapper around nomali_reg_write_raw(). */ void writeRegRaw(nomali_addr_t reg, uint32_t value); + /** + * Wrapper around nomali_int_state() + * + * @param intno Interrupt number + * @return True if asserted, false otherwise. + */ + bool intState(nomali_int_t intno); + + /** @} */ + /** * Format a NoMali error into an error message and panic. * @@ -108,6 +110,42 @@ class NoMaliGpu : public PioDevice gpuPanic(err, msg); } + protected: /* Callbacks */ + /** + * @{ + * @name Callbacks + */ + + /** + * Interrupt callback from the NoMali library + * + * This method is called whenever there is an interrupt state change. + * + * @param intno Interrupt number + * @param set True is the interrupt is being asserted, false otherwise. + */ + virtual void onInterrupt(nomali_int_t intno, bool set); + + /** @} */ + + private: /* Callback helpers */ + /** Wrapper around nomali_set_callback() */ + void setCallback(const nomali_callback_t &callback); + + /** + * 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); + protected: /** Device base address */ const Addr pioAddr; @@ -118,7 +156,6 @@ class NoMaliGpu : public PioDevice * interrupts */ const std::map interruptMap; - /** Cached information struct from the NoMali library */ nomali_info_t nomaliInfo; -- cgit v1.2.3