gpu_nomali.cc revision 11349:9e46b77e5e56
12929Sktlim@umich.edu/* 22929Sktlim@umich.edu * Copyright (c) 2014-2016 ARM Limited 32932Sktlim@umich.edu * All rights reserved 42929Sktlim@umich.edu * 52929Sktlim@umich.edu * The license below extends only to copyright in the software and shall 62929Sktlim@umich.edu * not be construed as granting a license to any other intellectual 72929Sktlim@umich.edu * property including but not limited to intellectual property relating 82929Sktlim@umich.edu * to a hardware implementation of the functionality of the software 92929Sktlim@umich.edu * licensed hereunder. You may use the software subject to the license 102929Sktlim@umich.edu * terms below provided that you ensure that this notice is replicated 112929Sktlim@umich.edu * unmodified and in its entirety in all distributions of the software, 122929Sktlim@umich.edu * modified or unmodified, in source code or in binary form. 132929Sktlim@umich.edu * 142929Sktlim@umich.edu * Redistribution and use in source and binary forms, with or without 152929Sktlim@umich.edu * modification, are permitted provided that the following conditions are 162929Sktlim@umich.edu * met: redistributions of source code must retain the above copyright 172929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer; 182929Sktlim@umich.edu * redistributions in binary form must reproduce the above copyright 192929Sktlim@umich.edu * notice, this list of conditions and the following disclaimer in the 202929Sktlim@umich.edu * documentation and/or other materials provided with the distribution; 212929Sktlim@umich.edu * neither the name of the copyright holders nor the names of its 222929Sktlim@umich.edu * contributors may be used to endorse or promote products derived from 232929Sktlim@umich.edu * this software without specific prior written permission. 242929Sktlim@umich.edu * 252929Sktlim@umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 262929Sktlim@umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 272929Sktlim@umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 282932Sktlim@umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 292932Sktlim@umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 302932Sktlim@umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 312929Sktlim@umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 326007Ssteve.reinhardt@amd.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 337735SAli.Saidi@ARM.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 342929Sktlim@umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 352929Sktlim@umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 362929Sktlim@umich.edu * 372929Sktlim@umich.edu * Authors: Andreas Sandberg 382929Sktlim@umich.edu */ 392929Sktlim@umich.edu 402929Sktlim@umich.edu#include "dev/arm/gpu_nomali.hh" 412929Sktlim@umich.edu 422929Sktlim@umich.edu#include "debug/NoMali.hh" 432929Sktlim@umich.edu#include "dev/arm/base_gic.hh" 442929Sktlim@umich.edu#include "dev/arm/realview.hh" 452929Sktlim@umich.edu#include "enums/MemoryMode.hh" 462929Sktlim@umich.edu#include "mem/packet_access.hh" 476007Ssteve.reinhardt@amd.com#include "params/NoMaliGpu.hh" 486007Ssteve.reinhardt@amd.com 496007Ssteve.reinhardt@amd.comstatic const std::map<Enums::NoMaliGpuType, nomali_gpu_type_t> gpuTypeMap{ 506007Ssteve.reinhardt@amd.com { Enums::T60x, NOMALI_GPU_T60X }, 516007Ssteve.reinhardt@amd.com { Enums::T62x, NOMALI_GPU_T62X }, 526007Ssteve.reinhardt@amd.com { Enums::T760, NOMALI_GPU_T760 }, 536007Ssteve.reinhardt@amd.com}; 546007Ssteve.reinhardt@amd.com 556007Ssteve.reinhardt@amd.comNoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p) 566007Ssteve.reinhardt@amd.com : PioDevice(p), 576007Ssteve.reinhardt@amd.com pioAddr(p->pio_addr), 586007Ssteve.reinhardt@amd.com platform(p->platform), 596007Ssteve.reinhardt@amd.com interruptMap{ 606007Ssteve.reinhardt@amd.com { NOMALI_INT_GPU, p->int_gpu }, 616007Ssteve.reinhardt@amd.com { NOMALI_INT_JOB, p->int_job }, 626007Ssteve.reinhardt@amd.com { NOMALI_INT_MMU, p->int_mmu }, 636007Ssteve.reinhardt@amd.com } 646007Ssteve.reinhardt@amd.com{ 656007Ssteve.reinhardt@amd.com if (nomali_api_version() != NOMALI_API_VERSION) 666007Ssteve.reinhardt@amd.com panic("NoMali library API mismatch!\n"); 676007Ssteve.reinhardt@amd.com 686007Ssteve.reinhardt@amd.com /* Setup the GPU configuration based on our param struct */ 696007Ssteve.reinhardt@amd.com nomali_config_t cfg; 706007Ssteve.reinhardt@amd.com memset(&cfg, 0, sizeof(cfg)); 716007Ssteve.reinhardt@amd.com 726007Ssteve.reinhardt@amd.com const auto it_gpu(gpuTypeMap.find(p->gpu_type)); 736007Ssteve.reinhardt@amd.com if (it_gpu == gpuTypeMap.end()) { 746007Ssteve.reinhardt@amd.com fatal("Unrecognized GPU type: %s (%i)\n", 756007Ssteve.reinhardt@amd.com Enums::NoMaliGpuTypeStrings[p->gpu_type], p->gpu_type); 762929Sktlim@umich.edu } 772929Sktlim@umich.edu cfg.type = it_gpu->second; 782929Sktlim@umich.edu 796007Ssteve.reinhardt@amd.com cfg.ver_maj = p->ver_maj; 806007Ssteve.reinhardt@amd.com cfg.ver_min = p->ver_min; 816007Ssteve.reinhardt@amd.com cfg.ver_status = p->ver_status; 826007Ssteve.reinhardt@amd.com 836007Ssteve.reinhardt@amd.com panicOnErr( 846007Ssteve.reinhardt@amd.com nomali_create(&nomali, &cfg), 852929Sktlim@umich.edu "Failed to instantiate NoMali"); 862929Sktlim@umich.edu 872929Sktlim@umich.edu 882929Sktlim@umich.edu /* Setup an interrupt callback */ 892929Sktlim@umich.edu nomali_callback_t cbk_int; 906011Ssteve.reinhardt@amd.com cbk_int.type = NOMALI_CALLBACK_INT; 916007Ssteve.reinhardt@amd.com cbk_int.usr = (void *)this; 926007Ssteve.reinhardt@amd.com cbk_int.func.interrupt = NoMaliGpu::_interrupt; 936007Ssteve.reinhardt@amd.com setCallback(cbk_int); 946007Ssteve.reinhardt@amd.com 956007Ssteve.reinhardt@amd.com panicOnErr( 966007Ssteve.reinhardt@amd.com nomali_get_info(nomali, &nomaliInfo), 976007Ssteve.reinhardt@amd.com "Failed to get NoMali information struct"); 986007Ssteve.reinhardt@amd.com} 996007Ssteve.reinhardt@amd.com 1006007Ssteve.reinhardt@amd.comNoMaliGpu::~NoMaliGpu() 1016007Ssteve.reinhardt@amd.com{ 1026007Ssteve.reinhardt@amd.com nomali_destroy(nomali); 1036007Ssteve.reinhardt@amd.com} 1046007Ssteve.reinhardt@amd.com 1057735SAli.Saidi@ARM.comvoid 1066011Ssteve.reinhardt@amd.comNoMaliGpu::serialize(CheckpointOut &cp) const 1076007Ssteve.reinhardt@amd.com{ 1086007Ssteve.reinhardt@amd.com std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2); 1096007Ssteve.reinhardt@amd.com 1106007Ssteve.reinhardt@amd.com for (int i = 0; i < nomaliInfo.reg_size; i += 4) 1117735SAli.Saidi@ARM.com regs[i >> 2] = readRegRaw(i); 1127735SAli.Saidi@ARM.com 1137735SAli.Saidi@ARM.com SERIALIZE_CONTAINER(regs); 1147735SAli.Saidi@ARM.com} 1157735SAli.Saidi@ARM.com 1167735SAli.Saidi@ARM.comvoid 1177735SAli.Saidi@ARM.comNoMaliGpu::unserialize(CheckpointIn &cp) 1187735SAli.Saidi@ARM.com{ 1197735SAli.Saidi@ARM.com std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2); 1207735SAli.Saidi@ARM.com 1217735SAli.Saidi@ARM.com UNSERIALIZE_CONTAINER(regs); 1227735SAli.Saidi@ARM.com 1237735SAli.Saidi@ARM.com for (int i = 0; i < nomaliInfo.reg_size; i += 4) 1247735SAli.Saidi@ARM.com writeRegRaw(i, regs[i >> 2]); 1256007Ssteve.reinhardt@amd.com} 1267685Ssteve.reinhardt@amd.com 1276007Ssteve.reinhardt@amd.comTick 1286011Ssteve.reinhardt@amd.comNoMaliGpu::read(PacketPtr pkt) 1296007Ssteve.reinhardt@amd.com{ 1306007Ssteve.reinhardt@amd.com assert(pkt->getAddr() >= pioAddr); 1316007Ssteve.reinhardt@amd.com const Addr addr(pkt->getAddr() - pioAddr); 1326007Ssteve.reinhardt@amd.com const unsigned size(pkt->getSize()); 1336007Ssteve.reinhardt@amd.com 1346007Ssteve.reinhardt@amd.com if (addr + size >= nomaliInfo.reg_size) 1356011Ssteve.reinhardt@amd.com panic("GPU register '0x%x' out of range!\n", addr); 1366007Ssteve.reinhardt@amd.com 1376007Ssteve.reinhardt@amd.com if (size != 4) 1386007Ssteve.reinhardt@amd.com panic("Unexpected GPU register read size: %i\n", size); 1396007Ssteve.reinhardt@amd.com else if (addr & 0x3) 1406007Ssteve.reinhardt@amd.com panic("Unaligned GPU read: %i\n", size); 1416008Ssteve.reinhardt@amd.com 1426007Ssteve.reinhardt@amd.com pkt->set<uint32_t>(readReg(addr)); 1436008Ssteve.reinhardt@amd.com pkt->makeResponse(); 1446008Ssteve.reinhardt@amd.com 1456008Ssteve.reinhardt@amd.com return 0; 1466008Ssteve.reinhardt@amd.com} 1476008Ssteve.reinhardt@amd.com 1486008Ssteve.reinhardt@amd.comTick 1496008Ssteve.reinhardt@amd.comNoMaliGpu::write(PacketPtr pkt) 1506007Ssteve.reinhardt@amd.com{ 1516007Ssteve.reinhardt@amd.com assert(pkt->getAddr() >= pioAddr); 1526007Ssteve.reinhardt@amd.com const Addr addr(pkt->getAddr() - pioAddr); 1536007Ssteve.reinhardt@amd.com const unsigned size(pkt->getSize()); 1546007Ssteve.reinhardt@amd.com 1552929Sktlim@umich.edu if (addr + size >= nomaliInfo.reg_size) 1562929Sktlim@umich.edu panic("GPU register '0x%x' out of range!\n", addr); 1572929Sktlim@umich.edu 1582929Sktlim@umich.edu if (size != 4) 1596007Ssteve.reinhardt@amd.com panic("Unexpected GPU register write size: %i\n", size); 1606007Ssteve.reinhardt@amd.com else if (addr & 0x3) 1612929Sktlim@umich.edu panic("Unaligned GPU write: %i\n", size); 1622929Sktlim@umich.edu 1632929Sktlim@umich.edu writeReg(addr, pkt->get<uint32_t>()); 1642929Sktlim@umich.edu pkt->makeAtomicResponse(); 1656007Ssteve.reinhardt@amd.com 1666007Ssteve.reinhardt@amd.com return 0; 1672929Sktlim@umich.edu} 1682929Sktlim@umich.edu 1696007Ssteve.reinhardt@amd.comAddrRangeList 1702929Sktlim@umich.eduNoMaliGpu::getAddrRanges() const 1712929Sktlim@umich.edu{ 1722929Sktlim@umich.edu return AddrRangeList({ RangeSize(pioAddr, nomaliInfo.reg_size) }); 1732929Sktlim@umich.edu} 1742929Sktlim@umich.edu 1752929Sktlim@umich.eduvoid 1762929Sktlim@umich.eduNoMaliGpu::reset() 1774937Sstever@gmail.com{ 1784937Sstever@gmail.com DPRINTF(NoMali, "reset()\n"); 1794937Sstever@gmail.com 1804937Sstever@gmail.com panicOnErr( 1818120Sgblack@eecs.umich.edu nomali_reset(nomali), 1824937Sstever@gmail.com "Failed to reset GPU"); 1834937Sstever@gmail.com} 1844937Sstever@gmail.com 1854937Sstever@gmail.comuint32_t 1865773Snate@binkert.orgNoMaliGpu::readReg(nomali_addr_t reg) 1874937Sstever@gmail.com{ 1884937Sstever@gmail.com uint32_t value; 1894937Sstever@gmail.com 1902929Sktlim@umich.edu panicOnErr( 1912929Sktlim@umich.edu nomali_reg_read(nomali, &value, reg), 1922929Sktlim@umich.edu "GPU register read failed"); 1935773Snate@binkert.org 1942929Sktlim@umich.edu DPRINTF(NoMali, "readReg(0x%x): 0x%x\n", 1952929Sktlim@umich.edu reg, value); 1962929Sktlim@umich.edu 1972929Sktlim@umich.edu return value; 1982929Sktlim@umich.edu} 1992929Sktlim@umich.edu 2004937Sstever@gmail.com 2014937Sstever@gmail.comvoid 2024937Sstever@gmail.comNoMaliGpu::writeReg(nomali_addr_t reg, uint32_t value) 2034937Sstever@gmail.com{ 2044937Sstever@gmail.com DPRINTF(NoMali, "writeReg(0x%x, 0x%x)\n", 2054937Sstever@gmail.com reg, value); 2064937Sstever@gmail.com 2074937Sstever@gmail.com panicOnErr( 2084937Sstever@gmail.com nomali_reg_write(nomali, reg, value), 2094937Sstever@gmail.com "GPU register write failed"); 2104937Sstever@gmail.com} 2114937Sstever@gmail.com 2124937Sstever@gmail.comuint32_t 2134937Sstever@gmail.comNoMaliGpu::readRegRaw(nomali_addr_t reg) const 2144937Sstever@gmail.com{ 2152929Sktlim@umich.edu uint32_t value; 2162929Sktlim@umich.edu 2172929Sktlim@umich.edu panicOnErr( 2182929Sktlim@umich.edu nomali_reg_read_raw(nomali, &value, reg), 2192929Sktlim@umich.edu "GPU raw register read failed"); 2202929Sktlim@umich.edu 2212929Sktlim@umich.edu return value; 2226011Ssteve.reinhardt@amd.com} 2232929Sktlim@umich.edu 2242929Sktlim@umich.edu 2252929Sktlim@umich.eduvoid 2262929Sktlim@umich.eduNoMaliGpu::writeRegRaw(nomali_addr_t reg, uint32_t value) 2272929Sktlim@umich.edu{ 2282929Sktlim@umich.edu panicOnErr( 2292929Sktlim@umich.edu nomali_reg_write_raw(nomali, reg, value), 2302929Sktlim@umich.edu "GPU raw register write failed"); 2312997Sstever@eecs.umich.edu} 2322997Sstever@eecs.umich.edu 2332929Sktlim@umich.edubool 2342997Sstever@eecs.umich.eduNoMaliGpu::intState(nomali_int_t intno) 2352997Sstever@eecs.umich.edu{ 2362929Sktlim@umich.edu int state = 0; 2372997Sstever@eecs.umich.edu panicOnErr( 2382997Sstever@eecs.umich.edu nomali_int_state(nomali, &state, intno), 2392997Sstever@eecs.umich.edu "Failed to get interrupt state"); 2402929Sktlim@umich.edu 2412997Sstever@eecs.umich.edu return !!state; 2422997Sstever@eecs.umich.edu} 2432997Sstever@eecs.umich.edu 2442997Sstever@eecs.umich.eduvoid 2455773Snate@binkert.orgNoMaliGpu::gpuPanic(nomali_error_t err, const char *msg) 2465773Snate@binkert.org{ 2472997Sstever@eecs.umich.edu panic("%s: %s\n", msg, nomali_errstr(err)); 2482997Sstever@eecs.umich.edu} 2496007Ssteve.reinhardt@amd.com 2506007Ssteve.reinhardt@amd.com 2512997Sstever@eecs.umich.eduvoid 2522929Sktlim@umich.eduNoMaliGpu::onInterrupt(nomali_int_t intno, bool set) 2532997Sstever@eecs.umich.edu{ 2548120Sgblack@eecs.umich.edu const auto it_int(interruptMap.find(intno)); 2552997Sstever@eecs.umich.edu if (it_int == interruptMap.end()) 2562997Sstever@eecs.umich.edu panic("Unhandled interrupt from NoMali: %i\n", intno); 2572997Sstever@eecs.umich.edu 2582997Sstever@eecs.umich.edu DPRINTF(NoMali, "Interrupt %i->%i: %i\n", 2592997Sstever@eecs.umich.edu intno, it_int->second, set); 2602929Sktlim@umich.edu 2612997Sstever@eecs.umich.edu assert(platform); 2622929Sktlim@umich.edu assert(platform->gic); 2632929Sktlim@umich.edu 2643005Sstever@eecs.umich.edu if (set) 2653005Sstever@eecs.umich.edu platform->gic->sendInt(it_int->second); 2663005Sstever@eecs.umich.edu else 2673005Sstever@eecs.umich.edu platform->gic->clearInt(it_int->second); 2686025Snate@binkert.org} 2696025Snate@binkert.org 2706025Snate@binkert.orgvoid 2716025Snate@binkert.orgNoMaliGpu::setCallback(const nomali_callback_t &callback) 2726025Snate@binkert.org{ 2736025Snate@binkert.org DPRINTF(NoMali, "Registering callback %i\n", 2744130Ssaidi@eecs.umich.edu callback.type); 2754130Ssaidi@eecs.umich.edu 2764130Ssaidi@eecs.umich.edu panicOnErr( 2777735SAli.Saidi@ARM.com nomali_set_callback(nomali, &callback), 2787735SAli.Saidi@ARM.com "Failed to register callback"); 2798150SAli.Saidi@ARM.com} 2808150SAli.Saidi@ARM.com 2817926Sgblack@eecs.umich.eduvoid 2827926Sgblack@eecs.umich.eduNoMaliGpu::_interrupt(nomali_handle_t h, void *usr, 2837926Sgblack@eecs.umich.edu nomali_int_t intno, int set) 2843691Shsul@eecs.umich.edu{ 2853005Sstever@eecs.umich.edu NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr)); 2865721Shsul@eecs.umich.edu 2876194Sksewell@umich.edu _this->onInterrupt(intno, !!set); 2886928SBrad.Beckmann@amd.com} 2893005Sstever@eecs.umich.edu 2906168Snate@binkert.orgNoMaliGpu * 2916928SBrad.Beckmann@amd.comNoMaliGpuParams::create() 2926928SBrad.Beckmann@amd.com{ 2936928SBrad.Beckmann@amd.com return new NoMaliGpu(this); 2946928SBrad.Beckmann@amd.com} 2956928SBrad.Beckmann@amd.com