1/*
2 * Copyright (c) 2014-2016 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_REGUTILS_HH
21#define _LIBNOMALIMODEL_REGUTILS_HH
22
23#include <cassert>
24
25#include "types.hh"
26#include "mali_midg_regmap.h"
27
28namespace NoMali {
29
30/** Size of a function block in bytes */
31static const uint32_t BLOCK_REGS_SIZE(0x1000);
32/** Number of registers in a function block */
33static const uint32_t BLOCK_NUM_REGS = BLOCK_REGS_SIZE >> 2;
34
35/**
36 * Register blocks within the GPU.
37 *
38 * The GPU splits its register space into chunks belonging to specific
39 * blocks. This enum lists those blocks.
40 */
41enum class RegBlock : uint16_t {
42    GPU = 0x0,
43    JOB = 0x1,
44    MMU = 0x2,
45
46    UNKNOWN = 0xFFFF,
47};
48
49/** Get the register block from a GPU register address */
50static inline RegBlock
51getRegBlock(RegAddr addr)
52{
53    return RegBlock(addr.value >> 12);
54}
55
56/**
57 * Get the register address within a GPU block.
58 *
59 * This method masks away the block offset from a GPU register
60 * address. The resulting address is the address <i>within</i> a
61 * function block.
62 */
63static inline RegAddr
64getBlockReg(RegAddr addr)
65{
66    static_assert((BLOCK_REGS_SIZE & (BLOCK_REGS_SIZE - 1)) == 0,
67                  "BLOCK_REGS_SIZE is not a power of 2");
68    return RegAddr(addr.value & (BLOCK_REGS_SIZE - 1));
69}
70
71/**
72 * Get the slot number owning an address within the JobControl block.
73 *
74 * @param Address relative to the JobControl block.
75 */
76static inline unsigned
77getJobSlotNo(const RegAddr &addr)
78{
79    assert(addr.value >= JOB_SLOT0);
80    assert(addr.value <= 0xFFF);
81    return (addr.value - JOB_SLOT0) >> 7;
82}
83
84/**
85 * Get a JobSlot-relative address from a JobControl-relative address.
86 *
87 * @param Address relative to the JobControl block.
88 * @return Address relative the start of the JobSlot.
89 */
90static inline RegAddr
91getJobSlotAddr(const RegAddr &addr)
92{
93    const unsigned slot_no(getJobSlotNo(addr));
94    const RegAddr slot_base(RegAddr(JOB_SLOT0 + slot_no * 0x80));
95    return addr - slot_base;
96}
97
98
99/** Number of registers per job slot */
100static const unsigned JSn_NO_REGS = 0x20;
101
102/**
103 * Does this MMU register belong to an address space block?
104 *
105 * @return 1 if the address maps to a valid address space block, 0
106 * otherwise.
107 */
108static inline bool
109isAddrSpaceReg(const RegAddr &addr)
110{
111    return addr.value >= MMU_AS0 && addr.value <= 0x7FF;
112}
113
114/**
115 * Get the address space number owning an address within the MMU
116 * block.
117 *
118 * @param addr Address relative to the JobControl block.
119 */
120static inline unsigned
121getAddrSpaceNo(const RegAddr &addr)
122{
123    assert(isAddrSpaceReg(addr));
124    return (addr.value - MMU_AS0) >> 6;
125}
126
127/**
128 * Get a AS-relative address from a MMU-relative
129 * address.
130 *
131 * @param addr Address relative to the MMU block.
132 * @return Address relative the start of the address space block.
133 */
134static inline RegAddr
135getAddrSpaceAddr(const RegAddr &addr)
136{
137    const unsigned as_no(getAddrSpaceNo(addr));
138    const RegAddr as_base(RegAddr(MMU_AS0 + as_no * 0x40));
139    return addr - as_base;
140}
141
142/** Number of registers per address space */
143static const unsigned ASn_NO_REGS = 0x10;
144
145}
146
147#endif //_LIBNOMALIMODEL_REGUTILS_HH
148