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.
This commit is contained in:
Andreas Sandberg 2016-02-23 11:49:34 +00:00
parent 826e0047b0
commit 81a8ce3564
2 changed files with 106 additions and 42 deletions

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2015 ARM Limited * Copyright (c) 2014-2016 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * The license below extends only to copyright in the software and shall
@ -46,6 +46,12 @@
#include "mem/packet_access.hh" #include "mem/packet_access.hh"
#include "params/NoMaliGpu.hh" #include "params/NoMaliGpu.hh"
static const std::map<Enums::NoMaliGpuType, nomali_gpu_type_t> gpuTypeMap{
{ Enums::T60x, NOMALI_GPU_T60X },
{ Enums::T62x, NOMALI_GPU_T62X },
{ Enums::T760, NOMALI_GPU_T760 },
};
NoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p) NoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p)
: PioDevice(p), : PioDevice(p),
pioAddr(p->pio_addr), pioAddr(p->pio_addr),
@ -63,22 +69,12 @@ NoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p)
nomali_config_t cfg; nomali_config_t cfg;
memset(&cfg, 0, sizeof(cfg)); memset(&cfg, 0, sizeof(cfg));
switch (p->gpu_type) { const auto it_gpu(gpuTypeMap.find(p->gpu_type));
case Enums::T60x: if (it_gpu == gpuTypeMap.end()) {
cfg.type = NOMALI_GPU_T60X; fatal("Unrecognized GPU type: %s (%i)\n",
break; Enums::NoMaliGpuTypeStrings[p->gpu_type], p->gpu_type);
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.type = it_gpu->second;
cfg.ver_maj = p->ver_maj; cfg.ver_maj = p->ver_maj;
cfg.ver_min = p->ver_min; cfg.ver_min = p->ver_min;
@ -94,9 +90,7 @@ NoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p)
cbk_int.type = NOMALI_CALLBACK_INT; cbk_int.type = NOMALI_CALLBACK_INT;
cbk_int.usr = (void *)this; cbk_int.usr = (void *)this;
cbk_int.func.interrupt = NoMaliGpu::_interrupt; cbk_int.func.interrupt = NoMaliGpu::_interrupt;
panicOnErr( setCallback(cbk_int);
nomali_set_callback(nomali, &cbk_int),
"Failed to setup interrupt callback");
panicOnErr( panicOnErr(
nomali_get_info(nomali, &nomaliInfo), nomali_get_info(nomali, &nomaliInfo),
@ -108,7 +102,6 @@ NoMaliGpu::~NoMaliGpu()
nomali_destroy(nomali); nomali_destroy(nomali);
} }
void void
NoMaliGpu::serialize(CheckpointOut &cp) const NoMaliGpu::serialize(CheckpointOut &cp) const
{ {
@ -179,6 +172,16 @@ NoMaliGpu::getAddrRanges() const
return AddrRangeList({ RangeSize(pioAddr, nomaliInfo.reg_size) }); return AddrRangeList({ RangeSize(pioAddr, nomaliInfo.reg_size) });
} }
void
NoMaliGpu::reset()
{
DPRINTF(NoMali, "reset()\n");
panicOnErr(
nomali_reset(nomali),
"Failed to reset GPU");
}
uint32_t uint32_t
NoMaliGpu::readReg(nomali_addr_t reg) NoMaliGpu::readReg(nomali_addr_t reg)
{ {
@ -227,16 +230,26 @@ NoMaliGpu::writeRegRaw(nomali_addr_t reg, uint32_t value)
"GPU raw register write failed"); "GPU raw register write failed");
} }
void bool
NoMaliGpu::_interrupt(nomali_handle_t h, void *usr, nomali_int_t intno, int set) NoMaliGpu::intState(nomali_int_t intno)
{ {
NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr)); int state = 0;
panicOnErr(
nomali_int_state(nomali, &state, intno),
"Failed to get interrupt state");
_this->onInterrupt(h, intno, !!set); return !!state;
} }
void void
NoMaliGpu::onInterrupt(nomali_handle_t h, nomali_int_t intno, bool set) NoMaliGpu::gpuPanic(nomali_error_t err, const char *msg)
{
panic("%s: %s\n", msg, nomali_errstr(err));
}
void
NoMaliGpu::onInterrupt(nomali_int_t intno, bool set)
{ {
const auto it_int(interruptMap.find(intno)); const auto it_int(interruptMap.find(intno));
if (it_int == interruptMap.end()) if (it_int == interruptMap.end())
@ -255,9 +268,23 @@ NoMaliGpu::onInterrupt(nomali_handle_t h, nomali_int_t intno, bool set)
} }
void 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<NoMaliGpu *>(usr));
_this->onInterrupt(intno, !!set);
} }
NoMaliGpu * NoMaliGpu *

View file

@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2014-2015 ARM Limited * Copyright (c) 2014-2016 ARM Limited
* All rights reserved * All rights reserved
* *
* The license below extends only to copyright in the software and shall * 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; Tick write(PacketPtr pkt) override;
AddrRangeList getAddrRanges() const override; AddrRangeList getAddrRanges() const override;
private: protected: /* API wrappers/helpers */
/** /**
* Interrupt callback from the NoMali library. * @{
* * @name API wrappers
* 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_reset(). */
void reset();
/** Wrapper around nomali_reg_read(). */ /** Wrapper around nomali_reg_read(). */
uint32_t readReg(nomali_addr_t reg); uint32_t readReg(nomali_addr_t reg);
@ -90,6 +82,16 @@ class NoMaliGpu : public PioDevice
/** Wrapper around nomali_reg_write_raw(). */ /** Wrapper around nomali_reg_write_raw(). */
void writeRegRaw(nomali_addr_t reg, uint32_t value); 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. * Format a NoMali error into an error message and panic.
* *
@ -108,6 +110,42 @@ class NoMaliGpu : public PioDevice
gpuPanic(err, msg); 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 */ /** Device base address */
const Addr pioAddr; const Addr pioAddr;
@ -118,7 +156,6 @@ class NoMaliGpu : public PioDevice
* interrupts */ * interrupts */
const std::map<nomali_int_t, uint32_t> interruptMap; const std::map<nomali_int_t, uint32_t> interruptMap;
/** Cached information struct from the NoMali library */ /** Cached information struct from the NoMali library */
nomali_info_t nomaliInfo; nomali_info_t nomaliInfo;