COMPMID-482: Add mali counters

Change-Id: I1782c3d92f7fea5a73ed89868d8c3ce04ffcf518
Reviewed-on: http://mpd-gerrit.cambridge.arm.com/85020
Reviewed-by: Anthony Barbier <anthony.barbier@arm.com>
Tested-by: Kaizen <jeremy.johnson+kaizengerrit@arm.com>
diff --git a/tests/framework/Framework.cpp b/tests/framework/Framework.cpp
index 31e5243..853ea25 100644
--- a/tests/framework/Framework.cpp
+++ b/tests/framework/Framework.cpp
@@ -47,6 +47,9 @@
 #ifdef PMU_ENABLED
     _available_instruments.emplace(InstrumentType::PMU, Instrument::make_instrument<PMUCounter>);
 #endif /* PMU_ENABLED */
+#ifdef MALI_ENABLED
+    _available_instruments.emplace(InstrumentType::MALI, Instrument::make_instrument<MaliCounter>);
+#endif /* MALI_ENABLED */
 }
 
 std::set<InstrumentType> Framework::available_instruments() const
diff --git a/tests/framework/SConscript b/tests/framework/SConscript
index 62837f8..92cbd55 100644
--- a/tests/framework/SConscript
+++ b/tests/framework/SConscript
@@ -27,7 +27,8 @@
 
 # vars is imported from arm_compute:
 variables = [
-    BoolVariable("pmu", "Enable PMU counters", False)
+    BoolVariable("pmu", "Enable PMU counters", False),
+    BoolVariable("mali", "Enable Mali hardware counters", False)
 ]
 
 # We need a separate set of Variables for the Help message (Otherwise the global variables will get displayed twice)
@@ -61,6 +62,12 @@
 else:
     framework_env.Append(CPPDEFINES = ['PMU_ENABLED'])
 
+if not framework_env['mali']:
+    # Remove MALI files
+    files = [f for f in files if "MaliCounter" not in os.path.basename(str(f))]
+else:
+    framework_env.Append(CPPDEFINES = ['MALI_ENABLED'])
+
 arm_compute_test_framework = framework_env.StaticLibrary('arm_compute_test_framework', files)
 
 Default(arm_compute_test_framework)
diff --git a/tests/framework/instruments/Instruments.cpp b/tests/framework/instruments/Instruments.cpp
index 699a11d..1c21f07 100644
--- a/tests/framework/instruments/Instruments.cpp
+++ b/tests/framework/instruments/Instruments.cpp
@@ -44,6 +44,7 @@
         { "pmu", InstrumentType::PMU },
         { "pmu_cycles", InstrumentType::PMU_CYCLE_COUNTER },
         { "pmu_instructions", InstrumentType::PMU_INSTRUCTION_COUNTER },
+        { "mali", InstrumentType::MALI },
     };
 
     try
diff --git a/tests/framework/instruments/Instruments.h b/tests/framework/instruments/Instruments.h
index aa37f9c..df6aa62 100644
--- a/tests/framework/instruments/Instruments.h
+++ b/tests/framework/instruments/Instruments.h
@@ -24,6 +24,7 @@
 #ifndef ARM_COMPUTE_TEST_INSTRUMENTS
 #define ARM_COMPUTE_TEST_INSTRUMENTS
 
+#include "MaliCounter.h"
 #include "PMUCounter.h"
 #include "WallClockTimer.h"
 
@@ -44,6 +45,7 @@
     PMU                     = 0x0200,
     PMU_CYCLE_COUNTER       = 0x0201,
     PMU_INSTRUCTION_COUNTER = 0x0202,
+    MALI                    = 0x0300,
 };
 
 InstrumentType instrument_type_from_name(const std::string &name);
@@ -72,6 +74,9 @@
         case InstrumentType::PMU_INSTRUCTION_COUNTER:
             stream << "PMU_INSTRUCTION_COUNTER";
             break;
+        case InstrumentType::MALI:
+            stream << "MALI";
+            break;
         case InstrumentType::ALL:
             stream << "ALL";
             break;
