c274057840
Add revision 9adf9d6e2d889a483a92136c96eb8a434d360561 of NoMali-model from https://github.com/ARM-software/nomali-model. This library implements the register interface of the Mali T6xx/T7xx series GPUs, but doesn't do any rendering. It can be used to hide the effects of software rendering.
156 lines
3.1 KiB
C++
156 lines
3.1 KiB
C++
/*
|
|
* Copyright (c) 2014-2015 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
|
|
*/
|
|
|
|
#include "gpublock.hh"
|
|
|
|
#include "gpu.hh"
|
|
#include "regutils.hh"
|
|
|
|
namespace NoMali {
|
|
|
|
GPUBlock::GPUBlock(GPU &_gpu)
|
|
: gpu(_gpu), regs(BLOCK_NUM_REGS)
|
|
{
|
|
}
|
|
|
|
GPUBlock::GPUBlock(GPU &_gpu, RegVector::size_type no_regs)
|
|
: gpu(_gpu), regs(no_regs)
|
|
{
|
|
}
|
|
|
|
GPUBlock::GPUBlock(GPUBlock &&rhs)
|
|
: gpu(rhs.gpu),
|
|
regs(std::move(rhs.regs))
|
|
{
|
|
}
|
|
|
|
GPUBlock::~GPUBlock()
|
|
{
|
|
}
|
|
|
|
void
|
|
GPUBlock::reset()
|
|
{
|
|
for (auto &r : regs)
|
|
r = 0;
|
|
}
|
|
|
|
uint32_t
|
|
GPUBlock::readReg(RegAddr addr)
|
|
{
|
|
return readRegRaw(addr);
|
|
}
|
|
|
|
void
|
|
GPUBlock::writeReg(RegAddr addr, uint32_t value)
|
|
{
|
|
writeRegRaw(addr, value);
|
|
}
|
|
|
|
uint32_t
|
|
GPUBlock::readRegRaw(RegAddr addr)
|
|
{
|
|
return regs[addr];
|
|
}
|
|
|
|
void
|
|
GPUBlock::writeRegRaw(RegAddr addr, uint32_t value)
|
|
{
|
|
regs[addr] = value;
|
|
}
|
|
|
|
|
|
|
|
GPUBlockInt::GPUBlockInt(GPU &_gpu,
|
|
const RegAddr &irq_raw_stat,
|
|
const RegAddr &irq_clear,
|
|
const RegAddr &irq_mask,
|
|
const RegAddr &irq_stat)
|
|
: GPUBlock(_gpu),
|
|
addrIrqRawStat(irq_raw_stat), addrIrqClear(irq_clear),
|
|
addrIrqMask(irq_mask), addrIrqStat(irq_stat)
|
|
{
|
|
}
|
|
|
|
GPUBlockInt::~GPUBlockInt()
|
|
{
|
|
}
|
|
|
|
uint32_t
|
|
GPUBlockInt::readReg(RegAddr addr)
|
|
{
|
|
if (addr == addrIrqStat) {
|
|
return irqStatus();
|
|
} else {
|
|
return GPUBlock::readReg(addr);
|
|
}
|
|
}
|
|
|
|
void
|
|
GPUBlockInt::writeReg(RegAddr addr, uint32_t value)
|
|
{
|
|
if (addr == addrIrqRawStat) {
|
|
raiseInterrupt(value);
|
|
} else if (addr == addrIrqClear) {
|
|
clearInterrupt(value);
|
|
} else if (addr == addrIrqMask ) {
|
|
const bool old_int(intAsserted());
|
|
GPUBlock::writeReg(addr, value);
|
|
if (old_int != intAsserted())
|
|
onInterrupt(intAsserted());
|
|
} else if (addr == addrIrqStat ) {
|
|
// Ignore writes to the IRQ status register
|
|
} else {
|
|
// Handle addrIrqMask & defaults
|
|
GPUBlock::writeReg(addr, value);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
void
|
|
GPUBlockInt::raiseInterrupt(uint32_t ints)
|
|
{
|
|
const bool old_int(intAsserted());
|
|
|
|
regs[addrIrqRawStat] |= ints;
|
|
// Is the interrupt line going high?
|
|
if (!old_int && intAsserted())
|
|
onInterrupt(1);
|
|
}
|
|
|
|
void
|
|
GPUBlockInt::clearInterrupt(uint32_t ints)
|
|
{
|
|
const bool old_int(intAsserted());
|
|
|
|
regs[addrIrqRawStat] &= ~ints;
|
|
// Is the interrupt line going low?
|
|
if (old_int && !intAsserted())
|
|
onInterrupt(0);
|
|
}
|
|
|
|
uint32_t
|
|
GPUBlockInt::irqStatus() const
|
|
{
|
|
return regs[addrIrqRawStat] & regs[addrIrqMask];
|
|
}
|
|
|
|
|
|
}
|