gpu_nomali.cc revision 13230:2988dc5d1d6f
12567SN/A/* 212531Sandreas.sandberg@arm.com * Copyright (c) 2014-2016 ARM Limited 37650SAli.Saidi@ARM.com * All rights reserved 47650SAli.Saidi@ARM.com * 57650SAli.Saidi@ARM.com * The license below extends only to copyright in the software and shall 67650SAli.Saidi@ARM.com * not be construed as granting a license to any other intellectual 77650SAli.Saidi@ARM.com * property including but not limited to intellectual property relating 87650SAli.Saidi@ARM.com * to a hardware implementation of the functionality of the software 97650SAli.Saidi@ARM.com * licensed hereunder. You may use the software subject to the license 107650SAli.Saidi@ARM.com * terms below provided that you ensure that this notice is replicated 117650SAli.Saidi@ARM.com * unmodified and in its entirety in all distributions of the software, 127650SAli.Saidi@ARM.com * modified or unmodified, in source code or in binary form. 137650SAli.Saidi@ARM.com * 142567SN/A * Redistribution and use in source and binary forms, with or without 152567SN/A * modification, are permitted provided that the following conditions are 162567SN/A * met: redistributions of source code must retain the above copyright 172567SN/A * notice, this list of conditions and the following disclaimer; 182567SN/A * redistributions in binary form must reproduce the above copyright 192567SN/A * notice, this list of conditions and the following disclaimer in the 202567SN/A * documentation and/or other materials provided with the distribution; 212567SN/A * neither the name of the copyright holders nor the names of its 222567SN/A * contributors may be used to endorse or promote products derived from 232567SN/A * this software without specific prior written permission. 242567SN/A * 252567SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 262567SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 272567SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 282567SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 292567SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 302567SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 312567SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 322567SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 332567SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 342567SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 352567SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 362567SN/A * 372567SN/A * Authors: Andreas Sandberg 382567SN/A */ 392665SN/A 402665SN/A#include "dev/arm/gpu_nomali.hh" 412567SN/A 422567SN/A#include "debug/NoMali.hh" 436757SAli.Saidi@ARM.com#include "dev/arm/base_gic.hh" 446757SAli.Saidi@ARM.com#include "dev/arm/realview.hh" 452567SN/A#include "enums/MemoryMode.hh" 4611234Sandreas.sandberg@arm.com#include "mem/packet_access.hh" 472567SN/A#include "nomali/lib/mali_midg_regmap.h" 482567SN/A#include "params/CustomNoMaliGpu.hh" 492567SN/A#include "params/NoMaliGpu.hh" 508229Snate@binkert.org 516757SAli.Saidi@ARM.comstatic const std::map<Enums::NoMaliGpuType, nomali_gpu_type_t> gpuTypeMap{ 5210810Sbr@bsdpad.com { Enums::T60x, NOMALI_GPU_T60X }, 532567SN/A { Enums::T62x, NOMALI_GPU_T62X }, 542567SN/A { Enums::T760, NOMALI_GPU_T760 }, 552567SN/A}; 5610844Sandreas.sandberg@arm.com 5710037SARM gem5 DevelopersNoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p) 5810037SARM gem5 Developers : PioDevice(p), 596757SAli.Saidi@ARM.com pioAddr(p->pio_addr), 602567SN/A platform(p->platform), 618285SPrakash.Ramrakhyani@arm.com interruptMap{ 627650SAli.Saidi@ARM.com { NOMALI_INT_GPU, p->int_gpu }, 637650SAli.Saidi@ARM.com { NOMALI_INT_JOB, p->int_job }, 647650SAli.Saidi@ARM.com { NOMALI_INT_MMU, p->int_mmu }, 657650SAli.Saidi@ARM.com } 667650SAli.Saidi@ARM.com{ 677650SAli.Saidi@ARM.com if (nomali_api_version() != NOMALI_API_VERSION) 6811234Sandreas.sandberg@arm.com panic("NoMali library API mismatch!\n"); 6911234Sandreas.sandberg@arm.com 7011234Sandreas.sandberg@arm.com /* Setup the GPU configuration based on our param struct */ 718286SAli.Saidi@ARM.com nomali_config_t cfg; 728286SAli.Saidi@ARM.com memset(&cfg, 0, sizeof(cfg)); 738286SAli.Saidi@ARM.com 748286SAli.Saidi@ARM.com const auto it_gpu(gpuTypeMap.find(p->gpu_type)); 758286SAli.Saidi@ARM.com if (it_gpu == gpuTypeMap.end()) { 7610037SARM gem5 Developers fatal("Unrecognized GPU type: %s (%i)\n", 7710037SARM gem5 Developers Enums::NoMaliGpuTypeStrings[p->gpu_type], p->gpu_type); 7810037SARM gem5 Developers } 7910037SARM gem5 Developers cfg.type = it_gpu->second; 8010037SARM gem5 Developers 8110037SARM gem5 Developers cfg.ver_maj = p->ver_maj; 8210037SARM gem5 Developers cfg.ver_min = p->ver_min; 8310037SARM gem5 Developers cfg.ver_status = p->ver_status; 8410037SARM gem5 Developers 8510037SARM gem5 Developers panicOnErr( 8610037SARM gem5 Developers nomali_create(&nomali, &cfg), 8710037SARM gem5 Developers "Failed to instantiate NoMali"); 8810037SARM gem5 Developers 8910037SARM gem5 Developers 9010037SARM gem5 Developers /* Setup an interrupt callback */ 9110037SARM gem5 Developers nomali_callback_t cbk_int; 9213173Sgiacomo.travaglini@arm.com cbk_int.type = NOMALI_CALLBACK_INT; 9313173Sgiacomo.travaglini@arm.com cbk_int.usr = (void *)this; 9413173Sgiacomo.travaglini@arm.com cbk_int.func.interrupt = NoMaliGpu::_interrupt; 9513173Sgiacomo.travaglini@arm.com setCallback(cbk_int); 9613173Sgiacomo.travaglini@arm.com 9710037SARM gem5 Developers /* Setup a reset callback */ 9810037SARM gem5 Developers nomali_callback_t cbk_rst; 9910037SARM gem5 Developers cbk_rst.type = NOMALI_CALLBACK_RESET; 10010037SARM gem5 Developers cbk_rst.usr = (void *)this; 10110037SARM gem5 Developers cbk_rst.func.reset = NoMaliGpu::_reset; 10213396Sgiacomo.travaglini@arm.com setCallback(cbk_rst); 10313396Sgiacomo.travaglini@arm.com 10413396Sgiacomo.travaglini@arm.com panicOnErr( 10513396Sgiacomo.travaglini@arm.com nomali_get_info(nomali, &nomaliInfo), 10613396Sgiacomo.travaglini@arm.com "Failed to get NoMali information struct"); 10710037SARM gem5 Developers} 10810037SARM gem5 Developers 10910037SARM gem5 DevelopersNoMaliGpu::~NoMaliGpu() 11010037SARM gem5 Developers{ 11110037SARM gem5 Developers nomali_destroy(nomali); 11210037SARM gem5 Developers} 11310037SARM gem5 Developers 11410037SARM gem5 Developers 11510037SARM gem5 Developersvoid 11610037SARM gem5 DevelopersNoMaliGpu::init() 11710037SARM gem5 Developers{ 11810037SARM gem5 Developers PioDevice::init(); 11910037SARM gem5 Developers 12010037SARM gem5 Developers /* Reset the GPU here since the reset callback won't have been 12110037SARM gem5 Developers * installed when the GPU was reset at instantiation time. 12210037SARM gem5 Developers */ 12312005Sandreas.sandberg@arm.com reset(); 12412005Sandreas.sandberg@arm.com} 12512005Sandreas.sandberg@arm.com 12612005Sandreas.sandberg@arm.comvoid 12712005Sandreas.sandberg@arm.comNoMaliGpu::serialize(CheckpointOut &cp) const 12812005Sandreas.sandberg@arm.com{ 12912531Sandreas.sandberg@arm.com std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2); 13012531Sandreas.sandberg@arm.com 13112531Sandreas.sandberg@arm.com for (int i = 0; i < nomaliInfo.reg_size; i += 4) 13212531Sandreas.sandberg@arm.com regs[i >> 2] = readRegRaw(i); 13312531Sandreas.sandberg@arm.com 13411234Sandreas.sandberg@arm.com SERIALIZE_CONTAINER(regs); 13511234Sandreas.sandberg@arm.com} 13611234Sandreas.sandberg@arm.com 13711234Sandreas.sandberg@arm.comvoid 13811234Sandreas.sandberg@arm.comNoMaliGpu::unserialize(CheckpointIn &cp) 13911234Sandreas.sandberg@arm.com{ 14011234Sandreas.sandberg@arm.com std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2); 14111234Sandreas.sandberg@arm.com 14211234Sandreas.sandberg@arm.com UNSERIALIZE_CONTAINER(regs); 14311234Sandreas.sandberg@arm.com 1442567SN/A for (int i = 0; i < nomaliInfo.reg_size; i += 4) 1456757SAli.Saidi@ARM.com writeRegRaw(i, regs[i >> 2]); 1468286SAli.Saidi@ARM.com} 1478286SAli.Saidi@ARM.com 1488286SAli.Saidi@ARM.comTick 1498286SAli.Saidi@ARM.comNoMaliGpu::read(PacketPtr pkt) 1508286SAli.Saidi@ARM.com{ 1518286SAli.Saidi@ARM.com assert(pkt->getAddr() >= pioAddr); 1526757SAli.Saidi@ARM.com const Addr addr(pkt->getAddr() - pioAddr); 1536757SAli.Saidi@ARM.com const unsigned size(pkt->getSize()); 1548286SAli.Saidi@ARM.com 1558706Sandreas.hansson@arm.com if (addr + size >= nomaliInfo.reg_size) 1568706Sandreas.hansson@arm.com panic("GPU register '0x%x' out of range!\n", addr); 1578706Sandreas.hansson@arm.com 1588706Sandreas.hansson@arm.com if (size != 4) 1598286SAli.Saidi@ARM.com panic("Unexpected GPU register read size: %i\n", size); 1603553SN/A else if (addr & 0x3) 1613553SN/A panic("Unaligned GPU read: %i\n", size); 1627693SAli.Saidi@ARM.com 1637693SAli.Saidi@ARM.com pkt->setLE<uint32_t>(readReg(addr)); 1647693SAli.Saidi@ARM.com pkt->makeResponse(); 1657720Sgblack@eecs.umich.edu 1663553SN/A return 0; 1673553SN/A} 1689050Schander.sudanthi@arm.com 1699050Schander.sudanthi@arm.comTick 1709050Schander.sudanthi@arm.comNoMaliGpu::write(PacketPtr pkt) 17110037SARM gem5 Developers{ 17210037SARM gem5 Developers assert(pkt->getAddr() >= pioAddr); 17310037SARM gem5 Developers const Addr addr(pkt->getAddr() - pioAddr); 17410037SARM gem5 Developers const unsigned size(pkt->getSize()); 17510037SARM gem5 Developers 17610037SARM gem5 Developers if (addr + size >= nomaliInfo.reg_size) 17710037SARM gem5 Developers panic("GPU register '0x%x' out of range!\n", addr); 17810037SARM gem5 Developers 17910037SARM gem5 Developers if (size != 4) 18010037SARM gem5 Developers panic("Unexpected GPU register write size: %i\n", size); 18110037SARM gem5 Developers else if (addr & 0x3) 18210037SARM gem5 Developers panic("Unaligned GPU write: %i\n", size); 18310037SARM gem5 Developers 18413173Sgiacomo.travaglini@arm.com writeReg(addr, pkt->getLE<uint32_t>()); 18513173Sgiacomo.travaglini@arm.com pkt->makeAtomicResponse(); 18613173Sgiacomo.travaglini@arm.com 18713173Sgiacomo.travaglini@arm.com return 0; 18813173Sgiacomo.travaglini@arm.com} 18910037SARM gem5 Developers 19010037SARM gem5 DevelopersAddrRangeList 19110037SARM gem5 DevelopersNoMaliGpu::getAddrRanges() const 19210037SARM gem5 Developers{ 19310037SARM gem5 Developers return AddrRangeList({ RangeSize(pioAddr, nomaliInfo.reg_size) }); 19410037SARM gem5 Developers} 19510844Sandreas.sandberg@arm.com 19610844Sandreas.sandberg@arm.comvoid 19710037SARM gem5 DevelopersNoMaliGpu::reset() 19810037SARM gem5 Developers{ 19910037SARM gem5 Developers DPRINTF(NoMali, "reset()\n"); 20010037SARM gem5 Developers 20110037SARM gem5 Developers panicOnErr( 20210037SARM gem5 Developers nomali_reset(nomali), 20310037SARM gem5 Developers "Failed to reset GPU"); 20410037SARM gem5 Developers} 20510037SARM gem5 Developers 20610037SARM gem5 Developersuint32_t 20711574SCurtis.Dunham@arm.comNoMaliGpu::readReg(nomali_addr_t reg) 20811574SCurtis.Dunham@arm.com{ 20910037SARM gem5 Developers uint32_t value; 21010037SARM gem5 Developers 21110037SARM gem5 Developers panicOnErr( 21210037SARM gem5 Developers nomali_reg_read(nomali, &value, reg), 21310037SARM gem5 Developers "GPU register read failed"); 21413396Sgiacomo.travaglini@arm.com 21510037SARM gem5 Developers DPRINTF(NoMali, "readReg(0x%x): 0x%x\n", 21610037SARM gem5 Developers reg, value); 21710037SARM gem5 Developers 21810037SARM gem5 Developers return value; 21910037SARM gem5 Developers} 22010037SARM gem5 Developers 22110037SARM gem5 Developers 22210037SARM gem5 Developersvoid 22310037SARM gem5 DevelopersNoMaliGpu::writeReg(nomali_addr_t reg, uint32_t value) 22410037SARM gem5 Developers{ 22510037SARM gem5 Developers DPRINTF(NoMali, "writeReg(0x%x, 0x%x)\n", 22610037SARM gem5 Developers reg, value); 22710037SARM gem5 Developers 22810037SARM gem5 Developers panicOnErr( 22910037SARM gem5 Developers nomali_reg_write(nomali, reg, value), 23010037SARM gem5 Developers "GPU register write failed"); 23110037SARM gem5 Developers} 23210037SARM gem5 Developers 23310037SARM gem5 Developersuint32_t 23410037SARM gem5 DevelopersNoMaliGpu::readRegRaw(nomali_addr_t reg) const 23510037SARM gem5 Developers{ 23610037SARM gem5 Developers uint32_t value; 23710037SARM gem5 Developers 23810037SARM gem5 Developers panicOnErr( 23912005Sandreas.sandberg@arm.com nomali_reg_read_raw(nomali, &value, reg), 24012005Sandreas.sandberg@arm.com "GPU raw register read failed"); 24112005Sandreas.sandberg@arm.com 24212005Sandreas.sandberg@arm.com return value; 24312005Sandreas.sandberg@arm.com} 24412005Sandreas.sandberg@arm.com 24512531Sandreas.sandberg@arm.com 24612531Sandreas.sandberg@arm.comvoid 24712531Sandreas.sandberg@arm.comNoMaliGpu::writeRegRaw(nomali_addr_t reg, uint32_t value) 24812317Sgiacomo.travaglini@arm.com{ 24912317Sgiacomo.travaglini@arm.com panicOnErr( 25012317Sgiacomo.travaglini@arm.com nomali_reg_write_raw(nomali, reg, value), 25112317Sgiacomo.travaglini@arm.com "GPU raw register write failed"); 25212317Sgiacomo.travaglini@arm.com} 25312317Sgiacomo.travaglini@arm.com 25410037SARM gem5 Developersbool 25510037SARM gem5 DevelopersNoMaliGpu::intState(nomali_int_t intno) 25610037SARM gem5 Developers{ 25710037SARM gem5 Developers int state = 0; 25810037SARM gem5 Developers panicOnErr( 25910037SARM gem5 Developers nomali_int_state(nomali, &state, intno), 26010037SARM gem5 Developers "Failed to get interrupt state"); 26110037SARM gem5 Developers 26210037SARM gem5 Developers return !!state; 26310037SARM gem5 Developers} 26410037SARM gem5 Developers 26510037SARM gem5 Developersvoid 26610037SARM gem5 DevelopersNoMaliGpu::gpuPanic(nomali_error_t err, const char *msg) 26710037SARM gem5 Developers{ 26810037SARM gem5 Developers panic("%s: %s\n", msg, nomali_errstr(err)); 26910037SARM gem5 Developers} 27010037SARM gem5 Developers 27110037SARM gem5 Developers 27210037SARM gem5 Developersvoid 27310037SARM gem5 DevelopersNoMaliGpu::onInterrupt(nomali_int_t intno, bool set) 27410037SARM gem5 Developers{ 27510037SARM gem5 Developers const auto it_int(interruptMap.find(intno)); 27610037SARM gem5 Developers if (it_int == interruptMap.end()) 27710037SARM gem5 Developers panic("Unhandled interrupt from NoMali: %i\n", intno); 27810037SARM gem5 Developers 27912318Sgiacomo.travaglini@arm.com DPRINTF(NoMali, "Interrupt %i->%i: %i\n", 28012318Sgiacomo.travaglini@arm.com intno, it_int->second, set); 28112318Sgiacomo.travaglini@arm.com 28212318Sgiacomo.travaglini@arm.com assert(platform); 28312318Sgiacomo.travaglini@arm.com assert(platform->gic); 28410037SARM gem5 Developers 28513396Sgiacomo.travaglini@arm.com if (set) 28610037SARM gem5 Developers platform->gic->sendInt(it_int->second); 28710037SARM gem5 Developers else 28810037SARM gem5 Developers platform->gic->clearInt(it_int->second); 28910037SARM gem5 Developers} 29010037SARM gem5 Developers 29110037SARM gem5 Developersvoid 29210037SARM gem5 DevelopersNoMaliGpu::onReset() 29310037SARM gem5 Developers{ 29410037SARM gem5 Developers DPRINTF(NoMali, "Reset\n"); 29510037SARM gem5 Developers} 29610037SARM gem5 Developers 29710037SARM gem5 Developersvoid 29810037SARM gem5 DevelopersNoMaliGpu::setCallback(const nomali_callback_t &callback) 29910037SARM gem5 Developers{ 30012531Sandreas.sandberg@arm.com DPRINTF(NoMali, "Registering callback %i\n", 30112531Sandreas.sandberg@arm.com callback.type); 30212531Sandreas.sandberg@arm.com 30312531Sandreas.sandberg@arm.com panicOnErr( 30412531Sandreas.sandberg@arm.com nomali_set_callback(nomali, &callback), 30512531Sandreas.sandberg@arm.com "Failed to register callback"); 30612531Sandreas.sandberg@arm.com} 30712531Sandreas.sandberg@arm.com 30812531Sandreas.sandberg@arm.comvoid 30912531Sandreas.sandberg@arm.comNoMaliGpu::_interrupt(nomali_handle_t h, void *usr, 31012531Sandreas.sandberg@arm.com nomali_int_t intno, int set) 31110810Sbr@bsdpad.com{ 31210037SARM gem5 Developers NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr)); 31310810Sbr@bsdpad.com 31410810Sbr@bsdpad.com _this->onInterrupt(intno, !!set); 31510810Sbr@bsdpad.com} 31610810Sbr@bsdpad.com 31710810Sbr@bsdpad.comvoid 31810810Sbr@bsdpad.comNoMaliGpu::_reset(nomali_handle_t h, void *usr) 31910810Sbr@bsdpad.com{ 32010810Sbr@bsdpad.com NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr)); 32110810Sbr@bsdpad.com 32210810Sbr@bsdpad.com _this->onReset(); 32310810Sbr@bsdpad.com} 32410810Sbr@bsdpad.com 32510810Sbr@bsdpad.com 32610810Sbr@bsdpad.comCustomNoMaliGpu::CustomNoMaliGpu(const CustomNoMaliGpuParams *p) 32710810Sbr@bsdpad.com : NoMaliGpu(p), 32810810Sbr@bsdpad.com idRegs{ 32910810Sbr@bsdpad.com { GPU_CONTROL_REG(GPU_ID), p->gpu_id }, 3302567SN/A { GPU_CONTROL_REG(L2_FEATURES), p->l2_features }, 3312567SN/A { GPU_CONTROL_REG(TILER_FEATURES), p->tiler_features }, 3322567SN/A { GPU_CONTROL_REG(MEM_FEATURES), p->mem_features }, 333 { GPU_CONTROL_REG(MMU_FEATURES), p->mmu_features }, 334 { GPU_CONTROL_REG(AS_PRESENT), p->as_present }, 335 { GPU_CONTROL_REG(JS_PRESENT), p->js_present }, 336 337 { GPU_CONTROL_REG(THREAD_MAX_THREADS), p->thread_max_threads }, 338 { GPU_CONTROL_REG(THREAD_MAX_WORKGROUP_SIZE), 339 p->thread_max_workgroup_size }, 340 { GPU_CONTROL_REG(THREAD_MAX_BARRIER_SIZE), 341 p->thread_max_barrier_size }, 342 { GPU_CONTROL_REG(THREAD_FEATURES), p->thread_features }, 343 344 { GPU_CONTROL_REG(SHADER_PRESENT_LO), bits(p->shader_present, 31, 0) }, 345 { GPU_CONTROL_REG(SHADER_PRESENT_HI), bits(p->shader_present, 63, 32) }, 346 { GPU_CONTROL_REG(TILER_PRESENT_LO), bits(p->tiler_present, 31, 0) }, 347 { GPU_CONTROL_REG(TILER_PRESENT_HI), bits(p->tiler_present, 63, 32) }, 348 { GPU_CONTROL_REG(L2_PRESENT_LO), bits(p->l2_present, 31, 0) }, 349 { GPU_CONTROL_REG(L2_PRESENT_HI), bits(p->l2_present, 63, 32) }, 350 } 351{ 352 fatal_if(p->texture_features.size() > 3, 353 "Too many texture feature registers specified (%i)\n", 354 p->texture_features.size()); 355 356 fatal_if(p->js_features.size() > 16, 357 "Too many job slot feature registers specified (%i)\n", 358 p->js_features.size()); 359 360 for (int i = 0; i < p->texture_features.size(); i++) 361 idRegs[TEXTURE_FEATURES_REG(i)] = p->texture_features[i]; 362 363 for (int i = 0; i < p->js_features.size(); i++) 364 idRegs[JS_FEATURES_REG(i)] = p->js_features[i]; 365} 366 367CustomNoMaliGpu::~CustomNoMaliGpu() 368{ 369} 370 371void 372CustomNoMaliGpu::onReset() 373{ 374 NoMaliGpu::onReset(); 375 376 for (const auto ® : idRegs) 377 writeRegRaw(reg.first, reg.second); 378} 379 380 381 382NoMaliGpu * 383NoMaliGpuParams::create() 384{ 385 return new NoMaliGpu(this); 386} 387 388CustomNoMaliGpu * 389CustomNoMaliGpuParams::create() 390{ 391 return new CustomNoMaliGpu(this); 392} 393