113996Sgiacomo.travaglini@arm.com/*
213996Sgiacomo.travaglini@arm.com * Copyright (c) 2019 ARM Limited
313996Sgiacomo.travaglini@arm.com * All rights reserved
413996Sgiacomo.travaglini@arm.com *
513996Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall
613996Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual
713996Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating
813996Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software
913996Sgiacomo.travaglini@arm.com * licensed hereunder.  You may use the software subject to the license
1013996Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated
1113996Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software,
1213996Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form.
1313996Sgiacomo.travaglini@arm.com *
1413996Sgiacomo.travaglini@arm.com * Redistribution and use in source and binary forms, with or without
1513996Sgiacomo.travaglini@arm.com * modification, are permitted provided that the following conditions are
1613996Sgiacomo.travaglini@arm.com * met: redistributions of source code must retain the above copyright
1713996Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer;
1813996Sgiacomo.travaglini@arm.com * redistributions in binary form must reproduce the above copyright
1913996Sgiacomo.travaglini@arm.com * notice, this list of conditions and the following disclaimer in the
2013996Sgiacomo.travaglini@arm.com * documentation and/or other materials provided with the distribution;
2113996Sgiacomo.travaglini@arm.com * neither the name of the copyright holders nor the names of its
2213996Sgiacomo.travaglini@arm.com * contributors may be used to endorse or promote products derived from
2313996Sgiacomo.travaglini@arm.com * this software without specific prior written permission.
2413996Sgiacomo.travaglini@arm.com *
2513996Sgiacomo.travaglini@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2613996Sgiacomo.travaglini@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2713996Sgiacomo.travaglini@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2813996Sgiacomo.travaglini@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2913996Sgiacomo.travaglini@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3013996Sgiacomo.travaglini@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3113996Sgiacomo.travaglini@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3213996Sgiacomo.travaglini@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3313996Sgiacomo.travaglini@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3413996Sgiacomo.travaglini@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3513996Sgiacomo.travaglini@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3613996Sgiacomo.travaglini@arm.com *
3713996Sgiacomo.travaglini@arm.com * Authors: Giacomo Travaglini
3813996Sgiacomo.travaglini@arm.com */
3913996Sgiacomo.travaglini@arm.com
4013996Sgiacomo.travaglini@arm.com#include "dev/arm/gic_v3_its.hh"
4113996Sgiacomo.travaglini@arm.com
4213996Sgiacomo.travaglini@arm.com#include "debug/AddrRanges.hh"
4313996Sgiacomo.travaglini@arm.com#include "debug/Drain.hh"
4413996Sgiacomo.travaglini@arm.com#include "debug/GIC.hh"
4513996Sgiacomo.travaglini@arm.com#include "debug/ITS.hh"
4613996Sgiacomo.travaglini@arm.com#include "dev/arm/gic_v3.hh"
4713996Sgiacomo.travaglini@arm.com#include "dev/arm/gic_v3_distributor.hh"
4813996Sgiacomo.travaglini@arm.com#include "dev/arm/gic_v3_redistributor.hh"
4913996Sgiacomo.travaglini@arm.com#include "mem/packet_access.hh"
5013996Sgiacomo.travaglini@arm.com
5113996Sgiacomo.travaglini@arm.com#define COMMAND(x, method) { x, DispatchEntry(#x, method) }
5213996Sgiacomo.travaglini@arm.com
5313996Sgiacomo.travaglini@arm.comconst AddrRange Gicv3Its::GITS_BASER(0x0100, 0x0138);
5413996Sgiacomo.travaglini@arm.com
5514181Sgiacomo.travaglini@arm.comconst uint32_t Gicv3Its::CTLR_QUIESCENT = 0x80000000;
5614181Sgiacomo.travaglini@arm.com
5713996Sgiacomo.travaglini@arm.comItsProcess::ItsProcess(Gicv3Its &_its)
5813996Sgiacomo.travaglini@arm.com  : its(_its), coroutine(nullptr)
5913996Sgiacomo.travaglini@arm.com{
6013996Sgiacomo.travaglini@arm.com}
6113996Sgiacomo.travaglini@arm.com
6213996Sgiacomo.travaglini@arm.comItsProcess::~ItsProcess()
6313996Sgiacomo.travaglini@arm.com{
6413996Sgiacomo.travaglini@arm.com}
6513996Sgiacomo.travaglini@arm.com
6613996Sgiacomo.travaglini@arm.comvoid
6713996Sgiacomo.travaglini@arm.comItsProcess::reinit()
6813996Sgiacomo.travaglini@arm.com{
6913996Sgiacomo.travaglini@arm.com    coroutine.reset(new Coroutine(
7013996Sgiacomo.travaglini@arm.com        std::bind(&ItsProcess::main, this, std::placeholders::_1)));
7113996Sgiacomo.travaglini@arm.com}
7213996Sgiacomo.travaglini@arm.com
7313996Sgiacomo.travaglini@arm.comconst std::string
7413996Sgiacomo.travaglini@arm.comItsProcess::name() const
7513996Sgiacomo.travaglini@arm.com{
7613996Sgiacomo.travaglini@arm.com    return its.name();
7713996Sgiacomo.travaglini@arm.com}
7813996Sgiacomo.travaglini@arm.com
7913996Sgiacomo.travaglini@arm.comItsAction
8013996Sgiacomo.travaglini@arm.comItsProcess::run(PacketPtr pkt)
8113996Sgiacomo.travaglini@arm.com{
8213996Sgiacomo.travaglini@arm.com    assert(coroutine != nullptr);
8313996Sgiacomo.travaglini@arm.com    assert(*coroutine);
8413996Sgiacomo.travaglini@arm.com    return (*coroutine)(pkt).get();
8513996Sgiacomo.travaglini@arm.com}
8613996Sgiacomo.travaglini@arm.com
8713996Sgiacomo.travaglini@arm.comvoid
8813996Sgiacomo.travaglini@arm.comItsProcess::doRead(Yield &yield, Addr addr, void *ptr, size_t size)
8913996Sgiacomo.travaglini@arm.com{
9013996Sgiacomo.travaglini@arm.com    ItsAction a;
9113996Sgiacomo.travaglini@arm.com    a.type = ItsActionType::SEND_REQ;
9213996Sgiacomo.travaglini@arm.com
9313996Sgiacomo.travaglini@arm.com    RequestPtr req = std::make_shared<Request>(
9413996Sgiacomo.travaglini@arm.com        addr, size, 0, its.masterId);
9513996Sgiacomo.travaglini@arm.com
9613996Sgiacomo.travaglini@arm.com    req->taskId(ContextSwitchTaskId::DMA);
9713996Sgiacomo.travaglini@arm.com
9813996Sgiacomo.travaglini@arm.com    a.pkt = new Packet(req, MemCmd::ReadReq);
9913996Sgiacomo.travaglini@arm.com    a.pkt->dataStatic(ptr);
10013996Sgiacomo.travaglini@arm.com
10113996Sgiacomo.travaglini@arm.com    a.delay = 0;
10213996Sgiacomo.travaglini@arm.com
10313996Sgiacomo.travaglini@arm.com    PacketPtr pkt = yield(a).get();
10413996Sgiacomo.travaglini@arm.com
10513996Sgiacomo.travaglini@arm.com    assert(pkt);
10613996Sgiacomo.travaglini@arm.com    assert(pkt->getSize() >= size);
10713996Sgiacomo.travaglini@arm.com
10813996Sgiacomo.travaglini@arm.com    delete pkt;
10913996Sgiacomo.travaglini@arm.com}
11013996Sgiacomo.travaglini@arm.com
11113996Sgiacomo.travaglini@arm.comvoid
11213996Sgiacomo.travaglini@arm.comItsProcess::doWrite(Yield &yield, Addr addr, void *ptr, size_t size)
11313996Sgiacomo.travaglini@arm.com{
11413996Sgiacomo.travaglini@arm.com    ItsAction a;
11513996Sgiacomo.travaglini@arm.com    a.type = ItsActionType::SEND_REQ;
11613996Sgiacomo.travaglini@arm.com
11713996Sgiacomo.travaglini@arm.com    RequestPtr req = std::make_shared<Request>(
11813996Sgiacomo.travaglini@arm.com        addr, size, 0, its.masterId);
11913996Sgiacomo.travaglini@arm.com
12013996Sgiacomo.travaglini@arm.com    req->taskId(ContextSwitchTaskId::DMA);
12113996Sgiacomo.travaglini@arm.com
12213996Sgiacomo.travaglini@arm.com    a.pkt = new Packet(req, MemCmd::WriteReq);
12313996Sgiacomo.travaglini@arm.com    a.pkt->dataStatic(ptr);
12413996Sgiacomo.travaglini@arm.com
12513996Sgiacomo.travaglini@arm.com    a.delay = 0;
12613996Sgiacomo.travaglini@arm.com
12713996Sgiacomo.travaglini@arm.com    PacketPtr pkt = yield(a).get();
12813996Sgiacomo.travaglini@arm.com
12913996Sgiacomo.travaglini@arm.com    assert(pkt);
13013996Sgiacomo.travaglini@arm.com    assert(pkt->getSize() >= size);
13113996Sgiacomo.travaglini@arm.com
13213996Sgiacomo.travaglini@arm.com    delete pkt;
13313996Sgiacomo.travaglini@arm.com}
13413996Sgiacomo.travaglini@arm.com
13513996Sgiacomo.travaglini@arm.comvoid
13613996Sgiacomo.travaglini@arm.comItsProcess::terminate(Yield &yield)
13713996Sgiacomo.travaglini@arm.com{
13813996Sgiacomo.travaglini@arm.com    ItsAction a;
13913996Sgiacomo.travaglini@arm.com    a.type = ItsActionType::TERMINATE;
14013996Sgiacomo.travaglini@arm.com    a.pkt = NULL;
14113996Sgiacomo.travaglini@arm.com    a.delay = 0;
14213996Sgiacomo.travaglini@arm.com    yield(a);
14313996Sgiacomo.travaglini@arm.com}
14413996Sgiacomo.travaglini@arm.com
14513996Sgiacomo.travaglini@arm.comvoid
14613996Sgiacomo.travaglini@arm.comItsProcess::writeDeviceTable(Yield &yield, uint32_t device_id, DTE dte)
14713996Sgiacomo.travaglini@arm.com{
14813996Sgiacomo.travaglini@arm.com    const Addr base = its.pageAddress(Gicv3Its::DEVICE_TABLE);
14914188Sgiacomo.travaglini@arm.com    const Addr address = base + (device_id * sizeof(dte));
15013996Sgiacomo.travaglini@arm.com
15113996Sgiacomo.travaglini@arm.com    DPRINTF(ITS, "Writing DTE at address %#x: %#x\n", address, dte);
15213996Sgiacomo.travaglini@arm.com
15313996Sgiacomo.travaglini@arm.com    doWrite(yield, address, &dte, sizeof(dte));
15413996Sgiacomo.travaglini@arm.com}
15513996Sgiacomo.travaglini@arm.com
15613996Sgiacomo.travaglini@arm.comvoid
15713996Sgiacomo.travaglini@arm.comItsProcess::writeIrqTranslationTable(
15813996Sgiacomo.travaglini@arm.com    Yield &yield, const Addr itt_base, uint32_t event_id, ITTE itte)
15913996Sgiacomo.travaglini@arm.com{
16014188Sgiacomo.travaglini@arm.com    const Addr address = itt_base + (event_id * sizeof(itte));
16113996Sgiacomo.travaglini@arm.com
16213996Sgiacomo.travaglini@arm.com    doWrite(yield, address, &itte, sizeof(itte));
16313996Sgiacomo.travaglini@arm.com
16413996Sgiacomo.travaglini@arm.com    DPRINTF(ITS, "Writing ITTE at address %#x: %#x\n", address, itte);
16513996Sgiacomo.travaglini@arm.com}
16613996Sgiacomo.travaglini@arm.com
16713996Sgiacomo.travaglini@arm.comvoid
16813996Sgiacomo.travaglini@arm.comItsProcess::writeIrqCollectionTable(
16913996Sgiacomo.travaglini@arm.com    Yield &yield, uint32_t collection_id, CTE cte)
17013996Sgiacomo.travaglini@arm.com{
17113996Sgiacomo.travaglini@arm.com    const Addr base = its.pageAddress(Gicv3Its::COLLECTION_TABLE);
17214188Sgiacomo.travaglini@arm.com    const Addr address = base + (collection_id * sizeof(cte));
17313996Sgiacomo.travaglini@arm.com
17413996Sgiacomo.travaglini@arm.com    doWrite(yield, address, &cte, sizeof(cte));
17513996Sgiacomo.travaglini@arm.com
17613996Sgiacomo.travaglini@arm.com    DPRINTF(ITS, "Writing CTE at address %#x: %#x\n", address, cte);
17713996Sgiacomo.travaglini@arm.com}
17813996Sgiacomo.travaglini@arm.com
17913996Sgiacomo.travaglini@arm.comuint64_t
18013996Sgiacomo.travaglini@arm.comItsProcess::readDeviceTable(Yield &yield, uint32_t device_id)
18113996Sgiacomo.travaglini@arm.com{
18214188Sgiacomo.travaglini@arm.com    uint64_t dte;
18313996Sgiacomo.travaglini@arm.com    const Addr base = its.pageAddress(Gicv3Its::DEVICE_TABLE);
18414188Sgiacomo.travaglini@arm.com    const Addr address = base + (device_id * sizeof(dte));
18513996Sgiacomo.travaglini@arm.com
18613996Sgiacomo.travaglini@arm.com    doRead(yield, address, &dte, sizeof(dte));
18713996Sgiacomo.travaglini@arm.com
18813996Sgiacomo.travaglini@arm.com    DPRINTF(ITS, "Reading DTE at address %#x: %#x\n", address, dte);
18913996Sgiacomo.travaglini@arm.com    return dte;
19013996Sgiacomo.travaglini@arm.com}
19113996Sgiacomo.travaglini@arm.com
19213996Sgiacomo.travaglini@arm.comuint64_t
19313996Sgiacomo.travaglini@arm.comItsProcess::readIrqTranslationTable(
19413996Sgiacomo.travaglini@arm.com    Yield &yield, const Addr itt_base, uint32_t event_id)
19513996Sgiacomo.travaglini@arm.com{
19614188Sgiacomo.travaglini@arm.com    uint64_t itte;
19714188Sgiacomo.travaglini@arm.com    const Addr address = itt_base + (event_id * sizeof(itte));
19813996Sgiacomo.travaglini@arm.com
19913996Sgiacomo.travaglini@arm.com    doRead(yield, address, &itte, sizeof(itte));
20013996Sgiacomo.travaglini@arm.com
20113996Sgiacomo.travaglini@arm.com    DPRINTF(ITS, "Reading ITTE at address %#x: %#x\n", address, itte);
20213996Sgiacomo.travaglini@arm.com    return itte;
20313996Sgiacomo.travaglini@arm.com}
20413996Sgiacomo.travaglini@arm.com
20513996Sgiacomo.travaglini@arm.comuint64_t
20613996Sgiacomo.travaglini@arm.comItsProcess::readIrqCollectionTable(Yield &yield, uint32_t collection_id)
20713996Sgiacomo.travaglini@arm.com{
20814188Sgiacomo.travaglini@arm.com    uint64_t cte;
20913996Sgiacomo.travaglini@arm.com    const Addr base = its.pageAddress(Gicv3Its::COLLECTION_TABLE);
21014188Sgiacomo.travaglini@arm.com    const Addr address = base + (collection_id * sizeof(cte));
21113996Sgiacomo.travaglini@arm.com
21213996Sgiacomo.travaglini@arm.com    doRead(yield, address, &cte, sizeof(cte));
21313996Sgiacomo.travaglini@arm.com
21413996Sgiacomo.travaglini@arm.com    DPRINTF(ITS, "Reading CTE at address %#x: %#x\n", address, cte);
21513996Sgiacomo.travaglini@arm.com    return cte;
21613996Sgiacomo.travaglini@arm.com}
21713996Sgiacomo.travaglini@arm.com
21813996Sgiacomo.travaglini@arm.comItsTranslation::ItsTranslation(Gicv3Its &_its)
21913996Sgiacomo.travaglini@arm.com  : ItsProcess(_its)
22013996Sgiacomo.travaglini@arm.com{
22113996Sgiacomo.travaglini@arm.com    reinit();
22213996Sgiacomo.travaglini@arm.com    its.pendingTranslations++;
22314181Sgiacomo.travaglini@arm.com    its.gitsControl.quiescent = 0;
22413996Sgiacomo.travaglini@arm.com}
22513996Sgiacomo.travaglini@arm.com
22613996Sgiacomo.travaglini@arm.comItsTranslation::~ItsTranslation()
22713996Sgiacomo.travaglini@arm.com{
22813996Sgiacomo.travaglini@arm.com    assert(its.pendingTranslations >= 1);
22913996Sgiacomo.travaglini@arm.com    its.pendingTranslations--;
23014181Sgiacomo.travaglini@arm.com    if (!its.pendingTranslations && !its.pendingCommands)
23114181Sgiacomo.travaglini@arm.com        its.gitsControl.quiescent = 1;
23213996Sgiacomo.travaglini@arm.com}
23313996Sgiacomo.travaglini@arm.com
23413996Sgiacomo.travaglini@arm.comvoid
23513996Sgiacomo.travaglini@arm.comItsTranslation::main(Yield &yield)
23613996Sgiacomo.travaglini@arm.com{
23713996Sgiacomo.travaglini@arm.com    PacketPtr pkt = yield.get();
23813996Sgiacomo.travaglini@arm.com
23913996Sgiacomo.travaglini@arm.com    const uint32_t device_id = pkt->req->streamId();
24013996Sgiacomo.travaglini@arm.com    const uint32_t event_id = pkt->getLE<uint32_t>();
24113996Sgiacomo.travaglini@arm.com
24213996Sgiacomo.travaglini@arm.com    auto result = translateLPI(yield, device_id, event_id);
24313996Sgiacomo.travaglini@arm.com
24413996Sgiacomo.travaglini@arm.com    uint32_t intid = result.first;
24513996Sgiacomo.travaglini@arm.com    Gicv3Redistributor *redist = result.second;
24613996Sgiacomo.travaglini@arm.com
24713996Sgiacomo.travaglini@arm.com    // Set the LPI in the redistributor
24813996Sgiacomo.travaglini@arm.com    redist->setClrLPI(intid, true);
24913996Sgiacomo.travaglini@arm.com
25013996Sgiacomo.travaglini@arm.com    // Update the value in GITS_TRANSLATER only once we know
25113996Sgiacomo.travaglini@arm.com    // there was no error in the tranlation process (before
25213996Sgiacomo.travaglini@arm.com    // terminating the translation
25313996Sgiacomo.travaglini@arm.com    its.gitsTranslater = event_id;
25413996Sgiacomo.travaglini@arm.com
25513996Sgiacomo.travaglini@arm.com    terminate(yield);
25613996Sgiacomo.travaglini@arm.com}
25713996Sgiacomo.travaglini@arm.com
25813996Sgiacomo.travaglini@arm.comstd::pair<uint32_t, Gicv3Redistributor *>
25913996Sgiacomo.travaglini@arm.comItsTranslation::translateLPI(Yield &yield, uint32_t device_id,
26013996Sgiacomo.travaglini@arm.com                             uint32_t event_id)
26113996Sgiacomo.travaglini@arm.com{
26213996Sgiacomo.travaglini@arm.com    if (its.deviceOutOfRange(device_id)) {
26313996Sgiacomo.travaglini@arm.com        terminate(yield);
26413996Sgiacomo.travaglini@arm.com    }
26513996Sgiacomo.travaglini@arm.com
26613996Sgiacomo.travaglini@arm.com    DTE dte = readDeviceTable(yield, device_id);
26713996Sgiacomo.travaglini@arm.com
26813996Sgiacomo.travaglini@arm.com    if (!dte.valid || its.idOutOfRange(event_id, dte.ittRange)) {
26913996Sgiacomo.travaglini@arm.com        terminate(yield);
27013996Sgiacomo.travaglini@arm.com    }
27113996Sgiacomo.travaglini@arm.com
27213996Sgiacomo.travaglini@arm.com    ITTE itte = readIrqTranslationTable(yield, dte.ittAddress, event_id);
27313996Sgiacomo.travaglini@arm.com    const auto collection_id = itte.icid;
27413996Sgiacomo.travaglini@arm.com
27513996Sgiacomo.travaglini@arm.com    if (!itte.valid || its.collectionOutOfRange(collection_id)) {
27613996Sgiacomo.travaglini@arm.com        terminate(yield);
27713996Sgiacomo.travaglini@arm.com    }
27813996Sgiacomo.travaglini@arm.com
27913996Sgiacomo.travaglini@arm.com    CTE cte = readIrqCollectionTable(yield, collection_id);
28013996Sgiacomo.travaglini@arm.com
28113996Sgiacomo.travaglini@arm.com    if (!cte.valid) {
28213996Sgiacomo.travaglini@arm.com        terminate(yield);
28313996Sgiacomo.travaglini@arm.com    }
28413996Sgiacomo.travaglini@arm.com
28513996Sgiacomo.travaglini@arm.com    // Returning the INTID and the target Redistributor
28613996Sgiacomo.travaglini@arm.com    return std::make_pair(itte.intNum, its.getRedistributor(cte));
28713996Sgiacomo.travaglini@arm.com}
28813996Sgiacomo.travaglini@arm.com
28913996Sgiacomo.travaglini@arm.comItsCommand::DispatchTable ItsCommand::cmdDispatcher =
29013996Sgiacomo.travaglini@arm.com{
29113996Sgiacomo.travaglini@arm.com    COMMAND(CLEAR, &ItsCommand::clear),
29213996Sgiacomo.travaglini@arm.com    COMMAND(DISCARD, &ItsCommand::discard),
29313996Sgiacomo.travaglini@arm.com    COMMAND(INT, &ItsCommand::doInt),
29413996Sgiacomo.travaglini@arm.com    COMMAND(INV, &ItsCommand::inv),
29513996Sgiacomo.travaglini@arm.com    COMMAND(INVALL, &ItsCommand::invall),
29613996Sgiacomo.travaglini@arm.com    COMMAND(MAPC, &ItsCommand::mapc),
29713996Sgiacomo.travaglini@arm.com    COMMAND(MAPD, &ItsCommand::mapd),
29813996Sgiacomo.travaglini@arm.com    COMMAND(MAPI, &ItsCommand::mapi),
29913996Sgiacomo.travaglini@arm.com    COMMAND(MAPTI, &ItsCommand::mapti),
30013996Sgiacomo.travaglini@arm.com    COMMAND(MOVALL, &ItsCommand::movall),
30113996Sgiacomo.travaglini@arm.com    COMMAND(MOVI, &ItsCommand::movi),
30213996Sgiacomo.travaglini@arm.com    COMMAND(SYNC, &ItsCommand::sync),
30313996Sgiacomo.travaglini@arm.com    COMMAND(VINVALL, &ItsCommand::vinvall),
30413996Sgiacomo.travaglini@arm.com    COMMAND(VMAPI, &ItsCommand::vmapi),
30513996Sgiacomo.travaglini@arm.com    COMMAND(VMAPP, &ItsCommand::vmapp),
30613996Sgiacomo.travaglini@arm.com    COMMAND(VMAPTI, &ItsCommand::vmapti),
30713996Sgiacomo.travaglini@arm.com    COMMAND(VMOVI, &ItsCommand::vmovi),
30813996Sgiacomo.travaglini@arm.com    COMMAND(VMOVP, &ItsCommand::vmovp),
30913996Sgiacomo.travaglini@arm.com    COMMAND(VSYNC, &ItsCommand::vsync),
31013996Sgiacomo.travaglini@arm.com};
31113996Sgiacomo.travaglini@arm.com
31213996Sgiacomo.travaglini@arm.comItsCommand::ItsCommand(Gicv3Its &_its)
31313996Sgiacomo.travaglini@arm.com  : ItsProcess(_its)
31413996Sgiacomo.travaglini@arm.com{
31513996Sgiacomo.travaglini@arm.com    reinit();
31613996Sgiacomo.travaglini@arm.com    its.pendingCommands = true;
31714181Sgiacomo.travaglini@arm.com
31814181Sgiacomo.travaglini@arm.com    its.gitsControl.quiescent = 0;
31913996Sgiacomo.travaglini@arm.com}
32013996Sgiacomo.travaglini@arm.com
32113996Sgiacomo.travaglini@arm.comItsCommand::~ItsCommand()
32213996Sgiacomo.travaglini@arm.com{
32313996Sgiacomo.travaglini@arm.com    its.pendingCommands = false;
32414181Sgiacomo.travaglini@arm.com
32514181Sgiacomo.travaglini@arm.com    if (!its.pendingTranslations)
32614181Sgiacomo.travaglini@arm.com        its.gitsControl.quiescent = 1;
32713996Sgiacomo.travaglini@arm.com}
32813996Sgiacomo.travaglini@arm.com
32913996Sgiacomo.travaglini@arm.comstd::string
33013996Sgiacomo.travaglini@arm.comItsCommand::commandName(uint32_t cmd)
33113996Sgiacomo.travaglini@arm.com{
33213996Sgiacomo.travaglini@arm.com    const auto entry = cmdDispatcher.find(cmd);
33313996Sgiacomo.travaglini@arm.com    return entry != cmdDispatcher.end() ? entry->second.name : "INVALID";
33413996Sgiacomo.travaglini@arm.com}
33513996Sgiacomo.travaglini@arm.com
33613996Sgiacomo.travaglini@arm.comvoid
33713996Sgiacomo.travaglini@arm.comItsCommand::main(Yield &yield)
33813996Sgiacomo.travaglini@arm.com{
33913996Sgiacomo.travaglini@arm.com    ItsAction a;
34013996Sgiacomo.travaglini@arm.com    a.type = ItsActionType::INITIAL_NOP;
34113996Sgiacomo.travaglini@arm.com    a.pkt = nullptr;
34213996Sgiacomo.travaglini@arm.com    a.delay = 0;
34313996Sgiacomo.travaglini@arm.com    yield(a);
34413996Sgiacomo.travaglini@arm.com
34513996Sgiacomo.travaglini@arm.com    while (its.gitsCwriter.offset != its.gitsCreadr.offset) {
34613996Sgiacomo.travaglini@arm.com        CommandEntry command;
34713996Sgiacomo.travaglini@arm.com
34813996Sgiacomo.travaglini@arm.com        // Reading the command from CMDQ
34913996Sgiacomo.travaglini@arm.com        readCommand(yield, command);
35013996Sgiacomo.travaglini@arm.com
35113996Sgiacomo.travaglini@arm.com        processCommand(yield, command);
35213996Sgiacomo.travaglini@arm.com
35313996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
35413996Sgiacomo.travaglini@arm.com    }
35513996Sgiacomo.travaglini@arm.com
35613996Sgiacomo.travaglini@arm.com    terminate(yield);
35713996Sgiacomo.travaglini@arm.com}
35813996Sgiacomo.travaglini@arm.com
35913996Sgiacomo.travaglini@arm.comvoid
36013996Sgiacomo.travaglini@arm.comItsCommand::readCommand(Yield &yield, CommandEntry &command)
36113996Sgiacomo.travaglini@arm.com{
36213996Sgiacomo.travaglini@arm.com    // read the command pointed by GITS_CREADR
36313996Sgiacomo.travaglini@arm.com    const Addr cmd_addr =
36413996Sgiacomo.travaglini@arm.com        (its.gitsCbaser.physAddr << 12) + (its.gitsCreadr.offset << 5);
36513996Sgiacomo.travaglini@arm.com
36613996Sgiacomo.travaglini@arm.com    doRead(yield, cmd_addr, &command, sizeof(command));
36713996Sgiacomo.travaglini@arm.com
36813996Sgiacomo.travaglini@arm.com    DPRINTF(ITS, "Command %s read from queue at address: %#x\n",
36913996Sgiacomo.travaglini@arm.com            commandName(command.type), cmd_addr);
37013996Sgiacomo.travaglini@arm.com    DPRINTF(ITS, "dw0: %#x dw1: %#x dw2: %#x dw3: %#x\n",
37113996Sgiacomo.travaglini@arm.com            command.raw[0], command.raw[1], command.raw[2], command.raw[3]);
37213996Sgiacomo.travaglini@arm.com}
37313996Sgiacomo.travaglini@arm.com
37413996Sgiacomo.travaglini@arm.comvoid
37513996Sgiacomo.travaglini@arm.comItsCommand::processCommand(Yield &yield, CommandEntry &command)
37613996Sgiacomo.travaglini@arm.com{
37713996Sgiacomo.travaglini@arm.com    const auto entry = cmdDispatcher.find(command.type);
37813996Sgiacomo.travaglini@arm.com
37913996Sgiacomo.travaglini@arm.com    if (entry != cmdDispatcher.end()) {
38013996Sgiacomo.travaglini@arm.com        // Execute the command
38113996Sgiacomo.travaglini@arm.com        entry->second.exec(this, yield, command);
38213996Sgiacomo.travaglini@arm.com    } else {
38313996Sgiacomo.travaglini@arm.com        panic("Unrecognized command type: %u", command.type);
38413996Sgiacomo.travaglini@arm.com    }
38513996Sgiacomo.travaglini@arm.com}
38613996Sgiacomo.travaglini@arm.com
38713996Sgiacomo.travaglini@arm.comvoid
38813996Sgiacomo.travaglini@arm.comItsCommand::clear(Yield &yield, CommandEntry &command)
38913996Sgiacomo.travaglini@arm.com{
39013996Sgiacomo.travaglini@arm.com    if (deviceOutOfRange(command)) {
39113996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
39213996Sgiacomo.travaglini@arm.com        terminate(yield);
39313996Sgiacomo.travaglini@arm.com    }
39413996Sgiacomo.travaglini@arm.com
39513996Sgiacomo.travaglini@arm.com    DTE dte = readDeviceTable(yield, command.deviceId);
39613996Sgiacomo.travaglini@arm.com
39713996Sgiacomo.travaglini@arm.com    if (!dte.valid || idOutOfRange(command, dte)) {
39813996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
39913996Sgiacomo.travaglini@arm.com        terminate(yield);
40013996Sgiacomo.travaglini@arm.com    }
40113996Sgiacomo.travaglini@arm.com
40213996Sgiacomo.travaglini@arm.com    ITTE itte = readIrqTranslationTable(
40313996Sgiacomo.travaglini@arm.com        yield, dte.ittAddress, command.eventId);
40413996Sgiacomo.travaglini@arm.com
40513996Sgiacomo.travaglini@arm.com    if (!itte.valid) {
40613996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
40713996Sgiacomo.travaglini@arm.com        terminate(yield);
40813996Sgiacomo.travaglini@arm.com    }
40913996Sgiacomo.travaglini@arm.com
41013996Sgiacomo.travaglini@arm.com    const auto collection_id = itte.icid;
41113996Sgiacomo.travaglini@arm.com    CTE cte = readIrqCollectionTable(yield, collection_id);
41213996Sgiacomo.travaglini@arm.com
41313996Sgiacomo.travaglini@arm.com    if (!cte.valid) {
41413996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
41513996Sgiacomo.travaglini@arm.com        terminate(yield);
41613996Sgiacomo.travaglini@arm.com    }
41713996Sgiacomo.travaglini@arm.com
41813996Sgiacomo.travaglini@arm.com    // Clear the LPI in the redistributor
41913996Sgiacomo.travaglini@arm.com    its.getRedistributor(cte)->setClrLPI(itte.intNum, false);
42013996Sgiacomo.travaglini@arm.com}
42113996Sgiacomo.travaglini@arm.com
42213996Sgiacomo.travaglini@arm.comvoid
42313996Sgiacomo.travaglini@arm.comItsCommand::discard(Yield &yield, CommandEntry &command)
42413996Sgiacomo.travaglini@arm.com{
42513996Sgiacomo.travaglini@arm.com    if (deviceOutOfRange(command)) {
42613996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
42713996Sgiacomo.travaglini@arm.com        terminate(yield);
42813996Sgiacomo.travaglini@arm.com    }
42913996Sgiacomo.travaglini@arm.com
43013996Sgiacomo.travaglini@arm.com    DTE dte = readDeviceTable(yield, command.deviceId);
43113996Sgiacomo.travaglini@arm.com
43213996Sgiacomo.travaglini@arm.com    if (!dte.valid || idOutOfRange(command, dte)) {
43313996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
43413996Sgiacomo.travaglini@arm.com        terminate(yield);
43513996Sgiacomo.travaglini@arm.com    }
43613996Sgiacomo.travaglini@arm.com
43713996Sgiacomo.travaglini@arm.com    ITTE itte = readIrqTranslationTable(
43813996Sgiacomo.travaglini@arm.com        yield, dte.ittAddress, command.eventId);
43913996Sgiacomo.travaglini@arm.com
44013996Sgiacomo.travaglini@arm.com    if (!itte.valid) {
44113996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
44213996Sgiacomo.travaglini@arm.com        terminate(yield);
44313996Sgiacomo.travaglini@arm.com    }
44413996Sgiacomo.travaglini@arm.com
44513996Sgiacomo.travaglini@arm.com    const auto collection_id = itte.icid;
44613996Sgiacomo.travaglini@arm.com    Gicv3Its::CTE cte = readIrqCollectionTable(yield, collection_id);
44713996Sgiacomo.travaglini@arm.com
44813996Sgiacomo.travaglini@arm.com    if (!cte.valid) {
44913996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
45013996Sgiacomo.travaglini@arm.com        terminate(yield);
45113996Sgiacomo.travaglini@arm.com    }
45213996Sgiacomo.travaglini@arm.com
45313996Sgiacomo.travaglini@arm.com    its.getRedistributor(cte)->setClrLPI(itte.intNum, false);
45413996Sgiacomo.travaglini@arm.com
45513996Sgiacomo.travaglini@arm.com    // Then removes the mapping from the ITT (invalidating)
45613996Sgiacomo.travaglini@arm.com    itte.valid = 0;
45713996Sgiacomo.travaglini@arm.com    writeIrqTranslationTable(
45813996Sgiacomo.travaglini@arm.com        yield, dte.ittAddress, command.eventId, itte);
45913996Sgiacomo.travaglini@arm.com}
46013996Sgiacomo.travaglini@arm.com
46113996Sgiacomo.travaglini@arm.comvoid
46213996Sgiacomo.travaglini@arm.comItsCommand::doInt(Yield &yield, CommandEntry &command)
46313996Sgiacomo.travaglini@arm.com{
46413996Sgiacomo.travaglini@arm.com    if (deviceOutOfRange(command)) {
46513996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
46613996Sgiacomo.travaglini@arm.com        terminate(yield);
46713996Sgiacomo.travaglini@arm.com    }
46813996Sgiacomo.travaglini@arm.com
46913996Sgiacomo.travaglini@arm.com    DTE dte = readDeviceTable(yield, command.deviceId);
47013996Sgiacomo.travaglini@arm.com
47113996Sgiacomo.travaglini@arm.com    if (!dte.valid || idOutOfRange(command, dte)) {
47213996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
47313996Sgiacomo.travaglini@arm.com        terminate(yield);
47413996Sgiacomo.travaglini@arm.com    }
47513996Sgiacomo.travaglini@arm.com
47613996Sgiacomo.travaglini@arm.com    ITTE itte = readIrqTranslationTable(
47713996Sgiacomo.travaglini@arm.com        yield, dte.ittAddress, command.eventId);
47813996Sgiacomo.travaglini@arm.com
47913996Sgiacomo.travaglini@arm.com    if (!itte.valid) {
48013996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
48113996Sgiacomo.travaglini@arm.com        terminate(yield);
48213996Sgiacomo.travaglini@arm.com    }
48313996Sgiacomo.travaglini@arm.com
48413996Sgiacomo.travaglini@arm.com    const auto collection_id = itte.icid;
48513996Sgiacomo.travaglini@arm.com    CTE cte = readIrqCollectionTable(yield, collection_id);
48613996Sgiacomo.travaglini@arm.com
48713996Sgiacomo.travaglini@arm.com    if (!cte.valid) {
48813996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
48913996Sgiacomo.travaglini@arm.com        terminate(yield);
49013996Sgiacomo.travaglini@arm.com    }
49113996Sgiacomo.travaglini@arm.com
49213996Sgiacomo.travaglini@arm.com    // Set the LPI in the redistributor
49313996Sgiacomo.travaglini@arm.com    its.getRedistributor(cte)->setClrLPI(itte.intNum, true);
49413996Sgiacomo.travaglini@arm.com}
49513996Sgiacomo.travaglini@arm.com
49613996Sgiacomo.travaglini@arm.comvoid
49713996Sgiacomo.travaglini@arm.comItsCommand::inv(Yield &yield, CommandEntry &command)
49813996Sgiacomo.travaglini@arm.com{
49913996Sgiacomo.travaglini@arm.com    if (deviceOutOfRange(command)) {
50013996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
50113996Sgiacomo.travaglini@arm.com        terminate(yield);
50213996Sgiacomo.travaglini@arm.com    }
50313996Sgiacomo.travaglini@arm.com
50413996Sgiacomo.travaglini@arm.com    DTE dte = readDeviceTable(yield, command.deviceId);
50513996Sgiacomo.travaglini@arm.com
50613996Sgiacomo.travaglini@arm.com    if (!dte.valid || idOutOfRange(command, dte)) {
50713996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
50813996Sgiacomo.travaglini@arm.com        terminate(yield);
50913996Sgiacomo.travaglini@arm.com    }
51013996Sgiacomo.travaglini@arm.com
51113996Sgiacomo.travaglini@arm.com    ITTE itte = readIrqTranslationTable(
51213996Sgiacomo.travaglini@arm.com        yield, dte.ittAddress, command.eventId);
51313996Sgiacomo.travaglini@arm.com
51413996Sgiacomo.travaglini@arm.com    if (!itte.valid) {
51513996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
51613996Sgiacomo.travaglini@arm.com        terminate(yield);
51713996Sgiacomo.travaglini@arm.com    }
51813996Sgiacomo.travaglini@arm.com
51913996Sgiacomo.travaglini@arm.com    const auto collection_id = itte.icid;
52013996Sgiacomo.travaglini@arm.com    CTE cte = readIrqCollectionTable(yield, collection_id);
52113996Sgiacomo.travaglini@arm.com
52213996Sgiacomo.travaglini@arm.com    if (!cte.valid) {
52313996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
52413996Sgiacomo.travaglini@arm.com        terminate(yield);
52513996Sgiacomo.travaglini@arm.com    }
52613996Sgiacomo.travaglini@arm.com    // Do nothing since caching is currently not supported in
52713996Sgiacomo.travaglini@arm.com    // Redistributor
52813996Sgiacomo.travaglini@arm.com}
52913996Sgiacomo.travaglini@arm.com
53013996Sgiacomo.travaglini@arm.comvoid
53113996Sgiacomo.travaglini@arm.comItsCommand::invall(Yield &yield, CommandEntry &command)
53213996Sgiacomo.travaglini@arm.com{
53313996Sgiacomo.travaglini@arm.com    if (collectionOutOfRange(command)) {
53413996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
53513996Sgiacomo.travaglini@arm.com        terminate(yield);
53613996Sgiacomo.travaglini@arm.com    }
53713996Sgiacomo.travaglini@arm.com
53813996Sgiacomo.travaglini@arm.com    const auto icid = bits(command.raw[2], 15, 0);
53913996Sgiacomo.travaglini@arm.com
54013996Sgiacomo.travaglini@arm.com    CTE cte = readIrqCollectionTable(yield, icid);
54113996Sgiacomo.travaglini@arm.com
54213996Sgiacomo.travaglini@arm.com    if (!cte.valid) {
54313996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
54413996Sgiacomo.travaglini@arm.com        terminate(yield);
54513996Sgiacomo.travaglini@arm.com    }
54613996Sgiacomo.travaglini@arm.com    // Do nothing since caching is currently not supported in
54713996Sgiacomo.travaglini@arm.com    // Redistributor
54813996Sgiacomo.travaglini@arm.com}
54913996Sgiacomo.travaglini@arm.com
55013996Sgiacomo.travaglini@arm.comvoid
55113996Sgiacomo.travaglini@arm.comItsCommand::mapc(Yield &yield, CommandEntry &command)
55213996Sgiacomo.travaglini@arm.com{
55313996Sgiacomo.travaglini@arm.com    if (collectionOutOfRange(command)) {
55413996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
55513996Sgiacomo.travaglini@arm.com        terminate(yield);
55613996Sgiacomo.travaglini@arm.com    }
55713996Sgiacomo.travaglini@arm.com
55813996Sgiacomo.travaglini@arm.com    CTE cte = 0;
55913996Sgiacomo.travaglini@arm.com    cte.valid = bits(command.raw[2], 63);
56013996Sgiacomo.travaglini@arm.com    cte.rdBase = bits(command.raw[2], 50, 16);
56113996Sgiacomo.travaglini@arm.com
56213996Sgiacomo.travaglini@arm.com    const auto icid = bits(command.raw[2], 15, 0);
56313996Sgiacomo.travaglini@arm.com
56413996Sgiacomo.travaglini@arm.com    writeIrqCollectionTable(yield, icid, cte);
56513996Sgiacomo.travaglini@arm.com}
56613996Sgiacomo.travaglini@arm.com
56713996Sgiacomo.travaglini@arm.comvoid
56813996Sgiacomo.travaglini@arm.comItsCommand::mapd(Yield &yield, CommandEntry &command)
56913996Sgiacomo.travaglini@arm.com{
57013996Sgiacomo.travaglini@arm.com    if (deviceOutOfRange(command) || sizeOutOfRange(command)) {
57113996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
57213996Sgiacomo.travaglini@arm.com        terminate(yield);
57313996Sgiacomo.travaglini@arm.com    }
57413996Sgiacomo.travaglini@arm.com
57513996Sgiacomo.travaglini@arm.com    DTE dte = 0;
57613996Sgiacomo.travaglini@arm.com    dte.valid = bits(command.raw[2], 63);
57713996Sgiacomo.travaglini@arm.com    dte.ittAddress = mbits(command.raw[2], 51, 8);
57813996Sgiacomo.travaglini@arm.com    dte.ittRange = bits(command.raw[1], 4, 0);
57913996Sgiacomo.travaglini@arm.com
58013996Sgiacomo.travaglini@arm.com    writeDeviceTable(yield, command.deviceId, dte);
58113996Sgiacomo.travaglini@arm.com}
58213996Sgiacomo.travaglini@arm.com
58313996Sgiacomo.travaglini@arm.comvoid
58413996Sgiacomo.travaglini@arm.comItsCommand::mapi(Yield &yield, CommandEntry &command)
58513996Sgiacomo.travaglini@arm.com{
58613996Sgiacomo.travaglini@arm.com    if (deviceOutOfRange(command)) {
58713996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
58813996Sgiacomo.travaglini@arm.com        terminate(yield);
58913996Sgiacomo.travaglini@arm.com    }
59013996Sgiacomo.travaglini@arm.com
59113996Sgiacomo.travaglini@arm.com    if (collectionOutOfRange(command)) {
59213996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
59313996Sgiacomo.travaglini@arm.com        terminate(yield);
59413996Sgiacomo.travaglini@arm.com    }
59513996Sgiacomo.travaglini@arm.com
59613996Sgiacomo.travaglini@arm.com    DTE dte = readDeviceTable(yield, command.deviceId);
59713996Sgiacomo.travaglini@arm.com
59813996Sgiacomo.travaglini@arm.com    if (!dte.valid || idOutOfRange(command, dte) ||
59913996Sgiacomo.travaglini@arm.com        its.lpiOutOfRange(command.eventId)) {
60013996Sgiacomo.travaglini@arm.com
60113996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
60213996Sgiacomo.travaglini@arm.com        terminate(yield);
60313996Sgiacomo.travaglini@arm.com    }
60413996Sgiacomo.travaglini@arm.com
60513996Sgiacomo.travaglini@arm.com    Gicv3Its::ITTE itte = readIrqTranslationTable(
60613996Sgiacomo.travaglini@arm.com        yield, dte.ittAddress, command.eventId);
60713996Sgiacomo.travaglini@arm.com
60813996Sgiacomo.travaglini@arm.com    itte.valid = 1;
60913996Sgiacomo.travaglini@arm.com    itte.intType = Gicv3Its::PHYSICAL_INTERRUPT;
61013996Sgiacomo.travaglini@arm.com    itte.intNum = command.eventId;
61113996Sgiacomo.travaglini@arm.com    itte.icid = bits(command.raw[2], 15, 0);
61213996Sgiacomo.travaglini@arm.com
61313996Sgiacomo.travaglini@arm.com    writeIrqTranslationTable(
61413996Sgiacomo.travaglini@arm.com        yield, dte.ittAddress, command.eventId, itte);
61513996Sgiacomo.travaglini@arm.com}
61613996Sgiacomo.travaglini@arm.com
61713996Sgiacomo.travaglini@arm.comvoid
61813996Sgiacomo.travaglini@arm.comItsCommand::mapti(Yield &yield, CommandEntry &command)
61913996Sgiacomo.travaglini@arm.com{
62013996Sgiacomo.travaglini@arm.com    if (deviceOutOfRange(command)) {
62113996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
62213996Sgiacomo.travaglini@arm.com        terminate(yield);
62313996Sgiacomo.travaglini@arm.com    }
62413996Sgiacomo.travaglini@arm.com
62513996Sgiacomo.travaglini@arm.com    if (collectionOutOfRange(command)) {
62613996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
62713996Sgiacomo.travaglini@arm.com        terminate(yield);
62813996Sgiacomo.travaglini@arm.com    }
62913996Sgiacomo.travaglini@arm.com
63013996Sgiacomo.travaglini@arm.com    DTE dte = readDeviceTable(yield, command.deviceId);
63113996Sgiacomo.travaglini@arm.com
63213996Sgiacomo.travaglini@arm.com    const auto pintid = bits(command.raw[1], 63, 32);
63313996Sgiacomo.travaglini@arm.com
63413996Sgiacomo.travaglini@arm.com    if (!dte.valid || idOutOfRange(command, dte) ||
63513996Sgiacomo.travaglini@arm.com        its.lpiOutOfRange(pintid)) {
63613996Sgiacomo.travaglini@arm.com
63713996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
63813996Sgiacomo.travaglini@arm.com        terminate(yield);
63913996Sgiacomo.travaglini@arm.com    }
64013996Sgiacomo.travaglini@arm.com
64113996Sgiacomo.travaglini@arm.com    ITTE itte = readIrqTranslationTable(
64213996Sgiacomo.travaglini@arm.com        yield, dte.ittAddress, command.eventId);
64313996Sgiacomo.travaglini@arm.com
64413996Sgiacomo.travaglini@arm.com    itte.valid = 1;
64513996Sgiacomo.travaglini@arm.com    itte.intType = Gicv3Its::PHYSICAL_INTERRUPT;
64613996Sgiacomo.travaglini@arm.com    itte.intNum = pintid;
64713996Sgiacomo.travaglini@arm.com    itte.icid = bits(command.raw[2], 15, 0);
64813996Sgiacomo.travaglini@arm.com
64913996Sgiacomo.travaglini@arm.com    writeIrqTranslationTable(
65013996Sgiacomo.travaglini@arm.com        yield, dte.ittAddress, command.eventId, itte);
65113996Sgiacomo.travaglini@arm.com}
65213996Sgiacomo.travaglini@arm.com
65313996Sgiacomo.travaglini@arm.comvoid
65413996Sgiacomo.travaglini@arm.comItsCommand::movall(Yield &yield, CommandEntry &command)
65513996Sgiacomo.travaglini@arm.com{
65613996Sgiacomo.travaglini@arm.com    const uint64_t rd1 = bits(command.raw[2], 50, 16);
65713996Sgiacomo.travaglini@arm.com    const uint64_t rd2 = bits(command.raw[3], 50, 16);
65813996Sgiacomo.travaglini@arm.com
65913996Sgiacomo.travaglini@arm.com    if (rd1 != rd2) {
66013996Sgiacomo.travaglini@arm.com        Gicv3Redistributor * redist1 = its.getRedistributor(rd1);
66113996Sgiacomo.travaglini@arm.com        Gicv3Redistributor * redist2 = its.getRedistributor(rd2);
66213996Sgiacomo.travaglini@arm.com
66313996Sgiacomo.travaglini@arm.com        its.moveAllPendingState(redist1, redist2);
66413996Sgiacomo.travaglini@arm.com    }
66513996Sgiacomo.travaglini@arm.com}
66613996Sgiacomo.travaglini@arm.com
66713996Sgiacomo.travaglini@arm.comvoid
66813996Sgiacomo.travaglini@arm.comItsCommand::movi(Yield &yield, CommandEntry &command)
66913996Sgiacomo.travaglini@arm.com{
67013996Sgiacomo.travaglini@arm.com    if (deviceOutOfRange(command)) {
67113996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
67213996Sgiacomo.travaglini@arm.com        terminate(yield);
67313996Sgiacomo.travaglini@arm.com    }
67413996Sgiacomo.travaglini@arm.com
67513996Sgiacomo.travaglini@arm.com    if (collectionOutOfRange(command)) {
67613996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
67713996Sgiacomo.travaglini@arm.com        terminate(yield);
67813996Sgiacomo.travaglini@arm.com    }
67913996Sgiacomo.travaglini@arm.com
68013996Sgiacomo.travaglini@arm.com    DTE dte = readDeviceTable(yield, command.deviceId);
68113996Sgiacomo.travaglini@arm.com
68213996Sgiacomo.travaglini@arm.com    if (!dte.valid || idOutOfRange(command, dte)) {
68313996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
68413996Sgiacomo.travaglini@arm.com        terminate(yield);
68513996Sgiacomo.travaglini@arm.com    }
68613996Sgiacomo.travaglini@arm.com
68713996Sgiacomo.travaglini@arm.com    ITTE itte = readIrqTranslationTable(
68813996Sgiacomo.travaglini@arm.com        yield, dte.ittAddress, command.eventId);
68913996Sgiacomo.travaglini@arm.com
69013996Sgiacomo.travaglini@arm.com    if (!itte.valid || itte.intType == Gicv3Its::VIRTUAL_INTERRUPT) {
69113996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
69213996Sgiacomo.travaglini@arm.com        terminate(yield);
69313996Sgiacomo.travaglini@arm.com    }
69413996Sgiacomo.travaglini@arm.com
69513996Sgiacomo.travaglini@arm.com    const auto collection_id1 = itte.icid;
69613996Sgiacomo.travaglini@arm.com    CTE cte1 = readIrqCollectionTable(yield, collection_id1);
69713996Sgiacomo.travaglini@arm.com
69813996Sgiacomo.travaglini@arm.com    if (!cte1.valid) {
69913996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
70013996Sgiacomo.travaglini@arm.com        terminate(yield);
70113996Sgiacomo.travaglini@arm.com    }
70213996Sgiacomo.travaglini@arm.com
70313996Sgiacomo.travaglini@arm.com    const auto collection_id2 = bits(command.raw[2], 15, 0);
70413996Sgiacomo.travaglini@arm.com    CTE cte2 = readIrqCollectionTable(yield, collection_id2);
70513996Sgiacomo.travaglini@arm.com
70613996Sgiacomo.travaglini@arm.com    if (!cte2.valid) {
70713996Sgiacomo.travaglini@arm.com        its.incrementReadPointer();
70813996Sgiacomo.travaglini@arm.com        terminate(yield);
70913996Sgiacomo.travaglini@arm.com    }
71013996Sgiacomo.travaglini@arm.com
71113996Sgiacomo.travaglini@arm.com    Gicv3Redistributor *first_redist = its.getRedistributor(cte1);
71213996Sgiacomo.travaglini@arm.com    Gicv3Redistributor *second_redist = its.getRedistributor(cte2);
71313996Sgiacomo.travaglini@arm.com
71413996Sgiacomo.travaglini@arm.com    if (second_redist != first_redist) {
71513996Sgiacomo.travaglini@arm.com        // move pending state of the interrupt from one redistributor
71613996Sgiacomo.travaglini@arm.com        // to the other.
71713996Sgiacomo.travaglini@arm.com        if (first_redist->isPendingLPI(itte.intNum)) {
71813996Sgiacomo.travaglini@arm.com            first_redist->setClrLPI(itte.intNum, false);
71913996Sgiacomo.travaglini@arm.com            second_redist->setClrLPI(itte.intNum, true);
72013996Sgiacomo.travaglini@arm.com        }
72113996Sgiacomo.travaglini@arm.com    }
72213996Sgiacomo.travaglini@arm.com
72313996Sgiacomo.travaglini@arm.com    itte.icid = collection_id2;
72413996Sgiacomo.travaglini@arm.com    writeIrqTranslationTable(
72513996Sgiacomo.travaglini@arm.com        yield, dte.ittAddress, command.eventId, itte);
72613996Sgiacomo.travaglini@arm.com}
72713996Sgiacomo.travaglini@arm.com
72813996Sgiacomo.travaglini@arm.comvoid
72913996Sgiacomo.travaglini@arm.comItsCommand::sync(Yield &yield, CommandEntry &command)
73013996Sgiacomo.travaglini@arm.com{
73113996Sgiacomo.travaglini@arm.com    warn("ITS %s command unimplemented", __func__);
73213996Sgiacomo.travaglini@arm.com}
73313996Sgiacomo.travaglini@arm.com
73413996Sgiacomo.travaglini@arm.comvoid
73513996Sgiacomo.travaglini@arm.comItsCommand::vinvall(Yield &yield, CommandEntry &command)
73613996Sgiacomo.travaglini@arm.com{
73713996Sgiacomo.travaglini@arm.com    panic("ITS %s command unimplemented", __func__);
73813996Sgiacomo.travaglini@arm.com}
73913996Sgiacomo.travaglini@arm.com
74013996Sgiacomo.travaglini@arm.comvoid
74113996Sgiacomo.travaglini@arm.comItsCommand::vmapi(Yield &yield, CommandEntry &command)
74213996Sgiacomo.travaglini@arm.com{
74313996Sgiacomo.travaglini@arm.com    panic("ITS %s command unimplemented", __func__);
74413996Sgiacomo.travaglini@arm.com}
74513996Sgiacomo.travaglini@arm.com
74613996Sgiacomo.travaglini@arm.comvoid
74713996Sgiacomo.travaglini@arm.comItsCommand::vmapp(Yield &yield, CommandEntry &command)
74813996Sgiacomo.travaglini@arm.com{
74913996Sgiacomo.travaglini@arm.com    panic("ITS %s command unimplemented", __func__);
75013996Sgiacomo.travaglini@arm.com}
75113996Sgiacomo.travaglini@arm.com
75213996Sgiacomo.travaglini@arm.comvoid
75313996Sgiacomo.travaglini@arm.comItsCommand::vmapti(Yield &yield, CommandEntry &command)
75413996Sgiacomo.travaglini@arm.com{
75513996Sgiacomo.travaglini@arm.com    panic("ITS %s command unimplemented", __func__);
75613996Sgiacomo.travaglini@arm.com}
75713996Sgiacomo.travaglini@arm.com
75813996Sgiacomo.travaglini@arm.comvoid
75913996Sgiacomo.travaglini@arm.comItsCommand::vmovi(Yield &yield, CommandEntry &command)
76013996Sgiacomo.travaglini@arm.com{
76113996Sgiacomo.travaglini@arm.com    panic("ITS %s command unimplemented", __func__);
76213996Sgiacomo.travaglini@arm.com}
76313996Sgiacomo.travaglini@arm.com
76413996Sgiacomo.travaglini@arm.comvoid
76513996Sgiacomo.travaglini@arm.comItsCommand::vmovp(Yield &yield, CommandEntry &command)
76613996Sgiacomo.travaglini@arm.com{
76713996Sgiacomo.travaglini@arm.com    panic("ITS %s command unimplemented", __func__);
76813996Sgiacomo.travaglini@arm.com}
76913996Sgiacomo.travaglini@arm.com
77013996Sgiacomo.travaglini@arm.comvoid
77113996Sgiacomo.travaglini@arm.comItsCommand::vsync(Yield &yield, CommandEntry &command)
77213996Sgiacomo.travaglini@arm.com{
77313996Sgiacomo.travaglini@arm.com    panic("ITS %s command unimplemented", __func__);
77413996Sgiacomo.travaglini@arm.com}
77513996Sgiacomo.travaglini@arm.com
77613996Sgiacomo.travaglini@arm.comGicv3Its::Gicv3Its(const Gicv3ItsParams *params)
77713996Sgiacomo.travaglini@arm.com : BasicPioDevice(params, params->pio_size),
77813996Sgiacomo.travaglini@arm.com   dmaPort(name() + ".dma", *this),
77914181Sgiacomo.travaglini@arm.com   gitsControl(CTLR_QUIESCENT),
78013996Sgiacomo.travaglini@arm.com   gitsTyper(params->gits_typer),
78113996Sgiacomo.travaglini@arm.com   gitsCbaser(0), gitsCreadr(0),
78213996Sgiacomo.travaglini@arm.com   gitsCwriter(0), gitsIidr(0),
78314187Sgiacomo.travaglini@arm.com   tableBases(NUM_BASER_REGS, 0),
78413996Sgiacomo.travaglini@arm.com   masterId(params->system->getMasterId(this)),
78513996Sgiacomo.travaglini@arm.com   gic(nullptr),
78613996Sgiacomo.travaglini@arm.com   commandEvent([this] { checkCommandQueue(); }, name()),
78713996Sgiacomo.travaglini@arm.com   pendingCommands(false),
78813996Sgiacomo.travaglini@arm.com   pendingTranslations(0)
78913996Sgiacomo.travaglini@arm.com{
79014187Sgiacomo.travaglini@arm.com    BASER device_baser = 0;
79114187Sgiacomo.travaglini@arm.com    device_baser.type = DEVICE_TABLE;
79214187Sgiacomo.travaglini@arm.com    device_baser.entrySize = sizeof(uint64_t) - 1;
79314187Sgiacomo.travaglini@arm.com    tableBases[0] = device_baser;
79414187Sgiacomo.travaglini@arm.com
79514187Sgiacomo.travaglini@arm.com    BASER icollect_baser = 0;
79614187Sgiacomo.travaglini@arm.com    icollect_baser.type = COLLECTION_TABLE;
79714187Sgiacomo.travaglini@arm.com    icollect_baser.entrySize = sizeof(uint64_t) - 1;
79814187Sgiacomo.travaglini@arm.com    tableBases[1] = icollect_baser;
79913996Sgiacomo.travaglini@arm.com}
80013996Sgiacomo.travaglini@arm.com
80113996Sgiacomo.travaglini@arm.comvoid
80213996Sgiacomo.travaglini@arm.comGicv3Its::setGIC(Gicv3 *_gic)
80313996Sgiacomo.travaglini@arm.com{
80413996Sgiacomo.travaglini@arm.com    assert(!gic);
80513996Sgiacomo.travaglini@arm.com    gic = _gic;
80613996Sgiacomo.travaglini@arm.com}
80713996Sgiacomo.travaglini@arm.com
80813996Sgiacomo.travaglini@arm.comAddrRangeList
80913996Sgiacomo.travaglini@arm.comGicv3Its::getAddrRanges() const
81013996Sgiacomo.travaglini@arm.com{
81113996Sgiacomo.travaglini@arm.com    assert(pioSize != 0);
81213996Sgiacomo.travaglini@arm.com    AddrRangeList ranges;
81313996Sgiacomo.travaglini@arm.com    DPRINTF(AddrRanges, "registering range: %#x-%#x\n", pioAddr, pioSize);
81413996Sgiacomo.travaglini@arm.com    ranges.push_back(RangeSize(pioAddr, pioSize));
81513996Sgiacomo.travaglini@arm.com    return ranges;
81613996Sgiacomo.travaglini@arm.com}
81713996Sgiacomo.travaglini@arm.com
81813996Sgiacomo.travaglini@arm.comTick
81913996Sgiacomo.travaglini@arm.comGicv3Its::read(PacketPtr pkt)
82013996Sgiacomo.travaglini@arm.com{
82113996Sgiacomo.travaglini@arm.com    const Addr addr = pkt->getAddr() - pioAddr;
82213996Sgiacomo.travaglini@arm.com    uint64_t value = 0;
82313996Sgiacomo.travaglini@arm.com
82413996Sgiacomo.travaglini@arm.com    DPRINTF(GIC, "%s register at addr: %#x\n", __func__, addr);
82513996Sgiacomo.travaglini@arm.com
82613996Sgiacomo.travaglini@arm.com    switch (addr) {
82713996Sgiacomo.travaglini@arm.com      case GITS_CTLR:
82813996Sgiacomo.travaglini@arm.com        value = gitsControl;
82913996Sgiacomo.travaglini@arm.com        break;
83013996Sgiacomo.travaglini@arm.com
83113996Sgiacomo.travaglini@arm.com      case GITS_IIDR:
83213996Sgiacomo.travaglini@arm.com        value = gitsIidr;
83313996Sgiacomo.travaglini@arm.com        break;
83413996Sgiacomo.travaglini@arm.com
83513996Sgiacomo.travaglini@arm.com      case GITS_TYPER:
83613996Sgiacomo.travaglini@arm.com        value = gitsTyper;
83713996Sgiacomo.travaglini@arm.com        break;
83813996Sgiacomo.travaglini@arm.com
83914235Sgiacomo.travaglini@arm.com      case GITS_TYPER + 4:
84014235Sgiacomo.travaglini@arm.com        value = gitsTyper.high;
84114235Sgiacomo.travaglini@arm.com        break;
84214235Sgiacomo.travaglini@arm.com
84313996Sgiacomo.travaglini@arm.com      case GITS_CBASER:
84413996Sgiacomo.travaglini@arm.com        value = gitsCbaser;
84513996Sgiacomo.travaglini@arm.com        break;
84613996Sgiacomo.travaglini@arm.com
84714180Sgiacomo.travaglini@arm.com      case GITS_CBASER + 4:
84814180Sgiacomo.travaglini@arm.com        value = gitsCbaser.high;
84914180Sgiacomo.travaglini@arm.com        break;
85014180Sgiacomo.travaglini@arm.com
85113996Sgiacomo.travaglini@arm.com      case GITS_CWRITER:
85213996Sgiacomo.travaglini@arm.com        value = gitsCwriter;
85313996Sgiacomo.travaglini@arm.com        break;
85413996Sgiacomo.travaglini@arm.com
85514180Sgiacomo.travaglini@arm.com      case GITS_CWRITER + 4:
85614180Sgiacomo.travaglini@arm.com        value = gitsCwriter.high;
85714180Sgiacomo.travaglini@arm.com        break;
85814180Sgiacomo.travaglini@arm.com
85913996Sgiacomo.travaglini@arm.com      case GITS_CREADR:
86013996Sgiacomo.travaglini@arm.com        value = gitsCreadr;
86113996Sgiacomo.travaglini@arm.com        break;
86213996Sgiacomo.travaglini@arm.com
86314180Sgiacomo.travaglini@arm.com      case GITS_CREADR + 4:
86414180Sgiacomo.travaglini@arm.com        value = gitsCreadr.high;
86514180Sgiacomo.travaglini@arm.com        break;
86614180Sgiacomo.travaglini@arm.com
86714168Sgiacomo.travaglini@arm.com      case GITS_PIDR2:
86814168Sgiacomo.travaglini@arm.com        value = gic->getDistributor()->gicdPidr2;
86914168Sgiacomo.travaglini@arm.com        break;
87014168Sgiacomo.travaglini@arm.com
87113996Sgiacomo.travaglini@arm.com      case GITS_TRANSLATER:
87213996Sgiacomo.travaglini@arm.com        value = gitsTranslater;
87313996Sgiacomo.travaglini@arm.com        break;
87413996Sgiacomo.travaglini@arm.com
87513996Sgiacomo.travaglini@arm.com      default:
87613996Sgiacomo.travaglini@arm.com        if (GITS_BASER.contains(addr)) {
87713996Sgiacomo.travaglini@arm.com            auto relative_addr = addr - GITS_BASER.start();
87813996Sgiacomo.travaglini@arm.com            auto baser_index = relative_addr / sizeof(uint64_t);
87913996Sgiacomo.travaglini@arm.com
88013996Sgiacomo.travaglini@arm.com            value = tableBases[baser_index];
88113996Sgiacomo.travaglini@arm.com            break;
88213996Sgiacomo.travaglini@arm.com        } else {
88313996Sgiacomo.travaglini@arm.com            panic("Unrecognized register access\n");
88413996Sgiacomo.travaglini@arm.com        }
88513996Sgiacomo.travaglini@arm.com    }
88613996Sgiacomo.travaglini@arm.com
88713996Sgiacomo.travaglini@arm.com    pkt->setUintX(value, LittleEndianByteOrder);
88813996Sgiacomo.travaglini@arm.com    pkt->makeAtomicResponse();
88913996Sgiacomo.travaglini@arm.com    return pioDelay;
89013996Sgiacomo.travaglini@arm.com}
89113996Sgiacomo.travaglini@arm.com
89213996Sgiacomo.travaglini@arm.comTick
89313996Sgiacomo.travaglini@arm.comGicv3Its::write(PacketPtr pkt)
89413996Sgiacomo.travaglini@arm.com{
89513996Sgiacomo.travaglini@arm.com    Addr addr = pkt->getAddr() - pioAddr;
89613996Sgiacomo.travaglini@arm.com
89713996Sgiacomo.travaglini@arm.com    DPRINTF(GIC, "%s register at addr: %#x\n", __func__, addr);
89813996Sgiacomo.travaglini@arm.com
89913996Sgiacomo.travaglini@arm.com    switch (addr) {
90013996Sgiacomo.travaglini@arm.com      case GITS_CTLR:
90113996Sgiacomo.travaglini@arm.com        assert(pkt->getSize() == sizeof(uint32_t));
90214181Sgiacomo.travaglini@arm.com        gitsControl = (pkt->getLE<uint32_t>() & ~CTLR_QUIESCENT);
90314181Sgiacomo.travaglini@arm.com        // We should check here if the ITS has been disabled, and if
90414181Sgiacomo.travaglini@arm.com        // that's the case, flush GICv3 caches to external memory.
90514181Sgiacomo.travaglini@arm.com        // This is not happening now, since LPI caching is not
90614181Sgiacomo.travaglini@arm.com        // currently implemented in gem5.
90713996Sgiacomo.travaglini@arm.com        break;
90813996Sgiacomo.travaglini@arm.com
90913996Sgiacomo.travaglini@arm.com      case GITS_IIDR:
91013996Sgiacomo.travaglini@arm.com        panic("GITS_IIDR is Read Only\n");
91113996Sgiacomo.travaglini@arm.com
91213996Sgiacomo.travaglini@arm.com      case GITS_TYPER:
91313996Sgiacomo.travaglini@arm.com        panic("GITS_TYPER is Read Only\n");
91413996Sgiacomo.travaglini@arm.com
91513996Sgiacomo.travaglini@arm.com      case GITS_CBASER:
91614180Sgiacomo.travaglini@arm.com        if (pkt->getSize() == sizeof(uint32_t)) {
91714180Sgiacomo.travaglini@arm.com            gitsCbaser.low = pkt->getLE<uint32_t>();
91814180Sgiacomo.travaglini@arm.com        } else {
91914180Sgiacomo.travaglini@arm.com            assert(pkt->getSize() == sizeof(uint64_t));
92014180Sgiacomo.travaglini@arm.com            gitsCbaser = pkt->getLE<uint64_t>();
92114180Sgiacomo.travaglini@arm.com        }
92214180Sgiacomo.travaglini@arm.com
92314180Sgiacomo.travaglini@arm.com        gitsCreadr = 0; // Cleared when CBASER gets written
92414180Sgiacomo.travaglini@arm.com
92514180Sgiacomo.travaglini@arm.com        checkCommandQueue();
92614180Sgiacomo.travaglini@arm.com        break;
92714180Sgiacomo.travaglini@arm.com
92814180Sgiacomo.travaglini@arm.com      case GITS_CBASER + 4:
92914180Sgiacomo.travaglini@arm.com        assert(pkt->getSize() == sizeof(uint32_t));
93014180Sgiacomo.travaglini@arm.com        gitsCbaser.high = pkt->getLE<uint32_t>();
93114180Sgiacomo.travaglini@arm.com
93213996Sgiacomo.travaglini@arm.com        gitsCreadr = 0; // Cleared when CBASER gets written
93313996Sgiacomo.travaglini@arm.com
93413996Sgiacomo.travaglini@arm.com        checkCommandQueue();
93513996Sgiacomo.travaglini@arm.com        break;
93613996Sgiacomo.travaglini@arm.com
93713996Sgiacomo.travaglini@arm.com      case GITS_CWRITER:
93814180Sgiacomo.travaglini@arm.com        if (pkt->getSize() == sizeof(uint32_t)) {
93914180Sgiacomo.travaglini@arm.com            gitsCwriter.low = pkt->getLE<uint32_t>();
94014180Sgiacomo.travaglini@arm.com        } else {
94114180Sgiacomo.travaglini@arm.com            assert(pkt->getSize() == sizeof(uint64_t));
94214180Sgiacomo.travaglini@arm.com            gitsCwriter = pkt->getLE<uint64_t>();
94314180Sgiacomo.travaglini@arm.com        }
94414180Sgiacomo.travaglini@arm.com
94514180Sgiacomo.travaglini@arm.com        checkCommandQueue();
94614180Sgiacomo.travaglini@arm.com        break;
94714180Sgiacomo.travaglini@arm.com
94814180Sgiacomo.travaglini@arm.com      case GITS_CWRITER + 4:
94914180Sgiacomo.travaglini@arm.com        assert(pkt->getSize() == sizeof(uint32_t));
95014180Sgiacomo.travaglini@arm.com        gitsCwriter.high = pkt->getLE<uint32_t>();
95113996Sgiacomo.travaglini@arm.com
95213996Sgiacomo.travaglini@arm.com        checkCommandQueue();
95313996Sgiacomo.travaglini@arm.com        break;
95413996Sgiacomo.travaglini@arm.com
95513996Sgiacomo.travaglini@arm.com      case GITS_CREADR:
95613996Sgiacomo.travaglini@arm.com        panic("GITS_READR is Read Only\n");
95713996Sgiacomo.travaglini@arm.com
95813996Sgiacomo.travaglini@arm.com      case GITS_TRANSLATER:
95913996Sgiacomo.travaglini@arm.com        if (gitsControl.enabled) {
96013996Sgiacomo.travaglini@arm.com            translate(pkt);
96113996Sgiacomo.travaglini@arm.com        }
96213996Sgiacomo.travaglini@arm.com        break;
96313996Sgiacomo.travaglini@arm.com
96413996Sgiacomo.travaglini@arm.com      default:
96513996Sgiacomo.travaglini@arm.com        if (GITS_BASER.contains(addr)) {
96613996Sgiacomo.travaglini@arm.com            auto relative_addr = addr - GITS_BASER.start();
96713996Sgiacomo.travaglini@arm.com            auto baser_index = relative_addr / sizeof(uint64_t);
96813996Sgiacomo.travaglini@arm.com
96914187Sgiacomo.travaglini@arm.com            const uint64_t table_base = tableBases[baser_index];
97014187Sgiacomo.travaglini@arm.com            const uint64_t w_mask = tableBases[baser_index].type ?
97114187Sgiacomo.travaglini@arm.com                BASER_WMASK : BASER_WMASK_UNIMPL;
97214187Sgiacomo.travaglini@arm.com            const uint64_t val = pkt->getLE<uint64_t>() & w_mask;
97313996Sgiacomo.travaglini@arm.com
97414187Sgiacomo.travaglini@arm.com            tableBases[baser_index] = table_base | val;
97513996Sgiacomo.travaglini@arm.com            break;
97613996Sgiacomo.travaglini@arm.com        } else {
97713996Sgiacomo.travaglini@arm.com            panic("Unrecognized register access\n");
97813996Sgiacomo.travaglini@arm.com        }
97913996Sgiacomo.travaglini@arm.com    }
98013996Sgiacomo.travaglini@arm.com
98113996Sgiacomo.travaglini@arm.com    pkt->makeAtomicResponse();
98213996Sgiacomo.travaglini@arm.com    return pioDelay;
98313996Sgiacomo.travaglini@arm.com}
98413996Sgiacomo.travaglini@arm.com
98513996Sgiacomo.travaglini@arm.combool
98613996Sgiacomo.travaglini@arm.comGicv3Its::idOutOfRange(uint32_t event_id, uint8_t itt_range) const
98713996Sgiacomo.travaglini@arm.com{
98813996Sgiacomo.travaglini@arm.com    const uint32_t id_bits = gitsTyper.idBits;
98913996Sgiacomo.travaglini@arm.com    return event_id >= (1ULL << (id_bits + 1)) ||
99013996Sgiacomo.travaglini@arm.com        event_id >= ((1ULL << itt_range) + 1);
99113996Sgiacomo.travaglini@arm.com}
99213996Sgiacomo.travaglini@arm.com
99313996Sgiacomo.travaglini@arm.combool
99413996Sgiacomo.travaglini@arm.comGicv3Its::deviceOutOfRange(uint32_t device_id) const
99513996Sgiacomo.travaglini@arm.com{
99613996Sgiacomo.travaglini@arm.com    return device_id >= (1ULL << (gitsTyper.devBits + 1));
99713996Sgiacomo.travaglini@arm.com}
99813996Sgiacomo.travaglini@arm.com
99913996Sgiacomo.travaglini@arm.combool
100013996Sgiacomo.travaglini@arm.comGicv3Its::sizeOutOfRange(uint32_t size) const
100113996Sgiacomo.travaglini@arm.com{
100213996Sgiacomo.travaglini@arm.com    return size > gitsTyper.idBits;
100313996Sgiacomo.travaglini@arm.com}
100413996Sgiacomo.travaglini@arm.com
100513996Sgiacomo.travaglini@arm.combool
100613996Sgiacomo.travaglini@arm.comGicv3Its::collectionOutOfRange(uint32_t collection_id) const
100713996Sgiacomo.travaglini@arm.com{
100813996Sgiacomo.travaglini@arm.com    // If GITS_TYPER.CIL == 0, ITS supports 16-bit CollectionID
100913996Sgiacomo.travaglini@arm.com    // Otherwise, #bits is specified by GITS_TYPER.CIDbits
101013996Sgiacomo.travaglini@arm.com    const auto cid_bits = gitsTyper.cil == 0 ?
101113996Sgiacomo.travaglini@arm.com        16 : gitsTyper.cidBits + 1;
101213996Sgiacomo.travaglini@arm.com
101313996Sgiacomo.travaglini@arm.com    return collection_id >= (1ULL << cid_bits);
101413996Sgiacomo.travaglini@arm.com}
101513996Sgiacomo.travaglini@arm.com
101613996Sgiacomo.travaglini@arm.combool
101713996Sgiacomo.travaglini@arm.comGicv3Its::lpiOutOfRange(uint32_t intid) const
101813996Sgiacomo.travaglini@arm.com{
101913996Sgiacomo.travaglini@arm.com    return intid >= (1ULL << (Gicv3Distributor::IDBITS + 1)) ||
102013996Sgiacomo.travaglini@arm.com           (intid < Gicv3Redistributor::SMALLEST_LPI_ID &&
102113996Sgiacomo.travaglini@arm.com            intid != Gicv3::INTID_SPURIOUS);
102213996Sgiacomo.travaglini@arm.com}
102313996Sgiacomo.travaglini@arm.com
102413996Sgiacomo.travaglini@arm.comDrainState
102513996Sgiacomo.travaglini@arm.comGicv3Its::drain()
102613996Sgiacomo.travaglini@arm.com{
102713996Sgiacomo.travaglini@arm.com    if (!pendingCommands && !pendingTranslations) {
102813996Sgiacomo.travaglini@arm.com        return DrainState::Drained;
102913996Sgiacomo.travaglini@arm.com    } else {
103013996Sgiacomo.travaglini@arm.com        DPRINTF(Drain, "GICv3 ITS not drained\n");
103113996Sgiacomo.travaglini@arm.com        return DrainState::Draining;
103213996Sgiacomo.travaglini@arm.com    }
103313996Sgiacomo.travaglini@arm.com}
103413996Sgiacomo.travaglini@arm.com
103513996Sgiacomo.travaglini@arm.comvoid
103613996Sgiacomo.travaglini@arm.comGicv3Its::serialize(CheckpointOut & cp) const
103713996Sgiacomo.travaglini@arm.com{
103813996Sgiacomo.travaglini@arm.com    SERIALIZE_SCALAR(gitsControl);
103913996Sgiacomo.travaglini@arm.com    SERIALIZE_SCALAR(gitsTyper);
104013996Sgiacomo.travaglini@arm.com    SERIALIZE_SCALAR(gitsCbaser);
104113996Sgiacomo.travaglini@arm.com    SERIALIZE_SCALAR(gitsCreadr);
104213996Sgiacomo.travaglini@arm.com    SERIALIZE_SCALAR(gitsCwriter);
104313996Sgiacomo.travaglini@arm.com    SERIALIZE_SCALAR(gitsIidr);
104413996Sgiacomo.travaglini@arm.com
104513996Sgiacomo.travaglini@arm.com    SERIALIZE_CONTAINER(tableBases);
104613996Sgiacomo.travaglini@arm.com}
104713996Sgiacomo.travaglini@arm.com
104813996Sgiacomo.travaglini@arm.comvoid
104913996Sgiacomo.travaglini@arm.comGicv3Its::unserialize(CheckpointIn & cp)
105013996Sgiacomo.travaglini@arm.com{
105113996Sgiacomo.travaglini@arm.com    UNSERIALIZE_SCALAR(gitsControl);
105213996Sgiacomo.travaglini@arm.com    UNSERIALIZE_SCALAR(gitsTyper);
105313996Sgiacomo.travaglini@arm.com    UNSERIALIZE_SCALAR(gitsCbaser);
105413996Sgiacomo.travaglini@arm.com    UNSERIALIZE_SCALAR(gitsCreadr);
105513996Sgiacomo.travaglini@arm.com    UNSERIALIZE_SCALAR(gitsCwriter);
105613996Sgiacomo.travaglini@arm.com    UNSERIALIZE_SCALAR(gitsIidr);
105713996Sgiacomo.travaglini@arm.com
105813996Sgiacomo.travaglini@arm.com    UNSERIALIZE_CONTAINER(tableBases);
105913996Sgiacomo.travaglini@arm.com}
106013996Sgiacomo.travaglini@arm.com
106113996Sgiacomo.travaglini@arm.comvoid
106213996Sgiacomo.travaglini@arm.comGicv3Its::incrementReadPointer()
106313996Sgiacomo.travaglini@arm.com{
106413996Sgiacomo.travaglini@arm.com    // Make the reader point to the next element
106513996Sgiacomo.travaglini@arm.com    gitsCreadr.offset = gitsCreadr.offset + 1;
106613996Sgiacomo.travaglini@arm.com
106713996Sgiacomo.travaglini@arm.com    // Check for wrapping
106814255Sgiacomo.travaglini@arm.com    if (gitsCreadr.offset == maxCommands()) {
106913996Sgiacomo.travaglini@arm.com        gitsCreadr.offset = 0;
107013996Sgiacomo.travaglini@arm.com    }
107113996Sgiacomo.travaglini@arm.com}
107213996Sgiacomo.travaglini@arm.com
107314255Sgiacomo.travaglini@arm.comuint64_t
107414255Sgiacomo.travaglini@arm.comGicv3Its::maxCommands() const
107514255Sgiacomo.travaglini@arm.com{
107614255Sgiacomo.travaglini@arm.com    return (4096 * (gitsCbaser.size + 1)) / sizeof(ItsCommand::CommandEntry);
107714255Sgiacomo.travaglini@arm.com}
107814255Sgiacomo.travaglini@arm.com
107913996Sgiacomo.travaglini@arm.comvoid
108013996Sgiacomo.travaglini@arm.comGicv3Its::checkCommandQueue()
108113996Sgiacomo.travaglini@arm.com{
108213996Sgiacomo.travaglini@arm.com    if (!gitsControl.enabled || !gitsCbaser.valid)
108313996Sgiacomo.travaglini@arm.com        return;
108413996Sgiacomo.travaglini@arm.com
108514255Sgiacomo.travaglini@arm.com    // If GITS_CWRITER gets set by sw to a value bigger than the
108614255Sgiacomo.travaglini@arm.com    // allowed one, the command queue should stop processing commands
108714255Sgiacomo.travaglini@arm.com    // until the register gets reset to an allowed one
108814255Sgiacomo.travaglini@arm.com    if (gitsCwriter.offset >= maxCommands()) {
108914255Sgiacomo.travaglini@arm.com        return;
109014255Sgiacomo.travaglini@arm.com    }
109114255Sgiacomo.travaglini@arm.com
109213996Sgiacomo.travaglini@arm.com    if (gitsCwriter.offset != gitsCreadr.offset) {
109313996Sgiacomo.travaglini@arm.com        // writer and reader pointing to different command
109413996Sgiacomo.travaglini@arm.com        // entries: queue not empty.
109513996Sgiacomo.travaglini@arm.com        DPRINTF(ITS, "Reading command from queue\n");
109613996Sgiacomo.travaglini@arm.com
109713996Sgiacomo.travaglini@arm.com        if (!pendingCommands) {
109813996Sgiacomo.travaglini@arm.com            auto *cmd_proc = new ItsCommand(*this);
109913996Sgiacomo.travaglini@arm.com
110013996Sgiacomo.travaglini@arm.com            runProcess(cmd_proc, nullptr);
110113996Sgiacomo.travaglini@arm.com        } else {
110213996Sgiacomo.travaglini@arm.com            DPRINTF(ITS, "Waiting for pending command to finish\n");
110313996Sgiacomo.travaglini@arm.com        }
110413996Sgiacomo.travaglini@arm.com    }
110513996Sgiacomo.travaglini@arm.com}
110613996Sgiacomo.travaglini@arm.com
110713996Sgiacomo.travaglini@arm.comPort &
110813996Sgiacomo.travaglini@arm.comGicv3Its::getPort(const std::string &if_name, PortID idx)
110913996Sgiacomo.travaglini@arm.com{
111013996Sgiacomo.travaglini@arm.com    if (if_name == "dma") {
111113996Sgiacomo.travaglini@arm.com        return dmaPort;
111213996Sgiacomo.travaglini@arm.com    }
111313996Sgiacomo.travaglini@arm.com    return BasicPioDevice::getPort(if_name, idx);
111413996Sgiacomo.travaglini@arm.com}
111513996Sgiacomo.travaglini@arm.com
111613996Sgiacomo.travaglini@arm.comvoid
111713996Sgiacomo.travaglini@arm.comGicv3Its::recvReqRetry()
111813996Sgiacomo.travaglini@arm.com{
111913996Sgiacomo.travaglini@arm.com    assert(!packetsToRetry.empty());
112013996Sgiacomo.travaglini@arm.com
112113996Sgiacomo.travaglini@arm.com    while (!packetsToRetry.empty()) {
112213996Sgiacomo.travaglini@arm.com        ItsAction a = packetsToRetry.front();
112313996Sgiacomo.travaglini@arm.com
112413996Sgiacomo.travaglini@arm.com        assert(a.type == ItsActionType::SEND_REQ);
112513996Sgiacomo.travaglini@arm.com
112613996Sgiacomo.travaglini@arm.com        if (!dmaPort.sendTimingReq(a.pkt))
112713996Sgiacomo.travaglini@arm.com            break;
112813996Sgiacomo.travaglini@arm.com
112913996Sgiacomo.travaglini@arm.com        packetsToRetry.pop();
113013996Sgiacomo.travaglini@arm.com    }
113113996Sgiacomo.travaglini@arm.com}
113213996Sgiacomo.travaglini@arm.com
113313996Sgiacomo.travaglini@arm.combool
113413996Sgiacomo.travaglini@arm.comGicv3Its::recvTimingResp(PacketPtr pkt)
113513996Sgiacomo.travaglini@arm.com{
113613996Sgiacomo.travaglini@arm.com    // @todo: We need to pay for this and not just zero it out
113713996Sgiacomo.travaglini@arm.com    pkt->headerDelay = pkt->payloadDelay = 0;
113813996Sgiacomo.travaglini@arm.com
113913996Sgiacomo.travaglini@arm.com    ItsProcess *proc =
114013996Sgiacomo.travaglini@arm.com        safe_cast<ItsProcess *>(pkt->popSenderState());
114113996Sgiacomo.travaglini@arm.com
114213996Sgiacomo.travaglini@arm.com    runProcessTiming(proc, pkt);
114313996Sgiacomo.travaglini@arm.com
114413996Sgiacomo.travaglini@arm.com    return true;
114513996Sgiacomo.travaglini@arm.com}
114613996Sgiacomo.travaglini@arm.com
114713996Sgiacomo.travaglini@arm.comItsAction
114813996Sgiacomo.travaglini@arm.comGicv3Its::runProcess(ItsProcess *proc, PacketPtr pkt)
114913996Sgiacomo.travaglini@arm.com{
115013996Sgiacomo.travaglini@arm.com    if (sys->isAtomicMode()) {
115113996Sgiacomo.travaglini@arm.com        return runProcessAtomic(proc, pkt);
115213996Sgiacomo.travaglini@arm.com    } else if (sys->isTimingMode()) {
115313996Sgiacomo.travaglini@arm.com        return runProcessTiming(proc, pkt);
115413996Sgiacomo.travaglini@arm.com    } else {
115513996Sgiacomo.travaglini@arm.com        panic("Not in timing or atomic mode\n");
115613996Sgiacomo.travaglini@arm.com    }
115713996Sgiacomo.travaglini@arm.com}
115813996Sgiacomo.travaglini@arm.com
115913996Sgiacomo.travaglini@arm.comItsAction
116013996Sgiacomo.travaglini@arm.comGicv3Its::runProcessTiming(ItsProcess *proc, PacketPtr pkt)
116113996Sgiacomo.travaglini@arm.com{
116213996Sgiacomo.travaglini@arm.com    ItsAction action = proc->run(pkt);
116313996Sgiacomo.travaglini@arm.com
116413996Sgiacomo.travaglini@arm.com    switch (action.type) {
116513996Sgiacomo.travaglini@arm.com      case ItsActionType::SEND_REQ:
116613996Sgiacomo.travaglini@arm.com        action.pkt->pushSenderState(proc);
116713996Sgiacomo.travaglini@arm.com
116813996Sgiacomo.travaglini@arm.com        if (packetsToRetry.empty() &&
116913996Sgiacomo.travaglini@arm.com            dmaPort.sendTimingReq(action.pkt)) {
117013996Sgiacomo.travaglini@arm.com
117113996Sgiacomo.travaglini@arm.com        } else {
117213996Sgiacomo.travaglini@arm.com            packetsToRetry.push(action);
117313996Sgiacomo.travaglini@arm.com        }
117413996Sgiacomo.travaglini@arm.com        break;
117513996Sgiacomo.travaglini@arm.com
117613996Sgiacomo.travaglini@arm.com      case ItsActionType::TERMINATE:
117713996Sgiacomo.travaglini@arm.com        delete proc;
117813996Sgiacomo.travaglini@arm.com        if (!pendingCommands && !commandEvent.scheduled()) {
117913996Sgiacomo.travaglini@arm.com            schedule(commandEvent, clockEdge());
118013996Sgiacomo.travaglini@arm.com        }
118113996Sgiacomo.travaglini@arm.com        break;
118213996Sgiacomo.travaglini@arm.com
118313996Sgiacomo.travaglini@arm.com      default:
118413996Sgiacomo.travaglini@arm.com        panic("Unknown action\n");
118513996Sgiacomo.travaglini@arm.com    }
118613996Sgiacomo.travaglini@arm.com
118713996Sgiacomo.travaglini@arm.com    return action;
118813996Sgiacomo.travaglini@arm.com}
118913996Sgiacomo.travaglini@arm.com
119013996Sgiacomo.travaglini@arm.comItsAction
119113996Sgiacomo.travaglini@arm.comGicv3Its::runProcessAtomic(ItsProcess *proc, PacketPtr pkt)
119213996Sgiacomo.travaglini@arm.com{
119313996Sgiacomo.travaglini@arm.com    ItsAction action;
119413996Sgiacomo.travaglini@arm.com    Tick delay = 0;
119513996Sgiacomo.travaglini@arm.com    bool terminate = false;
119613996Sgiacomo.travaglini@arm.com
119713996Sgiacomo.travaglini@arm.com    do {
119813996Sgiacomo.travaglini@arm.com        action = proc->run(pkt);
119913996Sgiacomo.travaglini@arm.com
120013996Sgiacomo.travaglini@arm.com        switch (action.type) {
120113996Sgiacomo.travaglini@arm.com          case ItsActionType::SEND_REQ:
120213996Sgiacomo.travaglini@arm.com            delay += dmaPort.sendAtomic(action.pkt);
120313996Sgiacomo.travaglini@arm.com            pkt = action.pkt;
120413996Sgiacomo.travaglini@arm.com            break;
120513996Sgiacomo.travaglini@arm.com
120613996Sgiacomo.travaglini@arm.com          case ItsActionType::TERMINATE:
120713996Sgiacomo.travaglini@arm.com            delete proc;
120813996Sgiacomo.travaglini@arm.com            terminate = true;
120913996Sgiacomo.travaglini@arm.com            break;
121013996Sgiacomo.travaglini@arm.com
121113996Sgiacomo.travaglini@arm.com          default:
121213996Sgiacomo.travaglini@arm.com            panic("Unknown action\n");
121313996Sgiacomo.travaglini@arm.com        }
121413996Sgiacomo.travaglini@arm.com
121513996Sgiacomo.travaglini@arm.com    } while (!terminate);
121613996Sgiacomo.travaglini@arm.com
121713996Sgiacomo.travaglini@arm.com    action.delay = delay;
121813996Sgiacomo.travaglini@arm.com
121913996Sgiacomo.travaglini@arm.com    return action;
122013996Sgiacomo.travaglini@arm.com}
122113996Sgiacomo.travaglini@arm.com
122213996Sgiacomo.travaglini@arm.comvoid
122313996Sgiacomo.travaglini@arm.comGicv3Its::translate(PacketPtr pkt)
122413996Sgiacomo.travaglini@arm.com{
122513996Sgiacomo.travaglini@arm.com    DPRINTF(ITS, "Starting Translation Request\n");
122613996Sgiacomo.travaglini@arm.com
122713996Sgiacomo.travaglini@arm.com    auto *proc = new ItsTranslation(*this);
122813996Sgiacomo.travaglini@arm.com    runProcess(proc, pkt);
122913996Sgiacomo.travaglini@arm.com}
123013996Sgiacomo.travaglini@arm.com
123113996Sgiacomo.travaglini@arm.comGicv3Redistributor*
123213996Sgiacomo.travaglini@arm.comGicv3Its::getRedistributor(uint64_t rd_base)
123313996Sgiacomo.travaglini@arm.com{
123413996Sgiacomo.travaglini@arm.com    if (gitsTyper.pta == 1) {
123513996Sgiacomo.travaglini@arm.com        // RDBase is a redistributor address
123613996Sgiacomo.travaglini@arm.com        return gic->getRedistributorByAddr(rd_base << 16);
123713996Sgiacomo.travaglini@arm.com    } else {
123813996Sgiacomo.travaglini@arm.com        // RDBase is a redistributor number
123913996Sgiacomo.travaglini@arm.com        return gic->getRedistributor(rd_base);
124013996Sgiacomo.travaglini@arm.com    }
124113996Sgiacomo.travaglini@arm.com}
124213996Sgiacomo.travaglini@arm.com
124313996Sgiacomo.travaglini@arm.comAddr
124413996Sgiacomo.travaglini@arm.comGicv3Its::pageAddress(Gicv3Its::ItsTables table)
124513996Sgiacomo.travaglini@arm.com{
124614187Sgiacomo.travaglini@arm.com    auto base_it = std::find_if(
124714187Sgiacomo.travaglini@arm.com        tableBases.begin(), tableBases.end(),
124814187Sgiacomo.travaglini@arm.com        [table] (const BASER &b) { return b.type == table; }
124914187Sgiacomo.travaglini@arm.com    );
125014187Sgiacomo.travaglini@arm.com
125114187Sgiacomo.travaglini@arm.com    panic_if(base_it == tableBases.end(),
125214187Sgiacomo.travaglini@arm.com        "ITS Table not recognised\n");
125314187Sgiacomo.travaglini@arm.com
125414187Sgiacomo.travaglini@arm.com    const BASER base = *base_it;
125514187Sgiacomo.travaglini@arm.com
125613996Sgiacomo.travaglini@arm.com    // real address depends on page size
125713996Sgiacomo.travaglini@arm.com    switch (base.pageSize) {
125813996Sgiacomo.travaglini@arm.com      case SIZE_4K:
125913996Sgiacomo.travaglini@arm.com      case SIZE_16K:
126013996Sgiacomo.travaglini@arm.com        return mbits(base, 47, 12);
126113996Sgiacomo.travaglini@arm.com      case SIZE_64K:
126213996Sgiacomo.travaglini@arm.com        return mbits(base, 47, 16) | (bits(base, 15, 12) << 48);
126313996Sgiacomo.travaglini@arm.com      default:
126413996Sgiacomo.travaglini@arm.com        panic("Unsupported page size\n");
126513996Sgiacomo.travaglini@arm.com    }
126613996Sgiacomo.travaglini@arm.com}
126713996Sgiacomo.travaglini@arm.com
126813996Sgiacomo.travaglini@arm.comvoid
126913996Sgiacomo.travaglini@arm.comGicv3Its::moveAllPendingState(
127013996Sgiacomo.travaglini@arm.com    Gicv3Redistributor *rd1, Gicv3Redistributor *rd2)
127113996Sgiacomo.travaglini@arm.com{
127213996Sgiacomo.travaglini@arm.com    const uint64_t largest_lpi_id = 1ULL << (rd1->lpiIDBits + 1);
127313996Sgiacomo.travaglini@arm.com    uint8_t lpi_pending_table[largest_lpi_id / 8];
127413996Sgiacomo.travaglini@arm.com
127513996Sgiacomo.travaglini@arm.com    // Copying the pending table from redistributor 1 to redistributor 2
127613996Sgiacomo.travaglini@arm.com    rd1->memProxy->readBlob(
127713996Sgiacomo.travaglini@arm.com        rd1->lpiPendingTablePtr, (uint8_t *)lpi_pending_table,
127813996Sgiacomo.travaglini@arm.com        sizeof(lpi_pending_table));
127913996Sgiacomo.travaglini@arm.com
128013996Sgiacomo.travaglini@arm.com    rd2->memProxy->writeBlob(
128113996Sgiacomo.travaglini@arm.com        rd2->lpiPendingTablePtr, (uint8_t *)lpi_pending_table,
128213996Sgiacomo.travaglini@arm.com        sizeof(lpi_pending_table));
128313996Sgiacomo.travaglini@arm.com
128413996Sgiacomo.travaglini@arm.com    // Clearing pending table in redistributor 2
128513996Sgiacomo.travaglini@arm.com    rd1->memProxy->memsetBlob(
128613996Sgiacomo.travaglini@arm.com        rd1->lpiPendingTablePtr,
128713996Sgiacomo.travaglini@arm.com        0, sizeof(lpi_pending_table));
128813996Sgiacomo.travaglini@arm.com
128914231Sgiacomo.travaglini@arm.com    rd2->updateDistributor();
129013996Sgiacomo.travaglini@arm.com}
129113996Sgiacomo.travaglini@arm.com
129213996Sgiacomo.travaglini@arm.comGicv3Its *
129313996Sgiacomo.travaglini@arm.comGicv3ItsParams::create()
129413996Sgiacomo.travaglini@arm.com{
129513996Sgiacomo.travaglini@arm.com    return new Gicv3Its(this);
129613996Sgiacomo.travaglini@arm.com}
1297