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