diff --git a/tests/framework/instruments/MaliCounter.cpp b/tests/framework/instruments/MaliCounter.cpp
new file mode 100644
index 0000000..bf73fec
--- /dev/null
+++ b/tests/framework/instruments/MaliCounter.cpp
@@ -0,0 +1,423 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#include "MaliCounter.h"
+
+namespace arm_compute
+{
+namespace test
+{
+namespace framework
+{
+namespace
+{
+struct MaliHWInfo
+{
+    unsigned mp_count;
+    unsigned gpu_id;
+    unsigned r_value;
+    unsigned p_value;
+    unsigned core_mask;
+};
+
+MaliHWInfo get_mali_hw_info(const char *path)
+{
+    int fd = open(path, O_RDWR); // NOLINT
+
+    if(fd < 0)
+    {
+        throw std::runtime_error("Failed to get HW info.");
+    }
+
+    {
+        mali_userspace::uku_version_check_args version_check_args;                // NOLINT
+        version_check_args.header.id = mali_userspace::UKP_FUNC_ID_CHECK_VERSION; // NOLINT
+        version_check_args.major     = 10;
+        version_check_args.minor     = 2;
+
+        if(mali_userspace::mali_ioctl(fd, version_check_args) != 0)
+        {
+            throw std::runtime_error("Failed to check version.");
+            close(fd);
+        }
+    }
+
+    {
+        mali_userspace::kbase_uk_hwcnt_reader_set_flags flags; // NOLINT
+        memset(&flags, 0, sizeof(flags));
+        flags.header.id    = mali_userspace::KBASE_FUNC_SET_FLAGS; // NOLINT
+        flags.create_flags = mali_userspace::BASE_CONTEXT_CREATE_KERNEL_FLAGS;
+
+        if(mali_userspace::mali_ioctl(fd, flags) != 0)
+        {
+            throw std::runtime_error("Failed settings flags ioctl.");
+            close(fd);
+        }
+    }
+
+    {
+        mali_userspace::kbase_uk_gpuprops props;                         // NOLINT
+        props.header.id = mali_userspace::KBASE_FUNC_GPU_PROPS_REG_DUMP; // NOLINT
+
+        if(mali_ioctl(fd, props) != 0)
+        {
+            throw std::runtime_error("Failed settings flags ioctl.");
+            close(fd);
+        }
+
+        MaliHWInfo hw_info; // NOLINT
+        memset(&hw_info, 0, sizeof(hw_info));
+        hw_info.gpu_id  = props.props.core_props.product_id;
+        hw_info.r_value = props.props.core_props.major_revision;
+        hw_info.p_value = props.props.core_props.minor_revision;
+
+        for(unsigned int i = 0; i < props.props.coherency_info.num_core_groups; ++i)
+        {
+            hw_info.core_mask |= props.props.coherency_info.group[i].core_mask;
+        }
+
+        hw_info.mp_count = __builtin_popcountll(hw_info.core_mask);
+
+        close(fd);
+
+        return hw_info;
+    }
+}
+} // namespace
+
+MaliCounter::MaliCounter()
+{
+    _counters =
+    {
+        { "GPU_ACTIVE", TypedMeasurement<uint64_t>(0, "cycles") },
+    };
+
+    _core_counters =
+    {
+        { "ARITH_WORDS", { "Arithmetic pipe", std::map<int, uint64_t>(), "instructions" } },
+        { "LS_ISSUE", { "LS pipe", std::map<int, uint64_t>(), "instructions" } },
+        { "TEX_ISSUE", { "Texture pipe", std::map<int, uint64_t>(), "instructions" } },
+        { "COMPUTE_ACTIVE", { "Compute core", std::map<int, uint64_t>(), "cycles" } },
+        { "FRAG_ACTIVE", { "Fragment core", std::map<int, uint64_t>(), "cycles" } },
+    };
+
+    init();
+}
+
+MaliCounter::~MaliCounter()
+{
+    term();
+}
+
+void MaliCounter::init()
+{
+    term();
+
+    MaliHWInfo hw_info = get_mali_hw_info(_device);
+
+    _num_cores = hw_info.mp_count;
+
+    _fd = open(_device, O_RDWR | O_CLOEXEC | O_NONBLOCK); // NOLINT
+
+    if(_fd < 0)
+    {
+        throw std::runtime_error("Failed to open /dev/mali0.");
+    }
+
+    {
+        mali_userspace::kbase_uk_hwcnt_reader_version_check_args check; // NOLINT
+        memset(&check, 0, sizeof(check));
+
+        if(mali_userspace::mali_ioctl(_fd, check) != 0)
+        {
+            throw std::runtime_error("Failed to get ABI version.");
+        }
+        else if(check.major < 10)
+        {
+            throw std::runtime_error("Unsupported ABI version 10.");
+        }
+    }
+
+    {
+        mali_userspace::kbase_uk_hwcnt_reader_set_flags flags; // NOLINT
+        memset(&flags, 0, sizeof(flags));
+        flags.header.id    = mali_userspace::KBASE_FUNC_SET_FLAGS; // NOLINT
+        flags.create_flags = mali_userspace::BASE_CONTEXT_CREATE_KERNEL_FLAGS;
+
+        if(mali_userspace::mali_ioctl(_fd, flags) != 0)
+        {
+            throw std::runtime_error("Failed settings flags ioctl.");
+        }
+    }
+
+    {
+        mali_userspace::kbase_uk_hwcnt_reader_setup setup; // NOLINT
+        memset(&setup, 0, sizeof(setup));
+        setup.header.id    = mali_userspace::KBASE_FUNC_HWCNT_READER_SETUP; // NOLINT
+        setup.buffer_count = _buffer_count;
+        setup.jm_bm        = -1;
+        setup.shader_bm    = -1;
+        setup.tiler_bm     = -1;
+        setup.mmu_l2_bm    = -1;
+        setup.fd           = -1;
+
+        if(mali_userspace::mali_ioctl(_fd, setup) != 0)
+        {
+            throw std::runtime_error("Failed setting hwcnt reader ioctl.");
+        }
+
+        _hwc_fd = setup.fd;
+    }
+
+    {
+        uint32_t api_version = ~mali_userspace::HWCNT_READER_API;
+
+        if(ioctl(_hwc_fd, mali_userspace::KBASE_HWCNT_READER_GET_API_VERSION, &api_version) != 0) // NOLINT
+        {
+            throw std::runtime_error("Could not determine hwcnt reader API.");
+        }
+        else if(api_version != mali_userspace::HWCNT_READER_API)
+        {
+            throw std::runtime_error("Invalid API version.");
+        }
+    }
+
+    if(ioctl(_hwc_fd, mali_userspace::KBASE_HWCNT_READER_GET_BUFFER_SIZE, &_buffer_size) != 0) // NOLINT
+    {
+        throw std::runtime_error("Failed to get buffer size.");
+    }
+
+    if(ioctl(_hwc_fd, mali_userspace::KBASE_HWCNT_READER_GET_HWVER, &_hw_ver) != 0) // NOLINT
+    {
+        throw std::runtime_error("Could not determine HW version.");
+    }
+
+    if(_hw_ver < 5)
+    {
+        throw std::runtime_error("Unsupported HW version.");
+    }
+
+    _sample_data = static_cast<uint8_t *>(mmap(nullptr, _buffer_count * _buffer_size, PROT_READ, MAP_PRIVATE, _hwc_fd, 0));
+
+    if(_sample_data == MAP_FAILED) // NOLINT
+    {
+        throw std::runtime_error("Failed to map sample data.");
+    }
+
+    auto product = std::find_if(std::begin(mali_userspace::products), std::end(mali_userspace::products), [&](const mali_userspace::CounterMapping & cm)
+    {
+        return (cm.product_mask & hw_info.gpu_id) == cm.product_id;
+    });
+
+    if(product != std::end(mali_userspace::products))
+    {
+        _names_lut = product->names_lut;
+    }
+    else
+    {
+        throw std::runtime_error("Could not identify GPU.");
+    }
+
+    _raw_counter_buffer.resize(_buffer_size / sizeof(uint32_t));
+
+    // Build core remap table.
+    _core_index_remap.clear();
+    _core_index_remap.reserve(hw_info.mp_count);
+
+    unsigned int mask = hw_info.core_mask;
+
+    while(mask != 0)
+    {
+        unsigned int bit = __builtin_ctz(mask);
+        _core_index_remap.push_back(bit);
+        mask &= ~(1u << bit);
+    }
+}
+
+void MaliCounter::term()
+{
+    if(_sample_data != nullptr)
+    {
+        munmap(_sample_data, _buffer_count * _buffer_size);
+        _sample_data = nullptr;
+    }
+
+    if(_hwc_fd >= 0)
+    {
+        close(_hwc_fd);
+        _hwc_fd = -1;
+    }
+
+    if(_fd >= 0)
+    {
+        close(_fd);
+        _fd = -1;
+    }
+}
+
+void MaliCounter::sample_counters()
+{
+    if(ioctl(_hwc_fd, mali_userspace::KBASE_HWCNT_READER_DUMP, 0) != 0)
+    {
+        throw std::runtime_error("Could not sample hardware counters.");
+    }
+}
+
+void MaliCounter::wait_next_event()
+{
+    pollfd poll_fd; // NOLINT
+    poll_fd.fd     = _hwc_fd;
+    poll_fd.events = POLLIN;
+
+    const int count = poll(&poll_fd, 1, -1);
+
+    if(count < 0)
+    {
+        throw std::runtime_error("poll() failed.");
+    }
+
+    if((poll_fd.revents & POLLIN) != 0)
+    {
+        mali_userspace::kbase_hwcnt_reader_metadata meta; // NOLINT
+
+        if(ioctl(_hwc_fd, mali_userspace::KBASE_HWCNT_READER_GET_BUFFER, &meta) != 0) // NOLINT
+        {
+            throw std::runtime_error("Failed READER_GET_BUFFER.");
+        }
+
+        memcpy(_raw_counter_buffer.data(), _sample_data + _buffer_size * meta.buffer_idx, _buffer_size);
+        _timestamp = meta.timestamp;
+
+        if(ioctl(_hwc_fd, mali_userspace::KBASE_HWCNT_READER_PUT_BUFFER, &meta) != 0) // NOLINT
+        {
+            throw std::runtime_error("Failed READER_PUT_BUFFER.");
+        }
+    }
+    else if((poll_fd.revents & POLLHUP) != 0)
+    {
+        throw std::runtime_error("HWC hung up.");
+    }
+}
+
+const uint32_t *MaliCounter::get_counters() const
+{
+    return _raw_counter_buffer.data();
+}
+
+const uint32_t *MaliCounter::get_counters(mali_userspace::MaliCounterBlockName block, int core) const
+{
+    switch(block)
+    {
+        case mali_userspace::MALI_NAME_BLOCK_JM:
+            return _raw_counter_buffer.data() + mali_userspace::MALI_NAME_BLOCK_SIZE * 0;
+        case mali_userspace::MALI_NAME_BLOCK_MMU:
+            return _raw_counter_buffer.data() + mali_userspace::MALI_NAME_BLOCK_SIZE * 2;
+        case mali_userspace::MALI_NAME_BLOCK_TILER:
+            return _raw_counter_buffer.data() + mali_userspace::MALI_NAME_BLOCK_SIZE * 1;
+        default:
+            if(core < 0)
+            {
+                std::runtime_error("Invalid core number.");
+            }
+
+            return _raw_counter_buffer.data() + mali_userspace::MALI_NAME_BLOCK_SIZE * (3 + _core_index_remap[core]);
+    }
+}
+
+int MaliCounter::find_counter_index_by_name(mali_userspace::MaliCounterBlockName block, const char *name)
+{
+    const char *const *names = &_names_lut[mali_userspace::MALI_NAME_BLOCK_SIZE * block];
+
+    for(int i = 0; i < mali_userspace::MALI_NAME_BLOCK_SIZE; ++i)
+    {
+        if(strstr(names[i], name) != nullptr)
+        {
+            return i;
+        }
+    }
+
+    return -1;
+}
+
+void MaliCounter::start()
+{
+    sample_counters();
+    wait_next_event();
+    _start_time = _timestamp;
+}
+
+void MaliCounter::stop()
+{
+    sample_counters();
+    wait_next_event();
+
+    const auto counter               = get_counters(mali_userspace::MALI_NAME_BLOCK_JM);
+    _counters.at("GPU_ACTIVE").value = counter[find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_JM, "GPU_ACTIVE")];
+
+    const int arith_index   = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "ARITH_WORDS");
+    const int ls_index      = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "LS_ISSUE");
+    const int tex_index     = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "TEX_ISSUE");
+    const int compute_index = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "COMPUTE_ACTIVE");
+    const int frag_index    = find_counter_index_by_name(mali_userspace::MALI_NAME_BLOCK_SHADER, "FRAG_ACTIVE");
+
+    // Shader core counters can be averaged if desired, but here we don't.
+    for(int core = 0; core < _num_cores; ++core)
+    {
+        const auto sc_counter = get_counters(mali_userspace::MALI_NAME_BLOCK_SHADER, core);
+
+        _core_counters.at("ARITH_WORDS").values[core]    = sc_counter[arith_index];
+        _core_counters.at("LS_ISSUE").values[core]       = sc_counter[ls_index];
+        _core_counters.at("TEX_ISSUE").values[core]      = sc_counter[tex_index];
+        _core_counters.at("COMPUTE_ACTIVE").values[core] = sc_counter[compute_index];
+        _core_counters.at("FRAG_ACTIVE").values[core]    = sc_counter[frag_index];
+    }
+
+    _stop_time = _timestamp;
+}
+
+std::string MaliCounter::id() const
+{
+    return "Mali Counter";
+}
+
+Instrument::MeasurementsMap MaliCounter::measurements() const
+{
+    MeasurementsMap measurements
+    {
+        { "Timespan", TypedMeasurement<uint64_t>(_stop_time - _start_time, "ns") },
+        { "GPU active", _counters.at("GPU_ACTIVE") },
+    };
+
+    for(const auto &counter : _core_counters)
+    {
+        for(const auto &core : counter.second.values)
+        {
+            measurements.emplace(counter.second.name + " #" + support::cpp11::to_string(core.first), TypedMeasurement<uint64_t>(core.second, counter.second.unit));
+        }
+    }
+
+    return measurements;
+}
+} // namespace framework
+} // namespace test
+} // namespace arm_compute
diff --git a/tests/framework/instruments/MaliCounter.h b/tests/framework/instruments/MaliCounter.h
new file mode 100644
index 0000000..c7aaa3c
--- /dev/null
+++ b/tests/framework/instruments/MaliCounter.h
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef ARM_COMPUTE_TEST_MALI_COUNTER
+#define ARM_COMPUTE_TEST_MALI_COUNTER
+
+#include "Instrument.h"
+#include "Measurement.h"
+#include "hwc.hpp"
+
+#include <map>
+#include <vector>
+
+namespace arm_compute
+{
+namespace test
+{
+namespace framework
+{
+/** Instrument implementation for mali hw counters. */
+class MaliCounter : public Instrument
+{
+public:
+    /** Default constructor. */
+    MaliCounter();
+
+    MaliCounter(const MaliCounter &) = delete;
+    MaliCounter &operator=(const MaliCounter &) = delete;
+
+    /** Default destructor */
+    ~MaliCounter();
+
+    std::string     id() const override;
+    void            start() override;
+    void            stop() override;
+    MeasurementsMap measurements() const override;
+
+private:
+    void init();
+    void term();
+
+    void            sample_counters();
+    void            wait_next_event();
+    const uint32_t *get_counters() const;
+    const uint32_t *get_counters(mali_userspace::MaliCounterBlockName block, int core = -1) const;
+    int find_counter_index_by_name(mali_userspace::MaliCounterBlockName block, const char *name);
+
+    std::map<std::string, TypedMeasurement<uint64_t>> _counters{};
+
+    struct core_counters
+    {
+        std::string name;
+        std::map<int, uint64_t> values;
+        std::string unit;
+    };
+
+    std::map<std::string, core_counters> _core_counters{};
+    uint64_t _start_time{ 0 };
+    uint64_t _stop_time{ 0 };
+
+    const char *const  _device
+    { "/dev/mali0"
+    };
+    int                _num_cores{ 0 };
+    uint32_t           _hw_ver{ 0 };
+    int                _buffer_count{ 16 };
+    size_t             _buffer_size{ 0 };
+    uint8_t           *_sample_data{ nullptr };
+    uint64_t           _timestamp{ 0 };
+    const char *const *_names_lut
+    {
+        nullptr
+    };
+    std::vector<uint32_t>     _raw_counter_buffer{};
+    std::vector<unsigned int> _core_index_remap{};
+    int                       _fd{ -1 };
+    int                       _hwc_fd{ -1 };
+};
+} // namespace framework
+} // namespace test
+} // namespace arm_compute
+#endif /* ARM_COMPUTE_TEST_MALI_COUNTER */
diff --git a/tests/framework/instruments/hwc.hpp b/tests/framework/instruments/hwc.hpp
new file mode 100644
index 0000000..8411576
--- /dev/null
+++ b/tests/framework/instruments/hwc.hpp
@@ -0,0 +1,379 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef ARM_COMPUTE_TEST_HWC
+#define ARM_COMPUTE_TEST_HWC
+
+#include "hwc_names.hpp"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+
+#if defined(ANDROID) || defined(__ANDROID__)
+/* We use _IOR_BAD/_IOW_BAD rather than _IOR/_IOW otherwise fails to compile with NDK-BUILD because of _IOC_TYPECHECK is defined, not because the paramter is invalid */
+#define MALI_IOR(a,b,c)  _IOR_BAD(a, b, c)
+#define MALI_IOW(a,b,c)  _IOW_BAD(a, b, c)
+#else /* defined(ANDROID) || defined(__ANDROID__) */
+#define MALI_IOR(a,b,c)  _IOR(a, b, c)
+#define MALI_IOW(a,b,c)  _IOW(a, b, c)
+#endif /* defined(ANDROID) || defined(__ANDROID__) */
+
+namespace mali_userspace
+{
+union uk_header
+{
+	uint32_t id;
+	uint32_t ret;
+	uint64_t sizer;
+};
+
+#define BASE_GPU_NUM_TEXTURE_FEATURES_REGISTERS 3
+#define BASE_MAX_COHERENT_GROUPS 16
+
+struct mali_base_gpu_core_props
+{
+	uint32_t product_id;
+	uint16_t version_status;
+	uint16_t minor_revision;
+	uint16_t major_revision;
+	uint16_t padding;
+	uint32_t gpu_speed_mhz;
+	uint32_t gpu_freq_khz_max;
+	uint32_t gpu_freq_khz_min;
+	uint32_t log2_program_counter_size;
+	uint32_t texture_features[BASE_GPU_NUM_TEXTURE_FEATURES_REGISTERS];
+	uint64_t gpu_available_memory_size;
+};
+
+struct mali_base_gpu_l2_cache_props
+{
+	uint8_t log2_line_size;
+	uint8_t log2_cache_size;
+	uint8_t num_l2_slices;
+	uint8_t padding[5];
+};
+
+struct mali_base_gpu_tiler_props
+{
+	uint32_t bin_size_bytes;
+	uint32_t max_active_levels;
+};
+
+struct mali_base_gpu_thread_props
+{
+	uint32_t max_threads;
+	uint32_t max_workgroup_size;
+	uint32_t max_barrier_size;
+	uint16_t max_registers;
+	uint8_t max_task_queue;
+	uint8_t max_thread_group_split;
+	uint8_t impl_tech;
+	uint8_t padding[7];
+};
+
+struct mali_base_gpu_coherent_group
+{
+	uint64_t core_mask;
+	uint16_t num_cores;
+	uint16_t padding[3];
+};
+
+struct mali_base_gpu_coherent_group_info
+{
+	uint32_t num_groups;
+	uint32_t num_core_groups;
+	uint32_t coherency;
+	uint32_t padding;
+	mali_base_gpu_coherent_group group[BASE_MAX_COHERENT_GROUPS];
+};
+
+#define GPU_MAX_JOB_SLOTS 16
+struct gpu_raw_gpu_props
+{
+	uint64_t shader_present;
+	uint64_t tiler_present;
+	uint64_t l2_present;
+	uint64_t unused_1;
+
+	uint32_t l2_features;
+	uint32_t suspend_size;
+	uint32_t mem_features;
+	uint32_t mmu_features;
+
+	uint32_t as_present;
+
+	uint32_t js_present;
+	uint32_t js_features[GPU_MAX_JOB_SLOTS];
+	uint32_t tiler_features;
+	uint32_t texture_features[3];
+
+	uint32_t gpu_id;
+
+	uint32_t thread_max_threads;
+	uint32_t thread_max_workgroup_size;
+	uint32_t thread_max_barrier_size;
+	uint32_t thread_features;
+
+	uint32_t coherency_mode;
+};
+
+struct mali_base_gpu_props
+{
+	mali_base_gpu_core_props core_props;
+	mali_base_gpu_l2_cache_props l2_props;
+	uint64_t unused;
+	mali_base_gpu_tiler_props tiler_props;
+	mali_base_gpu_thread_props thread_props;
+	gpu_raw_gpu_props raw_props;
+	mali_base_gpu_coherent_group_info coherency_info;
+};
+
+struct kbase_uk_gpuprops
+{
+	uk_header header;
+	mali_base_gpu_props props;
+};
+
+#define KBASE_GPUPROP_VALUE_SIZE_U8  (0x0)
+#define KBASE_GPUPROP_VALUE_SIZE_U16 (0x1)
+#define KBASE_GPUPROP_VALUE_SIZE_U32 (0x2)
+#define KBASE_GPUPROP_VALUE_SIZE_U64 (0x3)
+
+#define KBASE_GPUPROP_PRODUCT_ID                1
+#define KBASE_GPUPROP_MINOR_REVISION			3
+#define KBASE_GPUPROP_MAJOR_REVISION			4
+
+#define KBASE_GPUPROP_COHERENCY_NUM_GROUPS		61
+#define KBASE_GPUPROP_COHERENCY_NUM_CORE_GROUPS		62
+#define KBASE_GPUPROP_COHERENCY_GROUP_0			64
+#define KBASE_GPUPROP_COHERENCY_GROUP_1			65
+#define KBASE_GPUPROP_COHERENCY_GROUP_2			66
+#define KBASE_GPUPROP_COHERENCY_GROUP_3			67
+#define KBASE_GPUPROP_COHERENCY_GROUP_4			68
+#define KBASE_GPUPROP_COHERENCY_GROUP_5			69
+#define KBASE_GPUPROP_COHERENCY_GROUP_6			70
+#define KBASE_GPUPROP_COHERENCY_GROUP_7			71
+#define KBASE_GPUPROP_COHERENCY_GROUP_8			72
+#define KBASE_GPUPROP_COHERENCY_GROUP_9			73
+#define KBASE_GPUPROP_COHERENCY_GROUP_10		74
+#define KBASE_GPUPROP_COHERENCY_GROUP_11		75
+#define KBASE_GPUPROP_COHERENCY_GROUP_12		76
+#define KBASE_GPUPROP_COHERENCY_GROUP_13		77
+#define KBASE_GPUPROP_COHERENCY_GROUP_14		78
+#define KBASE_GPUPROP_COHERENCY_GROUP_15		79
+
+struct gpu_props
+{
+    uint32_t product_id;
+    uint16_t minor_revision;
+    uint16_t major_revision;
+	uint32_t num_groups;
+    uint32_t num_core_groups;
+    uint64_t core_mask[16];
+};
+
+static const struct {
+    uint32_t type;
+    size_t offset;
+    int size;
+} gpu_property_mapping[] = {
+#define PROP(name, member) \
+	{KBASE_GPUPROP_ ## name, offsetof(struct gpu_props, member), \
+		sizeof(((struct gpu_props*)0)->member)}
+#define PROP2(name, member, off) \
+	{KBASE_GPUPROP_ ## name, offsetof(struct gpu_props, member) + off, \
+		sizeof(((struct gpu_props*)0)->member)}
+        PROP(PRODUCT_ID,                    product_id),
+        PROP(MINOR_REVISION,                minor_revision),
+        PROP(MAJOR_REVISION,                major_revision),
+        PROP(COHERENCY_NUM_GROUPS,          num_groups),
+        PROP(COHERENCY_NUM_CORE_GROUPS,     num_core_groups),
+        PROP2(COHERENCY_GROUP_0,             core_mask, 0),
+        PROP2(COHERENCY_GROUP_1,             core_mask, 1),
+        PROP2(COHERENCY_GROUP_2,             core_mask, 2),
+        PROP2(COHERENCY_GROUP_3,             core_mask, 3),
+        PROP2(COHERENCY_GROUP_4,             core_mask, 4),
+        PROP2(COHERENCY_GROUP_5,             core_mask, 5),
+        PROP2(COHERENCY_GROUP_6,             core_mask, 6),
+        PROP2(COHERENCY_GROUP_7,             core_mask, 7),
+        PROP2(COHERENCY_GROUP_8,             core_mask, 8),
+        PROP2(COHERENCY_GROUP_9,             core_mask, 9),
+        PROP2(COHERENCY_GROUP_10,            core_mask, 10),
+        PROP2(COHERENCY_GROUP_11,            core_mask, 11),
+        PROP2(COHERENCY_GROUP_12,            core_mask, 12),
+        PROP2(COHERENCY_GROUP_13,            core_mask, 13),
+        PROP2(COHERENCY_GROUP_14,            core_mask, 14),
+        PROP2(COHERENCY_GROUP_15,            core_mask, 15),
+#undef PROP
+#undef PROP2
+        {0, 0, 0}
+};
+
+struct kbase_hwcnt_reader_metadata
+{
+    uint64_t timestamp = 0;
+    uint32_t event_id = 0;
+    uint32_t buffer_idx = 0;
+};
+
+namespace
+{
+/** Message header */
+union kbase_uk_hwcnt_header {
+    /* 32-bit number identifying the UK function to be called. */
+    uint32_t id;
+    /* The int return code returned by the called UK function. */
+    uint32_t ret;
+    /* Used to ensure 64-bit alignment of this union. Do not remove. */
+    uint64_t sizer;
+};
+
+/** IOCTL parameters to check version */
+struct kbase_uk_hwcnt_reader_version_check_args {
+    union kbase_uk_hwcnt_header header;
+
+    uint16_t major;
+    uint16_t minor;
+    uint8_t  padding[4];
+};
+
+union kbase_pointer {
+	void *value;
+	uint32_t compat_value;
+	uint64_t sizer;
+};
+
+struct kbase_ioctl_get_gpuprops {
+	kbase_pointer buffer;
+	uint32_t size;
+	uint32_t flags;
+};
+
+#define KBASE_IOCTL_TYPE 0x80
+#define KBASE_IOCTL_GET_GPUPROPS MALI_IOW(KBASE_IOCTL_TYPE, 3, struct kbase_ioctl_get_gpuprops)
+
+/** IOCTL parameters to set flags */
+struct kbase_uk_hwcnt_reader_set_flags {
+    union kbase_uk_hwcnt_header header;
+
+    uint32_t create_flags;
+    uint32_t padding;
+};
+
+/** IOCTL parameters to configure reader */
+struct kbase_uk_hwcnt_reader_setup
+{
+    union kbase_uk_hwcnt_header header;
+
+    /* IN */
+    uint32_t buffer_count;
+    uint32_t jm_bm;
+    uint32_t shader_bm;
+    uint32_t tiler_bm;
+    uint32_t mmu_l2_bm;
+
+    /* OUT */
+    int32_t  fd;
+};
+
+static const uint32_t HWCNT_READER_API = 1;
+
+
+struct uku_version_check_args
+{
+	uk_header header;
+	uint16_t major;
+	uint16_t minor;
+	uint8_t padding[4];
+};
+
+enum {
+	UKP_FUNC_ID_CHECK_VERSION = 0,
+    /* Related to mali0 ioctl interface */
+            LINUX_UK_BASE_MAGIC                 = 0x80,
+    BASE_CONTEXT_CREATE_KERNEL_FLAGS    = 0x2,
+    KBASE_FUNC_HWCNT_UK_FUNC_ID         = 512,
+	KBASE_FUNC_GPU_PROPS_REG_DUMP       = KBASE_FUNC_HWCNT_UK_FUNC_ID + 14,
+    KBASE_FUNC_HWCNT_READER_SETUP       = KBASE_FUNC_HWCNT_UK_FUNC_ID + 36,
+    KBASE_FUNC_HWCNT_DUMP               = KBASE_FUNC_HWCNT_UK_FUNC_ID + 11,
+    KBASE_FUNC_HWCNT_CLEAR              = KBASE_FUNC_HWCNT_UK_FUNC_ID + 12,
+    KBASE_FUNC_SET_FLAGS                = KBASE_FUNC_HWCNT_UK_FUNC_ID + 18,
+
+    /* The ids of ioctl commands for the reader interface */
+            KBASE_HWCNT_READER                  = 0xBE,
+    KBASE_HWCNT_READER_GET_HWVER        = MALI_IOR(KBASE_HWCNT_READER, 0x00, uint32_t),
+    KBASE_HWCNT_READER_GET_BUFFER_SIZE  = MALI_IOR(KBASE_HWCNT_READER, 0x01, uint32_t),
+    KBASE_HWCNT_READER_DUMP             = MALI_IOW(KBASE_HWCNT_READER, 0x10, uint32_t),
+    KBASE_HWCNT_READER_CLEAR            = MALI_IOW(KBASE_HWCNT_READER, 0x11, uint32_t),
+    KBASE_HWCNT_READER_GET_BUFFER       = MALI_IOR(KBASE_HWCNT_READER, 0x20, struct kbase_hwcnt_reader_metadata),
+    KBASE_HWCNT_READER_PUT_BUFFER       = MALI_IOW(KBASE_HWCNT_READER, 0x21, struct kbase_hwcnt_reader_metadata),
+    KBASE_HWCNT_READER_SET_INTERVAL     = MALI_IOW(KBASE_HWCNT_READER, 0x30, uint32_t),
+    KBASE_HWCNT_READER_ENABLE_EVENT     = MALI_IOW(KBASE_HWCNT_READER, 0x40, uint32_t),
+    KBASE_HWCNT_READER_DISABLE_EVENT    = MALI_IOW(KBASE_HWCNT_READER, 0x41, uint32_t),
+    KBASE_HWCNT_READER_GET_API_VERSION  = MALI_IOW(KBASE_HWCNT_READER, 0xFF, uint32_t)
+
+};
+
+enum
+{
+    PIPE_DESCRIPTOR_IN,   /**< The index of a pipe's input descriptor. */
+    PIPE_DESCRIPTOR_OUT,  /**< The index of a pipe's output descriptor. */
+
+    PIPE_DESCRIPTOR_COUNT /**< The number of descriptors forming a pipe. */
+};
+
+enum
+{
+    POLL_DESCRIPTOR_SIGNAL,       /**< The index of the signal descriptor in poll fds array. */
+    POLL_DESCRIPTOR_HWCNT_READER, /**< The index of the hwcnt reader descriptor in poll fds array. */
+
+    POLL_DESCRIPTOR_COUNT         /**< The number of descriptors poll is waiting for. */
+};
+
+/** Write a single byte into the pipe to interrupt the reader thread */
+typedef char poll_data_t;
+}
+
+template<typename T>
+static inline int mali_ioctl(int fd, T &arg)
+{
+    auto *hdr = &arg.header;
+    const int cmd = _IOC(_IOC_READ | _IOC_WRITE, LINUX_UK_BASE_MAGIC, hdr->id, sizeof(T));
+
+    if (ioctl(fd, cmd, &arg))
+        return -1;
+    if (hdr->ret)
+        return -1;
+
+    return 0;
+}
+} // namespace mali_userspace
+#endif /* ARM_COMPUTE_TEST_HWC */
diff --git a/tests/framework/instruments/hwc_names.hpp b/tests/framework/instruments/hwc_names.hpp
new file mode 100644
index 0000000..181af7f
--- /dev/null
+++ b/tests/framework/instruments/hwc_names.hpp
@@ -0,0 +1,3017 @@
+/*
+ * Copyright (c) 2017 ARM Limited.
+ *
+ * SPDX-License-Identifier: MIT
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+#ifndef ARM_COMPUTE_TEST_HWC_NAMES
+#define ARM_COMPUTE_TEST_HWC_NAMES
+
+namespace mali_userspace
+{
+	enum MaliCounterBlockName {
+		MALI_NAME_BLOCK_JM      = 0,
+		MALI_NAME_BLOCK_TILER   = 1,
+		MALI_NAME_BLOCK_SHADER  = 2,
+		MALI_NAME_BLOCK_MMU     = 3
+	};
+
+	enum { MALI_NAME_BLOCK_SIZE = 64 };
+
+    /*
+     * "Short names" for hardware counters used by Streamline. Counters names are
+     * stored in accordance with their memory layout in the binary counter block
+     * emitted by the Mali GPU. Each "master" in the GPU emits a fixed-size block
+     * of 64 counters, and each GPU implements the same set of "masters" although
+     * the counters each master exposes within its block of 64 may vary.
+     *
+     * Counters which are an empty string are simply "holes" in the counter memory
+     * where no counter exists.
+     */
+
+    static const char * const hardware_counters_mali_t60x[] = {
+        /* Job Manager */
+        "",
+        "",
+        "",
+        "",
+        "T60x_MESSAGES_SENT",
+        "T60x_MESSAGES_RECEIVED",
+        "T60x_GPU_ACTIVE",
+        "T60x_IRQ_ACTIVE",
+        "T60x_JS0_JOBS",
+        "T60x_JS0_TASKS",
+        "T60x_JS0_ACTIVE",
+        "",
+        "T60x_JS0_WAIT_READ",
+        "T60x_JS0_WAIT_ISSUE",
+        "T60x_JS0_WAIT_DEPEND",
+        "T60x_JS0_WAIT_FINISH",
+        "T60x_JS1_JOBS",
+        "T60x_JS1_TASKS",
+        "T60x_JS1_ACTIVE",
+        "",
+        "T60x_JS1_WAIT_READ",
+        "T60x_JS1_WAIT_ISSUE",
+        "T60x_JS1_WAIT_DEPEND",
+        "T60x_JS1_WAIT_FINISH",
+        "T60x_JS2_JOBS",
+        "T60x_JS2_TASKS",
+        "T60x_JS2_ACTIVE",
+        "",
+        "T60x_JS2_WAIT_READ",
+        "T60x_JS2_WAIT_ISSUE",
+        "T60x_JS2_WAIT_DEPEND",
+        "T60x_JS2_WAIT_FINISH",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /*Tiler */
+        "",
+        "",
+        "",
+        "T60x_TI_JOBS_PROCESSED",
+        "T60x_TI_TRIANGLES",
+        "T60x_TI_QUADS",
+        "T60x_TI_POLYGONS",
+        "T60x_TI_POINTS",
+        "T60x_TI_LINES",
+        "T60x_TI_VCACHE_HIT",
+        "T60x_TI_VCACHE_MISS",
+        "T60x_TI_FRONT_FACING",
+        "T60x_TI_BACK_FACING",
+        "T60x_TI_PRIM_VISIBLE",
+        "T60x_TI_PRIM_CULLED",
+        "T60x_TI_PRIM_CLIPPED",
+        "T60x_TI_LEVEL0",
+        "T60x_TI_LEVEL1",
+        "T60x_TI_LEVEL2",
+        "T60x_TI_LEVEL3",
+        "T60x_TI_LEVEL4",
+        "T60x_TI_LEVEL5",
+        "T60x_TI_LEVEL6",
+        "T60x_TI_LEVEL7",
+        "T60x_TI_COMMAND_1",
+        "T60x_TI_COMMAND_2",
+        "T60x_TI_COMMAND_3",
+        "T60x_TI_COMMAND_4",
+        "T60x_TI_COMMAND_4_7",
+        "T60x_TI_COMMAND_8_15",
+        "T60x_TI_COMMAND_16_63",
+        "T60x_TI_COMMAND_64",
+        "T60x_TI_COMPRESS_IN",
+        "T60x_TI_COMPRESS_OUT",
+        "T60x_TI_COMPRESS_FLUSH",
+        "T60x_TI_TIMESTAMPS",
+        "T60x_TI_PCACHE_HIT",
+        "T60x_TI_PCACHE_MISS",
+        "T60x_TI_PCACHE_LINE",
+        "T60x_TI_PCACHE_STALL",
+        "T60x_TI_WRBUF_HIT",
+        "T60x_TI_WRBUF_MISS",
+        "T60x_TI_WRBUF_LINE",
+        "T60x_TI_WRBUF_PARTIAL",
+        "T60x_TI_WRBUF_STALL",
+        "T60x_TI_ACTIVE",
+        "T60x_TI_LOADING_DESC",
+        "T60x_TI_INDEX_WAIT",
+        "T60x_TI_INDEX_RANGE_WAIT",
+        "T60x_TI_VERTEX_WAIT",
+        "T60x_TI_PCACHE_WAIT",
+        "T60x_TI_WRBUF_WAIT",
+        "T60x_TI_BUS_READ",
+        "T60x_TI_BUS_WRITE",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T60x_TI_UTLB_STALL",
+        "T60x_TI_UTLB_REPLAY_MISS",
+        "T60x_TI_UTLB_REPLAY_FULL",
+        "T60x_TI_UTLB_NEW_MISS",
+        "T60x_TI_UTLB_HIT",
+
+        /* Shader Core */
+        "",
+        "",
+        "",
+        "",
+        "T60x_FRAG_ACTIVE",
+        "T60x_FRAG_PRIMITIVES",
+        "T60x_FRAG_PRIMITIVES_DROPPED",
+        "T60x_FRAG_CYCLES_DESC",
+        "T60x_FRAG_CYCLES_PLR",
+        "T60x_FRAG_CYCLES_VERT",
+        "T60x_FRAG_CYCLES_TRISETUP",
+        "T60x_FRAG_CYCLES_RAST",
+        "T60x_FRAG_THREADS",
+        "T60x_FRAG_DUMMY_THREADS",
+        "T60x_FRAG_QUADS_RAST",
+        "T60x_FRAG_QUADS_EZS_TEST",
+        "T60x_FRAG_QUADS_EZS_KILLED",
+        "T60x_FRAG_THREADS_LZS_TEST",
+        "T60x_FRAG_THREADS_LZS_KILLED",
+        "T60x_FRAG_CYCLES_NO_TILE",
+        "T60x_FRAG_NUM_TILES",
+        "T60x_FRAG_TRANS_ELIM",
+        "T60x_COMPUTE_ACTIVE",
+        "T60x_COMPUTE_TASKS",
+        "T60x_COMPUTE_THREADS",
+        "T60x_COMPUTE_CYCLES_DESC",
+        "T60x_TRIPIPE_ACTIVE",
+        "T60x_ARITH_WORDS",
+        "T60x_ARITH_CYCLES_REG",
+        "T60x_ARITH_CYCLES_L0",
+        "T60x_ARITH_FRAG_DEPEND",
+        "T60x_LS_WORDS",
+        "T60x_LS_ISSUES",
+        "T60x_LS_RESTARTS",
+        "T60x_LS_REISSUES_MISS",
+        "T60x_LS_REISSUES_VD",
+        "T60x_LS_REISSUE_ATTRIB_MISS",
+        "T60x_LS_NO_WB",
+        "T60x_TEX_WORDS",
+        "T60x_TEX_BUBBLES",
+        "T60x_TEX_WORDS_L0",
+        "T60x_TEX_WORDS_DESC",
+        "T60x_TEX_ISSUES",
+        "T60x_TEX_RECIRC_FMISS",
+        "T60x_TEX_RECIRC_DESC",
+        "T60x_TEX_RECIRC_MULTI",
+        "T60x_TEX_RECIRC_PMISS",
+        "T60x_TEX_RECIRC_CONF",
+        "T60x_LSC_READ_HITS",
+        "T60x_LSC_READ_MISSES",
+        "T60x_LSC_WRITE_HITS",
+        "T60x_LSC_WRITE_MISSES",
+        "T60x_LSC_ATOMIC_HITS",
+        "T60x_LSC_ATOMIC_MISSES",
+        "T60x_LSC_LINE_FETCHES",
+        "T60x_LSC_DIRTY_LINE",
+        "T60x_LSC_SNOOPS",
+        "T60x_AXI_TLB_STALL",
+        "T60x_AXI_TLB_MISS",
+        "T60x_AXI_TLB_TRANSACTION",
+        "T60x_LS_TLB_MISS",
+        "T60x_LS_TLB_HIT",
+        "T60x_AXI_BEATS_READ",
+        "T60x_AXI_BEATS_WRITTEN",
+
+        /*L2 and MMU */
+        "",
+        "",
+        "",
+        "",
+        "T60x_MMU_HIT",
+        "T60x_MMU_NEW_MISS",
+        "T60x_MMU_REPLAY_FULL",
+        "T60x_MMU_REPLAY_MISS",
+        "T60x_MMU_TABLE_WALK",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T60x_UTLB_HIT",
+        "T60x_UTLB_NEW_MISS",
+        "T60x_UTLB_REPLAY_FULL",
+        "T60x_UTLB_REPLAY_MISS",
+        "T60x_UTLB_STALL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T60x_L2_EXT_WRITE_BEATS",
+        "T60x_L2_EXT_READ_BEATS",
+        "T60x_L2_ANY_LOOKUP",
+        "T60x_L2_READ_LOOKUP",
+        "T60x_L2_SREAD_LOOKUP",
+        "T60x_L2_READ_REPLAY",
+        "T60x_L2_READ_SNOOP",
+        "T60x_L2_READ_HIT",
+        "T60x_L2_CLEAN_MISS",
+        "T60x_L2_WRITE_LOOKUP",
+        "T60x_L2_SWRITE_LOOKUP",
+        "T60x_L2_WRITE_REPLAY",
+        "T60x_L2_WRITE_SNOOP",
+        "T60x_L2_WRITE_HIT",
+        "T60x_L2_EXT_READ_FULL",
+        "T60x_L2_EXT_READ_HALF",
+        "T60x_L2_EXT_WRITE_FULL",
+        "T60x_L2_EXT_WRITE_HALF",
+        "T60x_L2_EXT_READ",
+        "T60x_L2_EXT_READ_LINE",
+        "T60x_L2_EXT_WRITE",
+        "T60x_L2_EXT_WRITE_LINE",
+        "T60x_L2_EXT_WRITE_SMALL",
+        "T60x_L2_EXT_BARRIER",
+        "T60x_L2_EXT_AR_STALL",
+        "T60x_L2_EXT_R_BUF_FULL",
+        "T60x_L2_EXT_RD_BUF_FULL",
+        "T60x_L2_EXT_R_RAW",
+        "T60x_L2_EXT_W_STALL",
+        "T60x_L2_EXT_W_BUF_FULL",
+        "T60x_L2_EXT_R_W_HAZARD",
+        "T60x_L2_TAG_HAZARD",
+        "T60x_L2_SNOOP_FULL",
+        "T60x_L2_REPLAY_FULL"
+    };
+    static const char * const hardware_counters_mali_t62x[] = {
+        /* Job Manager */
+        "",
+        "",
+        "",
+        "",
+        "T62x_MESSAGES_SENT",
+        "T62x_MESSAGES_RECEIVED",
+        "T62x_GPU_ACTIVE",
+        "T62x_IRQ_ACTIVE",
+        "T62x_JS0_JOBS",
+        "T62x_JS0_TASKS",
+        "T62x_JS0_ACTIVE",
+        "",
+        "T62x_JS0_WAIT_READ",
+        "T62x_JS0_WAIT_ISSUE",
+        "T62x_JS0_WAIT_DEPEND",
+        "T62x_JS0_WAIT_FINISH",
+        "T62x_JS1_JOBS",
+        "T62x_JS1_TASKS",
+        "T62x_JS1_ACTIVE",
+        "",
+        "T62x_JS1_WAIT_READ",
+        "T62x_JS1_WAIT_ISSUE",
+        "T62x_JS1_WAIT_DEPEND",
+        "T62x_JS1_WAIT_FINISH",
+        "T62x_JS2_JOBS",
+        "T62x_JS2_TASKS",
+        "T62x_JS2_ACTIVE",
+        "",
+        "T62x_JS2_WAIT_READ",
+        "T62x_JS2_WAIT_ISSUE",
+        "T62x_JS2_WAIT_DEPEND",
+        "T62x_JS2_WAIT_FINISH",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /*Tiler */
+        "",
+        "",
+        "",
+        "T62x_TI_JOBS_PROCESSED",
+        "T62x_TI_TRIANGLES",
+        "T62x_TI_QUADS",
+        "T62x_TI_POLYGONS",
+        "T62x_TI_POINTS",
+        "T62x_TI_LINES",
+        "T62x_TI_VCACHE_HIT",
+        "T62x_TI_VCACHE_MISS",
+        "T62x_TI_FRONT_FACING",
+        "T62x_TI_BACK_FACING",
+        "T62x_TI_PRIM_VISIBLE",
+        "T62x_TI_PRIM_CULLED",
+        "T62x_TI_PRIM_CLIPPED",
+        "T62x_TI_LEVEL0",
+        "T62x_TI_LEVEL1",
+        "T62x_TI_LEVEL2",
+        "T62x_TI_LEVEL3",
+        "T62x_TI_LEVEL4",
+        "T62x_TI_LEVEL5",
+        "T62x_TI_LEVEL6",
+        "T62x_TI_LEVEL7",
+        "T62x_TI_COMMAND_1",
+        "T62x_TI_COMMAND_2",
+        "T62x_TI_COMMAND_3",
+        "T62x_TI_COMMAND_4",
+        "T62x_TI_COMMAND_5_7",
+        "T62x_TI_COMMAND_8_15",
+        "T62x_TI_COMMAND_16_63",
+        "T62x_TI_COMMAND_64",
+        "T62x_TI_COMPRESS_IN",
+        "T62x_TI_COMPRESS_OUT",
+        "T62x_TI_COMPRESS_FLUSH",
+        "T62x_TI_TIMESTAMPS",
+        "T62x_TI_PCACHE_HIT",
+        "T62x_TI_PCACHE_MISS",
+        "T62x_TI_PCACHE_LINE",
+        "T62x_TI_PCACHE_STALL",
+        "T62x_TI_WRBUF_HIT",
+        "T62x_TI_WRBUF_MISS",
+        "T62x_TI_WRBUF_LINE",
+        "T62x_TI_WRBUF_PARTIAL",
+        "T62x_TI_WRBUF_STALL",
+        "T62x_TI_ACTIVE",
+        "T62x_TI_LOADING_DESC",
+        "T62x_TI_INDEX_WAIT",
+        "T62x_TI_INDEX_RANGE_WAIT",
+        "T62x_TI_VERTEX_WAIT",
+        "T62x_TI_PCACHE_WAIT",
+        "T62x_TI_WRBUF_WAIT",
+        "T62x_TI_BUS_READ",
+        "T62x_TI_BUS_WRITE",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T62x_TI_UTLB_STALL",
+        "T62x_TI_UTLB_REPLAY_MISS",
+        "T62x_TI_UTLB_REPLAY_FULL",
+        "T62x_TI_UTLB_NEW_MISS",
+        "T62x_TI_UTLB_HIT",
+
+        /* Shader Core */
+        "",
+        "",
+        "",
+        "T62x_SHADER_CORE_ACTIVE",
+        "T62x_FRAG_ACTIVE",
+        "T62x_FRAG_PRIMITIVES",
+        "T62x_FRAG_PRIMITIVES_DROPPED",
+        "T62x_FRAG_CYCLES_DESC",
+        "T62x_FRAG_CYCLES_FPKQ_ACTIVE",
+        "T62x_FRAG_CYCLES_VERT",
+        "T62x_FRAG_CYCLES_TRISETUP",
+        "T62x_FRAG_CYCLES_EZS_ACTIVE",
+        "T62x_FRAG_THREADS",
+        "T62x_FRAG_DUMMY_THREADS",
+        "T62x_FRAG_QUADS_RAST",
+        "T62x_FRAG_QUADS_EZS_TEST",
+        "T62x_FRAG_QUADS_EZS_KILLED",
+        "T62x_FRAG_THREADS_LZS_TEST",
+        "T62x_FRAG_THREADS_LZS_KILLED",
+        "T62x_FRAG_CYCLES_NO_TILE",
+        "T62x_FRAG_NUM_TILES",
+        "T62x_FRAG_TRANS_ELIM",
+        "T62x_COMPUTE_ACTIVE",
+        "T62x_COMPUTE_TASKS",
+        "T62x_COMPUTE_THREADS",
+        "T62x_COMPUTE_CYCLES_DESC",
+        "T62x_TRIPIPE_ACTIVE",
+        "T62x_ARITH_WORDS",
+        "T62x_ARITH_CYCLES_REG",
+        "T62x_ARITH_CYCLES_L0",
+        "T62x_ARITH_FRAG_DEPEND",
+        "T62x_LS_WORDS",
+        "T62x_LS_ISSUES",
+        "T62x_LS_RESTARTS",
+        "T62x_LS_REISSUES_MISS",
+        "T62x_LS_REISSUES_VD",
+        "T62x_LS_REISSUE_ATTRIB_MISS",
+        "T62x_LS_NO_WB",
+        "T62x_TEX_WORDS",
+        "T62x_TEX_BUBBLES",
+        "T62x_TEX_WORDS_L0",
+        "T62x_TEX_WORDS_DESC",
+        "T62x_TEX_ISSUES",
+        "T62x_TEX_RECIRC_FMISS",
+        "T62x_TEX_RECIRC_DESC",
+        "T62x_TEX_RECIRC_MULTI",
+        "T62x_TEX_RECIRC_PMISS",
+        "T62x_TEX_RECIRC_CONF",
+        "T62x_LSC_READ_HITS",
+        "T62x_LSC_READ_MISSES",
+        "T62x_LSC_WRITE_HITS",
+        "T62x_LSC_WRITE_MISSES",
+        "T62x_LSC_ATOMIC_HITS",
+        "T62x_LSC_ATOMIC_MISSES",
+        "T62x_LSC_LINE_FETCHES",
+        "T62x_LSC_DIRTY_LINE",
+        "T62x_LSC_SNOOPS",
+        "T62x_AXI_TLB_STALL",
+        "T62x_AXI_TLB_MISS",
+        "T62x_AXI_TLB_TRANSACTION",
+        "T62x_LS_TLB_MISS",
+        "T62x_LS_TLB_HIT",
+        "T62x_AXI_BEATS_READ",
+        "T62x_AXI_BEATS_WRITTEN",
+
+        /*L2 and MMU */
+        "",
+        "",
+        "",
+        "",
+        "T62x_MMU_HIT",
+        "T62x_MMU_NEW_MISS",
+        "T62x_MMU_REPLAY_FULL",
+        "T62x_MMU_REPLAY_MISS",
+        "T62x_MMU_TABLE_WALK",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T62x_UTLB_HIT",
+        "T62x_UTLB_NEW_MISS",
+        "T62x_UTLB_REPLAY_FULL",
+        "T62x_UTLB_REPLAY_MISS",
+        "T62x_UTLB_STALL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T62x_L2_EXT_WRITE_BEATS",
+        "T62x_L2_EXT_READ_BEATS",
+        "T62x_L2_ANY_LOOKUP",
+        "T62x_L2_READ_LOOKUP",
+        "T62x_L2_SREAD_LOOKUP",
+        "T62x_L2_READ_REPLAY",
+        "T62x_L2_READ_SNOOP",
+        "T62x_L2_READ_HIT",
+        "T62x_L2_CLEAN_MISS",
+        "T62x_L2_WRITE_LOOKUP",
+        "T62x_L2_SWRITE_LOOKUP",
+        "T62x_L2_WRITE_REPLAY",
+        "T62x_L2_WRITE_SNOOP",
+        "T62x_L2_WRITE_HIT",
+        "T62x_L2_EXT_READ_FULL",
+        "T62x_L2_EXT_READ_HALF",
+        "T62x_L2_EXT_WRITE_FULL",
+        "T62x_L2_EXT_WRITE_HALF",
+        "T62x_L2_EXT_READ",
+        "T62x_L2_EXT_READ_LINE",
+        "T62x_L2_EXT_WRITE",
+        "T62x_L2_EXT_WRITE_LINE",
+        "T62x_L2_EXT_WRITE_SMALL",
+        "T62x_L2_EXT_BARRIER",
+        "T62x_L2_EXT_AR_STALL",
+        "T62x_L2_EXT_R_BUF_FULL",
+        "T62x_L2_EXT_RD_BUF_FULL",
+        "T62x_L2_EXT_R_RAW",
+        "T62x_L2_EXT_W_STALL",
+        "T62x_L2_EXT_W_BUF_FULL",
+        "T62x_L2_EXT_R_W_HAZARD",
+        "T62x_L2_TAG_HAZARD",
+        "T62x_L2_SNOOP_FULL",
+        "T62x_L2_REPLAY_FULL"
+    };
+
+    static const char * const hardware_counters_mali_t72x[] = {
+        /* Job Manager */
+        "",
+        "",
+        "",
+        "",
+        "T72x_GPU_ACTIVE",
+        "T72x_IRQ_ACTIVE",
+        "T72x_JS0_JOBS",
+        "T72x_JS0_TASKS",
+        "T72x_JS0_ACTIVE",
+        "T72x_JS1_JOBS",
+        "T72x_JS1_TASKS",
+        "T72x_JS1_ACTIVE",
+        "T72x_JS2_JOBS",
+        "T72x_JS2_TASKS",
+        "T72x_JS2_ACTIVE",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /*Tiler */
+        "",
+        "",
+        "",
+        "T72x_TI_JOBS_PROCESSED",
+        "T72x_TI_TRIANGLES",
+        "T72x_TI_QUADS",
+        "T72x_TI_POLYGONS",
+        "T72x_TI_POINTS",
+        "T72x_TI_LINES",
+        "T72x_TI_FRONT_FACING",
+        "T72x_TI_BACK_FACING",
+        "T72x_TI_PRIM_VISIBLE",
+        "T72x_TI_PRIM_CULLED",
+        "T72x_TI_PRIM_CLIPPED",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T72x_TI_ACTIVE",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /* Shader Core */
+        "",
+        "",
+        "",
+        "",
+        "T72x_FRAG_ACTIVE",
+        "T72x_FRAG_PRIMITIVES",
+        "T72x_FRAG_PRIMITIVES_DROPPED",
+        "T72x_FRAG_THREADS",
+        "T72x_FRAG_DUMMY_THREADS",
+        "T72x_FRAG_QUADS_RAST",
+        "T72x_FRAG_QUADS_EZS_TEST",
+        "T72x_FRAG_QUADS_EZS_KILLED",
+        "T72x_FRAG_THREADS_LZS_TEST",
+        "T72x_FRAG_THREADS_LZS_KILLED",
+        "T72x_FRAG_CYCLES_NO_TILE",
+        "T72x_FRAG_NUM_TILES",
+        "T72x_FRAG_TRANS_ELIM",
+        "T72x_COMPUTE_ACTIVE",
+        "T72x_COMPUTE_TASKS",
+        "T72x_COMPUTE_THREADS",
+        "T72x_TRIPIPE_ACTIVE",
+        "T72x_ARITH_WORDS",
+        "T72x_ARITH_CYCLES_REG",
+        "T72x_LS_WORDS",
+        "T72x_LS_ISSUES",
+        "T72x_LS_RESTARTS",
+        "T72x_LS_REISSUES_MISS",
+        "T72x_TEX_WORDS",
+        "T72x_TEX_BUBBLES",
+        "T72x_TEX_ISSUES",
+        "T72x_LSC_READ_HITS",
+        "T72x_LSC_READ_MISSES",
+        "T72x_LSC_WRITE_HITS",
+        "T72x_LSC_WRITE_MISSES",
+        "T72x_LSC_ATOMIC_HITS",
+        "T72x_LSC_ATOMIC_MISSES",
+        "T72x_LSC_LINE_FETCHES",
+        "T72x_LSC_DIRTY_LINE",
+        "T72x_LSC_SNOOPS",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /*L2 and MMU */
+        "",
+        "",
+        "",
+        "",
+        "T72x_L2_EXT_WRITE_BEAT",
+        "T72x_L2_EXT_READ_BEAT",
+        "T72x_L2_READ_SNOOP",
+        "T72x_L2_READ_HIT",
+        "T72x_L2_WRITE_SNOOP",
+        "T72x_L2_WRITE_HIT",
+        "T72x_L2_EXT_WRITE_SMALL",
+        "T72x_L2_EXT_BARRIER",
+        "T72x_L2_EXT_AR_STALL",
+        "T72x_L2_EXT_W_STALL",
+        "T72x_L2_SNOOP_FULL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        ""
+    };
+
+    static const char * const hardware_counters_mali_t76x[] = {
+        /* Job Manager */
+        "",
+        "",
+        "",
+        "",
+        "T76x_MESSAGES_SENT",
+        "T76x_MESSAGES_RECEIVED",
+        "T76x_GPU_ACTIVE",
+        "T76x_IRQ_ACTIVE",
+        "T76x_JS0_JOBS",
+        "T76x_JS0_TASKS",
+        "T76x_JS0_ACTIVE",
+        "",
+        "T76x_JS0_WAIT_READ",
+        "T76x_JS0_WAIT_ISSUE",
+        "T76x_JS0_WAIT_DEPEND",
+        "T76x_JS0_WAIT_FINISH",
+        "T76x_JS1_JOBS",
+        "T76x_JS1_TASKS",
+        "T76x_JS1_ACTIVE",
+        "",
+        "T76x_JS1_WAIT_READ",
+        "T76x_JS1_WAIT_ISSUE",
+        "T76x_JS1_WAIT_DEPEND",
+        "T76x_JS1_WAIT_FINISH",
+        "T76x_JS2_JOBS",
+        "T76x_JS2_TASKS",
+        "T76x_JS2_ACTIVE",
+        "",
+        "T76x_JS2_WAIT_READ",
+        "T76x_JS2_WAIT_ISSUE",
+        "T76x_JS2_WAIT_DEPEND",
+        "T76x_JS2_WAIT_FINISH",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /*Tiler */
+        "",
+        "",
+        "",
+        "T76x_TI_JOBS_PROCESSED",
+        "T76x_TI_TRIANGLES",
+        "T76x_TI_QUADS",
+        "T76x_TI_POLYGONS",
+        "T76x_TI_POINTS",
+        "T76x_TI_LINES",
+        "T76x_TI_VCACHE_HIT",
+        "T76x_TI_VCACHE_MISS",
+        "T76x_TI_FRONT_FACING",
+        "T76x_TI_BACK_FACING",
+        "T76x_TI_PRIM_VISIBLE",
+        "T76x_TI_PRIM_CULLED",
+        "T76x_TI_PRIM_CLIPPED",
+        "T76x_TI_LEVEL0",
+        "T76x_TI_LEVEL1",
+        "T76x_TI_LEVEL2",
+        "T76x_TI_LEVEL3",
+        "T76x_TI_LEVEL4",
+        "T76x_TI_LEVEL5",
+        "T76x_TI_LEVEL6",
+        "T76x_TI_LEVEL7",
+        "T76x_TI_COMMAND_1",
+        "T76x_TI_COMMAND_2",
+        "T76x_TI_COMMAND_3",
+        "T76x_TI_COMMAND_4",
+        "T76x_TI_COMMAND_5_7",
+        "T76x_TI_COMMAND_8_15",
+        "T76x_TI_COMMAND_16_63",
+        "T76x_TI_COMMAND_64",
+        "T76x_TI_COMPRESS_IN",
+        "T76x_TI_COMPRESS_OUT",
+        "T76x_TI_COMPRESS_FLUSH",
+        "T76x_TI_TIMESTAMPS",
+        "T76x_TI_PCACHE_HIT",
+        "T76x_TI_PCACHE_MISS",
+        "T76x_TI_PCACHE_LINE",
+        "T76x_TI_PCACHE_STALL",
+        "T76x_TI_WRBUF_HIT",
+        "T76x_TI_WRBUF_MISS",
+        "T76x_TI_WRBUF_LINE",
+        "T76x_TI_WRBUF_PARTIAL",
+        "T76x_TI_WRBUF_STALL",
+        "T76x_TI_ACTIVE",
+        "T76x_TI_LOADING_DESC",
+        "T76x_TI_INDEX_WAIT",
+        "T76x_TI_INDEX_RANGE_WAIT",
+        "T76x_TI_VERTEX_WAIT",
+        "T76x_TI_PCACHE_WAIT",
+        "T76x_TI_WRBUF_WAIT",
+        "T76x_TI_BUS_READ",
+        "T76x_TI_BUS_WRITE",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T76x_TI_UTLB_HIT",
+        "T76x_TI_UTLB_NEW_MISS",
+        "T76x_TI_UTLB_REPLAY_FULL",
+        "T76x_TI_UTLB_REPLAY_MISS",
+        "T76x_TI_UTLB_STALL",
+
+        /* Shader Core */
+        "",
+        "",
+        "",
+        "",
+        "T76x_FRAG_ACTIVE",
+        "T76x_FRAG_PRIMITIVES",
+        "T76x_FRAG_PRIMITIVES_DROPPED",
+        "T76x_FRAG_CYCLES_DESC",
+        "T76x_FRAG_CYCLES_FPKQ_ACTIVE",
+        "T76x_FRAG_CYCLES_VERT",
+        "T76x_FRAG_CYCLES_TRISETUP",
+        "T76x_FRAG_CYCLES_EZS_ACTIVE",
+        "T76x_FRAG_THREADS",
+        "T76x_FRAG_DUMMY_THREADS",
+        "T76x_FRAG_QUADS_RAST",
+        "T76x_FRAG_QUADS_EZS_TEST",
+        "T76x_FRAG_QUADS_EZS_KILLED",
+        "T76x_FRAG_THREADS_LZS_TEST",
+        "T76x_FRAG_THREADS_LZS_KILLED",
+        "T76x_FRAG_CYCLES_NO_TILE",
+        "T76x_FRAG_NUM_TILES",
+        "T76x_FRAG_TRANS_ELIM",
+        "T76x_COMPUTE_ACTIVE",
+        "T76x_COMPUTE_TASKS",
+        "T76x_COMPUTE_THREADS",
+        "T76x_COMPUTE_CYCLES_DESC",
+        "T76x_TRIPIPE_ACTIVE",
+        "T76x_ARITH_WORDS",
+        "T76x_ARITH_CYCLES_REG",
+        "T76x_ARITH_CYCLES_L0",
+        "T76x_ARITH_FRAG_DEPEND",
+        "T76x_LS_WORDS",
+        "T76x_LS_ISSUES",
+        "T76x_LS_REISSUE_ATTR",
+        "T76x_LS_REISSUES_VARY",
+        "T76x_LS_VARY_RV_MISS",
+        "T76x_LS_VARY_RV_HIT",
+        "T76x_LS_NO_UNPARK",
+        "T76x_TEX_WORDS",
+        "T76x_TEX_BUBBLES",
+        "T76x_TEX_WORDS_L0",
+        "T76x_TEX_WORDS_DESC",
+        "T76x_TEX_ISSUES",
+        "T76x_TEX_RECIRC_FMISS",
+        "T76x_TEX_RECIRC_DESC",
+        "T76x_TEX_RECIRC_MULTI",
+        "T76x_TEX_RECIRC_PMISS",
+        "T76x_TEX_RECIRC_CONF",
+        "T76x_LSC_READ_HITS",
+        "T76x_LSC_READ_OP",
+        "T76x_LSC_WRITE_HITS",
+        "T76x_LSC_WRITE_OP",
+        "T76x_LSC_ATOMIC_HITS",
+        "T76x_LSC_ATOMIC_OP",
+        "T76x_LSC_LINE_FETCHES",
+        "T76x_LSC_DIRTY_LINE",
+        "T76x_LSC_SNOOPS",
+        "T76x_AXI_TLB_STALL",
+        "T76x_AXI_TLB_MISS",
+        "T76x_AXI_TLB_TRANSACTION",
+        "T76x_LS_TLB_MISS",
+        "T76x_LS_TLB_HIT",
+        "T76x_AXI_BEATS_READ",
+        "T76x_AXI_BEATS_WRITTEN",
+
+        /*L2 and MMU */
+        "",
+        "",
+        "",
+        "",
+        "T76x_MMU_HIT",
+        "T76x_MMU_NEW_MISS",
+        "T76x_MMU_REPLAY_FULL",
+        "T76x_MMU_REPLAY_MISS",
+        "T76x_MMU_TABLE_WALK",
+        "T76x_MMU_REQUESTS",
+        "",
+        "",
+        "T76x_UTLB_HIT",
+        "T76x_UTLB_NEW_MISS",
+        "T76x_UTLB_REPLAY_FULL",
+        "T76x_UTLB_REPLAY_MISS",
+        "T76x_UTLB_STALL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T76x_L2_EXT_WRITE_BEATS",
+        "T76x_L2_EXT_READ_BEATS",
+        "T76x_L2_ANY_LOOKUP",
+        "T76x_L2_READ_LOOKUP",
+        "T76x_L2_SREAD_LOOKUP",
+        "T76x_L2_READ_REPLAY",
+        "T76x_L2_READ_SNOOP",
+        "T76x_L2_READ_HIT",
+        "T76x_L2_CLEAN_MISS",
+        "T76x_L2_WRITE_LOOKUP",
+        "T76x_L2_SWRITE_LOOKUP",
+        "T76x_L2_WRITE_REPLAY",
+        "T76x_L2_WRITE_SNOOP",
+        "T76x_L2_WRITE_HIT",
+        "T76x_L2_EXT_READ_FULL",
+        "",
+        "T76x_L2_EXT_WRITE_FULL",
+        "T76x_L2_EXT_R_W_HAZARD",
+        "T76x_L2_EXT_READ",
+        "T76x_L2_EXT_READ_LINE",
+        "T76x_L2_EXT_WRITE",
+        "T76x_L2_EXT_WRITE_LINE",
+        "T76x_L2_EXT_WRITE_SMALL",
+        "T76x_L2_EXT_BARRIER",
+        "T76x_L2_EXT_AR_STALL",
+        "T76x_L2_EXT_R_BUF_FULL",
+        "T76x_L2_EXT_RD_BUF_FULL",
+        "T76x_L2_EXT_R_RAW",
+        "T76x_L2_EXT_W_STALL",
+        "T76x_L2_EXT_W_BUF_FULL",
+        "T76x_L2_EXT_R_BUF_FULL",
+        "T76x_L2_TAG_HAZARD",
+        "T76x_L2_SNOOP_FULL",
+        "T76x_L2_REPLAY_FULL"
+    };
+
+    static const char * const hardware_counters_mali_t82x[] = {
+        /* Job Manager */
+        "",
+        "",
+        "",
+        "",
+        "T82x_MESSAGES_SENT",
+        "T82x_MESSAGES_RECEIVED",
+        "T82x_GPU_ACTIVE",
+        "T82x_IRQ_ACTIVE",
+        "T82x_JS0_JOBS",
+        "T82x_JS0_TASKS",
+        "T82x_JS0_ACTIVE",
+        "",
+        "T82x_JS0_WAIT_READ",
+        "T82x_JS0_WAIT_ISSUE",
+        "T82x_JS0_WAIT_DEPEND",
+        "T82x_JS0_WAIT_FINISH",
+        "T82x_JS1_JOBS",
+        "T82x_JS1_TASKS",
+        "T82x_JS1_ACTIVE",
+        "",
+        "T82x_JS1_WAIT_READ",
+        "T82x_JS1_WAIT_ISSUE",
+        "T82x_JS1_WAIT_DEPEND",
+        "T82x_JS1_WAIT_FINISH",
+        "T82x_JS2_JOBS",
+        "T82x_JS2_TASKS",
+        "T82x_JS2_ACTIVE",
+        "",
+        "T82x_JS2_WAIT_READ",
+        "T82x_JS2_WAIT_ISSUE",
+        "T82x_JS2_WAIT_DEPEND",
+        "T82x_JS2_WAIT_FINISH",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /*Tiler */
+        "",
+        "",
+        "",
+        "T82x_TI_JOBS_PROCESSED",
+        "T82x_TI_TRIANGLES",
+        "T82x_TI_QUADS",
+        "T82x_TI_POLYGONS",
+        "T82x_TI_POINTS",
+        "T82x_TI_LINES",
+        "T82x_TI_FRONT_FACING",
+        "T82x_TI_BACK_FACING",
+        "T82x_TI_PRIM_VISIBLE",
+        "T82x_TI_PRIM_CULLED",
+        "T82x_TI_PRIM_CLIPPED",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T82x_TI_ACTIVE",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /* Shader Core */
+        "",
+        "",
+        "",
+        "",
+        "T82x_FRAG_ACTIVE",
+        "T82x_FRAG_PRIMITIVES",
+        "T82x_FRAG_PRIMITIVES_DROPPED",
+        "T82x_FRAG_CYCLES_DESC",
+        "T82x_FRAG_CYCLES_FPKQ_ACTIVE",
+        "T82x_FRAG_CYCLES_VERT",
+        "T82x_FRAG_CYCLES_TRISETUP",
+        "T82x_FRAG_CYCLES_EZS_ACTIVE",
+        "T82x_FRAG_THREADS",
+        "T82x_FRAG_DUMMY_THREADS",
+        "T82x_FRAG_QUADS_RAST",
+        "T82x_FRAG_QUADS_EZS_TEST",
+        "T82x_FRAG_QUADS_EZS_KILLED",
+        "T82x_FRAG_THREADS_LZS_TEST",
+        "T82x_FRAG_THREADS_LZS_KILLED",
+        "T82x_FRAG_CYCLES_NO_TILE",
+        "T82x_FRAG_NUM_TILES",
+        "T82x_FRAG_TRANS_ELIM",
+        "T82x_COMPUTE_ACTIVE",
+        "T82x_COMPUTE_TASKS",
+        "T82x_COMPUTE_THREADS",
+        "T82x_COMPUTE_CYCLES_DESC",
+        "T82x_TRIPIPE_ACTIVE",
+        "T82x_ARITH_WORDS",
+        "T82x_ARITH_CYCLES_REG",
+        "T82x_ARITH_CYCLES_L0",
+        "T82x_ARITH_FRAG_DEPEND",
+        "T82x_LS_WORDS",
+        "T82x_LS_ISSUES",
+        "T82x_LS_REISSUE_ATTR",
+        "T82x_LS_REISSUES_VARY",
+        "T82x_LS_VARY_RV_MISS",
+        "T82x_LS_VARY_RV_HIT",
+        "T82x_LS_NO_UNPARK",
+        "T82x_TEX_WORDS",
+        "T82x_TEX_BUBBLES",
+        "T82x_TEX_WORDS_L0",
+        "T82x_TEX_WORDS_DESC",
+        "T82x_TEX_ISSUES",
+        "T82x_TEX_RECIRC_FMISS",
+        "T82x_TEX_RECIRC_DESC",
+        "T82x_TEX_RECIRC_MULTI",
+        "T82x_TEX_RECIRC_PMISS",
+        "T82x_TEX_RECIRC_CONF",
+        "T82x_LSC_READ_HITS",
+        "T82x_LSC_READ_OP",
+        "T82x_LSC_WRITE_HITS",
+        "T82x_LSC_WRITE_OP",
+        "T82x_LSC_ATOMIC_HITS",
+        "T82x_LSC_ATOMIC_OP",
+        "T82x_LSC_LINE_FETCHES",
+        "T82x_LSC_DIRTY_LINE",
+        "T82x_LSC_SNOOPS",
+        "T82x_AXI_TLB_STALL",
+        "T82x_AXI_TLB_MISS",
+        "T82x_AXI_TLB_TRANSACTION",
+        "T82x_LS_TLB_MISS",
+        "T82x_LS_TLB_HIT",
+        "T82x_AXI_BEATS_READ",
+        "T82x_AXI_BEATS_WRITTEN",
+
+        /*L2 and MMU */
+        "",
+        "",
+        "",
+        "",
+        "T82x_MMU_HIT",
+        "T82x_MMU_NEW_MISS",
+        "T82x_MMU_REPLAY_FULL",
+        "T82x_MMU_REPLAY_MISS",
+        "T82x_MMU_TABLE_WALK",
+        "T82x_MMU_REQUESTS",
+        "",
+        "",
+        "T82x_UTLB_HIT",
+        "T82x_UTLB_NEW_MISS",
+        "T82x_UTLB_REPLAY_FULL",
+        "T82x_UTLB_REPLAY_MISS",
+        "T82x_UTLB_STALL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T82x_L2_EXT_WRITE_BEATS",
+        "T82x_L2_EXT_READ_BEATS",
+        "T82x_L2_ANY_LOOKUP",
+        "T82x_L2_READ_LOOKUP",
+        "T82x_L2_SREAD_LOOKUP",
+        "T82x_L2_READ_REPLAY",
+        "T82x_L2_READ_SNOOP",
+        "T82x_L2_READ_HIT",
+        "T82x_L2_CLEAN_MISS",
+        "T82x_L2_WRITE_LOOKUP",
+        "T82x_L2_SWRITE_LOOKUP",
+        "T82x_L2_WRITE_REPLAY",
+        "T82x_L2_WRITE_SNOOP",
+        "T82x_L2_WRITE_HIT",
+        "T82x_L2_EXT_READ_FULL",
+        "",
+        "T82x_L2_EXT_WRITE_FULL",
+        "T82x_L2_EXT_R_W_HAZARD",
+        "T82x_L2_EXT_READ",
+        "T82x_L2_EXT_READ_LINE",
+        "T82x_L2_EXT_WRITE",
+        "T82x_L2_EXT_WRITE_LINE",
+        "T82x_L2_EXT_WRITE_SMALL",
+        "T82x_L2_EXT_BARRIER",
+        "T82x_L2_EXT_AR_STALL",
+        "T82x_L2_EXT_R_BUF_FULL",
+        "T82x_L2_EXT_RD_BUF_FULL",
+        "T82x_L2_EXT_R_RAW",
+        "T82x_L2_EXT_W_STALL",
+        "T82x_L2_EXT_W_BUF_FULL",
+        "T82x_L2_EXT_R_BUF_FULL",
+        "T82x_L2_TAG_HAZARD",
+        "T82x_L2_SNOOP_FULL",
+        "T82x_L2_REPLAY_FULL"
+    };
+
+    static const char * const hardware_counters_mali_t83x[] = {
+        /* Job Manager */
+        "",
+        "",
+        "",
+        "",
+        "T83x_MESSAGES_SENT",
+        "T83x_MESSAGES_RECEIVED",
+        "T83x_GPU_ACTIVE",
+        "T83x_IRQ_ACTIVE",
+        "T83x_JS0_JOBS",
+        "T83x_JS0_TASKS",
+        "T83x_JS0_ACTIVE",
+        "",
+        "T83x_JS0_WAIT_READ",
+        "T83x_JS0_WAIT_ISSUE",
+        "T83x_JS0_WAIT_DEPEND",
+        "T83x_JS0_WAIT_FINISH",
+        "T83x_JS1_JOBS",
+        "T83x_JS1_TASKS",
+        "T83x_JS1_ACTIVE",
+        "",
+        "T83x_JS1_WAIT_READ",
+        "T83x_JS1_WAIT_ISSUE",
+        "T83x_JS1_WAIT_DEPEND",
+        "T83x_JS1_WAIT_FINISH",
+        "T83x_JS2_JOBS",
+        "T83x_JS2_TASKS",
+        "T83x_JS2_ACTIVE",
+        "",
+        "T83x_JS2_WAIT_READ",
+        "T83x_JS2_WAIT_ISSUE",
+        "T83x_JS2_WAIT_DEPEND",
+        "T83x_JS2_WAIT_FINISH",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /*Tiler */
+        "",
+        "",
+        "",
+        "T83x_TI_JOBS_PROCESSED",
+        "T83x_TI_TRIANGLES",
+        "T83x_TI_QUADS",
+        "T83x_TI_POLYGONS",
+        "T83x_TI_POINTS",
+        "T83x_TI_LINES",
+        "T83x_TI_FRONT_FACING",
+        "T83x_TI_BACK_FACING",
+        "T83x_TI_PRIM_VISIBLE",
+        "T83x_TI_PRIM_CULLED",
+        "T83x_TI_PRIM_CLIPPED",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T83x_TI_ACTIVE",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /* Shader Core */
+        "",
+        "",
+        "",
+        "",
+        "T83x_FRAG_ACTIVE",
+        "T83x_FRAG_PRIMITIVES",
+        "T83x_FRAG_PRIMITIVES_DROPPED",
+        "T83x_FRAG_CYCLES_DESC",
+        "T83x_FRAG_CYCLES_FPKQ_ACTIVE",
+        "T83x_FRAG_CYCLES_VERT",
+        "T83x_FRAG_CYCLES_TRISETUP",
+        "T83x_FRAG_CYCLES_EZS_ACTIVE",
+        "T83x_FRAG_THREADS",
+        "T83x_FRAG_DUMMY_THREADS",
+        "T83x_FRAG_QUADS_RAST",
+        "T83x_FRAG_QUADS_EZS_TEST",
+        "T83x_FRAG_QUADS_EZS_KILLED",
+        "T83x_FRAG_THREADS_LZS_TEST",
+        "T83x_FRAG_THREADS_LZS_KILLED",
+        "T83x_FRAG_CYCLES_NO_TILE",
+        "T83x_FRAG_NUM_TILES",
+        "T83x_FRAG_TRANS_ELIM",
+        "T83x_COMPUTE_ACTIVE",
+        "T83x_COMPUTE_TASKS",
+        "T83x_COMPUTE_THREADS",
+        "T83x_COMPUTE_CYCLES_DESC",
+        "T83x_TRIPIPE_ACTIVE",
+        "T83x_ARITH_WORDS",
+        "T83x_ARITH_CYCLES_REG",
+        "T83x_ARITH_CYCLES_L0",
+        "T83x_ARITH_FRAG_DEPEND",
+        "T83x_LS_WORDS",
+        "T83x_LS_ISSUES",
+        "T83x_LS_REISSUE_ATTR",
+        "T83x_LS_REISSUES_VARY",
+        "T83x_LS_VARY_RV_MISS",
+        "T83x_LS_VARY_RV_HIT",
+        "T83x_LS_NO_UNPARK",
+        "T83x_TEX_WORDS",
+        "T83x_TEX_BUBBLES",
+        "T83x_TEX_WORDS_L0",
+        "T83x_TEX_WORDS_DESC",
+        "T83x_TEX_ISSUES",
+        "T83x_TEX_RECIRC_FMISS",
+        "T83x_TEX_RECIRC_DESC",
+        "T83x_TEX_RECIRC_MULTI",
+        "T83x_TEX_RECIRC_PMISS",
+        "T83x_TEX_RECIRC_CONF",
+        "T83x_LSC_READ_HITS",
+        "T83x_LSC_READ_OP",
+        "T83x_LSC_WRITE_HITS",
+        "T83x_LSC_WRITE_OP",
+        "T83x_LSC_ATOMIC_HITS",
+        "T83x_LSC_ATOMIC_OP",
+        "T83x_LSC_LINE_FETCHES",
+        "T83x_LSC_DIRTY_LINE",
+        "T83x_LSC_SNOOPS",
+        "T83x_AXI_TLB_STALL",
+        "T83x_AXI_TLB_MISS",
+        "T83x_AXI_TLB_TRANSACTION",
+        "T83x_LS_TLB_MISS",
+        "T83x_LS_TLB_HIT",
+        "T83x_AXI_BEATS_READ",
+        "T83x_AXI_BEATS_WRITTEN",
+
+        /*L2 and MMU */
+        "",
+        "",
+        "",
+        "",
+        "T83x_MMU_HIT",
+        "T83x_MMU_NEW_MISS",
+        "T83x_MMU_REPLAY_FULL",
+        "T83x_MMU_REPLAY_MISS",
+        "T83x_MMU_TABLE_WALK",
+        "T83x_MMU_REQUESTS",
+        "",
+        "",
+        "T83x_UTLB_HIT",
+        "T83x_UTLB_NEW_MISS",
+        "T83x_UTLB_REPLAY_FULL",
+        "T83x_UTLB_REPLAY_MISS",
+        "T83x_UTLB_STALL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T83x_L2_EXT_WRITE_BEATS",
+        "T83x_L2_EXT_READ_BEATS",
+        "T83x_L2_ANY_LOOKUP",
+        "T83x_L2_READ_LOOKUP",
+        "T83x_L2_SREAD_LOOKUP",
+        "T83x_L2_READ_REPLAY",
+        "T83x_L2_READ_SNOOP",
+        "T83x_L2_READ_HIT",
+        "T83x_L2_CLEAN_MISS",
+        "T83x_L2_WRITE_LOOKUP",
+        "T83x_L2_SWRITE_LOOKUP",
+        "T83x_L2_WRITE_REPLAY",
+        "T83x_L2_WRITE_SNOOP",
+        "T83x_L2_WRITE_HIT",
+        "T83x_L2_EXT_READ_FULL",
+        "",
+        "T83x_L2_EXT_WRITE_FULL",
+        "T83x_L2_EXT_R_W_HAZARD",
+        "T83x_L2_EXT_READ",
+        "T83x_L2_EXT_READ_LINE",
+        "T83x_L2_EXT_WRITE",
+        "T83x_L2_EXT_WRITE_LINE",
+        "T83x_L2_EXT_WRITE_SMALL",
+        "T83x_L2_EXT_BARRIER",
+        "T83x_L2_EXT_AR_STALL",
+        "T83x_L2_EXT_R_BUF_FULL",
+        "T83x_L2_EXT_RD_BUF_FULL",
+        "T83x_L2_EXT_R_RAW",
+        "T83x_L2_EXT_W_STALL",
+        "T83x_L2_EXT_W_BUF_FULL",
+        "T83x_L2_EXT_R_BUF_FULL",
+        "T83x_L2_TAG_HAZARD",
+        "T83x_L2_SNOOP_FULL",
+        "T83x_L2_REPLAY_FULL"
+    };
+
+    static const char * const hardware_counters_mali_t86x[] = {
+        /* Job Manager */
+        "",
+        "",
+        "",
+        "",
+        "T86x_MESSAGES_SENT",
+        "T86x_MESSAGES_RECEIVED",
+        "T86x_GPU_ACTIVE",
+        "T86x_IRQ_ACTIVE",
+        "T86x_JS0_JOBS",
+        "T86x_JS0_TASKS",
+        "T86x_JS0_ACTIVE",
+        "",
+        "T86x_JS0_WAIT_READ",
+        "T86x_JS0_WAIT_ISSUE",
+        "T86x_JS0_WAIT_DEPEND",
+        "T86x_JS0_WAIT_FINISH",
+        "T86x_JS1_JOBS",
+        "T86x_JS1_TASKS",
+        "T86x_JS1_ACTIVE",
+        "",
+        "T86x_JS1_WAIT_READ",
+        "T86x_JS1_WAIT_ISSUE",
+        "T86x_JS1_WAIT_DEPEND",
+        "T86x_JS1_WAIT_FINISH",
+        "T86x_JS2_JOBS",
+        "T86x_JS2_TASKS",
+        "T86x_JS2_ACTIVE",
+        "",
+        "T86x_JS2_WAIT_READ",
+        "T86x_JS2_WAIT_ISSUE",
+        "T86x_JS2_WAIT_DEPEND",
+        "T86x_JS2_WAIT_FINISH",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /*Tiler */
+        "",
+        "",
+        "",
+        "T86x_TI_JOBS_PROCESSED",
+        "T86x_TI_TRIANGLES",
+        "T86x_TI_QUADS",
+        "T86x_TI_POLYGONS",
+        "T86x_TI_POINTS",
+        "T86x_TI_LINES",
+        "T86x_TI_VCACHE_HIT",
+        "T86x_TI_VCACHE_MISS",
+        "T86x_TI_FRONT_FACING",
+        "T86x_TI_BACK_FACING",
+        "T86x_TI_PRIM_VISIBLE",
+        "T86x_TI_PRIM_CULLED",
+        "T86x_TI_PRIM_CLIPPED",
+        "T86x_TI_LEVEL0",
+        "T86x_TI_LEVEL1",
+        "T86x_TI_LEVEL2",
+        "T86x_TI_LEVEL3",
+        "T86x_TI_LEVEL4",
+        "T86x_TI_LEVEL5",
+        "T86x_TI_LEVEL6",
+        "T86x_TI_LEVEL7",
+        "T86x_TI_COMMAND_1",
+        "T86x_TI_COMMAND_2",
+        "T86x_TI_COMMAND_3",
+        "T86x_TI_COMMAND_4",
+        "T86x_TI_COMMAND_5_7",
+        "T86x_TI_COMMAND_8_15",
+        "T86x_TI_COMMAND_16_63",
+        "T86x_TI_COMMAND_64",
+        "T86x_TI_COMPRESS_IN",
+        "T86x_TI_COMPRESS_OUT",
+        "T86x_TI_COMPRESS_FLUSH",
+        "T86x_TI_TIMESTAMPS",
+        "T86x_TI_PCACHE_HIT",
+        "T86x_TI_PCACHE_MISS",
+        "T86x_TI_PCACHE_LINE",
+        "T86x_TI_PCACHE_STALL",
+        "T86x_TI_WRBUF_HIT",
+        "T86x_TI_WRBUF_MISS",
+        "T86x_TI_WRBUF_LINE",
+        "T86x_TI_WRBUF_PARTIAL",
+        "T86x_TI_WRBUF_STALL",
+        "T86x_TI_ACTIVE",
+        "T86x_TI_LOADING_DESC",
+        "T86x_TI_INDEX_WAIT",
+        "T86x_TI_INDEX_RANGE_WAIT",
+        "T86x_TI_VERTEX_WAIT",
+        "T86x_TI_PCACHE_WAIT",
+        "T86x_TI_WRBUF_WAIT",
+        "T86x_TI_BUS_READ",
+        "T86x_TI_BUS_WRITE",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T86x_TI_UTLB_HIT",
+        "T86x_TI_UTLB_NEW_MISS",
+        "T86x_TI_UTLB_REPLAY_FULL",
+        "T86x_TI_UTLB_REPLAY_MISS",
+        "T86x_TI_UTLB_STALL",
+
+        /* Shader Core */
+        "",
+        "",
+        "",
+        "",
+        "T86x_FRAG_ACTIVE",
+        "T86x_FRAG_PRIMITIVES",
+        "T86x_FRAG_PRIMITIVES_DROPPED",
+        "T86x_FRAG_CYCLES_DESC",
+        "T86x_FRAG_CYCLES_FPKQ_ACTIVE",
+        "T86x_FRAG_CYCLES_VERT",
+        "T86x_FRAG_CYCLES_TRISETUP",
+        "T86x_FRAG_CYCLES_EZS_ACTIVE",
+        "T86x_FRAG_THREADS",
+        "T86x_FRAG_DUMMY_THREADS",
+        "T86x_FRAG_QUADS_RAST",
+        "T86x_FRAG_QUADS_EZS_TEST",
+        "T86x_FRAG_QUADS_EZS_KILLED",
+        "T86x_FRAG_THREADS_LZS_TEST",
+        "T86x_FRAG_THREADS_LZS_KILLED",
+        "T86x_FRAG_CYCLES_NO_TILE",
+        "T86x_FRAG_NUM_TILES",
+        "T86x_FRAG_TRANS_ELIM",
+        "T86x_COMPUTE_ACTIVE",
+        "T86x_COMPUTE_TASKS",
+        "T86x_COMPUTE_THREADS",
+        "T86x_COMPUTE_CYCLES_DESC",
+        "T86x_TRIPIPE_ACTIVE",
+        "T86x_ARITH_WORDS",
+        "T86x_ARITH_CYCLES_REG",
+        "T86x_ARITH_CYCLES_L0",
+        "T86x_ARITH_FRAG_DEPEND",
+        "T86x_LS_WORDS",
+        "T86x_LS_ISSUES",
+        "T86x_LS_REISSUE_ATTR",
+        "T86x_LS_REISSUES_VARY",
+        "T86x_LS_VARY_RV_MISS",
+        "T86x_LS_VARY_RV_HIT",
+        "T86x_LS_NO_UNPARK",
+        "T86x_TEX_WORDS",
+        "T86x_TEX_BUBBLES",
+        "T86x_TEX_WORDS_L0",
+        "T86x_TEX_WORDS_DESC",
+        "T86x_TEX_ISSUES",
+        "T86x_TEX_RECIRC_FMISS",
+        "T86x_TEX_RECIRC_DESC",
+        "T86x_TEX_RECIRC_MULTI",
+        "T86x_TEX_RECIRC_PMISS",
+        "T86x_TEX_RECIRC_CONF",
+        "T86x_LSC_READ_HITS",
+        "T86x_LSC_READ_OP",
+        "T86x_LSC_WRITE_HITS",
+        "T86x_LSC_WRITE_OP",
+        "T86x_LSC_ATOMIC_HITS",
+        "T86x_LSC_ATOMIC_OP",
+        "T86x_LSC_LINE_FETCHES",
+        "T86x_LSC_DIRTY_LINE",
+        "T86x_LSC_SNOOPS",
+        "T86x_AXI_TLB_STALL",
+        "T86x_AXI_TLB_MISS",
+        "T86x_AXI_TLB_TRANSACTION",
+        "T86x_LS_TLB_MISS",
+        "T86x_LS_TLB_HIT",
+        "T86x_AXI_BEATS_READ",
+        "T86x_AXI_BEATS_WRITTEN",
+
+        /*L2 and MMU */
+        "",
+        "",
+        "",
+        "",
+        "T86x_MMU_HIT",
+        "T86x_MMU_NEW_MISS",
+        "T86x_MMU_REPLAY_FULL",
+        "T86x_MMU_REPLAY_MISS",
+        "T86x_MMU_TABLE_WALK",
+        "T86x_MMU_REQUESTS",
+        "",
+        "",
+        "T86x_UTLB_HIT",
+        "T86x_UTLB_NEW_MISS",
+        "T86x_UTLB_REPLAY_FULL",
+        "T86x_UTLB_REPLAY_MISS",
+        "T86x_UTLB_STALL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T86x_L2_EXT_WRITE_BEATS",
+        "T86x_L2_EXT_READ_BEATS",
+        "T86x_L2_ANY_LOOKUP",
+        "T86x_L2_READ_LOOKUP",
+        "T86x_L2_SREAD_LOOKUP",
+        "T86x_L2_READ_REPLAY",
+        "T86x_L2_READ_SNOOP",
+        "T86x_L2_READ_HIT",
+        "T86x_L2_CLEAN_MISS",
+        "T86x_L2_WRITE_LOOKUP",
+        "T86x_L2_SWRITE_LOOKUP",
+        "T86x_L2_WRITE_REPLAY",
+        "T86x_L2_WRITE_SNOOP",
+        "T86x_L2_WRITE_HIT",
+        "T86x_L2_EXT_READ_FULL",
+        "",
+        "T86x_L2_EXT_WRITE_FULL",
+        "T86x_L2_EXT_R_W_HAZARD",
+        "T86x_L2_EXT_READ",
+        "T86x_L2_EXT_READ_LINE",
+        "T86x_L2_EXT_WRITE",
+        "T86x_L2_EXT_WRITE_LINE",
+        "T86x_L2_EXT_WRITE_SMALL",
+        "T86x_L2_EXT_BARRIER",
+        "T86x_L2_EXT_AR_STALL",
+        "T86x_L2_EXT_R_BUF_FULL",
+        "T86x_L2_EXT_RD_BUF_FULL",
+        "T86x_L2_EXT_R_RAW",
+        "T86x_L2_EXT_W_STALL",
+        "T86x_L2_EXT_W_BUF_FULL",
+        "T86x_L2_EXT_R_BUF_FULL",
+        "T86x_L2_TAG_HAZARD",
+        "T86x_L2_SNOOP_FULL",
+        "T86x_L2_REPLAY_FULL"
+    };
+
+    static const char * const hardware_counters_mali_t88x[] = {
+        /* Job Manager */
+        "",
+        "",
+        "",
+        "",
+        "T88x_MESSAGES_SENT",
+        "T88x_MESSAGES_RECEIVED",
+        "T88x_GPU_ACTIVE",
+        "T88x_IRQ_ACTIVE",
+        "T88x_JS0_JOBS",
+        "T88x_JS0_TASKS",
+        "T88x_JS0_ACTIVE",
+        "",
+        "T88x_JS0_WAIT_READ",
+        "T88x_JS0_WAIT_ISSUE",
+        "T88x_JS0_WAIT_DEPEND",
+        "T88x_JS0_WAIT_FINISH",
+        "T88x_JS1_JOBS",
+        "T88x_JS1_TASKS",
+        "T88x_JS1_ACTIVE",
+        "",
+        "T88x_JS1_WAIT_READ",
+        "T88x_JS1_WAIT_ISSUE",
+        "T88x_JS1_WAIT_DEPEND",
+        "T88x_JS1_WAIT_FINISH",
+        "T88x_JS2_JOBS",
+        "T88x_JS2_TASKS",
+        "T88x_JS2_ACTIVE",
+        "",
+        "T88x_JS2_WAIT_READ",
+        "T88x_JS2_WAIT_ISSUE",
+        "T88x_JS2_WAIT_DEPEND",
+        "T88x_JS2_WAIT_FINISH",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /*Tiler */
+        "",
+        "",
+        "",
+        "T88x_TI_JOBS_PROCESSED",
+        "T88x_TI_TRIANGLES",
+        "T88x_TI_QUADS",
+        "T88x_TI_POLYGONS",
+        "T88x_TI_POINTS",
+        "T88x_TI_LINES",
+        "T88x_TI_VCACHE_HIT",
+        "T88x_TI_VCACHE_MISS",
+        "T88x_TI_FRONT_FACING",
+        "T88x_TI_BACK_FACING",
+        "T88x_TI_PRIM_VISIBLE",
+        "T88x_TI_PRIM_CULLED",
+        "T88x_TI_PRIM_CLIPPED",
+        "T88x_TI_LEVEL0",
+        "T88x_TI_LEVEL1",
+        "T88x_TI_LEVEL2",
+        "T88x_TI_LEVEL3",
+        "T88x_TI_LEVEL4",
+        "T88x_TI_LEVEL5",
+        "T88x_TI_LEVEL6",
+        "T88x_TI_LEVEL7",
+        "T88x_TI_COMMAND_1",
+        "T88x_TI_COMMAND_2",
+        "T88x_TI_COMMAND_3",
+        "T88x_TI_COMMAND_4",
+        "T88x_TI_COMMAND_5_7",
+        "T88x_TI_COMMAND_8_15",
+        "T88x_TI_COMMAND_16_63",
+        "T88x_TI_COMMAND_64",
+        "T88x_TI_COMPRESS_IN",
+        "T88x_TI_COMPRESS_OUT",
+        "T88x_TI_COMPRESS_FLUSH",
+        "T88x_TI_TIMESTAMPS",
+        "T88x_TI_PCACHE_HIT",
+        "T88x_TI_PCACHE_MISS",
+        "T88x_TI_PCACHE_LINE",
+        "T88x_TI_PCACHE_STALL",
+        "T88x_TI_WRBUF_HIT",
+        "T88x_TI_WRBUF_MISS",
+        "T88x_TI_WRBUF_LINE",
+        "T88x_TI_WRBUF_PARTIAL",
+        "T88x_TI_WRBUF_STALL",
+        "T88x_TI_ACTIVE",
+        "T88x_TI_LOADING_DESC",
+        "T88x_TI_INDEX_WAIT",
+        "T88x_TI_INDEX_RANGE_WAIT",
+        "T88x_TI_VERTEX_WAIT",
+        "T88x_TI_PCACHE_WAIT",
+        "T88x_TI_WRBUF_WAIT",
+        "T88x_TI_BUS_READ",
+        "T88x_TI_BUS_WRITE",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T88x_TI_UTLB_HIT",
+        "T88x_TI_UTLB_NEW_MISS",
+        "T88x_TI_UTLB_REPLAY_FULL",
+        "T88x_TI_UTLB_REPLAY_MISS",
+        "T88x_TI_UTLB_STALL",
+
+        /* Shader Core */
+        "",
+        "",
+        "",
+        "",
+        "T88x_FRAG_ACTIVE",
+        "T88x_FRAG_PRIMITIVES",
+        "T88x_FRAG_PRIMITIVES_DROPPED",
+        "T88x_FRAG_CYCLES_DESC",
+        "T88x_FRAG_CYCLES_FPKQ_ACTIVE",
+        "T88x_FRAG_CYCLES_VERT",
+        "T88x_FRAG_CYCLES_TRISETUP",
+        "T88x_FRAG_CYCLES_EZS_ACTIVE",
+        "T88x_FRAG_THREADS",
+        "T88x_FRAG_DUMMY_THREADS",
+        "T88x_FRAG_QUADS_RAST",
+        "T88x_FRAG_QUADS_EZS_TEST",
+        "T88x_FRAG_QUADS_EZS_KILLED",
+        "T88x_FRAG_THREADS_LZS_TEST",
+        "T88x_FRAG_THREADS_LZS_KILLED",
+        "T88x_FRAG_CYCLES_NO_TILE",
+        "T88x_FRAG_NUM_TILES",
+        "T88x_FRAG_TRANS_ELIM",
+        "T88x_COMPUTE_ACTIVE",
+        "T88x_COMPUTE_TASKS",
+        "T88x_COMPUTE_THREADS",
+        "T88x_COMPUTE_CYCLES_DESC",
+        "T88x_TRIPIPE_ACTIVE",
+        "T88x_ARITH_WORDS",
+        "T88x_ARITH_CYCLES_REG",
+        "T88x_ARITH_CYCLES_L0",
+        "T88x_ARITH_FRAG_DEPEND",
+        "T88x_LS_WORDS",
+        "T88x_LS_ISSUES",
+        "T88x_LS_REISSUE_ATTR",
+        "T88x_LS_REISSUES_VARY",
+        "T88x_LS_VARY_RV_MISS",
+        "T88x_LS_VARY_RV_HIT",
+        "T88x_LS_NO_UNPARK",
+        "T88x_TEX_WORDS",
+        "T88x_TEX_BUBBLES",
+        "T88x_TEX_WORDS_L0",
+        "T88x_TEX_WORDS_DESC",
+        "T88x_TEX_ISSUES",
+        "T88x_TEX_RECIRC_FMISS",
+        "T88x_TEX_RECIRC_DESC",
+        "T88x_TEX_RECIRC_MULTI",
+        "T88x_TEX_RECIRC_PMISS",
+        "T88x_TEX_RECIRC_CONF",
+        "T88x_LSC_READ_HITS",
+        "T88x_LSC_READ_OP",
+        "T88x_LSC_WRITE_HITS",
+        "T88x_LSC_WRITE_OP",
+        "T88x_LSC_ATOMIC_HITS",
+        "T88x_LSC_ATOMIC_OP",
+        "T88x_LSC_LINE_FETCHES",
+        "T88x_LSC_DIRTY_LINE",
+        "T88x_LSC_SNOOPS",
+        "T88x_AXI_TLB_STALL",
+        "T88x_AXI_TLB_MISS",
+        "T88x_AXI_TLB_TRANSACTION",
+        "T88x_LS_TLB_MISS",
+        "T88x_LS_TLB_HIT",
+        "T88x_AXI_BEATS_READ",
+        "T88x_AXI_BEATS_WRITTEN",
+
+        /*L2 and MMU */
+        "",
+        "",
+        "",
+        "",
+        "T88x_MMU_HIT",
+        "T88x_MMU_NEW_MISS",
+        "T88x_MMU_REPLAY_FULL",
+        "T88x_MMU_REPLAY_MISS",
+        "T88x_MMU_TABLE_WALK",
+        "T88x_MMU_REQUESTS",
+        "",
+        "",
+        "T88x_UTLB_HIT",
+        "T88x_UTLB_NEW_MISS",
+        "T88x_UTLB_REPLAY_FULL",
+        "T88x_UTLB_REPLAY_MISS",
+        "T88x_UTLB_STALL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "T88x_L2_EXT_WRITE_BEATS",
+        "T88x_L2_EXT_READ_BEATS",
+        "T88x_L2_ANY_LOOKUP",
+        "T88x_L2_READ_LOOKUP",
+        "T88x_L2_SREAD_LOOKUP",
+        "T88x_L2_READ_REPLAY",
+        "T88x_L2_READ_SNOOP",
+        "T88x_L2_READ_HIT",
+        "T88x_L2_CLEAN_MISS",
+        "T88x_L2_WRITE_LOOKUP",
+        "T88x_L2_SWRITE_LOOKUP",
+        "T88x_L2_WRITE_REPLAY",
+        "T88x_L2_WRITE_SNOOP",
+        "T88x_L2_WRITE_HIT",
+        "T88x_L2_EXT_READ_FULL",
+        "",
+        "T88x_L2_EXT_WRITE_FULL",
+        "T88x_L2_EXT_R_W_HAZARD",
+        "T88x_L2_EXT_READ",
+        "T88x_L2_EXT_READ_LINE",
+        "T88x_L2_EXT_WRITE",
+        "T88x_L2_EXT_WRITE_LINE",
+        "T88x_L2_EXT_WRITE_SMALL",
+        "T88x_L2_EXT_BARRIER",
+        "T88x_L2_EXT_AR_STALL",
+        "T88x_L2_EXT_R_BUF_FULL",
+        "T88x_L2_EXT_RD_BUF_FULL",
+        "T88x_L2_EXT_R_RAW",
+        "T88x_L2_EXT_W_STALL",
+        "T88x_L2_EXT_W_BUF_FULL",
+        "T88x_L2_EXT_R_BUF_FULL",
+        "T88x_L2_TAG_HAZARD",
+        "T88x_L2_SNOOP_FULL",
+        "T88x_L2_REPLAY_FULL"
+    };
+
+    static const char * const hardware_counters_mali_tHEx[] = {
+        /* Performance counters for the Job Manager */
+        "",
+        "",
+        "",
+        "",
+        "THEx_MESSAGES_SENT",
+        "THEx_MESSAGES_RECEIVED",
+        "THEx_GPU_ACTIVE",
+        "THEx_IRQ_ACTIVE",
+        "THEx_JS0_JOBS",
+        "THEx_JS0_TASKS",
+        "THEx_JS0_ACTIVE",
+        "",
+        "THEx_JS0_WAIT_READ",
+        "THEx_JS0_WAIT_ISSUE",
+        "THEx_JS0_WAIT_DEPEND",
+        "THEx_JS0_WAIT_FINISH",
+        "THEx_JS1_JOBS",
+        "THEx_JS1_TASKS",
+        "THEx_JS1_ACTIVE",
+        "",
+        "THEx_JS1_WAIT_READ",
+        "THEx_JS1_WAIT_ISSUE",
+        "THEx_JS1_WAIT_DEPEND",
+        "THEx_JS1_WAIT_FINISH",
+        "THEx_JS2_JOBS",
+        "THEx_JS2_TASKS",
+        "THEx_JS2_ACTIVE",
+        "",
+        "THEx_JS2_WAIT_READ",
+        "THEx_JS2_WAIT_ISSUE",
+        "THEx_JS2_WAIT_DEPEND",
+        "THEx_JS2_WAIT_FINISH",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /* Performance counters for the Tiler */
+        "",
+        "",
+        "",
+        "",
+        "THEx_TILER_ACTIVE",
+        "THEx_JOBS_PROCESSED",
+        "THEx_TRIANGLES",
+        "THEx_LINES",
+        "THEx_POINTS",
+        "THEx_FRONT_FACING",
+        "THEx_BACK_FACING",
+        "THEx_PRIM_VISIBLE",
+        "THEx_PRIM_CULLED",
+        "THEx_PRIM_CLIPPED",
+        "THEx_PRIM_SAT_CULLED",
+        "",
+        "",
+        "THEx_BUS_READ",
+        "",
+        "THEx_BUS_WRITE",
+        "THEx_LOADING_DESC",
+        "THEx_IDVS_POS_SHAD_REQ",
+        "THEx_IDVS_POS_SHAD_WAIT",
+        "THEx_IDVS_POS_SHAD_STALL",
+        "THEx_IDVS_POS_FIFO_FULL",
+        "THEx_PREFETCH_STALL",
+        "THEx_VCACHE_HIT",
+        "THEx_VCACHE_MISS",
+        "THEx_VCACHE_LINE_WAIT",
+        "THEx_VFETCH_POS_READ_WAIT",
+        "THEx_VFETCH_VERTEX_WAIT",
+        "THEx_VFETCH_STALL",
+        "THEx_PRIMASSY_STALL",
+        "THEx_BBOX_GEN_STALL",
+        "THEx_IDVS_VBU_HIT",
+        "THEx_IDVS_VBU_MISS",
+        "THEx_IDVS_VBU_LINE_DEALLOCATE",
+        "THEx_IDVS_VAR_SHAD_REQ",
+        "THEx_IDVS_VAR_SHAD_STALL",
+        "THEx_BINNER_STALL",
+        "THEx_ITER_STALL",
+        "THEx_COMPRESS_MISS",
+        "THEx_COMPRESS_STALL",
+        "THEx_PCACHE_HIT",
+        "THEx_PCACHE_MISS",
+        "THEx_PCACHE_MISS_STALL",
+        "THEx_PCACHE_EVICT_STALL",
+        "THEx_PMGR_PTR_WR_STALL",
+        "THEx_PMGR_PTR_RD_STALL",
+        "THEx_PMGR_CMD_WR_STALL",
+        "THEx_WRBUF_ACTIVE",
+        "THEx_WRBUF_HIT",
+        "THEx_WRBUF_MISS",
+        "THEx_WRBUF_NO_FREE_LINE_STALL",
+        "THEx_WRBUF_NO_AXI_ID_STALL",
+        "THEx_WRBUF_AXI_STALL",
+        "",
+        "",
+        "",
+        "THEx_UTLB_TRANS",
+        "THEx_UTLB_TRANS_HIT",
+        "THEx_UTLB_TRANS_STALL",
+        "THEx_UTLB_TRANS_MISS_DELAY",
+        "THEx_UTLB_MMU_REQ",
+
+        /* Performance counters for the Shader Core */
+        "",
+        "",
+        "",
+        "",
+        "THEx_FRAG_ACTIVE",
+        "THEx_FRAG_PRIMITIVES",
+        "THEx_FRAG_PRIM_RAST",
+        "THEx_FRAG_FPK_ACTIVE",
+        "THEx_FRAG_STARVING",
+        "THEx_FRAG_WARPS",
+        "THEx_FRAG_PARTIAL_WARPS",
+        "THEx_FRAG_QUADS_RAST",
+        "THEx_FRAG_QUADS_EZS_TEST",
+        "THEx_FRAG_QUADS_EZS_UPDATE",
+        "THEx_FRAG_QUADS_EZS_KILL",
+        "THEx_FRAG_LZS_TEST",
+        "THEx_FRAG_LZS_KILL",
+        "",
+        "THEx_FRAG_PTILES",
+        "THEx_FRAG_TRANS_ELIM",
+        "THEx_QUAD_FPK_KILLER",
+        "",
+        "THEx_COMPUTE_ACTIVE",
+        "THEx_COMPUTE_TASKS",
+        "THEx_COMPUTE_WARPS",
+        "THEx_COMPUTE_STARVING",
+        "THEx_EXEC_CORE_ACTIVE",
+        "THEx_EXEC_ACTIVE",
+        "THEx_EXEC_INSTR_COUNT",
+        "THEx_EXEC_INSTR_DIVERGED",
+        "THEx_EXEC_INSTR_STARVING",
+        "THEx_ARITH_INSTR_SINGLE_FMA",
+        "THEx_ARITH_INSTR_DOUBLE",
+        "THEx_ARITH_INSTR_MSG",
+        "THEx_ARITH_INSTR_MSG_ONLY",
+        "THEx_TEX_INSTR",
+        "THEx_TEX_INSTR_MIPMAP",
+        "THEx_TEX_INSTR_COMPRESSED",
+        "THEx_TEX_INSTR_3D",
+        "THEx_TEX_INSTR_TRILINEAR",
+        "THEx_TEX_COORD_ISSUE",
+        "THEx_TEX_COORD_STALL",
+        "THEx_TEX_STARVE_CACHE",
+        "THEx_TEX_STARVE_FILTER",
+        "THEx_LS_MEM_READ_FULL",
+        "THEx_LS_MEM_READ_SHORT",
+        "THEx_LS_MEM_WRITE_FULL",
+        "THEx_LS_MEM_WRITE_SHORT",
+        "THEx_LS_MEM_ATOMIC",
+        "THEx_VARY_INSTR",
+        "THEx_VARY_SLOT_32",
+        "THEx_VARY_SLOT_16",
+        "THEx_ATTR_INSTR",
+        "THEx_ARITH_INSTR_FP_MUL",
+        "THEx_BEATS_RD_FTC",
+        "THEx_BEATS_RD_FTC_EXT",
+        "THEx_BEATS_RD_LSC",
+        "THEx_BEATS_RD_LSC_EXT",
+        "THEx_BEATS_RD_TEX",
+        "THEx_BEATS_RD_TEX_EXT",
+        "THEx_BEATS_RD_OTHER",
+        "THEx_BEATS_WR_LSC",
+        "THEx_BEATS_WR_TIB",
+        "",
+
+        /* Performance counters for the Memory System */
+        "",
+        "",
+        "",
+        "",
+        "THEx_MMU_REQUESTS",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "THEx_L2_RD_MSG_IN",
+        "THEx_L2_RD_MSG_IN_STALL",
+        "THEx_L2_WR_MSG_IN",
+        "THEx_L2_WR_MSG_IN_STALL",
+        "THEx_L2_SNP_MSG_IN",
+        "THEx_L2_SNP_MSG_IN_STALL",
+        "THEx_L2_RD_MSG_OUT",
+        "THEx_L2_RD_MSG_OUT_STALL",
+        "THEx_L2_WR_MSG_OUT",
+        "THEx_L2_ANY_LOOKUP",
+        "THEx_L2_READ_LOOKUP",
+        "THEx_L2_WRITE_LOOKUP",
+        "THEx_L2_EXT_SNOOP_LOOKUP",
+        "THEx_L2_EXT_READ",
+        "THEx_L2_EXT_READ_NOSNP",
+        "THEx_L2_EXT_READ_UNIQUE",
+        "THEx_L2_EXT_READ_BEATS",
+        "THEx_L2_EXT_AR_STALL",
+        "THEx_L2_EXT_AR_CNT_Q1",
+        "THEx_L2_EXT_AR_CNT_Q2",
+        "THEx_L2_EXT_AR_CNT_Q3",
+        "THEx_L2_EXT_RRESP_0_127",
+        "THEx_L2_EXT_RRESP_128_191",
+        "THEx_L2_EXT_RRESP_192_255",
+        "THEx_L2_EXT_RRESP_256_319",
+        "THEx_L2_EXT_RRESP_320_383",
+        "THEx_L2_EXT_WRITE",
+        "THEx_L2_EXT_WRITE_NOSNP_FULL",
+        "THEx_L2_EXT_WRITE_NOSNP_PTL",
+        "THEx_L2_EXT_WRITE_SNP_FULL",
+        "THEx_L2_EXT_WRITE_SNP_PTL",
+        "THEx_L2_EXT_WRITE_BEATS",
+        "THEx_L2_EXT_W_STALL",
+        "THEx_L2_EXT_AW_CNT_Q1",
+        "THEx_L2_EXT_AW_CNT_Q2",
+        "THEx_L2_EXT_AW_CNT_Q3",
+        "THEx_L2_EXT_SNOOP",
+        "THEx_L2_EXT_SNOOP_STALL",
+        "THEx_L2_EXT_SNOOP_RESP_CLEAN",
+        "THEx_L2_EXT_SNOOP_RESP_DATA",
+        "THEx_L2_EXT_SNOOP_INTERNAL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+    };
+
+    static const char * const hardware_counters_mali_tMIx[] = {
+        /* Performance counters for the Job Manager */
+        "",
+        "",
+        "",
+        "",
+        "TMIx_MESSAGES_SENT",
+        "TMIx_MESSAGES_RECEIVED",
+        "TMIx_GPU_ACTIVE",
+        "TMIx_IRQ_ACTIVE",
+        "TMIx_JS0_JOBS",
+        "TMIx_JS0_TASKS",
+        "TMIx_JS0_ACTIVE",
+        "",
+        "TMIx_JS0_WAIT_READ",
+        "TMIx_JS0_WAIT_ISSUE",
+        "TMIx_JS0_WAIT_DEPEND",
+        "TMIx_JS0_WAIT_FINISH",
+        "TMIx_JS1_JOBS",
+        "TMIx_JS1_TASKS",
+        "TMIx_JS1_ACTIVE",
+        "",
+        "TMIx_JS1_WAIT_READ",
+        "TMIx_JS1_WAIT_ISSUE",
+        "TMIx_JS1_WAIT_DEPEND",
+        "TMIx_JS1_WAIT_FINISH",
+        "TMIx_JS2_JOBS",
+        "TMIx_JS2_TASKS",
+        "TMIx_JS2_ACTIVE",
+        "",
+        "TMIx_JS2_WAIT_READ",
+        "TMIx_JS2_WAIT_ISSUE",
+        "TMIx_JS2_WAIT_DEPEND",
+        "TMIx_JS2_WAIT_FINISH",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /* Performance counters for the Tiler */
+        "",
+        "",
+        "",
+        "",
+        "TMIx_TILER_ACTIVE",
+        "TMIx_JOBS_PROCESSED",
+        "TMIx_TRIANGLES",
+        "TMIx_LINES",
+        "TMIx_POINTS",
+        "TMIx_FRONT_FACING",
+        "TMIx_BACK_FACING",
+        "TMIx_PRIM_VISIBLE",
+        "TMIx_PRIM_CULLED",
+        "TMIx_PRIM_CLIPPED",
+        "TMIx_PRIM_SAT_CULLED",
+        "",
+        "",
+        "TMIx_BUS_READ",
+        "",
+        "TMIx_BUS_WRITE",
+        "TMIx_LOADING_DESC",
+        "TMIx_IDVS_POS_SHAD_REQ",
+        "TMIx_IDVS_POS_SHAD_WAIT",
+        "TMIx_IDVS_POS_SHAD_STALL",
+        "TMIx_IDVS_POS_FIFO_FULL",
+        "TMIx_PREFETCH_STALL",
+        "TMIx_VCACHE_HIT",
+        "TMIx_VCACHE_MISS",
+        "TMIx_VCACHE_LINE_WAIT",
+        "TMIx_VFETCH_POS_READ_WAIT",
+        "TMIx_VFETCH_VERTEX_WAIT",
+        "TMIx_VFETCH_STALL",
+        "TMIx_PRIMASSY_STALL",
+        "TMIx_BBOX_GEN_STALL",
+        "TMIx_IDVS_VBU_HIT",
+        "TMIx_IDVS_VBU_MISS",
+        "TMIx_IDVS_VBU_LINE_DEALLOCATE",
+        "TMIx_IDVS_VAR_SHAD_REQ",
+        "TMIx_IDVS_VAR_SHAD_STALL",
+        "TMIx_BINNER_STALL",
+        "TMIx_ITER_STALL",
+        "TMIx_COMPRESS_MISS",
+        "TMIx_COMPRESS_STALL",
+        "TMIx_PCACHE_HIT",
+        "TMIx_PCACHE_MISS",
+        "TMIx_PCACHE_MISS_STALL",
+        "TMIx_PCACHE_EVICT_STALL",
+        "TMIx_PMGR_PTR_WR_STALL",
+        "TMIx_PMGR_PTR_RD_STALL",
+        "TMIx_PMGR_CMD_WR_STALL",
+        "TMIx_WRBUF_ACTIVE",
+        "TMIx_WRBUF_HIT",
+        "TMIx_WRBUF_MISS",
+        "TMIx_WRBUF_NO_FREE_LINE_STALL",
+        "TMIx_WRBUF_NO_AXI_ID_STALL",
+        "TMIx_WRBUF_AXI_STALL",
+        "",
+        "",
+        "",
+        "TMIx_UTLB_TRANS",
+        "TMIx_UTLB_TRANS_HIT",
+        "TMIx_UTLB_TRANS_STALL",
+        "TMIx_UTLB_TRANS_MISS_DELAY",
+        "TMIx_UTLB_MMU_REQ",
+
+        /* Performance counters for the Shader Core */
+        "",
+        "",
+        "",
+        "",
+        "TMIx_FRAG_ACTIVE",
+        "TMIx_FRAG_PRIMITIVES",
+        "TMIx_FRAG_PRIM_RAST",
+        "TMIx_FRAG_FPK_ACTIVE",
+        "TMIx_FRAG_STARVING",
+        "TMIx_FRAG_WARPS",
+        "TMIx_FRAG_PARTIAL_WARPS",
+        "TMIx_FRAG_QUADS_RAST",
+        "TMIx_FRAG_QUADS_EZS_TEST",
+        "TMIx_FRAG_QUADS_EZS_UPDATE",
+        "TMIx_FRAG_QUADS_EZS_KILL",
+        "TMIx_FRAG_LZS_TEST",
+        "TMIx_FRAG_LZS_KILL",
+        "",
+        "TMIx_FRAG_PTILES",
+        "TMIx_FRAG_TRANS_ELIM",
+        "TMIx_QUAD_FPK_KILLER",
+        "",
+        "TMIx_COMPUTE_ACTIVE",
+        "TMIx_COMPUTE_TASKS",
+        "TMIx_COMPUTE_WARPS",
+        "TMIx_COMPUTE_STARVING",
+        "TMIx_EXEC_CORE_ACTIVE",
+        "TMIx_EXEC_ACTIVE",
+        "TMIx_EXEC_INSTR_COUNT",
+        "TMIx_EXEC_INSTR_DIVERGED",
+        "TMIx_EXEC_INSTR_STARVING",
+        "TMIx_ARITH_INSTR_SINGLE_FMA",
+        "TMIx_ARITH_INSTR_DOUBLE",
+        "TMIx_ARITH_INSTR_MSG",
+        "TMIx_ARITH_INSTR_MSG_ONLY",
+        "TMIx_TEX_INSTR",
+        "TMIx_TEX_INSTR_MIPMAP",
+        "TMIx_TEX_INSTR_COMPRESSED",
+        "TMIx_TEX_INSTR_3D",
+        "TMIx_TEX_INSTR_TRILINEAR",
+        "TMIx_TEX_COORD_ISSUE",
+        "TMIx_TEX_COORD_STALL",
+        "TMIx_TEX_STARVE_CACHE",
+        "TMIx_TEX_STARVE_FILTER",
+        "TMIx_LS_MEM_READ_FULL",
+        "TMIx_LS_MEM_READ_SHORT",
+        "TMIx_LS_MEM_WRITE_FULL",
+        "TMIx_LS_MEM_WRITE_SHORT",
+        "TMIx_LS_MEM_ATOMIC",
+        "TMIx_VARY_INSTR",
+        "TMIx_VARY_SLOT_32",
+        "TMIx_VARY_SLOT_16",
+        "TMIx_ATTR_INSTR",
+        "TMIx_ARITH_INSTR_FP_MUL",
+        "TMIx_BEATS_RD_FTC",
+        "TMIx_BEATS_RD_FTC_EXT",
+        "TMIx_BEATS_RD_LSC",
+        "TMIx_BEATS_RD_LSC_EXT",
+        "TMIx_BEATS_RD_TEX",
+        "TMIx_BEATS_RD_TEX_EXT",
+        "TMIx_BEATS_RD_OTHER",
+        "TMIx_BEATS_WR_LSC",
+        "TMIx_BEATS_WR_TIB",
+        "",
+
+        /* Performance counters for the Memory System */
+        "",
+        "",
+        "",
+        "",
+        "TMIx_MMU_REQUESTS",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "TMIx_L2_RD_MSG_IN",
+        "TMIx_L2_RD_MSG_IN_STALL",
+        "TMIx_L2_WR_MSG_IN",
+        "TMIx_L2_WR_MSG_IN_STALL",
+        "TMIx_L2_SNP_MSG_IN",
+        "TMIx_L2_SNP_MSG_IN_STALL",
+        "TMIx_L2_RD_MSG_OUT",
+        "TMIx_L2_RD_MSG_OUT_STALL",
+        "TMIx_L2_WR_MSG_OUT",
+        "TMIx_L2_ANY_LOOKUP",
+        "TMIx_L2_READ_LOOKUP",
+        "TMIx_L2_WRITE_LOOKUP",
+        "TMIx_L2_EXT_SNOOP_LOOKUP",
+        "TMIx_L2_EXT_READ",
+        "TMIx_L2_EXT_READ_NOSNP",
+        "TMIx_L2_EXT_READ_UNIQUE",
+        "TMIx_L2_EXT_READ_BEATS",
+        "TMIx_L2_EXT_AR_STALL",
+        "TMIx_L2_EXT_AR_CNT_Q1",
+        "TMIx_L2_EXT_AR_CNT_Q2",
+        "TMIx_L2_EXT_AR_CNT_Q3",
+        "TMIx_L2_EXT_RRESP_0_127",
+        "TMIx_L2_EXT_RRESP_128_191",
+        "TMIx_L2_EXT_RRESP_192_255",
+        "TMIx_L2_EXT_RRESP_256_319",
+        "TMIx_L2_EXT_RRESP_320_383",
+        "TMIx_L2_EXT_WRITE",
+        "TMIx_L2_EXT_WRITE_NOSNP_FULL",
+        "TMIx_L2_EXT_WRITE_NOSNP_PTL",
+        "TMIx_L2_EXT_WRITE_SNP_FULL",
+        "TMIx_L2_EXT_WRITE_SNP_PTL",
+        "TMIx_L2_EXT_WRITE_BEATS",
+        "TMIx_L2_EXT_W_STALL",
+        "TMIx_L2_EXT_AW_CNT_Q1",
+        "TMIx_L2_EXT_AW_CNT_Q2",
+        "TMIx_L2_EXT_AW_CNT_Q3",
+        "TMIx_L2_EXT_SNOOP",
+        "TMIx_L2_EXT_SNOOP_STALL",
+        "TMIx_L2_EXT_SNOOP_RESP_CLEAN",
+        "TMIx_L2_EXT_SNOOP_RESP_DATA",
+        "TMIx_L2_EXT_SNOOP_INTERNAL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+    };
+
+    static const char * const hardware_counters_mali_tSIx[] = {
+        /* Performance counters for the Job Manager */
+        "",
+        "",
+        "",
+        "",
+        "TSIx_MESSAGES_SENT",
+        "TSIx_MESSAGES_RECEIVED",
+        "TSIx_GPU_ACTIVE",
+        "TSIx_IRQ_ACTIVE",
+        "TSIx_JS0_JOBS",
+        "TSIx_JS0_TASKS",
+        "TSIx_JS0_ACTIVE",
+        "",
+        "TSIx_JS0_WAIT_READ",
+        "TSIx_JS0_WAIT_ISSUE",
+        "TSIx_JS0_WAIT_DEPEND",
+        "TSIx_JS0_WAIT_FINISH",
+        "TSIx_JS1_JOBS",
+        "TSIx_JS1_TASKS",
+        "TSIx_JS1_ACTIVE",
+        "",
+        "TSIx_JS1_WAIT_READ",
+        "TSIx_JS1_WAIT_ISSUE",
+        "TSIx_JS1_WAIT_DEPEND",
+        "TSIx_JS1_WAIT_FINISH",
+        "TSIx_JS2_JOBS",
+        "TSIx_JS2_TASKS",
+        "TSIx_JS2_ACTIVE",
+        "",
+        "TSIx_JS2_WAIT_READ",
+        "TSIx_JS2_WAIT_ISSUE",
+        "TSIx_JS2_WAIT_DEPEND",
+        "TSIx_JS2_WAIT_FINISH",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+
+        /* Performance counters for the Tiler */
+        "",
+        "",
+        "",
+        "",
+        "TSIx_TILER_ACTIVE",
+        "TSIx_JOBS_PROCESSED",
+        "TSIx_TRIANGLES",
+        "TSIx_LINES",
+        "TSIx_POINTS",
+        "TSIx_FRONT_FACING",
+        "TSIx_BACK_FACING",
+        "TSIx_PRIM_VISIBLE",
+        "TSIx_PRIM_CULLED",
+        "TSIx_PRIM_CLIPPED",
+        "TSIx_PRIM_SAT_CULLED",
+        "",
+        "",
+        "TSIx_BUS_READ",
+        "",
+        "TSIx_BUS_WRITE",
+        "TSIx_LOADING_DESC",
+        "",
+        "",
+        "",
+        "",
+        "TSIx_PREFETCH_STALL",
+        "TSIx_VCACHE_HIT",
+        "TSIx_VCACHE_MISS",
+        "TSIx_VCACHE_LINE_WAIT",
+        "TSIx_VFETCH_POS_READ_WAIT",
+        "TSIx_VFETCH_VERTEX_WAIT",
+        "TSIx_VFETCH_STALL",
+        "TSIx_PRIMASSY_STALL",
+        "TSIx_BBOX_GEN_STALL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "TSIx_BINNER_STALL",
+        "TSIx_ITER_STALL",
+        "TSIx_COMPRESS_MISS",
+        "TSIx_COMPRESS_STALL",
+        "TSIx_PCACHE_HIT",
+        "TSIx_PCACHE_MISS",
+        "TSIx_PCACHE_MISS_STALL",
+        "TSIx_PCACHE_EVICT_STALL",
+        "TSIx_PMGR_PTR_WR_STALL",
+        "TSIx_PMGR_PTR_RD_STALL",
+        "TSIx_PMGR_CMD_WR_STALL",
+        "TSIx_WRBUF_ACTIVE",
+        "TSIx_WRBUF_HIT",
+        "TSIx_WRBUF_MISS",
+        "TSIx_WRBUF_NO_FREE_LINE_STALL",
+        "TSIx_WRBUF_NO_AXI_ID_STALL",
+        "TSIx_WRBUF_AXI_STALL",
+        "",
+        "",
+        "",
+        "TSIx_UTLB_TRANS",
+        "TSIx_UTLB_TRANS_HIT",
+        "TSIx_UTLB_TRANS_STALL",
+        "TSIx_UTLB_TRANS_MISS_DELAY",
+        "TSIx_UTLB_MMU_REQ",
+
+        /* Performance counters for the Shader Core */
+        "",
+        "",
+        "",
+        "",
+        "TSIx_FRAG_ACTIVE",
+        "TSIx_FRAG_PRIMITIVES",
+        "TSIx_FRAG_PRIM_RAST",
+        "TSIx_FRAG_FPK_ACTIVE",
+        "TSIx_FRAG_STARVING",
+        "TSIx_FRAG_WARPS",
+        "TSIx_FRAG_PARTIAL_WARPS",
+        "TSIx_FRAG_QUADS_RAST",
+        "TSIx_FRAG_QUADS_EZS_TEST",
+        "TSIx_FRAG_QUADS_EZS_UPDATE",
+        "TSIx_FRAG_QUADS_EZS_KILL",
+        "TSIx_FRAG_LZS_TEST",
+        "TSIx_FRAG_LZS_KILL",
+        "",
+        "TSIx_FRAG_PTILES",
+        "TSIx_FRAG_TRANS_ELIM",
+        "TSIx_QUAD_FPK_KILLER",
+        "",
+        "TSIx_COMPUTE_ACTIVE",
+        "TSIx_COMPUTE_TASKS",
+        "TSIx_COMPUTE_WARPS",
+        "TSIx_COMPUTE_STARVING",
+        "TSIx_EXEC_CORE_ACTIVE",
+        "TSIx_EXEC_ACTIVE",
+        "TSIx_EXEC_INSTR_COUNT",
+        "TSIx_EXEC_INSTR_DIVERGED",
+        "TSIx_EXEC_INSTR_STARVING",
+        "TSIx_ARITH_INSTR_SINGLE_FMA",
+        "TSIx_ARITH_INSTR_DOUBLE",
+        "TSIx_ARITH_INSTR_MSG",
+        "TSIx_ARITH_INSTR_MSG_ONLY",
+        "TSIx_TEX_INSTR",
+        "TSIx_TEX_INSTR_MIPMAP",
+        "TSIx_TEX_INSTR_COMPRESSED",
+        "TSIx_TEX_INSTR_3D",
+        "TSIx_TEX_INSTR_TRILINEAR",
+        "TSIx_TEX_COORD_ISSUE",
+        "TSIx_TEX_COORD_STALL",
+        "TSIx_TEX_STARVE_CACHE",
+        "TSIx_TEX_STARVE_FILTER",
+        "TSIx_LS_MEM_READ_FULL",
+        "TSIx_LS_MEM_READ_SHORT",
+        "TSIx_LS_MEM_WRITE_FULL",
+        "TSIx_LS_MEM_WRITE_SHORT",
+        "TSIx_LS_MEM_ATOMIC",
+        "TSIx_VARY_INSTR",
+        "TSIx_VARY_SLOT_32",
+        "TSIx_VARY_SLOT_16",
+        "TSIx_ATTR_INSTR",
+        "TSIx_ARITH_INSTR_FP_MUL",
+        "TSIx_BEATS_RD_FTC",
+        "TSIx_BEATS_RD_FTC_EXT",
+        "TSIx_BEATS_RD_LSC",
+        "TSIx_BEATS_RD_LSC_EXT",
+        "TSIx_BEATS_RD_TEX",
+        "TSIx_BEATS_RD_TEX_EXT",
+        "TSIx_BEATS_RD_OTHER",
+        "TSIx_BEATS_WR_LSC",
+        "TSIx_BEATS_WR_TIB",
+        "",
+
+        /* Performance counters for the Memory System */
+        "",
+        "",
+        "",
+        "",
+        "TSIx_MMU_REQUESTS",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "TSIx_L2_RD_MSG_IN",
+        "TSIx_L2_RD_MSG_IN_STALL",
+        "TSIx_L2_WR_MSG_IN",
+        "TSIx_L2_WR_MSG_IN_STALL",
+        "TSIx_L2_SNP_MSG_IN",
+        "TSIx_L2_SNP_MSG_IN_STALL",
+        "TSIx_L2_RD_MSG_OUT",
+        "TSIx_L2_RD_MSG_OUT_STALL",
+        "TSIx_L2_WR_MSG_OUT",
+        "TSIx_L2_ANY_LOOKUP",
+        "TSIx_L2_READ_LOOKUP",
+        "TSIx_L2_WRITE_LOOKUP",
+        "TSIx_L2_EXT_SNOOP_LOOKUP",
+        "TSIx_L2_EXT_READ",
+        "TSIx_L2_EXT_READ_NOSNP",
+        "TSIx_L2_EXT_READ_UNIQUE",
+        "TSIx_L2_EXT_READ_BEATS",
+        "TSIx_L2_EXT_AR_STALL",
+        "TSIx_L2_EXT_AR_CNT_Q1",
+        "TSIx_L2_EXT_AR_CNT_Q2",
+        "TSIx_L2_EXT_AR_CNT_Q3",
+        "TSIx_L2_EXT_RRESP_0_127",
+        "TSIx_L2_EXT_RRESP_128_191",
+        "TSIx_L2_EXT_RRESP_192_255",
+        "TSIx_L2_EXT_RRESP_256_319",
+        "TSIx_L2_EXT_RRESP_320_383",
+        "TSIx_L2_EXT_WRITE",
+        "TSIx_L2_EXT_WRITE_NOSNP_FULL",
+        "TSIx_L2_EXT_WRITE_NOSNP_PTL",
+        "TSIx_L2_EXT_WRITE_SNP_FULL",
+        "TSIx_L2_EXT_WRITE_SNP_PTL",
+        "TSIx_L2_EXT_WRITE_BEATS",
+        "TSIx_L2_EXT_W_STALL",
+        "TSIx_L2_EXT_AW_CNT_Q1",
+        "TSIx_L2_EXT_AW_CNT_Q2",
+        "TSIx_L2_EXT_AW_CNT_Q3",
+        "TSIx_L2_EXT_SNOOP",
+        "TSIx_L2_EXT_SNOOP_STALL",
+        "TSIx_L2_EXT_SNOOP_RESP_CLEAN",
+        "TSIx_L2_EXT_SNOOP_RESP_DATA",
+        "TSIx_L2_EXT_SNOOP_INTERNAL",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+        "",
+    };
+
+	enum {
+		/* product id masks for old and new versions of the id field. NB: the T60x must be tested before anything else as it could exceptionally be
+		 * treated as a new style of id with produce code 0x6006 */
+		PRODUCT_ID_MASK_OLD = 0xffff,
+		PRODUCT_ID_MASK_NEW = 0xf00f,
+		/* Old style product ids */
+		PRODUCT_ID_T60X = 0x6956,
+		PRODUCT_ID_T62X = 0x0620,
+		PRODUCT_ID_T72X = 0x0720,
+		PRODUCT_ID_T76X = 0x0750,
+		PRODUCT_ID_T82X = 0x0820,
+		PRODUCT_ID_T83X = 0x0830,
+		PRODUCT_ID_T86X = 0x0860,
+		PRODUCT_ID_TFRX = 0x0880,
+		/* New style product ids */
+		PRODUCT_ID_TMIX = 0x6000,
+		PRODUCT_ID_THEX = 0x6001,
+		PRODUCT_ID_TSIX = 0x7000
+	};
+
+	struct CounterMapping
+	{
+		uint32_t product_mask;
+		uint32_t product_id;
+		const char * const *names_lut;
+	};
+
+	static const CounterMapping products[] = {
+		{ PRODUCT_ID_MASK_OLD, PRODUCT_ID_T60X, hardware_counters_mali_t60x, },
+		{ PRODUCT_ID_MASK_OLD, PRODUCT_ID_T62X, hardware_counters_mali_t62x, },
+		{ PRODUCT_ID_MASK_OLD, PRODUCT_ID_T72X, hardware_counters_mali_t72x, },
+		{ PRODUCT_ID_MASK_OLD, PRODUCT_ID_T76X, hardware_counters_mali_t76x, },
+		{ PRODUCT_ID_MASK_OLD, PRODUCT_ID_T82X, hardware_counters_mali_t82x, },
+		{ PRODUCT_ID_MASK_OLD, PRODUCT_ID_T83X, hardware_counters_mali_t83x, },
+		{ PRODUCT_ID_MASK_OLD, PRODUCT_ID_T86X, hardware_counters_mali_t86x, },
+		{ PRODUCT_ID_MASK_OLD, PRODUCT_ID_TFRX, hardware_counters_mali_t88x, },
+		{ PRODUCT_ID_MASK_NEW, PRODUCT_ID_TMIX, hardware_counters_mali_tMIx, },
+		{ PRODUCT_ID_MASK_NEW, PRODUCT_ID_THEX, hardware_counters_mali_tHEx, },
+		{ PRODUCT_ID_MASK_NEW, PRODUCT_ID_TSIX, hardware_counters_mali_tSIx, },
+	};
+
+	enum { NUM_PRODUCTS = sizeof(products) / sizeof(products[0]) };
+} // namespace mali_userspace
+#endif /* ARM_COMPUTE_TEST_HWC_NAMES */