gpu_nomali.cc revision 11349
15409Sgblack@eecs.umich.edu/* 24519Sgblack@eecs.umich.edu * Copyright (c) 2014-2016 ARM Limited 34519Sgblack@eecs.umich.edu * All rights reserved 44519Sgblack@eecs.umich.edu * 54519Sgblack@eecs.umich.edu * The license below extends only to copyright in the software and shall 64519Sgblack@eecs.umich.edu * not be construed as granting a license to any other intellectual 74519Sgblack@eecs.umich.edu * property including but not limited to intellectual property relating 84519Sgblack@eecs.umich.edu * to a hardware implementation of the functionality of the software 94519Sgblack@eecs.umich.edu * licensed hereunder. You may use the software subject to the license 104519Sgblack@eecs.umich.edu * terms below provided that you ensure that this notice is replicated 114519Sgblack@eecs.umich.edu * unmodified and in its entirety in all distributions of the software, 124519Sgblack@eecs.umich.edu * modified or unmodified, in source code or in binary form. 134519Sgblack@eecs.umich.edu * 144519Sgblack@eecs.umich.edu * Redistribution and use in source and binary forms, with or without 154519Sgblack@eecs.umich.edu * modification, are permitted provided that the following conditions are 164519Sgblack@eecs.umich.edu * met: redistributions of source code must retain the above copyright 174519Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer; 184519Sgblack@eecs.umich.edu * redistributions in binary form must reproduce the above copyright 194519Sgblack@eecs.umich.edu * notice, this list of conditions and the following disclaimer in the 204519Sgblack@eecs.umich.edu * documentation and/or other materials provided with the distribution; 214519Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 224519Sgblack@eecs.umich.edu * contributors may be used to endorse or promote products derived from 234519Sgblack@eecs.umich.edu * this software without specific prior written permission. 244519Sgblack@eecs.umich.edu * 254519Sgblack@eecs.umich.edu * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 264519Sgblack@eecs.umich.edu * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 274519Sgblack@eecs.umich.edu * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 284519Sgblack@eecs.umich.edu * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 294519Sgblack@eecs.umich.edu * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 304519Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 314519Sgblack@eecs.umich.edu * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 324519Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 334519Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 344519Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 354519Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 364519Sgblack@eecs.umich.edu * 374519Sgblack@eecs.umich.edu * Authors: Andreas Sandberg 384519Sgblack@eecs.umich.edu */ 394519Sgblack@eecs.umich.edu 404519Sgblack@eecs.umich.edu#include "dev/arm/gpu_nomali.hh" 414519Sgblack@eecs.umich.edu 424519Sgblack@eecs.umich.edu#include "debug/NoMali.hh" 434519Sgblack@eecs.umich.edu#include "dev/arm/base_gic.hh" 444519Sgblack@eecs.umich.edu#include "dev/arm/realview.hh" 454519Sgblack@eecs.umich.edu#include "enums/MemoryMode.hh" 464519Sgblack@eecs.umich.edu#include "mem/packet_access.hh" 474519Sgblack@eecs.umich.edu#include "params/NoMaliGpu.hh" 484519Sgblack@eecs.umich.edu 494519Sgblack@eecs.umich.edustatic const std::map<Enums::NoMaliGpuType, nomali_gpu_type_t> gpuTypeMap{ 504519Sgblack@eecs.umich.edu { Enums::T60x, NOMALI_GPU_T60X }, 514519Sgblack@eecs.umich.edu { Enums::T62x, NOMALI_GPU_T62X }, 524519Sgblack@eecs.umich.edu { Enums::T760, NOMALI_GPU_T760 }, 534519Sgblack@eecs.umich.edu}; 544519Sgblack@eecs.umich.edu 554519Sgblack@eecs.umich.eduNoMaliGpu::NoMaliGpu(const NoMaliGpuParams *p) 564519Sgblack@eecs.umich.edu : PioDevice(p), 574519Sgblack@eecs.umich.edu pioAddr(p->pio_addr), 584519Sgblack@eecs.umich.edu platform(p->platform), 594519Sgblack@eecs.umich.edu interruptMap{ 604519Sgblack@eecs.umich.edu { NOMALI_INT_GPU, p->int_gpu }, 614519Sgblack@eecs.umich.edu { NOMALI_INT_JOB, p->int_job }, 624519Sgblack@eecs.umich.edu { NOMALI_INT_MMU, p->int_mmu }, 634519Sgblack@eecs.umich.edu } 644519Sgblack@eecs.umich.edu{ 654519Sgblack@eecs.umich.edu if (nomali_api_version() != NOMALI_API_VERSION) 664519Sgblack@eecs.umich.edu panic("NoMali library API mismatch!\n"); 674519Sgblack@eecs.umich.edu 684809Sgblack@eecs.umich.edu /* Setup the GPU configuration based on our param struct */ 694519Sgblack@eecs.umich.edu nomali_config_t cfg; 704519Sgblack@eecs.umich.edu memset(&cfg, 0, sizeof(cfg)); 714688Sgblack@eecs.umich.edu 724688Sgblack@eecs.umich.edu const auto it_gpu(gpuTypeMap.find(p->gpu_type)); 734688Sgblack@eecs.umich.edu if (it_gpu == gpuTypeMap.end()) { 744688Sgblack@eecs.umich.edu fatal("Unrecognized GPU type: %s (%i)\n", 754688Sgblack@eecs.umich.edu Enums::NoMaliGpuTypeStrings[p->gpu_type], p->gpu_type); 764688Sgblack@eecs.umich.edu } 774708Sgblack@eecs.umich.edu cfg.type = it_gpu->second; 784708Sgblack@eecs.umich.edu 794708Sgblack@eecs.umich.edu cfg.ver_maj = p->ver_maj; 804708Sgblack@eecs.umich.edu cfg.ver_min = p->ver_min; 814519Sgblack@eecs.umich.edu cfg.ver_status = p->ver_status; 824519Sgblack@eecs.umich.edu 834519Sgblack@eecs.umich.edu panicOnErr( 844519Sgblack@eecs.umich.edu nomali_create(&nomali, &cfg), 854519Sgblack@eecs.umich.edu "Failed to instantiate NoMali"); 864519Sgblack@eecs.umich.edu 874519Sgblack@eecs.umich.edu 884519Sgblack@eecs.umich.edu /* Setup an interrupt callback */ 894519Sgblack@eecs.umich.edu nomali_callback_t cbk_int; 904519Sgblack@eecs.umich.edu cbk_int.type = NOMALI_CALLBACK_INT; 914519Sgblack@eecs.umich.edu cbk_int.usr = (void *)this; 924951Sgblack@eecs.umich.edu cbk_int.func.interrupt = NoMaliGpu::_interrupt; 934519Sgblack@eecs.umich.edu setCallback(cbk_int); 944519Sgblack@eecs.umich.edu 954519Sgblack@eecs.umich.edu panicOnErr( 964519Sgblack@eecs.umich.edu nomali_get_info(nomali, &nomaliInfo), 974519Sgblack@eecs.umich.edu "Failed to get NoMali information struct"); 984519Sgblack@eecs.umich.edu} 994688Sgblack@eecs.umich.edu 1004688Sgblack@eecs.umich.eduNoMaliGpu::~NoMaliGpu() 1014688Sgblack@eecs.umich.edu{ 1024688Sgblack@eecs.umich.edu nomali_destroy(nomali); 1034688Sgblack@eecs.umich.edu} 1044688Sgblack@eecs.umich.edu 1054708Sgblack@eecs.umich.eduvoid 1064708Sgblack@eecs.umich.eduNoMaliGpu::serialize(CheckpointOut &cp) const 1074708Sgblack@eecs.umich.edu{ 1084708Sgblack@eecs.umich.edu std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2); 1094519Sgblack@eecs.umich.edu 1104519Sgblack@eecs.umich.edu for (int i = 0; i < nomaliInfo.reg_size; i += 4) 1114519Sgblack@eecs.umich.edu regs[i >> 2] = readRegRaw(i); 1124519Sgblack@eecs.umich.edu 1134519Sgblack@eecs.umich.edu SERIALIZE_CONTAINER(regs); 1144519Sgblack@eecs.umich.edu} 1154519Sgblack@eecs.umich.edu 1164519Sgblack@eecs.umich.eduvoid 1174519Sgblack@eecs.umich.eduNoMaliGpu::unserialize(CheckpointIn &cp) 1184519Sgblack@eecs.umich.edu{ 1194519Sgblack@eecs.umich.edu std::vector<uint32_t> regs(nomaliInfo.reg_size >> 2); 1204519Sgblack@eecs.umich.edu 1214519Sgblack@eecs.umich.edu UNSERIALIZE_CONTAINER(regs); 1224519Sgblack@eecs.umich.edu 1234519Sgblack@eecs.umich.edu for (int i = 0; i < nomaliInfo.reg_size; i += 4) 1244519Sgblack@eecs.umich.edu writeRegRaw(i, regs[i >> 2]); 1254519Sgblack@eecs.umich.edu} 1264519Sgblack@eecs.umich.edu 1274519Sgblack@eecs.umich.eduTick 1284519Sgblack@eecs.umich.eduNoMaliGpu::read(PacketPtr pkt) 1296345Sgblack@eecs.umich.edu{ 1304712Sgblack@eecs.umich.edu assert(pkt->getAddr() >= pioAddr); 1314519Sgblack@eecs.umich.edu const Addr addr(pkt->getAddr() - pioAddr); 1324519Sgblack@eecs.umich.edu const unsigned size(pkt->getSize()); 1334519Sgblack@eecs.umich.edu 1346345Sgblack@eecs.umich.edu if (addr + size >= nomaliInfo.reg_size) 1354712Sgblack@eecs.umich.edu panic("GPU register '0x%x' out of range!\n", addr); 1364519Sgblack@eecs.umich.edu 1374519Sgblack@eecs.umich.edu if (size != 4) 1384519Sgblack@eecs.umich.edu panic("Unexpected GPU register read size: %i\n", size); 1394519Sgblack@eecs.umich.edu else if (addr & 0x3) 1404519Sgblack@eecs.umich.edu panic("Unaligned GPU read: %i\n", size); 1414519Sgblack@eecs.umich.edu 1424519Sgblack@eecs.umich.edu pkt->set<uint32_t>(readReg(addr)); 1434951Sgblack@eecs.umich.edu pkt->makeResponse(); 1444519Sgblack@eecs.umich.edu 1454519Sgblack@eecs.umich.edu return 0; 1464519Sgblack@eecs.umich.edu} 1474519Sgblack@eecs.umich.edu 1484519Sgblack@eecs.umich.eduTick 1494951Sgblack@eecs.umich.eduNoMaliGpu::write(PacketPtr pkt) 1504519Sgblack@eecs.umich.edu{ 1514519Sgblack@eecs.umich.edu assert(pkt->getAddr() >= pioAddr); 1526345Sgblack@eecs.umich.edu const Addr addr(pkt->getAddr() - pioAddr); 1534712Sgblack@eecs.umich.edu const unsigned size(pkt->getSize()); 1544519Sgblack@eecs.umich.edu 1554951Sgblack@eecs.umich.edu if (addr + size >= nomaliInfo.reg_size) 1564519Sgblack@eecs.umich.edu panic("GPU register '0x%x' out of range!\n", addr); 1576345Sgblack@eecs.umich.edu 1584712Sgblack@eecs.umich.edu if (size != 4) 1594519Sgblack@eecs.umich.edu panic("Unexpected GPU register write size: %i\n", size); 1604519Sgblack@eecs.umich.edu else if (addr & 0x3) 1614519Sgblack@eecs.umich.edu panic("Unaligned GPU write: %i\n", size); 1624519Sgblack@eecs.umich.edu 1634519Sgblack@eecs.umich.edu writeReg(addr, pkt->get<uint32_t>()); 1644519Sgblack@eecs.umich.edu pkt->makeAtomicResponse(); 1654519Sgblack@eecs.umich.edu 1664519Sgblack@eecs.umich.edu return 0; 1674519Sgblack@eecs.umich.edu} 1684519Sgblack@eecs.umich.edu 1694519Sgblack@eecs.umich.eduAddrRangeList 1704519Sgblack@eecs.umich.eduNoMaliGpu::getAddrRanges() const 1714519Sgblack@eecs.umich.edu{ 1724519Sgblack@eecs.umich.edu return AddrRangeList({ RangeSize(pioAddr, nomaliInfo.reg_size) }); 1736345Sgblack@eecs.umich.edu} 1744712Sgblack@eecs.umich.edu 1754519Sgblack@eecs.umich.eduvoid 1764581Sgblack@eecs.umich.eduNoMaliGpu::reset() 1774688Sgblack@eecs.umich.edu{ 1784581Sgblack@eecs.umich.edu DPRINTF(NoMali, "reset()\n"); 1794519Sgblack@eecs.umich.edu 1804519Sgblack@eecs.umich.edu panicOnErr( 1814519Sgblack@eecs.umich.edu nomali_reset(nomali), 1824519Sgblack@eecs.umich.edu "Failed to reset GPU"); 1834519Sgblack@eecs.umich.edu} 1844519Sgblack@eecs.umich.edu 1854519Sgblack@eecs.umich.eduuint32_t 1866345Sgblack@eecs.umich.eduNoMaliGpu::readReg(nomali_addr_t reg) 1874712Sgblack@eecs.umich.edu{ 1884519Sgblack@eecs.umich.edu uint32_t value; 1894581Sgblack@eecs.umich.edu 1904688Sgblack@eecs.umich.edu panicOnErr( 1914581Sgblack@eecs.umich.edu nomali_reg_read(nomali, &value, reg), 1924519Sgblack@eecs.umich.edu "GPU register read failed"); 1934519Sgblack@eecs.umich.edu 1944519Sgblack@eecs.umich.edu DPRINTF(NoMali, "readReg(0x%x): 0x%x\n", 1954519Sgblack@eecs.umich.edu reg, value); 1964519Sgblack@eecs.umich.edu 1974519Sgblack@eecs.umich.edu return value; 1984519Sgblack@eecs.umich.edu} 1994951Sgblack@eecs.umich.edu 2004519Sgblack@eecs.umich.edu 2014519Sgblack@eecs.umich.eduvoid 2024519Sgblack@eecs.umich.eduNoMaliGpu::writeReg(nomali_addr_t reg, uint32_t value) 2034519Sgblack@eecs.umich.edu{ 2044951Sgblack@eecs.umich.edu DPRINTF(NoMali, "writeReg(0x%x, 0x%x)\n", 2054519Sgblack@eecs.umich.edu reg, value); 2066345Sgblack@eecs.umich.edu 2074712Sgblack@eecs.umich.edu panicOnErr( 2084519Sgblack@eecs.umich.edu nomali_reg_write(nomali, reg, value), 2094581Sgblack@eecs.umich.edu "GPU register write failed"); 2104688Sgblack@eecs.umich.edu} 2114581Sgblack@eecs.umich.edu 2124519Sgblack@eecs.umich.eduuint32_t 2134519Sgblack@eecs.umich.eduNoMaliGpu::readRegRaw(nomali_addr_t reg) const 2144519Sgblack@eecs.umich.edu{ 2154519Sgblack@eecs.umich.edu uint32_t value; 2164951Sgblack@eecs.umich.edu 2174519Sgblack@eecs.umich.edu panicOnErr( 2184519Sgblack@eecs.umich.edu nomali_reg_read_raw(nomali, &value, reg), 2196345Sgblack@eecs.umich.edu "GPU raw register read failed"); 2204712Sgblack@eecs.umich.edu 2214519Sgblack@eecs.umich.edu return value; 2224581Sgblack@eecs.umich.edu} 2234688Sgblack@eecs.umich.edu 2244581Sgblack@eecs.umich.edu 2254519Sgblack@eecs.umich.eduvoid 2264519Sgblack@eecs.umich.eduNoMaliGpu::writeRegRaw(nomali_addr_t reg, uint32_t value) 2274519Sgblack@eecs.umich.edu{ 2284519Sgblack@eecs.umich.edu panicOnErr( 2294519Sgblack@eecs.umich.edu nomali_reg_write_raw(nomali, reg, value), 2305075Sgblack@eecs.umich.edu "GPU raw register write failed"); 2315075Sgblack@eecs.umich.edu} 2325075Sgblack@eecs.umich.edu 2335075Sgblack@eecs.umich.edubool 2345428Sgblack@eecs.umich.eduNoMaliGpu::intState(nomali_int_t intno) 2355428Sgblack@eecs.umich.edu{ 2365674Sgblack@eecs.umich.edu int state = 0; 2375899Sgblack@eecs.umich.edu panicOnErr( 2385936Sgblack@eecs.umich.edu nomali_int_state(nomali, &state, intno), 2395428Sgblack@eecs.umich.edu "Failed to get interrupt state"); 2405678Sgblack@eecs.umich.edu 2415678Sgblack@eecs.umich.edu return !!state; 2425678Sgblack@eecs.umich.edu} 2435678Sgblack@eecs.umich.edu 2445678Sgblack@eecs.umich.eduvoid 2455678Sgblack@eecs.umich.eduNoMaliGpu::gpuPanic(nomali_error_t err, const char *msg) 2465678Sgblack@eecs.umich.edu{ 2475678Sgblack@eecs.umich.edu panic("%s: %s\n", msg, nomali_errstr(err)); 2485678Sgblack@eecs.umich.edu} 2495075Sgblack@eecs.umich.edu 2505075Sgblack@eecs.umich.edu 2515075Sgblack@eecs.umich.eduvoid 2525075Sgblack@eecs.umich.eduNoMaliGpu::onInterrupt(nomali_int_t intno, bool set) 2535075Sgblack@eecs.umich.edu{ 2545075Sgblack@eecs.umich.edu const auto it_int(interruptMap.find(intno)); 2555075Sgblack@eecs.umich.edu if (it_int == interruptMap.end()) 2565075Sgblack@eecs.umich.edu panic("Unhandled interrupt from NoMali: %i\n", intno); 2575075Sgblack@eecs.umich.edu 2585075Sgblack@eecs.umich.edu DPRINTF(NoMali, "Interrupt %i->%i: %i\n", 2595075Sgblack@eecs.umich.edu intno, it_int->second, set); 2605075Sgblack@eecs.umich.edu 2615075Sgblack@eecs.umich.edu assert(platform); 2625075Sgblack@eecs.umich.edu assert(platform->gic); 2635075Sgblack@eecs.umich.edu 2645075Sgblack@eecs.umich.edu if (set) 2655075Sgblack@eecs.umich.edu platform->gic->sendInt(it_int->second); 2665075Sgblack@eecs.umich.edu else 2675075Sgblack@eecs.umich.edu platform->gic->clearInt(it_int->second); 2685075Sgblack@eecs.umich.edu} 2695075Sgblack@eecs.umich.edu 2705075Sgblack@eecs.umich.eduvoid 2715075Sgblack@eecs.umich.eduNoMaliGpu::setCallback(const nomali_callback_t &callback) 2725075Sgblack@eecs.umich.edu{ 2735075Sgblack@eecs.umich.edu DPRINTF(NoMali, "Registering callback %i\n", 2745075Sgblack@eecs.umich.edu callback.type); 2755075Sgblack@eecs.umich.edu 2765075Sgblack@eecs.umich.edu panicOnErr( 2775075Sgblack@eecs.umich.edu nomali_set_callback(nomali, &callback), 2785075Sgblack@eecs.umich.edu "Failed to register callback"); 2795075Sgblack@eecs.umich.edu} 2805075Sgblack@eecs.umich.edu 2815075Sgblack@eecs.umich.eduvoid 2825075Sgblack@eecs.umich.eduNoMaliGpu::_interrupt(nomali_handle_t h, void *usr, 2835075Sgblack@eecs.umich.edu nomali_int_t intno, int set) 2844519Sgblack@eecs.umich.edu{ 2855040Sgblack@eecs.umich.edu NoMaliGpu *_this(static_cast<NoMaliGpu *>(usr)); 2865040Sgblack@eecs.umich.edu 2875040Sgblack@eecs.umich.edu _this->onInterrupt(intno, !!set); 2885040Sgblack@eecs.umich.edu} 2895040Sgblack@eecs.umich.edu 2905040Sgblack@eecs.umich.eduNoMaliGpu * 2915040Sgblack@eecs.umich.eduNoMaliGpuParams::create() 2925040Sgblack@eecs.umich.edu{ 2935040Sgblack@eecs.umich.edu return new NoMaliGpu(this); 2945040Sgblack@eecs.umich.edu} 2955040Sgblack@eecs.umich.edu