jobcontrol.cc revision 10915
110915Sandreas.sandberg@arm.com/* 210915Sandreas.sandberg@arm.com * Copyright (c) 2014-2015 ARM Limited 310915Sandreas.sandberg@arm.com * All rights reserved 410915Sandreas.sandberg@arm.com * 510915Sandreas.sandberg@arm.com * Licensed under the Apache License, Version 2.0 (the "License"); 610915Sandreas.sandberg@arm.com * you may not use this file except in compliance with the License. 710915Sandreas.sandberg@arm.com * You may obtain a copy of the License at 810915Sandreas.sandberg@arm.com * 910915Sandreas.sandberg@arm.com * http://www.apache.org/licenses/LICENSE-2.0 1010915Sandreas.sandberg@arm.com * 1110915Sandreas.sandberg@arm.com * Unless required by applicable law or agreed to in writing, software 1210915Sandreas.sandberg@arm.com * distributed under the License is distributed on an "AS IS" BASIS, 1310915Sandreas.sandberg@arm.com * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1410915Sandreas.sandberg@arm.com * See the License for the specific language governing permissions and 1510915Sandreas.sandberg@arm.com * limitations under the License. 1610915Sandreas.sandberg@arm.com * 1710915Sandreas.sandberg@arm.com * Authors: Andreas Sandberg 1810915Sandreas.sandberg@arm.com */ 1910915Sandreas.sandberg@arm.com 2010915Sandreas.sandberg@arm.com#include "jobcontrol.hh" 2110915Sandreas.sandberg@arm.com 2210915Sandreas.sandberg@arm.com#include "gpu.hh" 2310915Sandreas.sandberg@arm.com#include "regutils.hh" 2410915Sandreas.sandberg@arm.com 2510915Sandreas.sandberg@arm.comnamespace NoMali { 2610915Sandreas.sandberg@arm.com 2710915Sandreas.sandberg@arm.comJobControl::JobControl(GPU &_gpu) 2810915Sandreas.sandberg@arm.com : GPUBlockInt(_gpu, 2910915Sandreas.sandberg@arm.com RegAddr(JOB_IRQ_RAWSTAT), 3010915Sandreas.sandberg@arm.com RegAddr(JOB_IRQ_CLEAR), 3110915Sandreas.sandberg@arm.com RegAddr(JOB_IRQ_MASK), 3210915Sandreas.sandberg@arm.com RegAddr(JOB_IRQ_STATUS)) 3310915Sandreas.sandberg@arm.com{ 3410915Sandreas.sandberg@arm.com slots.reserve(16); 3510915Sandreas.sandberg@arm.com for (int i = 0; i < 16; ++i) 3610915Sandreas.sandberg@arm.com slots.emplace_back(_gpu, *this, i); 3710915Sandreas.sandberg@arm.com 3810915Sandreas.sandberg@arm.com} 3910915Sandreas.sandberg@arm.com 4010915Sandreas.sandberg@arm.comJobControl::~JobControl() 4110915Sandreas.sandberg@arm.com{ 4210915Sandreas.sandberg@arm.com} 4310915Sandreas.sandberg@arm.com 4410915Sandreas.sandberg@arm.comuint32_t 4510915Sandreas.sandberg@arm.comJobControl::readReg(RegAddr addr) 4610915Sandreas.sandberg@arm.com{ 4710915Sandreas.sandberg@arm.com if (addr >= RegAddr(JOB_SLOT0)) { 4810915Sandreas.sandberg@arm.com return slots[getJobSlotNo(addr)].readReg(getJobSlotAddr(addr)); 4910915Sandreas.sandberg@arm.com } else { 5010915Sandreas.sandberg@arm.com return GPUBlockInt::readReg(addr); 5110915Sandreas.sandberg@arm.com } 5210915Sandreas.sandberg@arm.com} 5310915Sandreas.sandberg@arm.com 5410915Sandreas.sandberg@arm.comvoid 5510915Sandreas.sandberg@arm.comJobControl::writeReg(RegAddr addr, uint32_t value) 5610915Sandreas.sandberg@arm.com{ 5710915Sandreas.sandberg@arm.com switch(addr.value) { 5810915Sandreas.sandberg@arm.com case JOB_IRQ_CLEAR: 5910915Sandreas.sandberg@arm.com // Update JS state for all jobs that were affected by the IRQ 6010915Sandreas.sandberg@arm.com // clear 6110915Sandreas.sandberg@arm.com updateJsState((value & 0xFFFF) | ((value & 0xFFFF0000) >> 16)); 6210915Sandreas.sandberg@arm.com 6310915Sandreas.sandberg@arm.com // FALLTHROUGH - IRQ handling in base class 6410915Sandreas.sandberg@arm.com case JOB_IRQ_RAWSTAT: 6510915Sandreas.sandberg@arm.com case JOB_IRQ_MASK: 6610915Sandreas.sandberg@arm.com case JOB_IRQ_STATUS: 6710915Sandreas.sandberg@arm.com GPUBlockInt::writeReg(addr, value); 6810915Sandreas.sandberg@arm.com break; 6910915Sandreas.sandberg@arm.com 7010915Sandreas.sandberg@arm.com default: 7110915Sandreas.sandberg@arm.com if (addr >= RegAddr(JOB_SLOT0)) 7210915Sandreas.sandberg@arm.com slots[getJobSlotNo(addr)].writeReg(getJobSlotAddr(addr), value); 7310915Sandreas.sandberg@arm.com break; 7410915Sandreas.sandberg@arm.com } 7510915Sandreas.sandberg@arm.com} 7610915Sandreas.sandberg@arm.com 7710915Sandreas.sandberg@arm.comuint32_t 7810915Sandreas.sandberg@arm.comJobControl::readRegRaw(RegAddr addr) 7910915Sandreas.sandberg@arm.com{ 8010915Sandreas.sandberg@arm.com if (addr >= RegAddr(JOB_SLOT0)) { 8110915Sandreas.sandberg@arm.com return slots[getJobSlotNo(addr)].readRegRaw(getJobSlotAddr(addr)); 8210915Sandreas.sandberg@arm.com } else { 8310915Sandreas.sandberg@arm.com return GPUBlockInt::readRegRaw(addr); 8410915Sandreas.sandberg@arm.com } 8510915Sandreas.sandberg@arm.com} 8610915Sandreas.sandberg@arm.com 8710915Sandreas.sandberg@arm.com 8810915Sandreas.sandberg@arm.comvoid 8910915Sandreas.sandberg@arm.comJobControl::writeRegRaw(RegAddr addr, uint32_t value) 9010915Sandreas.sandberg@arm.com{ 9110915Sandreas.sandberg@arm.com if (addr >= RegAddr(JOB_SLOT0)) { 9210915Sandreas.sandberg@arm.com slots[getJobSlotNo(addr)].writeRegRaw(getJobSlotAddr(addr), value); 9310915Sandreas.sandberg@arm.com } else { 9410915Sandreas.sandberg@arm.com GPUBlockInt::writeRegRaw(addr, value); 9510915Sandreas.sandberg@arm.com } 9610915Sandreas.sandberg@arm.com} 9710915Sandreas.sandberg@arm.com 9810915Sandreas.sandberg@arm.comvoid 9910915Sandreas.sandberg@arm.comJobControl::jobDone(uint8_t slot) 10010915Sandreas.sandberg@arm.com{ 10110915Sandreas.sandberg@arm.com assert(slot <= 15); 10210915Sandreas.sandberg@arm.com raiseInterrupt(1 << slot); 10310915Sandreas.sandberg@arm.com} 10410915Sandreas.sandberg@arm.com 10510915Sandreas.sandberg@arm.comvoid 10610915Sandreas.sandberg@arm.comJobControl::jobFailed(uint8_t slot) 10710915Sandreas.sandberg@arm.com{ 10810915Sandreas.sandberg@arm.com assert(slot <= 15); 10910915Sandreas.sandberg@arm.com raiseInterrupt(0x10000 << slot); 11010915Sandreas.sandberg@arm.com} 11110915Sandreas.sandberg@arm.com 11210915Sandreas.sandberg@arm.comvoid 11310915Sandreas.sandberg@arm.comJobControl::updateJsState(uint16_t jobs) 11410915Sandreas.sandberg@arm.com{ 11510915Sandreas.sandberg@arm.com // The JS_STATE register contains two bits per job slot; one bit 11610915Sandreas.sandberg@arm.com // representing an active job and one bit representing the queued 11710915Sandreas.sandberg@arm.com // job. We need to mask out bits of the jobs affected by this update. 11810915Sandreas.sandberg@arm.com const uint32_t job_mask(jobs | (jobs << 16)); 11910915Sandreas.sandberg@arm.com uint16_t js_state(regs[RegAddr(JOB_IRQ_JS_STATE)] & ~job_mask); 12010915Sandreas.sandberg@arm.com 12110915Sandreas.sandberg@arm.com // Find if there is an active or active next job for all jobs in 12210915Sandreas.sandberg@arm.com // the job mask. 12310915Sandreas.sandberg@arm.com for (int i = 0; i < 16; ++i) { 12410915Sandreas.sandberg@arm.com const JobSlot &slot(slots[i]); 12510915Sandreas.sandberg@arm.com if (jobs & (1 << i)) { 12610915Sandreas.sandberg@arm.com js_state |= slot.active() ? (1 << i) : 0 | 12710915Sandreas.sandberg@arm.com slot.activeNext() ? (0x10000 << i) : 0; 12810915Sandreas.sandberg@arm.com } 12910915Sandreas.sandberg@arm.com } 13010915Sandreas.sandberg@arm.com regs[RegAddr(JOB_IRQ_JS_STATE)] = js_state; 13110915Sandreas.sandberg@arm.com} 13210915Sandreas.sandberg@arm.com 13310915Sandreas.sandberg@arm.comvoid 13410915Sandreas.sandberg@arm.comJobControl::onInterrupt(int set) 13510915Sandreas.sandberg@arm.com{ 13610915Sandreas.sandberg@arm.com gpu.intJob(set); 13710915Sandreas.sandberg@arm.com} 13810915Sandreas.sandberg@arm.com 13910915Sandreas.sandberg@arm.com} 140