c274057840
Add revision 9adf9d6e2d889a483a92136c96eb8a434d360561 of NoMali-model from https://github.com/ARM-software/nomali-model. This library implements the register interface of the Mali T6xx/T7xx series GPUs, but doesn't do any rendering. It can be used to hide the effects of software rendering.
218 lines
5.2 KiB
C++
218 lines
5.2 KiB
C++
/*
|
|
* Copyright (c) 2014-2015 ARM Limited
|
|
* All rights reserved
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*
|
|
* Authors: Andreas Sandberg
|
|
*/
|
|
|
|
#ifndef _LIBNOMALIMODEL_TYPES_HH
|
|
#define _LIBNOMALIMODEL_TYPES_HH
|
|
|
|
#include <cassert>
|
|
#include <cstdint>
|
|
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
namespace NoMali{
|
|
|
|
/**
|
|
* @{
|
|
* @name Register handling utilities
|
|
*/
|
|
|
|
/**
|
|
* Register address wrapper
|
|
*
|
|
* This class wraps a register address. Unlike a simple typedef, this
|
|
* provides safety from automatic type conversions from other integer
|
|
* types since the constructor must be called explicitly.
|
|
*/
|
|
struct RegAddr {
|
|
explicit RegAddr(uint32_t v)
|
|
: value(v) {}
|
|
|
|
const uint32_t value;
|
|
};
|
|
|
|
inline bool
|
|
operator<(const RegAddr &lhs, const RegAddr &rhs) {
|
|
return lhs.value < rhs.value;
|
|
}
|
|
|
|
inline bool
|
|
operator>(const RegAddr &lhs, const RegAddr &rhs) {
|
|
return lhs.value > rhs.value;
|
|
}
|
|
|
|
inline bool
|
|
operator<=(const RegAddr &lhs, const RegAddr &rhs) {
|
|
return lhs.value <= rhs.value;
|
|
}
|
|
|
|
inline bool
|
|
operator>=(const RegAddr &lhs, const RegAddr &rhs) {
|
|
return lhs.value >= rhs.value;
|
|
}
|
|
|
|
inline bool
|
|
operator==(const RegAddr &lhs, const RegAddr &rhs) {
|
|
return lhs.value == rhs.value;
|
|
}
|
|
|
|
inline bool
|
|
operator!=(const RegAddr &lhs, const RegAddr &rhs) {
|
|
return lhs.value != rhs.value;
|
|
}
|
|
|
|
inline RegAddr
|
|
operator+(const RegAddr &lhs, const RegAddr &rhs) {
|
|
return RegAddr(lhs.value + rhs.value);
|
|
}
|
|
|
|
inline RegAddr
|
|
operator-(const RegAddr &lhs, const RegAddr &rhs) {
|
|
assert(lhs >= rhs);
|
|
return RegAddr(lhs.value - rhs.value);
|
|
}
|
|
|
|
/**
|
|
* Class for register storage
|
|
*
|
|
* This class wraps a std::vector and implements a subset of its
|
|
* functionality. Specifically, it is constant size and prevents
|
|
* indexing with anything other than RegAddr instances.
|
|
*/
|
|
class RegVector
|
|
{
|
|
private:
|
|
typedef std::vector<uint32_t> vector_t;
|
|
|
|
public:
|
|
typedef vector_t::iterator iterator;
|
|
typedef vector_t::const_iterator const_iterator;
|
|
typedef vector_t::size_type size_type;
|
|
|
|
public:
|
|
RegVector(size_type size)
|
|
: vector(size, 0) {}
|
|
|
|
/** @{ */
|
|
/**
|
|
* Helper function to get a 64-bit register.
|
|
*
|
|
* @param addr Address to the low part of the register.
|
|
* @return 64-bit value representing the concatenation of the HI
|
|
* and LO parts of the register.
|
|
*/
|
|
const uint32_t get64(const RegAddr &addr) const {
|
|
const unsigned idx_lo = index(addr);
|
|
const unsigned idx_hi = idx_lo + 1;
|
|
return (((uint64_t)vector[idx_hi]) << 32) | vector[idx_lo];
|
|
}
|
|
|
|
/**
|
|
* Helper function to set a 64-bit register.
|
|
*
|
|
* @param addr Address to the low part of the register.
|
|
* @param value Value to write into the 64-bit register.
|
|
*/
|
|
void set64(const RegAddr &addr, uint64_t value) {
|
|
const unsigned idx_lo = index(addr);
|
|
const unsigned idx_hi = idx_lo + 1;
|
|
vector[idx_lo] = value & 0xFFFFFFFF;
|
|
vector[idx_hi] = (value >> 32) & 0xFFFFFFFF;
|
|
}
|
|
|
|
const uint32_t &operator[](const RegAddr &addr) const {
|
|
return vector[index(addr)];
|
|
}
|
|
|
|
uint32_t &operator[](const RegAddr &addr) {
|
|
return vector[index(addr)];
|
|
}
|
|
|
|
|
|
iterator begin() noexcept { return vector.begin(); }
|
|
const_iterator begin() const noexcept { return vector.begin(); }
|
|
const_iterator cbegin() const noexcept { return vector.cbegin(); }
|
|
|
|
iterator end() noexcept { return vector.end(); }
|
|
const_iterator end() const noexcept { return vector.end(); }
|
|
const_iterator cend() const noexcept { return vector.cend(); }
|
|
|
|
const size_type size() const noexcept { return vector.size(); }
|
|
|
|
private:
|
|
// Disable default constructor
|
|
RegVector();
|
|
|
|
static uint32_t index(const RegAddr &addr) {
|
|
assert((addr.value & 0x3) == 0);
|
|
return addr.value >> 2;
|
|
}
|
|
|
|
|
|
vector_t vector;
|
|
};
|
|
/** @} */
|
|
|
|
/**
|
|
* Class representing the status codes in the Midgard architecture.
|
|
*/
|
|
struct Status {
|
|
/**
|
|
* Class representing the subsystem a status code originates from.
|
|
*/
|
|
enum StatusClass {
|
|
CLASS_NOFAULT = 0,
|
|
CLASS_JOB = 1,
|
|
CLASS_GPU = 2,
|
|
CLASS_MMU = 3,
|
|
};
|
|
|
|
typedef uint8_t Code;
|
|
typedef uint8_t SubCode;
|
|
|
|
Status(StatusClass cls, Code code, SubCode subcode)
|
|
: value((cls << 6) | (code << 3) | subcode) {
|
|
assert((cls & ~0x3) == 0);
|
|
assert((code & ~0x7) == 0);
|
|
assert((subcode & ~0x7) == 0);
|
|
}
|
|
|
|
explicit Status(uint8_t v)
|
|
: value(v) {}
|
|
|
|
StatusClass statusClass() const {
|
|
return (StatusClass)((value >> 6) & 0x3);
|
|
}
|
|
|
|
Code code() const {
|
|
return (value >> 3) & 0x7;
|
|
}
|
|
|
|
SubCode subCode() const {
|
|
return value & 0x7;
|
|
}
|
|
|
|
const uint8_t value;
|
|
};
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|