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#include "mmu.hh"
21
22#include "gpu.hh"
23#include "regutils.hh"
24
25namespace NoMali {
26
27MMU::MMU(GPU &_gpu)
28    : GPUBlockInt(_gpu,
29                  RegAddr(MMU_IRQ_RAWSTAT),
30                  RegAddr(MMU_IRQ_CLEAR),
31                  RegAddr(MMU_IRQ_MASK),
32                  RegAddr(MMU_IRQ_STATUS))
33{
34    spaces.reserve(16);
35    for (int i = 0; i < 16; ++i)
36        spaces.emplace_back(_gpu, *this, i);
37}
38
39MMU::~MMU()
40{
41}
42
43void
44MMU::reset()
45{
46    GPUBlockInt::reset();
47
48    for (auto &as : spaces)
49        as.reset();
50}
51
52uint32_t
53MMU::readReg(RegAddr addr)
54{
55    if (isAddrSpaceReg(addr)) {
56        return spaces[getAddrSpaceNo(addr)].readReg(getAddrSpaceAddr(addr));
57    } else {
58        return GPUBlockInt::readReg(addr);
59    }
60}
61
62void
63MMU::writeReg(RegAddr addr, uint32_t value)
64{
65    switch (addr.value) {
66      case MMU_IRQ_RAWSTAT:
67      case MMU_IRQ_CLEAR:
68      case MMU_IRQ_MASK:
69      case MMU_IRQ_STATUS:
70        GPUBlockInt::writeReg(addr, value);
71        break;
72
73      default:
74        if (isAddrSpaceReg(addr)) {
75            AddrSpace &as(spaces[getAddrSpaceNo(addr)]);
76            as.writeReg(getAddrSpaceAddr(addr), value);
77        }
78        break;
79    };
80}
81
82uint32_t
83MMU::readRegRaw(RegAddr addr)
84{
85    if (isAddrSpaceReg(addr)) {
86        return spaces[getAddrSpaceNo(addr)].readRegRaw(getAddrSpaceAddr(addr));
87    } else {
88        return GPUBlockInt::readRegRaw(addr);
89    }
90}
91
92void
93MMU::writeRegRaw(RegAddr addr, uint32_t value)
94{
95    if (isAddrSpaceReg(addr)) {
96        spaces[getAddrSpaceNo(addr)].writeRegRaw(getAddrSpaceAddr(addr), value);
97    } else {
98        GPUBlockInt::writeRegRaw(addr, value);
99    }
100}
101
102void
103MMU::onInterrupt(int set)
104{
105    gpu.intMMU(set);
106}
107
108}
109