1/* 2 * Copyright (c) 2014-2015 ARM Limited 3 * All rights reserved 4 * 5 * Licensed under the Apache License, Version 2.0 (the "License"); 6 * you may not use this file except in compliance with the License. 7 * You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 * 17 * Authors: Andreas Sandberg 18 */ 19 20#ifndef _LIBNOMALIMODEL_TYPES_HH 21#define _LIBNOMALIMODEL_TYPES_HH 22 23#include <cassert> 24#include <cstdint> 25 26#include <utility> 27#include <vector> 28 29namespace NoMali{ 30 31/** 32 * @{ 33 * @name Register handling utilities 34 */ 35 36/** 37 * Register address wrapper 38 * 39 * This class wraps a register address. Unlike a simple typedef, this 40 * provides safety from automatic type conversions from other integer 41 * types since the constructor must be called explicitly. 42 */ 43struct RegAddr { 44 explicit RegAddr(uint32_t v) 45 : value(v) {} 46 47 const uint32_t value; 48}; 49 50inline bool 51operator<(const RegAddr &lhs, const RegAddr &rhs) { 52 return lhs.value < rhs.value; 53} 54 55inline bool 56operator>(const RegAddr &lhs, const RegAddr &rhs) { 57 return lhs.value > rhs.value; 58} 59 60inline bool 61operator<=(const RegAddr &lhs, const RegAddr &rhs) { 62 return lhs.value <= rhs.value; 63} 64 65inline bool 66operator>=(const RegAddr &lhs, const RegAddr &rhs) { 67 return lhs.value >= rhs.value; 68} 69 70inline bool 71operator==(const RegAddr &lhs, const RegAddr &rhs) { 72 return lhs.value == rhs.value; 73} 74 75inline bool 76operator!=(const RegAddr &lhs, const RegAddr &rhs) { 77 return lhs.value != rhs.value; 78} 79 80inline RegAddr 81operator+(const RegAddr &lhs, const RegAddr &rhs) { 82 return RegAddr(lhs.value + rhs.value); 83} 84 85inline RegAddr 86operator-(const RegAddr &lhs, const RegAddr &rhs) { 87 assert(lhs >= rhs); 88 return RegAddr(lhs.value - rhs.value); 89} 90 91/** 92 * Class for register storage 93 * 94 * This class wraps a std::vector and implements a subset of its 95 * functionality. Specifically, it is constant size and prevents 96 * indexing with anything other than RegAddr instances. 97 */ 98class RegVector 99{ 100 private: 101 typedef std::vector<uint32_t> vector_t; 102 103 public: 104 typedef vector_t::iterator iterator; 105 typedef vector_t::const_iterator const_iterator; 106 typedef vector_t::size_type size_type; 107 108 public: 109 RegVector(size_type size) 110 : vector(size, 0) {} 111 112 /** @{ */ 113 /** 114 * Helper function to get a 64-bit register. 115 * 116 * @param addr Address to the low part of the register. 117 * @return 64-bit value representing the concatenation of the HI 118 * and LO parts of the register. 119 */ 120 const uint32_t get64(const RegAddr &addr) const { 121 const unsigned idx_lo = index(addr); 122 const unsigned idx_hi = idx_lo + 1; 123 return (((uint64_t)vector[idx_hi]) << 32) | vector[idx_lo]; 124 } 125 126 /** 127 * Helper function to set a 64-bit register. 128 * 129 * @param addr Address to the low part of the register. 130 * @param value Value to write into the 64-bit register. 131 */ 132 void set64(const RegAddr &addr, uint64_t value) { 133 const unsigned idx_lo = index(addr); 134 const unsigned idx_hi = idx_lo + 1; 135 vector[idx_lo] = value & 0xFFFFFFFF; 136 vector[idx_hi] = (value >> 32) & 0xFFFFFFFF; 137 } 138 139 const uint32_t &operator[](const RegAddr &addr) const { 140 return vector[index(addr)]; 141 } 142 143 uint32_t &operator[](const RegAddr &addr) { 144 return vector[index(addr)]; 145 } 146 147 148 iterator begin() noexcept { return vector.begin(); } 149 const_iterator begin() const noexcept { return vector.begin(); } 150 const_iterator cbegin() const noexcept { return vector.cbegin(); } 151 152 iterator end() noexcept { return vector.end(); } 153 const_iterator end() const noexcept { return vector.end(); } 154 const_iterator cend() const noexcept { return vector.cend(); } 155 156 const size_type size() const noexcept { return vector.size(); } 157 158 private: 159 // Disable default constructor 160 RegVector(); 161 162 static uint32_t index(const RegAddr &addr) { 163 assert((addr.value & 0x3) == 0); 164 return addr.value >> 2; 165 } 166 167 168 vector_t vector; 169}; 170/** @} */ 171 172/** 173 * Class representing the status codes in the Midgard architecture. 174 */ 175struct Status { 176 /** 177 * Class representing the subsystem a status code originates from. 178 */ 179 enum StatusClass { 180 CLASS_NOFAULT = 0, 181 CLASS_JOB = 1, 182 CLASS_GPU = 2, 183 CLASS_MMU = 3, 184 }; 185 186 typedef uint8_t Code; 187 typedef uint8_t SubCode; 188 189 Status(StatusClass cls, Code code, SubCode subcode) 190 : value((cls << 6) | (code << 3) | subcode) { 191 assert((cls & ~0x3) == 0); 192 assert((code & ~0x7) == 0); 193 assert((subcode & ~0x7) == 0); 194 } 195 196 explicit Status(uint8_t v) 197 : value(v) {} 198 199 StatusClass statusClass() const { 200 return (StatusClass)((value >> 6) & 0x3); 201 } 202 203 Code code() const { 204 return (value >> 3) & 0x7; 205 } 206 207 SubCode subCode() const { 208 return value & 0x7; 209 } 210 211 const uint8_t value; 212}; 213 214 215} 216 217#endif 218 219