1/* 2 * Copyright (c) 2014-2015 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 "gpublock.hh" 21 22#include "gpu.hh" 23#include "regutils.hh" 24 25namespace NoMali { 26 27GPUBlock::GPUBlock(GPU &_gpu) 28 : gpu(_gpu), regs(BLOCK_NUM_REGS) 29{ 30} 31 32GPUBlock::GPUBlock(GPU &_gpu, RegVector::size_type no_regs) 33 : gpu(_gpu), regs(no_regs) 34{ 35} 36 37GPUBlock::GPUBlock(GPUBlock &&rhs) 38 : gpu(rhs.gpu), 39 regs(std::move(rhs.regs)) 40{ 41} 42 43GPUBlock::~GPUBlock() 44{ 45} 46 47void 48GPUBlock::reset() 49{ 50 for (auto &r : regs) 51 r = 0; 52} 53 54uint32_t 55GPUBlock::readReg(RegAddr addr) 56{ 57 return readRegRaw(addr); 58} 59 60void 61GPUBlock::writeReg(RegAddr addr, uint32_t value) 62{ 63 writeRegRaw(addr, value); 64} 65 66uint32_t 67GPUBlock::readRegRaw(RegAddr addr) 68{ 69 return regs[addr]; 70} 71 72void 73GPUBlock::writeRegRaw(RegAddr addr, uint32_t value) 74{ 75 regs[addr] = value; 76} 77 78 79 80GPUBlockInt::GPUBlockInt(GPU &_gpu, 81 const RegAddr &irq_raw_stat, 82 const RegAddr &irq_clear, 83 const RegAddr &irq_mask, 84 const RegAddr &irq_stat) 85 : GPUBlock(_gpu), 86 addrIrqRawStat(irq_raw_stat), addrIrqClear(irq_clear), 87 addrIrqMask(irq_mask), addrIrqStat(irq_stat) 88{ 89} 90 91GPUBlockInt::~GPUBlockInt() 92{ 93} 94 95uint32_t 96GPUBlockInt::readReg(RegAddr addr) 97{ 98 if (addr == addrIrqStat) { 99 return irqStatus(); 100 } else { 101 return GPUBlock::readReg(addr); 102 } 103} 104 105void 106GPUBlockInt::writeReg(RegAddr addr, uint32_t value) 107{ 108 if (addr == addrIrqRawStat) { 109 raiseInterrupt(value); 110 } else if (addr == addrIrqClear) { 111 clearInterrupt(value); 112 } else if (addr == addrIrqMask ) { 113 const bool old_int(intAsserted()); 114 GPUBlock::writeReg(addr, value); 115 if (old_int != intAsserted()) 116 onInterrupt(intAsserted()); 117 } else if (addr == addrIrqStat ) { 118 // Ignore writes to the IRQ status register 119 } else { 120 // Handle addrIrqMask & defaults 121 GPUBlock::writeReg(addr, value); 122 } 123} 124 125 126 127void 128GPUBlockInt::raiseInterrupt(uint32_t ints) 129{ 130 const bool old_int(intAsserted()); 131 132 regs[addrIrqRawStat] |= ints; 133 // Is the interrupt line going high? 134 if (!old_int && intAsserted()) 135 onInterrupt(1); 136} 137 138void 139GPUBlockInt::clearInterrupt(uint32_t ints) 140{ 141 const bool old_int(intAsserted()); 142 143 regs[addrIrqRawStat] &= ~ints; 144 // Is the interrupt line going low? 145 if (old_int && !intAsserted()) 146 onInterrupt(0); 147} 148 149uint32_t 150GPUBlockInt::irqStatus() const 151{ 152 return regs[addrIrqRawStat] & regs[addrIrqMask]; 153} 154 155 156} 157