summaryrefslogtreecommitdiff
path: root/ext/nomali/lib/regutils.hh
blob: 841c684c5263f6852859fe4d27927d682cd57368 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
/*
 * Copyright (c) 2014-2016 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_REGUTILS_HH
#define _LIBNOMALIMODEL_REGUTILS_HH

#include <cassert>

#include "types.hh"
#include "mali_midg_regmap.h"

namespace NoMali {

/** Size of a function block in bytes */
static const uint32_t BLOCK_REGS_SIZE(0x1000);
/** Number of registers in a function block */
static const uint32_t BLOCK_NUM_REGS = BLOCK_REGS_SIZE >> 2;

/**
 * Register blocks within the GPU.
 *
 * The GPU splits its register space into chunks belonging to specific
 * blocks. This enum lists those blocks.
 */
enum class RegBlock : uint16_t {
    GPU = 0x0,
    JOB = 0x1,
    MMU = 0x2,

    UNKNOWN = 0xFFFF,
};

/** Get the register block from a GPU register address */
static inline RegBlock
getRegBlock(RegAddr addr)
{
    return RegBlock(addr.value >> 12);
}

/**
 * Get the register address within a GPU block.
 *
 * This method masks away the block offset from a GPU register
 * address. The resulting address is the address <i>within</i> a
 * function block.
 */
static inline RegAddr
getBlockReg(RegAddr addr)
{
    static_assert((BLOCK_REGS_SIZE & (BLOCK_REGS_SIZE - 1)) == 0,
                  "BLOCK_REGS_SIZE is not a power of 2");
    return RegAddr(addr.value & (BLOCK_REGS_SIZE - 1));
}

/**
 * Get the slot number owning an address within the JobControl block.
 *
 * @param Address relative to the JobControl block.
 */
static inline unsigned
getJobSlotNo(const RegAddr &addr)
{
    assert(addr.value >= JOB_SLOT0);
    assert(addr.value <= 0xFFF);
    return (addr.value - JOB_SLOT0) >> 7;
}

/**
 * Get a JobSlot-relative address from a JobControl-relative address.
 *
 * @param Address relative to the JobControl block.
 * @return Address relative the start of the JobSlot.
 */
static inline RegAddr
getJobSlotAddr(const RegAddr &addr)
{
    const unsigned slot_no(getJobSlotNo(addr));
    const RegAddr slot_base(RegAddr(JOB_SLOT0 + slot_no * 0x80));
    return addr - slot_base;
}


/** Number of registers per job slot */
static const unsigned JSn_NO_REGS = 0x20;

/**
 * Does this MMU register belong to an address space block?
 *
 * @return 1 if the address maps to a valid address space block, 0
 * otherwise.
 */
static inline bool
isAddrSpaceReg(const RegAddr &addr)
{
    return addr.value >= MMU_AS0 && addr.value <= 0x7FF;
}

/**
 * Get the address space number owning an address within the MMU
 * block.
 *
 * @param addr Address relative to the JobControl block.
 */
static inline unsigned
getAddrSpaceNo(const RegAddr &addr)
{
    assert(isAddrSpaceReg(addr));
    return (addr.value - MMU_AS0) >> 6;
}

/**
 * Get a AS-relative address from a MMU-relative
 * address.
 *
 * @param addr Address relative to the MMU block.
 * @return Address relative the start of the address space block.
 */
static inline RegAddr
getAddrSpaceAddr(const RegAddr &addr)
{
    const unsigned as_no(getAddrSpaceNo(addr));
    const RegAddr as_base(RegAddr(MMU_AS0 + as_no * 0x40));
    return addr - as_base;
}

/** Number of registers per address space */
static const unsigned ASn_NO_REGS = 0x10;

}

#endif //_LIBNOMALIMODEL_REGUTILS_HH