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