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