diff options
Diffstat (limited to 'ext/nomali/lib/types.hh')
-rw-r--r-- | ext/nomali/lib/types.hh | 218 |
1 files changed, 218 insertions, 0 deletions
diff --git a/ext/nomali/lib/types.hh b/ext/nomali/lib/types.hh new file mode 100644 index 000000000..7d2d6e1f6 --- /dev/null +++ b/ext/nomali/lib/types.hh @@ -0,0 +1,218 @@ +/* + * 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 + |