dev, arm: Refactor the NoMali GPU
authorAndreas Sandberg <andreas.sandberg@arm.com>
Tue, 23 Feb 2016 11:49:34 +0000 (11:49 +0000)
committerAndreas Sandberg <andreas.sandberg@arm.com>
Tue, 23 Feb 2016 11:49:34 +0000 (11:49 +0000)
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
src/dev/arm/gpu_nomali.hh

index 5aba13e4f9d0055fde1e7e33698dca97cde74394..3f074b5954713a2f5e4038614b11a69f73b8034b 100644 (file)
@@ -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
 #include "mem/packet_access.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)
     : 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<NoMaliGpu *>(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<NoMaliGpu *>(usr));
+
+    _this->onInterrupt(intno, !!set);
 }
 
 NoMaliGpu *
index 4e4f9dbcb6104b3b9a0e5c3147cc6018fa0392fe..eaf7f37cb12ea9d2c98937258f33aa4040b1db7d 100644 (file)
@@ -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<nomali_int_t, uint32_t> interruptMap;
 
-
     /** Cached information struct from the NoMali library */
     nomali_info_t nomaliInfo;