110915Sandreas.sandberg@arm.com/* 210915Sandreas.sandberg@arm.com * Copyright (c) 2014-2015 ARM Limited 310915Sandreas.sandberg@arm.com * All rights reserved 410915Sandreas.sandberg@arm.com * 510915Sandreas.sandberg@arm.com * Licensed under the Apache License, Version 2.0 (the "License"); 610915Sandreas.sandberg@arm.com * you may not use this file except in compliance with the License. 710915Sandreas.sandberg@arm.com * You may obtain a copy of the License at 810915Sandreas.sandberg@arm.com * 910915Sandreas.sandberg@arm.com * http://www.apache.org/licenses/LICENSE-2.0 1010915Sandreas.sandberg@arm.com * 1110915Sandreas.sandberg@arm.com * Unless required by applicable law or agreed to in writing, software 1210915Sandreas.sandberg@arm.com * distributed under the License is distributed on an "AS IS" BASIS, 1310915Sandreas.sandberg@arm.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1410915Sandreas.sandberg@arm.com * See the License for the specific language governing permissions and 1510915Sandreas.sandberg@arm.com * limitations under the License. 1610915Sandreas.sandberg@arm.com * 1710915Sandreas.sandberg@arm.com * Authors: Andreas Sandberg 1810915Sandreas.sandberg@arm.com */ 1910915Sandreas.sandberg@arm.com 2010915Sandreas.sandberg@arm.com#ifndef _LIBNOMALIMODEL_TYPES_HH 2110915Sandreas.sandberg@arm.com#define _LIBNOMALIMODEL_TYPES_HH 2210915Sandreas.sandberg@arm.com 2310915Sandreas.sandberg@arm.com#include <cassert> 2410915Sandreas.sandberg@arm.com#include <cstdint> 2510915Sandreas.sandberg@arm.com 2610915Sandreas.sandberg@arm.com#include <utility> 2710915Sandreas.sandberg@arm.com#include <vector> 2810915Sandreas.sandberg@arm.com 2910915Sandreas.sandberg@arm.comnamespace NoMali{ 3010915Sandreas.sandberg@arm.com 3110915Sandreas.sandberg@arm.com/** 3210915Sandreas.sandberg@arm.com * @{ 3310915Sandreas.sandberg@arm.com * @name Register handling utilities 3410915Sandreas.sandberg@arm.com */ 3510915Sandreas.sandberg@arm.com 3610915Sandreas.sandberg@arm.com/** 3710915Sandreas.sandberg@arm.com * Register address wrapper 3810915Sandreas.sandberg@arm.com * 3910915Sandreas.sandberg@arm.com * This class wraps a register address. Unlike a simple typedef, this 4010915Sandreas.sandberg@arm.com * provides safety from automatic type conversions from other integer 4110915Sandreas.sandberg@arm.com * types since the constructor must be called explicitly. 4210915Sandreas.sandberg@arm.com */ 4310915Sandreas.sandberg@arm.comstruct RegAddr { 4410915Sandreas.sandberg@arm.com explicit RegAddr(uint32_t v) 4510915Sandreas.sandberg@arm.com : value(v) {} 4610915Sandreas.sandberg@arm.com 4710915Sandreas.sandberg@arm.com const uint32_t value; 4810915Sandreas.sandberg@arm.com}; 4910915Sandreas.sandberg@arm.com 5010915Sandreas.sandberg@arm.cominline bool 5110915Sandreas.sandberg@arm.comoperator<(const RegAddr &lhs, const RegAddr &rhs) { 5210915Sandreas.sandberg@arm.com return lhs.value < rhs.value; 5310915Sandreas.sandberg@arm.com} 5410915Sandreas.sandberg@arm.com 5510915Sandreas.sandberg@arm.cominline bool 5610915Sandreas.sandberg@arm.comoperator>(const RegAddr &lhs, const RegAddr &rhs) { 5710915Sandreas.sandberg@arm.com return lhs.value > rhs.value; 5810915Sandreas.sandberg@arm.com} 5910915Sandreas.sandberg@arm.com 6010915Sandreas.sandberg@arm.cominline bool 6110915Sandreas.sandberg@arm.comoperator<=(const RegAddr &lhs, const RegAddr &rhs) { 6210915Sandreas.sandberg@arm.com return lhs.value <= rhs.value; 6310915Sandreas.sandberg@arm.com} 6410915Sandreas.sandberg@arm.com 6510915Sandreas.sandberg@arm.cominline bool 6610915Sandreas.sandberg@arm.comoperator>=(const RegAddr &lhs, const RegAddr &rhs) { 6710915Sandreas.sandberg@arm.com return lhs.value >= rhs.value; 6810915Sandreas.sandberg@arm.com} 6910915Sandreas.sandberg@arm.com 7010915Sandreas.sandberg@arm.cominline bool 7110915Sandreas.sandberg@arm.comoperator==(const RegAddr &lhs, const RegAddr &rhs) { 7210915Sandreas.sandberg@arm.com return lhs.value == rhs.value; 7310915Sandreas.sandberg@arm.com} 7410915Sandreas.sandberg@arm.com 7510915Sandreas.sandberg@arm.cominline bool 7610915Sandreas.sandberg@arm.comoperator!=(const RegAddr &lhs, const RegAddr &rhs) { 7710915Sandreas.sandberg@arm.com return lhs.value != rhs.value; 7810915Sandreas.sandberg@arm.com} 7910915Sandreas.sandberg@arm.com 8010915Sandreas.sandberg@arm.cominline RegAddr 8110915Sandreas.sandberg@arm.comoperator+(const RegAddr &lhs, const RegAddr &rhs) { 8210915Sandreas.sandberg@arm.com return RegAddr(lhs.value + rhs.value); 8310915Sandreas.sandberg@arm.com} 8410915Sandreas.sandberg@arm.com 8510915Sandreas.sandberg@arm.cominline RegAddr 8610915Sandreas.sandberg@arm.comoperator-(const RegAddr &lhs, const RegAddr &rhs) { 8710915Sandreas.sandberg@arm.com assert(lhs >= rhs); 8810915Sandreas.sandberg@arm.com return RegAddr(lhs.value - rhs.value); 8910915Sandreas.sandberg@arm.com} 9010915Sandreas.sandberg@arm.com 9110915Sandreas.sandberg@arm.com/** 9210915Sandreas.sandberg@arm.com * Class for register storage 9310915Sandreas.sandberg@arm.com * 9410915Sandreas.sandberg@arm.com * This class wraps a std::vector and implements a subset of its 9510915Sandreas.sandberg@arm.com * functionality. Specifically, it is constant size and prevents 9610915Sandreas.sandberg@arm.com * indexing with anything other than RegAddr instances. 9710915Sandreas.sandberg@arm.com */ 9810915Sandreas.sandberg@arm.comclass RegVector 9910915Sandreas.sandberg@arm.com{ 10010915Sandreas.sandberg@arm.com private: 10110915Sandreas.sandberg@arm.com typedef std::vector<uint32_t> vector_t; 10210915Sandreas.sandberg@arm.com 10310915Sandreas.sandberg@arm.com public: 10410915Sandreas.sandberg@arm.com typedef vector_t::iterator iterator; 10510915Sandreas.sandberg@arm.com typedef vector_t::const_iterator const_iterator; 10610915Sandreas.sandberg@arm.com typedef vector_t::size_type size_type; 10710915Sandreas.sandberg@arm.com 10810915Sandreas.sandberg@arm.com public: 10910915Sandreas.sandberg@arm.com RegVector(size_type size) 11010915Sandreas.sandberg@arm.com : vector(size, 0) {} 11110915Sandreas.sandberg@arm.com 11210915Sandreas.sandberg@arm.com /** @{ */ 11310915Sandreas.sandberg@arm.com /** 11410915Sandreas.sandberg@arm.com * Helper function to get a 64-bit register. 11510915Sandreas.sandberg@arm.com * 11610915Sandreas.sandberg@arm.com * @param addr Address to the low part of the register. 11710915Sandreas.sandberg@arm.com * @return 64-bit value representing the concatenation of the HI 11810915Sandreas.sandberg@arm.com * and LO parts of the register. 11910915Sandreas.sandberg@arm.com */ 12010915Sandreas.sandberg@arm.com const uint32_t get64(const RegAddr &addr) const { 12110915Sandreas.sandberg@arm.com const unsigned idx_lo = index(addr); 12210915Sandreas.sandberg@arm.com const unsigned idx_hi = idx_lo + 1; 12310915Sandreas.sandberg@arm.com return (((uint64_t)vector[idx_hi]) << 32) | vector[idx_lo]; 12410915Sandreas.sandberg@arm.com } 12510915Sandreas.sandberg@arm.com 12610915Sandreas.sandberg@arm.com /** 12710915Sandreas.sandberg@arm.com * Helper function to set a 64-bit register. 12810915Sandreas.sandberg@arm.com * 12910915Sandreas.sandberg@arm.com * @param addr Address to the low part of the register. 13010915Sandreas.sandberg@arm.com * @param value Value to write into the 64-bit register. 13110915Sandreas.sandberg@arm.com */ 13210915Sandreas.sandberg@arm.com void set64(const RegAddr &addr, uint64_t value) { 13310915Sandreas.sandberg@arm.com const unsigned idx_lo = index(addr); 13410915Sandreas.sandberg@arm.com const unsigned idx_hi = idx_lo + 1; 13510915Sandreas.sandberg@arm.com vector[idx_lo] = value & 0xFFFFFFFF; 13610915Sandreas.sandberg@arm.com vector[idx_hi] = (value >> 32) & 0xFFFFFFFF; 13710915Sandreas.sandberg@arm.com } 13810915Sandreas.sandberg@arm.com 13910915Sandreas.sandberg@arm.com const uint32_t &operator[](const RegAddr &addr) const { 14010915Sandreas.sandberg@arm.com return vector[index(addr)]; 14110915Sandreas.sandberg@arm.com } 14210915Sandreas.sandberg@arm.com 14310915Sandreas.sandberg@arm.com uint32_t &operator[](const RegAddr &addr) { 14410915Sandreas.sandberg@arm.com return vector[index(addr)]; 14510915Sandreas.sandberg@arm.com } 14610915Sandreas.sandberg@arm.com 14710915Sandreas.sandberg@arm.com 14810915Sandreas.sandberg@arm.com iterator begin() noexcept { return vector.begin(); } 14910915Sandreas.sandberg@arm.com const_iterator begin() const noexcept { return vector.begin(); } 15010915Sandreas.sandberg@arm.com const_iterator cbegin() const noexcept { return vector.cbegin(); } 15110915Sandreas.sandberg@arm.com 15210915Sandreas.sandberg@arm.com iterator end() noexcept { return vector.end(); } 15310915Sandreas.sandberg@arm.com const_iterator end() const noexcept { return vector.end(); } 15410915Sandreas.sandberg@arm.com const_iterator cend() const noexcept { return vector.cend(); } 15510915Sandreas.sandberg@arm.com 15610915Sandreas.sandberg@arm.com const size_type size() const noexcept { return vector.size(); } 15710915Sandreas.sandberg@arm.com 15810915Sandreas.sandberg@arm.com private: 15910915Sandreas.sandberg@arm.com // Disable default constructor 16010915Sandreas.sandberg@arm.com RegVector(); 16110915Sandreas.sandberg@arm.com 16210915Sandreas.sandberg@arm.com static uint32_t index(const RegAddr &addr) { 16310915Sandreas.sandberg@arm.com assert((addr.value & 0x3) == 0); 16410915Sandreas.sandberg@arm.com return addr.value >> 2; 16510915Sandreas.sandberg@arm.com } 16610915Sandreas.sandberg@arm.com 16710915Sandreas.sandberg@arm.com 16810915Sandreas.sandberg@arm.com vector_t vector; 16910915Sandreas.sandberg@arm.com}; 17010915Sandreas.sandberg@arm.com/** @} */ 17110915Sandreas.sandberg@arm.com 17210915Sandreas.sandberg@arm.com/** 17310915Sandreas.sandberg@arm.com * Class representing the status codes in the Midgard architecture. 17410915Sandreas.sandberg@arm.com */ 17510915Sandreas.sandberg@arm.comstruct Status { 17610915Sandreas.sandberg@arm.com /** 17710915Sandreas.sandberg@arm.com * Class representing the subsystem a status code originates from. 17810915Sandreas.sandberg@arm.com */ 17910915Sandreas.sandberg@arm.com enum StatusClass { 18010915Sandreas.sandberg@arm.com CLASS_NOFAULT = 0, 18110915Sandreas.sandberg@arm.com CLASS_JOB = 1, 18210915Sandreas.sandberg@arm.com CLASS_GPU = 2, 18310915Sandreas.sandberg@arm.com CLASS_MMU = 3, 18410915Sandreas.sandberg@arm.com }; 18510915Sandreas.sandberg@arm.com 18610915Sandreas.sandberg@arm.com typedef uint8_t Code; 18710915Sandreas.sandberg@arm.com typedef uint8_t SubCode; 18810915Sandreas.sandberg@arm.com 18910915Sandreas.sandberg@arm.com Status(StatusClass cls, Code code, SubCode subcode) 19010915Sandreas.sandberg@arm.com : value((cls << 6) | (code << 3) | subcode) { 19110915Sandreas.sandberg@arm.com assert((cls & ~0x3) == 0); 19210915Sandreas.sandberg@arm.com assert((code & ~0x7) == 0); 19310915Sandreas.sandberg@arm.com assert((subcode & ~0x7) == 0); 19410915Sandreas.sandberg@arm.com } 19510915Sandreas.sandberg@arm.com 19610915Sandreas.sandberg@arm.com explicit Status(uint8_t v) 19710915Sandreas.sandberg@arm.com : value(v) {} 19810915Sandreas.sandberg@arm.com 19910915Sandreas.sandberg@arm.com StatusClass statusClass() const { 20010915Sandreas.sandberg@arm.com return (StatusClass)((value >> 6) & 0x3); 20110915Sandreas.sandberg@arm.com } 20210915Sandreas.sandberg@arm.com 20310915Sandreas.sandberg@arm.com Code code() const { 20410915Sandreas.sandberg@arm.com return (value >> 3) & 0x7; 20510915Sandreas.sandberg@arm.com } 20610915Sandreas.sandberg@arm.com 20710915Sandreas.sandberg@arm.com SubCode subCode() const { 20810915Sandreas.sandberg@arm.com return value & 0x7; 20910915Sandreas.sandberg@arm.com } 21010915Sandreas.sandberg@arm.com 21110915Sandreas.sandberg@arm.com const uint8_t value; 21210915Sandreas.sandberg@arm.com}; 21310915Sandreas.sandberg@arm.com 21410915Sandreas.sandberg@arm.com 21510915Sandreas.sandberg@arm.com} 21610915Sandreas.sandberg@arm.com 21710915Sandreas.sandberg@arm.com#endif 21810915Sandreas.sandberg@arm.com 219