jobslot.cc revision 11313
110915Sandreas.sandberg@arm.com/* 211313Sandreas.sandberg@arm.com * Copyright (c) 2014-2016 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 "jobslot.hh" 2110915Sandreas.sandberg@arm.com 2210915Sandreas.sandberg@arm.com#include <cassert> 2310915Sandreas.sandberg@arm.com#include <cstdlib> 2410915Sandreas.sandberg@arm.com 2510915Sandreas.sandberg@arm.com#include "jobcontrol.hh" 2610915Sandreas.sandberg@arm.com#include "gpu.hh" 2710915Sandreas.sandberg@arm.com#include "regutils.hh" 2810915Sandreas.sandberg@arm.com 2910915Sandreas.sandberg@arm.comnamespace NoMali { 3010915Sandreas.sandberg@arm.com 3111313Sandreas.sandberg@arm.comstatic const Status STATUS_IDLE(Status::CLASS_NOFAULT, 0, 0); 3211313Sandreas.sandberg@arm.comstatic const Status STATUS_DONE(Status::CLASS_NOFAULT, 0, 1); 3311313Sandreas.sandberg@arm.comstatic const Status STATUS_ACTIVE(Status::CLASS_NOFAULT, 1, 0); 3411313Sandreas.sandberg@arm.com 3510915Sandreas.sandberg@arm.comconst std::vector<JobSlot::cmd_t> JobSlot::cmds { 3610915Sandreas.sandberg@arm.com &JobSlot::cmdNop, // JSn_COMMAND_NOP 3710915Sandreas.sandberg@arm.com &JobSlot::cmdStart, // JSn_COMMAND_START 3810915Sandreas.sandberg@arm.com &JobSlot::cmdSoftStop, // JSn_COMMAND_SOFT_STOP 3910915Sandreas.sandberg@arm.com &JobSlot::cmdHardStop, // JSn_COMMAND_HARD_STOP 4010915Sandreas.sandberg@arm.com &JobSlot::cmdSoftStop0, // JSn_COMMAND_SOFT_STOP_0 4110915Sandreas.sandberg@arm.com &JobSlot::cmdHardStop0, // JSn_COMMAND_HARD_STOP_0 4210915Sandreas.sandberg@arm.com &JobSlot::cmdSoftStop1, // JSn_COMMAND_SOFT_STOP_1 4310915Sandreas.sandberg@arm.com &JobSlot::cmdHardStop1, // JSn_COMMAND_HARD_STOP_1 4410915Sandreas.sandberg@arm.com}; 4510915Sandreas.sandberg@arm.com 4610915Sandreas.sandberg@arm.comJobSlot::JobSlot(GPU &_gpu, JobControl &_jc, uint8_t _id) 4710915Sandreas.sandberg@arm.com : GPUBlock(_gpu, JSn_NO_REGS), 4810915Sandreas.sandberg@arm.com id(_id), 4910915Sandreas.sandberg@arm.com jc(_jc) 5010915Sandreas.sandberg@arm.com{ 5110915Sandreas.sandberg@arm.com} 5210915Sandreas.sandberg@arm.com 5310915Sandreas.sandberg@arm.comJobSlot::JobSlot(JobSlot &&rhs) 5410915Sandreas.sandberg@arm.com : GPUBlock(std::move(rhs)), 5510915Sandreas.sandberg@arm.com id(std::move(rhs.id)), 5610915Sandreas.sandberg@arm.com jc(rhs.jc) 5710915Sandreas.sandberg@arm.com{ 5810915Sandreas.sandberg@arm.com} 5910915Sandreas.sandberg@arm.com 6010915Sandreas.sandberg@arm.comJobSlot::~JobSlot() 6110915Sandreas.sandberg@arm.com{ 6210915Sandreas.sandberg@arm.com} 6310915Sandreas.sandberg@arm.com 6410915Sandreas.sandberg@arm.comvoid 6510915Sandreas.sandberg@arm.comJobSlot::writeReg(RegAddr addr, uint32_t value) 6610915Sandreas.sandberg@arm.com{ 6710915Sandreas.sandberg@arm.com switch (addr.value) { 6810915Sandreas.sandberg@arm.com case JSn_COMMAND: 6910915Sandreas.sandberg@arm.com jobCommand(value); 7010915Sandreas.sandberg@arm.com break; 7110915Sandreas.sandberg@arm.com 7210915Sandreas.sandberg@arm.com case JSn_COMMAND_NEXT: 7310915Sandreas.sandberg@arm.com regs[addr] = value; 7410915Sandreas.sandberg@arm.com tryStart(); 7510915Sandreas.sandberg@arm.com break; 7610915Sandreas.sandberg@arm.com 7710915Sandreas.sandberg@arm.com case JSn_HEAD_NEXT_LO: 7810915Sandreas.sandberg@arm.com case JSn_HEAD_NEXT_HI: 7910915Sandreas.sandberg@arm.com case JSn_AFFINITY_NEXT_LO: 8010915Sandreas.sandberg@arm.com case JSn_AFFINITY_NEXT_HI: 8110915Sandreas.sandberg@arm.com case JSn_CONFIG_NEXT: 8210915Sandreas.sandberg@arm.com GPUBlock::writeReg(addr, value); 8310915Sandreas.sandberg@arm.com break; 8410915Sandreas.sandberg@arm.com 8510915Sandreas.sandberg@arm.com default: 8610915Sandreas.sandberg@arm.com // Ignore writes by default 8710915Sandreas.sandberg@arm.com break; 8810915Sandreas.sandberg@arm.com }; 8910915Sandreas.sandberg@arm.com} 9010915Sandreas.sandberg@arm.com 9110915Sandreas.sandberg@arm.combool 9210915Sandreas.sandberg@arm.comJobSlot::active() const 9310915Sandreas.sandberg@arm.com{ 9410915Sandreas.sandberg@arm.com return false; 9510915Sandreas.sandberg@arm.com} 9610915Sandreas.sandberg@arm.com 9710915Sandreas.sandberg@arm.combool 9810915Sandreas.sandberg@arm.comJobSlot::activeNext() const 9910915Sandreas.sandberg@arm.com{ 10010915Sandreas.sandberg@arm.com return regs[RegAddr(JSn_COMMAND_NEXT)] == JSn_COMMAND_START; 10110915Sandreas.sandberg@arm.com} 10210915Sandreas.sandberg@arm.com 10310915Sandreas.sandberg@arm.comvoid 10410915Sandreas.sandberg@arm.comJobSlot::tryStart() 10510915Sandreas.sandberg@arm.com{ 10610915Sandreas.sandberg@arm.com // Only actually start something if the next command is start 10710915Sandreas.sandberg@arm.com if (regs[RegAddr(JSn_COMMAND_NEXT)] != JSn_COMMAND_START ) 10810915Sandreas.sandberg@arm.com return; 10910915Sandreas.sandberg@arm.com 11010915Sandreas.sandberg@arm.com // Reset the status register 11111313Sandreas.sandberg@arm.com regs[RegAddr(JSn_STATUS)] = STATUS_ACTIVE.value; 11210915Sandreas.sandberg@arm.com 11310915Sandreas.sandberg@arm.com // Transfer the next job configuration to the active job 11410915Sandreas.sandberg@arm.com // configuration 11510915Sandreas.sandberg@arm.com regs.set64(RegAddr(JSn_HEAD_LO), regs.get64(RegAddr(JSn_HEAD_NEXT_LO))); 11610915Sandreas.sandberg@arm.com regs.set64(RegAddr(JSn_TAIL_LO), regs.get64(RegAddr(JSn_HEAD_NEXT_LO))); 11710915Sandreas.sandberg@arm.com regs.set64(RegAddr(JSn_AFFINITY_LO), 11810915Sandreas.sandberg@arm.com regs.get64(RegAddr(JSn_AFFINITY_NEXT_LO))); 11910915Sandreas.sandberg@arm.com regs[RegAddr(JSn_CONFIG)] = regs[RegAddr(JSn_CONFIG_NEXT)]; 12010915Sandreas.sandberg@arm.com 12110915Sandreas.sandberg@arm.com // Reset the next job configuration 12210915Sandreas.sandberg@arm.com regs.set64(RegAddr(JSn_HEAD_NEXT_LO), 0); 12310915Sandreas.sandberg@arm.com regs[RegAddr(JSn_COMMAND_NEXT)] = 0; 12410915Sandreas.sandberg@arm.com 12510915Sandreas.sandberg@arm.com runJob(); 12610915Sandreas.sandberg@arm.com} 12710915Sandreas.sandberg@arm.com 12810915Sandreas.sandberg@arm.comvoid 12910915Sandreas.sandberg@arm.comJobSlot::runJob() 13010915Sandreas.sandberg@arm.com{ 13111313Sandreas.sandberg@arm.com exitJob(STATUS_DONE, 13210915Sandreas.sandberg@arm.com 0); // Time stamp counter value 13310915Sandreas.sandberg@arm.com} 13410915Sandreas.sandberg@arm.com 13510915Sandreas.sandberg@arm.comvoid 13610915Sandreas.sandberg@arm.comJobSlot::exitJob(Status status, uint64_t fault_address) 13710915Sandreas.sandberg@arm.com{ 13810915Sandreas.sandberg@arm.com assert(status.statusClass() == Status::CLASS_NOFAULT || 13910915Sandreas.sandberg@arm.com status.statusClass() == Status::CLASS_JOB); 14010915Sandreas.sandberg@arm.com 14110915Sandreas.sandberg@arm.com regs[RegAddr(JSn_STATUS)] = status.value; 14210915Sandreas.sandberg@arm.com 14310915Sandreas.sandberg@arm.com if (status.statusClass() == Status::CLASS_NOFAULT) { 14410915Sandreas.sandberg@arm.com jc.jobDone(id); 14510915Sandreas.sandberg@arm.com } else { 14610915Sandreas.sandberg@arm.com jc.jobFailed(id); 14710915Sandreas.sandberg@arm.com } 14810915Sandreas.sandberg@arm.com} 14910915Sandreas.sandberg@arm.com 15010915Sandreas.sandberg@arm.comvoid 15110915Sandreas.sandberg@arm.comJobSlot::jobCommand(uint32_t cmd) 15210915Sandreas.sandberg@arm.com{ 15310915Sandreas.sandberg@arm.com if (cmd < cmds.size()) 15410915Sandreas.sandberg@arm.com (this->*cmds[cmd])(cmd); 15510915Sandreas.sandberg@arm.com} 15610915Sandreas.sandberg@arm.com 15710915Sandreas.sandberg@arm.comvoid 15810915Sandreas.sandberg@arm.comJobSlot::cmdNop(uint32_t cmd) 15910915Sandreas.sandberg@arm.com{ 16010915Sandreas.sandberg@arm.com assert(cmd == JSn_COMMAND_NOP); 16110915Sandreas.sandberg@arm.com} 16210915Sandreas.sandberg@arm.com 16310915Sandreas.sandberg@arm.comvoid 16410915Sandreas.sandberg@arm.comJobSlot::cmdStart(uint32_t cmd) 16510915Sandreas.sandberg@arm.com{ 16610915Sandreas.sandberg@arm.com assert(cmd == JSn_COMMAND_START); 16710915Sandreas.sandberg@arm.com // The JSn_COMMAND_START should never be issued through the 16810915Sandreas.sandberg@arm.com // JSn_COMMAND register. It should use the JSn_COMMAND_NEXT 16910915Sandreas.sandberg@arm.com // register instead. 17010915Sandreas.sandberg@arm.com abort(); 17110915Sandreas.sandberg@arm.com} 17210915Sandreas.sandberg@arm.com 17310915Sandreas.sandberg@arm.comvoid 17410915Sandreas.sandberg@arm.comJobSlot::cmdSoftStop(uint32_t cmd) 17510915Sandreas.sandberg@arm.com{ 17610915Sandreas.sandberg@arm.com assert(cmd == JSn_COMMAND_SOFT_STOP || 17710915Sandreas.sandberg@arm.com cmd == JSn_COMMAND_SOFT_STOP_0 || 17810915Sandreas.sandberg@arm.com cmd == JSn_COMMAND_SOFT_STOP_1); 17910915Sandreas.sandberg@arm.com} 18010915Sandreas.sandberg@arm.com 18110915Sandreas.sandberg@arm.comvoid 18210915Sandreas.sandberg@arm.comJobSlot::cmdHardStop(uint32_t cmd) 18310915Sandreas.sandberg@arm.com{ 18410915Sandreas.sandberg@arm.com assert(cmd == JSn_COMMAND_HARD_STOP || 18510915Sandreas.sandberg@arm.com cmd == JSn_COMMAND_HARD_STOP_0 || 18610915Sandreas.sandberg@arm.com cmd == JSn_COMMAND_HARD_STOP_1); 18710915Sandreas.sandberg@arm.com} 18810915Sandreas.sandberg@arm.com 18910915Sandreas.sandberg@arm.comvoid 19010915Sandreas.sandberg@arm.comJobSlot::cmdSoftStop0(uint32_t cmd) 19110915Sandreas.sandberg@arm.com{ 19210915Sandreas.sandberg@arm.com if (!(regs[RegAddr(JSn_CONFIG)] & JSn_CONFIG_JOB_CHAIN_FLAG)) 19310915Sandreas.sandberg@arm.com cmdSoftStop(cmd); 19410915Sandreas.sandberg@arm.com} 19510915Sandreas.sandberg@arm.com 19610915Sandreas.sandberg@arm.comvoid 19710915Sandreas.sandberg@arm.comJobSlot::cmdHardStop0(uint32_t cmd) 19810915Sandreas.sandberg@arm.com{ 19910915Sandreas.sandberg@arm.com if (!(regs[RegAddr(JSn_CONFIG)] & JSn_CONFIG_JOB_CHAIN_FLAG)) 20010915Sandreas.sandberg@arm.com cmdHardStop(cmd); 20110915Sandreas.sandberg@arm.com} 20210915Sandreas.sandberg@arm.com 20310915Sandreas.sandberg@arm.comvoid 20410915Sandreas.sandberg@arm.comJobSlot::cmdSoftStop1(uint32_t cmd) 20510915Sandreas.sandberg@arm.com{ 20610915Sandreas.sandberg@arm.com if (regs[RegAddr(JSn_CONFIG)] & JSn_CONFIG_JOB_CHAIN_FLAG) 20710915Sandreas.sandberg@arm.com cmdSoftStop(cmd); 20810915Sandreas.sandberg@arm.com} 20910915Sandreas.sandberg@arm.com 21010915Sandreas.sandberg@arm.comvoid 21110915Sandreas.sandberg@arm.comJobSlot::cmdHardStop1(uint32_t cmd) 21210915Sandreas.sandberg@arm.com{ 21310915Sandreas.sandberg@arm.com if (regs[RegAddr(JSn_CONFIG)] & JSn_CONFIG_JOB_CHAIN_FLAG) 21410915Sandreas.sandberg@arm.com cmdHardStop(cmd); 21510915Sandreas.sandberg@arm.com} 21610915Sandreas.sandberg@arm.com 21710915Sandreas.sandberg@arm.com} 218