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