gic_v3_its.hh revision 14255
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#ifndef __DEV_ARM_GICV3_ITS_H__ 4113996Sgiacomo.travaglini@arm.com#define __DEV_ARM_GICV3_ITS_H__ 4213996Sgiacomo.travaglini@arm.com 4313996Sgiacomo.travaglini@arm.com#include <queue> 4413996Sgiacomo.travaglini@arm.com 4513996Sgiacomo.travaglini@arm.com#include "base/coroutine.hh" 4613996Sgiacomo.travaglini@arm.com#include "dev/dma_device.hh" 4713996Sgiacomo.travaglini@arm.com#include "params/Gicv3Its.hh" 4813996Sgiacomo.travaglini@arm.com 4913996Sgiacomo.travaglini@arm.comclass Gicv3; 5013996Sgiacomo.travaglini@arm.comclass Gicv3Redistributor; 5113996Sgiacomo.travaglini@arm.comclass ItsProcess; 5213996Sgiacomo.travaglini@arm.comclass ItsTranslation; 5313996Sgiacomo.travaglini@arm.comclass ItsCommand; 5413996Sgiacomo.travaglini@arm.com 5513996Sgiacomo.travaglini@arm.comenum class ItsActionType 5613996Sgiacomo.travaglini@arm.com{ 5713996Sgiacomo.travaglini@arm.com INITIAL_NOP, 5813996Sgiacomo.travaglini@arm.com SEND_REQ, 5913996Sgiacomo.travaglini@arm.com TERMINATE, 6013996Sgiacomo.travaglini@arm.com}; 6113996Sgiacomo.travaglini@arm.com 6213996Sgiacomo.travaglini@arm.comstruct ItsAction 6313996Sgiacomo.travaglini@arm.com{ 6413996Sgiacomo.travaglini@arm.com ItsActionType type; 6513996Sgiacomo.travaglini@arm.com PacketPtr pkt; 6613996Sgiacomo.travaglini@arm.com Tick delay; 6713996Sgiacomo.travaglini@arm.com}; 6813996Sgiacomo.travaglini@arm.com 6913996Sgiacomo.travaglini@arm.com/** 7013996Sgiacomo.travaglini@arm.com * GICv3 ITS module. This class is just modelling a pio device with its 7113996Sgiacomo.travaglini@arm.com * memory mapped registers. Most of the ITS functionalities are 7213996Sgiacomo.travaglini@arm.com * implemented as processes (ItsProcess) objects, like ItsTranslation or 7313996Sgiacomo.travaglini@arm.com * ItsCommand. 7413996Sgiacomo.travaglini@arm.com * Main job of Gicv3Its is to spawn those processes upon receival of packets. 7513996Sgiacomo.travaglini@arm.com */ 7613996Sgiacomo.travaglini@arm.comclass Gicv3Its : public BasicPioDevice 7713996Sgiacomo.travaglini@arm.com{ 7813996Sgiacomo.travaglini@arm.com friend class ::ItsProcess; 7913996Sgiacomo.travaglini@arm.com friend class ::ItsTranslation; 8013996Sgiacomo.travaglini@arm.com friend class ::ItsCommand; 8113996Sgiacomo.travaglini@arm.com public: 8213996Sgiacomo.travaglini@arm.com class DataPort : public MasterPort 8313996Sgiacomo.travaglini@arm.com { 8413996Sgiacomo.travaglini@arm.com protected: 8513996Sgiacomo.travaglini@arm.com Gicv3Its &its; 8613996Sgiacomo.travaglini@arm.com 8713996Sgiacomo.travaglini@arm.com public: 8813996Sgiacomo.travaglini@arm.com DataPort(const std::string &_name, Gicv3Its &_its) : 8913996Sgiacomo.travaglini@arm.com MasterPort(_name, &_its), 9013996Sgiacomo.travaglini@arm.com its(_its) 9113996Sgiacomo.travaglini@arm.com {} 9213996Sgiacomo.travaglini@arm.com 9313996Sgiacomo.travaglini@arm.com virtual ~DataPort() {} 9413996Sgiacomo.travaglini@arm.com 9513996Sgiacomo.travaglini@arm.com bool recvTimingResp(PacketPtr pkt) { return its.recvTimingResp(pkt); } 9613996Sgiacomo.travaglini@arm.com void recvReqRetry() { return its.recvReqRetry(); } 9713996Sgiacomo.travaglini@arm.com }; 9813996Sgiacomo.travaglini@arm.com 9913996Sgiacomo.travaglini@arm.com DataPort dmaPort; 10013996Sgiacomo.travaglini@arm.com 10113996Sgiacomo.travaglini@arm.com Port & getPort(const std::string &if_name, PortID idx) override; 10213996Sgiacomo.travaglini@arm.com bool recvTimingResp(PacketPtr pkt); 10313996Sgiacomo.travaglini@arm.com void recvReqRetry(); 10413996Sgiacomo.travaglini@arm.com 10513996Sgiacomo.travaglini@arm.com Gicv3Its(const Gicv3ItsParams *params); 10613996Sgiacomo.travaglini@arm.com 10713996Sgiacomo.travaglini@arm.com void setGIC(Gicv3 *_gic); 10813996Sgiacomo.travaglini@arm.com 10913996Sgiacomo.travaglini@arm.com static const uint32_t itsControl = 0x0; 11013996Sgiacomo.travaglini@arm.com static const uint32_t itsTranslate = 0x10000; 11113996Sgiacomo.travaglini@arm.com 11213996Sgiacomo.travaglini@arm.com // Address range part of Control frame 11313996Sgiacomo.travaglini@arm.com static const AddrRange GITS_BASER; 11413996Sgiacomo.travaglini@arm.com 11513996Sgiacomo.travaglini@arm.com static const uint32_t NUM_BASER_REGS = 8; 11613996Sgiacomo.travaglini@arm.com 11714187Sgiacomo.travaglini@arm.com // We currently don't support two level ITS tables 11814187Sgiacomo.travaglini@arm.com // The indirect bit is RAZ/WI for implementations that only 11914187Sgiacomo.travaglini@arm.com // support flat tables. 12014187Sgiacomo.travaglini@arm.com static const uint64_t BASER_INDIRECT = 0x4000000000000000; 12114187Sgiacomo.travaglini@arm.com static const uint64_t BASER_TYPE = 0x0700000000000000; 12214187Sgiacomo.travaglini@arm.com static const uint64_t BASER_ESZ = 0x001F000000000000; 12314187Sgiacomo.travaglini@arm.com static const uint64_t BASER_SZ = 0x00000000000000FF; 12414187Sgiacomo.travaglini@arm.com static const uint64_t BASER_WMASK = 12514187Sgiacomo.travaglini@arm.com ~(BASER_INDIRECT | BASER_TYPE | BASER_ESZ); 12614187Sgiacomo.travaglini@arm.com static const uint64_t BASER_WMASK_UNIMPL = 12714187Sgiacomo.travaglini@arm.com ~(BASER_INDIRECT | BASER_TYPE | BASER_ESZ | BASER_SZ); 12814187Sgiacomo.travaglini@arm.com 12914181Sgiacomo.travaglini@arm.com // GITS_CTLR.quiescent mask 13014181Sgiacomo.travaglini@arm.com static const uint32_t CTLR_QUIESCENT; 13114181Sgiacomo.travaglini@arm.com 13213996Sgiacomo.travaglini@arm.com enum : Addr 13313996Sgiacomo.travaglini@arm.com { 13413996Sgiacomo.travaglini@arm.com // Control frame 13513996Sgiacomo.travaglini@arm.com GITS_CTLR = itsControl + 0x0000, 13613996Sgiacomo.travaglini@arm.com GITS_IIDR = itsControl + 0x0004, 13713996Sgiacomo.travaglini@arm.com GITS_TYPER = itsControl + 0x0008, 13813996Sgiacomo.travaglini@arm.com GITS_CBASER = itsControl + 0x0080, 13913996Sgiacomo.travaglini@arm.com GITS_CWRITER = itsControl + 0x0088, 14013996Sgiacomo.travaglini@arm.com GITS_CREADR = itsControl + 0x0090, 14114168Sgiacomo.travaglini@arm.com GITS_PIDR2 = itsControl + 0xffe8, 14213996Sgiacomo.travaglini@arm.com 14313996Sgiacomo.travaglini@arm.com // Translation frame 14413996Sgiacomo.travaglini@arm.com GITS_TRANSLATER = itsTranslate + 0x0040 14513996Sgiacomo.travaglini@arm.com }; 14613996Sgiacomo.travaglini@arm.com 14713996Sgiacomo.travaglini@arm.com AddrRangeList getAddrRanges() const override; 14813996Sgiacomo.travaglini@arm.com 14913996Sgiacomo.travaglini@arm.com Tick read(PacketPtr pkt) override; 15013996Sgiacomo.travaglini@arm.com Tick write(PacketPtr pkt) override; 15113996Sgiacomo.travaglini@arm.com 15213996Sgiacomo.travaglini@arm.com DrainState drain() override; 15313996Sgiacomo.travaglini@arm.com void serialize(CheckpointOut & cp) const override; 15413996Sgiacomo.travaglini@arm.com void unserialize(CheckpointIn & cp) override; 15513996Sgiacomo.travaglini@arm.com 15613996Sgiacomo.travaglini@arm.com void translate(PacketPtr pkt); 15713996Sgiacomo.travaglini@arm.com 15813996Sgiacomo.travaglini@arm.com BitUnion32(CTLR) 15913996Sgiacomo.travaglini@arm.com Bitfield<31> quiescent; 16013996Sgiacomo.travaglini@arm.com Bitfield<7, 4> itsNumber; 16113996Sgiacomo.travaglini@arm.com Bitfield<1> imDe; 16213996Sgiacomo.travaglini@arm.com Bitfield<0> enabled; 16313996Sgiacomo.travaglini@arm.com EndBitUnion(CTLR) 16413996Sgiacomo.travaglini@arm.com 16513996Sgiacomo.travaglini@arm.com // Command read/write, (CREADR, CWRITER) 16613996Sgiacomo.travaglini@arm.com BitUnion64(CRDWR) 16714180Sgiacomo.travaglini@arm.com Bitfield<63, 32> high; 16814180Sgiacomo.travaglini@arm.com Bitfield<31, 0> low; 16913996Sgiacomo.travaglini@arm.com Bitfield<19, 5> offset; 17013996Sgiacomo.travaglini@arm.com Bitfield<0> retry; 17113996Sgiacomo.travaglini@arm.com Bitfield<0> stalled; 17213996Sgiacomo.travaglini@arm.com EndBitUnion(CRDWR) 17313996Sgiacomo.travaglini@arm.com 17413996Sgiacomo.travaglini@arm.com BitUnion64(CBASER) 17514180Sgiacomo.travaglini@arm.com Bitfield<63, 32> high; 17614180Sgiacomo.travaglini@arm.com Bitfield<31, 0> low; 17713996Sgiacomo.travaglini@arm.com Bitfield<63> valid; 17813996Sgiacomo.travaglini@arm.com Bitfield<61, 59> innerCache; 17913996Sgiacomo.travaglini@arm.com Bitfield<55, 53> outerCache; 18013996Sgiacomo.travaglini@arm.com Bitfield<51, 12> physAddr; 18113996Sgiacomo.travaglini@arm.com Bitfield<11, 10> shareability; 18213996Sgiacomo.travaglini@arm.com Bitfield<7, 0> size; 18313996Sgiacomo.travaglini@arm.com EndBitUnion(CBASER) 18413996Sgiacomo.travaglini@arm.com 18513996Sgiacomo.travaglini@arm.com BitUnion64(BASER) 18613996Sgiacomo.travaglini@arm.com Bitfield<63> valid; 18713996Sgiacomo.travaglini@arm.com Bitfield<62> indirect; 18813996Sgiacomo.travaglini@arm.com Bitfield<61, 59> innerCache; 18913996Sgiacomo.travaglini@arm.com Bitfield<58, 56> type; 19013996Sgiacomo.travaglini@arm.com Bitfield<55, 53> outerCache; 19113996Sgiacomo.travaglini@arm.com Bitfield<52, 48> entrySize; 19213996Sgiacomo.travaglini@arm.com Bitfield<47, 12> physAddr; 19313996Sgiacomo.travaglini@arm.com Bitfield<11, 10> shareability; 19413996Sgiacomo.travaglini@arm.com Bitfield<9, 8> pageSize; 19513996Sgiacomo.travaglini@arm.com Bitfield<7, 0> size; 19613996Sgiacomo.travaglini@arm.com EndBitUnion(BASER) 19713996Sgiacomo.travaglini@arm.com 19813996Sgiacomo.travaglini@arm.com BitUnion64(TYPER) 19914235Sgiacomo.travaglini@arm.com Bitfield<63, 32> high; 20014235Sgiacomo.travaglini@arm.com Bitfield<31, 0> low; 20113996Sgiacomo.travaglini@arm.com Bitfield<37> vmovp; 20213996Sgiacomo.travaglini@arm.com Bitfield<36> cil; 20313996Sgiacomo.travaglini@arm.com Bitfield<35, 32> cidBits; 20413996Sgiacomo.travaglini@arm.com Bitfield<31, 24> hcc; 20513996Sgiacomo.travaglini@arm.com Bitfield<19> pta; 20613996Sgiacomo.travaglini@arm.com Bitfield<18> seis; 20713996Sgiacomo.travaglini@arm.com Bitfield<17, 13> devBits; 20813996Sgiacomo.travaglini@arm.com Bitfield<12, 8> idBits; 20913996Sgiacomo.travaglini@arm.com Bitfield<7, 4> ittEntrySize; 21013996Sgiacomo.travaglini@arm.com Bitfield<2> cct; 21113996Sgiacomo.travaglini@arm.com Bitfield<1> _virtual; 21213996Sgiacomo.travaglini@arm.com Bitfield<0> physical; 21313996Sgiacomo.travaglini@arm.com EndBitUnion(TYPER) 21413996Sgiacomo.travaglini@arm.com 21513996Sgiacomo.travaglini@arm.com CTLR gitsControl; 21613996Sgiacomo.travaglini@arm.com TYPER gitsTyper; 21713996Sgiacomo.travaglini@arm.com CBASER gitsCbaser; 21813996Sgiacomo.travaglini@arm.com CRDWR gitsCreadr; 21913996Sgiacomo.travaglini@arm.com CRDWR gitsCwriter; 22013996Sgiacomo.travaglini@arm.com uint32_t gitsIidr; 22113996Sgiacomo.travaglini@arm.com uint32_t gitsTranslater; 22213996Sgiacomo.travaglini@arm.com 22313996Sgiacomo.travaglini@arm.com std::vector<BASER> tableBases; 22413996Sgiacomo.travaglini@arm.com 22513996Sgiacomo.travaglini@arm.com /** 22613996Sgiacomo.travaglini@arm.com * Returns TRUE if the eventID supplied has bits above the implemented 22713996Sgiacomo.travaglini@arm.com * size or above the itt_range 22813996Sgiacomo.travaglini@arm.com */ 22913996Sgiacomo.travaglini@arm.com bool idOutOfRange(uint32_t event_id, uint8_t itt_range) const; 23013996Sgiacomo.travaglini@arm.com 23113996Sgiacomo.travaglini@arm.com /** 23213996Sgiacomo.travaglini@arm.com * Returns TRUE if the value supplied has bits above the implemented range 23313996Sgiacomo.travaglini@arm.com * or if the value supplied exceeds the maximum configured size in the 23413996Sgiacomo.travaglini@arm.com * appropriate GITS_BASER<n> 23513996Sgiacomo.travaglini@arm.com */ 23613996Sgiacomo.travaglini@arm.com bool deviceOutOfRange(uint32_t device_id) const; 23713996Sgiacomo.travaglini@arm.com 23813996Sgiacomo.travaglini@arm.com /** 23913996Sgiacomo.travaglini@arm.com * Returns TRUE if the value (size) supplied exceeds the maximum 24013996Sgiacomo.travaglini@arm.com * allowed by GITS_TYPER.ID_bits. Size is the parameter which is 24113996Sgiacomo.travaglini@arm.com * passed to the ITS via the MAPD command and is stored in the 24213996Sgiacomo.travaglini@arm.com * DTE.ittRange field. 24313996Sgiacomo.travaglini@arm.com */ 24413996Sgiacomo.travaglini@arm.com bool sizeOutOfRange(uint32_t size) const; 24513996Sgiacomo.travaglini@arm.com 24613996Sgiacomo.travaglini@arm.com /** 24713996Sgiacomo.travaglini@arm.com * Returns TRUE if the value supplied has bits above the implemented range 24813996Sgiacomo.travaglini@arm.com * or if the value exceeds the total number of collections supported in 24913996Sgiacomo.travaglini@arm.com * hardware and external memory 25013996Sgiacomo.travaglini@arm.com */ 25113996Sgiacomo.travaglini@arm.com bool collectionOutOfRange(uint32_t collection_id) const; 25213996Sgiacomo.travaglini@arm.com 25313996Sgiacomo.travaglini@arm.com /** 25413996Sgiacomo.travaglini@arm.com * Returns TRUE if the value supplied is larger than that permitted by 25513996Sgiacomo.travaglini@arm.com * GICD_TYPER.IDbits or not in the LPI range and is not 1023 25613996Sgiacomo.travaglini@arm.com */ 25713996Sgiacomo.travaglini@arm.com bool lpiOutOfRange(uint32_t intid) const; 25813996Sgiacomo.travaglini@arm.com 25913996Sgiacomo.travaglini@arm.com private: // Command 26014255Sgiacomo.travaglini@arm.com uint64_t maxCommands() const; 26113996Sgiacomo.travaglini@arm.com void checkCommandQueue(); 26213996Sgiacomo.travaglini@arm.com void incrementReadPointer(); 26313996Sgiacomo.travaglini@arm.com 26413996Sgiacomo.travaglini@arm.com public: // TableWalk 26513996Sgiacomo.travaglini@arm.com BitUnion64(DTE) 26613996Sgiacomo.travaglini@arm.com Bitfield<57, 53> ittRange; 26713996Sgiacomo.travaglini@arm.com Bitfield<52, 1> ittAddress; 26813996Sgiacomo.travaglini@arm.com Bitfield<0> valid; 26913996Sgiacomo.travaglini@arm.com EndBitUnion(DTE) 27013996Sgiacomo.travaglini@arm.com 27113996Sgiacomo.travaglini@arm.com BitUnion64(ITTE) 27213996Sgiacomo.travaglini@arm.com Bitfield<59, 46> vpeid; 27313996Sgiacomo.travaglini@arm.com Bitfield<45, 30> icid; 27413996Sgiacomo.travaglini@arm.com Bitfield<29, 16> intNumHyp; 27513996Sgiacomo.travaglini@arm.com Bitfield<15, 2> intNum; 27613996Sgiacomo.travaglini@arm.com Bitfield<1> intType; 27713996Sgiacomo.travaglini@arm.com Bitfield<0> valid; 27813996Sgiacomo.travaglini@arm.com EndBitUnion(ITTE) 27913996Sgiacomo.travaglini@arm.com 28013996Sgiacomo.travaglini@arm.com BitUnion64(CTE) 28113996Sgiacomo.travaglini@arm.com Bitfield<40, 1> rdBase; 28213996Sgiacomo.travaglini@arm.com Bitfield<0> valid; 28313996Sgiacomo.travaglini@arm.com EndBitUnion(CTE) 28413996Sgiacomo.travaglini@arm.com 28513996Sgiacomo.travaglini@arm.com enum InterruptType 28613996Sgiacomo.travaglini@arm.com { 28713996Sgiacomo.travaglini@arm.com VIRTUAL_INTERRUPT = 0, 28813996Sgiacomo.travaglini@arm.com PHYSICAL_INTERRUPT = 1 28913996Sgiacomo.travaglini@arm.com }; 29013996Sgiacomo.travaglini@arm.com 29113996Sgiacomo.travaglini@arm.com private: 29213996Sgiacomo.travaglini@arm.com Gicv3Redistributor* getRedistributor(uint64_t rd_base); 29313996Sgiacomo.travaglini@arm.com Gicv3Redistributor* getRedistributor(CTE cte) 29413996Sgiacomo.travaglini@arm.com { 29513996Sgiacomo.travaglini@arm.com return getRedistributor(cte.rdBase); 29613996Sgiacomo.travaglini@arm.com } 29713996Sgiacomo.travaglini@arm.com 29813996Sgiacomo.travaglini@arm.com ItsAction runProcess(ItsProcess *proc, PacketPtr pkt); 29913996Sgiacomo.travaglini@arm.com ItsAction runProcessTiming(ItsProcess *proc, PacketPtr pkt); 30013996Sgiacomo.travaglini@arm.com ItsAction runProcessAtomic(ItsProcess *proc, PacketPtr pkt); 30113996Sgiacomo.travaglini@arm.com 30213996Sgiacomo.travaglini@arm.com enum ItsTables 30313996Sgiacomo.travaglini@arm.com { 30413996Sgiacomo.travaglini@arm.com DEVICE_TABLE = 1, 30513996Sgiacomo.travaglini@arm.com VPE_TABLE = 2, 30613996Sgiacomo.travaglini@arm.com TRANSLATION_TABLE = 3, 30713996Sgiacomo.travaglini@arm.com COLLECTION_TABLE = 4 30813996Sgiacomo.travaglini@arm.com }; 30913996Sgiacomo.travaglini@arm.com 31013996Sgiacomo.travaglini@arm.com enum PageSize 31113996Sgiacomo.travaglini@arm.com { 31213996Sgiacomo.travaglini@arm.com SIZE_4K, 31313996Sgiacomo.travaglini@arm.com SIZE_16K, 31413996Sgiacomo.travaglini@arm.com SIZE_64K 31513996Sgiacomo.travaglini@arm.com }; 31613996Sgiacomo.travaglini@arm.com 31713996Sgiacomo.travaglini@arm.com Addr pageAddress(enum ItsTables table); 31813996Sgiacomo.travaglini@arm.com 31913996Sgiacomo.travaglini@arm.com void moveAllPendingState( 32013996Sgiacomo.travaglini@arm.com Gicv3Redistributor *rd1, Gicv3Redistributor *rd2); 32113996Sgiacomo.travaglini@arm.com 32213996Sgiacomo.travaglini@arm.com private: 32313996Sgiacomo.travaglini@arm.com std::queue<ItsAction> packetsToRetry; 32413996Sgiacomo.travaglini@arm.com uint32_t masterId; 32513996Sgiacomo.travaglini@arm.com Gicv3 *gic; 32613996Sgiacomo.travaglini@arm.com EventFunctionWrapper commandEvent; 32713996Sgiacomo.travaglini@arm.com 32813996Sgiacomo.travaglini@arm.com bool pendingCommands; 32913996Sgiacomo.travaglini@arm.com uint32_t pendingTranslations; 33013996Sgiacomo.travaglini@arm.com}; 33113996Sgiacomo.travaglini@arm.com 33213996Sgiacomo.travaglini@arm.com/** 33313996Sgiacomo.travaglini@arm.com * ItsProcess is a base coroutine wrapper which is spawned by 33413996Sgiacomo.travaglini@arm.com * the Gicv3Its module when the latter needs to perform different 33513996Sgiacomo.travaglini@arm.com * actions, like translating a peripheral's MSI into an LPI 33613996Sgiacomo.travaglini@arm.com * (See derived ItsTranslation) or processing a Command from the 33713996Sgiacomo.travaglini@arm.com * ITS queue (ItsCommand). 33813996Sgiacomo.travaglini@arm.com * The action to take is implemented by the method: 33913996Sgiacomo.travaglini@arm.com * 34013996Sgiacomo.travaglini@arm.com * virtual void main(Yield &yield) = 0; 34113996Sgiacomo.travaglini@arm.com * It's inheriting from Packet::SenderState since the generic process 34213996Sgiacomo.travaglini@arm.com * will be stopped (we are using coroutines) and sent with the packet 34313996Sgiacomo.travaglini@arm.com * to memory when doing table walks. 34413996Sgiacomo.travaglini@arm.com * When Gicv3Its receives a response, it will resume the coroutine from 34513996Sgiacomo.travaglini@arm.com * the point it stopped when yielding. 34613996Sgiacomo.travaglini@arm.com */ 34713996Sgiacomo.travaglini@arm.comclass ItsProcess : public Packet::SenderState 34813996Sgiacomo.travaglini@arm.com{ 34913996Sgiacomo.travaglini@arm.com public: 35013996Sgiacomo.travaglini@arm.com using DTE = Gicv3Its::DTE; 35113996Sgiacomo.travaglini@arm.com using ITTE = Gicv3Its::ITTE; 35213996Sgiacomo.travaglini@arm.com using CTE = Gicv3Its::CTE; 35313996Sgiacomo.travaglini@arm.com using Coroutine = m5::Coroutine<PacketPtr, ItsAction>; 35413996Sgiacomo.travaglini@arm.com using Yield = Coroutine::CallerType; 35513996Sgiacomo.travaglini@arm.com 35613996Sgiacomo.travaglini@arm.com ItsProcess(Gicv3Its &_its); 35713996Sgiacomo.travaglini@arm.com virtual ~ItsProcess(); 35813996Sgiacomo.travaglini@arm.com 35913996Sgiacomo.travaglini@arm.com /** Returns the Gicv3Its name. Mainly used for DPRINTS */ 36013996Sgiacomo.travaglini@arm.com const std::string name() const; 36113996Sgiacomo.travaglini@arm.com 36213996Sgiacomo.travaglini@arm.com ItsAction run(PacketPtr pkt); 36313996Sgiacomo.travaglini@arm.com 36413996Sgiacomo.travaglini@arm.com protected: 36513996Sgiacomo.travaglini@arm.com void reinit(); 36613996Sgiacomo.travaglini@arm.com virtual void main(Yield &yield) = 0; 36713996Sgiacomo.travaglini@arm.com 36813996Sgiacomo.travaglini@arm.com void writeDeviceTable(Yield &yield, uint32_t device_id, DTE dte); 36913996Sgiacomo.travaglini@arm.com 37013996Sgiacomo.travaglini@arm.com void writeIrqTranslationTable( 37113996Sgiacomo.travaglini@arm.com Yield &yield, const Addr itt_base, uint32_t event_id, ITTE itte); 37213996Sgiacomo.travaglini@arm.com 37313996Sgiacomo.travaglini@arm.com void writeIrqCollectionTable( 37413996Sgiacomo.travaglini@arm.com Yield &yield, uint32_t collection_id, CTE cte); 37513996Sgiacomo.travaglini@arm.com 37613996Sgiacomo.travaglini@arm.com uint64_t readDeviceTable( 37713996Sgiacomo.travaglini@arm.com Yield &yield, uint32_t device_id); 37813996Sgiacomo.travaglini@arm.com 37913996Sgiacomo.travaglini@arm.com uint64_t readIrqTranslationTable( 38013996Sgiacomo.travaglini@arm.com Yield &yield, const Addr itt_base, uint32_t event_id); 38113996Sgiacomo.travaglini@arm.com 38213996Sgiacomo.travaglini@arm.com uint64_t readIrqCollectionTable(Yield &yield, uint32_t collection_id); 38313996Sgiacomo.travaglini@arm.com 38413996Sgiacomo.travaglini@arm.com void doRead(Yield &yield, Addr addr, void *ptr, size_t size); 38513996Sgiacomo.travaglini@arm.com void doWrite(Yield &yield, Addr addr, void *ptr, size_t size); 38613996Sgiacomo.travaglini@arm.com void terminate(Yield &yield); 38713996Sgiacomo.travaglini@arm.com 38813996Sgiacomo.travaglini@arm.com protected: 38913996Sgiacomo.travaglini@arm.com Gicv3Its &its; 39013996Sgiacomo.travaglini@arm.com 39113996Sgiacomo.travaglini@arm.com private: 39213996Sgiacomo.travaglini@arm.com std::unique_ptr<Coroutine> coroutine; 39313996Sgiacomo.travaglini@arm.com}; 39413996Sgiacomo.travaglini@arm.com 39513996Sgiacomo.travaglini@arm.com/** 39613996Sgiacomo.travaglini@arm.com * An ItsTranslation is created whenever a peripheral writes a message in 39713996Sgiacomo.travaglini@arm.com * GITS_TRANSLATER (MSI). In this case main will simply do the table walks 39813996Sgiacomo.travaglini@arm.com * until it gets a redistributor and an INTID. It will then raise the 39913996Sgiacomo.travaglini@arm.com * LPI interrupt to the target redistributor. 40013996Sgiacomo.travaglini@arm.com */ 40113996Sgiacomo.travaglini@arm.comclass ItsTranslation : public ItsProcess 40213996Sgiacomo.travaglini@arm.com{ 40313996Sgiacomo.travaglini@arm.com public: 40413996Sgiacomo.travaglini@arm.com ItsTranslation(Gicv3Its &_its); 40513996Sgiacomo.travaglini@arm.com ~ItsTranslation(); 40613996Sgiacomo.travaglini@arm.com 40713996Sgiacomo.travaglini@arm.com protected: 40813996Sgiacomo.travaglini@arm.com void main(Yield &yield) override; 40913996Sgiacomo.travaglini@arm.com 41013996Sgiacomo.travaglini@arm.com std::pair<uint32_t, Gicv3Redistributor *> 41113996Sgiacomo.travaglini@arm.com translateLPI(Yield &yield, uint32_t device_id, uint32_t event_id); 41213996Sgiacomo.travaglini@arm.com}; 41313996Sgiacomo.travaglini@arm.com 41413996Sgiacomo.travaglini@arm.com/** 41513996Sgiacomo.travaglini@arm.com * An ItsCommand is created whenever there is a new command in the command 41613996Sgiacomo.travaglini@arm.com * queue. Only one command can be executed per time. 41713996Sgiacomo.travaglini@arm.com * main will firstly read the command from memory and then it will process 41813996Sgiacomo.travaglini@arm.com * it. 41913996Sgiacomo.travaglini@arm.com */ 42013996Sgiacomo.travaglini@arm.comclass ItsCommand : public ItsProcess 42113996Sgiacomo.travaglini@arm.com{ 42213996Sgiacomo.travaglini@arm.com public: 42313996Sgiacomo.travaglini@arm.com union CommandEntry 42413996Sgiacomo.travaglini@arm.com { 42513996Sgiacomo.travaglini@arm.com struct 42613996Sgiacomo.travaglini@arm.com { 42713996Sgiacomo.travaglini@arm.com uint32_t type; 42813996Sgiacomo.travaglini@arm.com uint32_t deviceId; 42913996Sgiacomo.travaglini@arm.com uint32_t eventId; 43013996Sgiacomo.travaglini@arm.com uint32_t pintId; 43113996Sgiacomo.travaglini@arm.com 43213996Sgiacomo.travaglini@arm.com uint32_t data[4]; 43313996Sgiacomo.travaglini@arm.com }; 43413996Sgiacomo.travaglini@arm.com uint64_t raw[4]; 43513996Sgiacomo.travaglini@arm.com }; 43613996Sgiacomo.travaglini@arm.com 43713996Sgiacomo.travaglini@arm.com enum CommandType : uint32_t 43813996Sgiacomo.travaglini@arm.com { 43913996Sgiacomo.travaglini@arm.com CLEAR = 0x04, 44013996Sgiacomo.travaglini@arm.com DISCARD = 0x0F, 44113996Sgiacomo.travaglini@arm.com INT = 0x03, 44213996Sgiacomo.travaglini@arm.com INV = 0x0C, 44313996Sgiacomo.travaglini@arm.com INVALL = 0x0D, 44413996Sgiacomo.travaglini@arm.com MAPC = 0x09, 44513996Sgiacomo.travaglini@arm.com MAPD = 0x08, 44613996Sgiacomo.travaglini@arm.com MAPI = 0x0B, 44713996Sgiacomo.travaglini@arm.com MAPTI = 0x0A, 44813996Sgiacomo.travaglini@arm.com MOVALL = 0x0E, 44913996Sgiacomo.travaglini@arm.com MOVI = 0x01, 45013996Sgiacomo.travaglini@arm.com SYNC = 0x05, 45113996Sgiacomo.travaglini@arm.com VINVALL = 0x2D, 45213996Sgiacomo.travaglini@arm.com VMAPI = 0x2B, 45313996Sgiacomo.travaglini@arm.com VMAPP = 0x29, 45413996Sgiacomo.travaglini@arm.com VMAPTI = 0x2A, 45513996Sgiacomo.travaglini@arm.com VMOVI = 0x21, 45613996Sgiacomo.travaglini@arm.com VMOVP = 0x22, 45713996Sgiacomo.travaglini@arm.com VSYNC = 0x25 45813996Sgiacomo.travaglini@arm.com }; 45913996Sgiacomo.travaglini@arm.com 46013996Sgiacomo.travaglini@arm.com ItsCommand(Gicv3Its &_its); 46113996Sgiacomo.travaglini@arm.com ~ItsCommand(); 46213996Sgiacomo.travaglini@arm.com 46313996Sgiacomo.travaglini@arm.com protected: 46413996Sgiacomo.travaglini@arm.com /** 46513996Sgiacomo.travaglini@arm.com * Dispatch entry is a metadata struct which contains information about 46613996Sgiacomo.travaglini@arm.com * the command (like the name) and the function object implementing 46713996Sgiacomo.travaglini@arm.com * the command. 46813996Sgiacomo.travaglini@arm.com */ 46913996Sgiacomo.travaglini@arm.com struct DispatchEntry 47013996Sgiacomo.travaglini@arm.com { 47113996Sgiacomo.travaglini@arm.com using ExecFn = std::function<void(ItsCommand*, Yield&, CommandEntry&)>; 47213996Sgiacomo.travaglini@arm.com 47313996Sgiacomo.travaglini@arm.com DispatchEntry(std::string _name, ExecFn _exec) 47413996Sgiacomo.travaglini@arm.com : name(_name), exec(_exec) 47513996Sgiacomo.travaglini@arm.com {} 47613996Sgiacomo.travaglini@arm.com 47713996Sgiacomo.travaglini@arm.com std::string name; 47813996Sgiacomo.travaglini@arm.com ExecFn exec; 47913996Sgiacomo.travaglini@arm.com }; 48013996Sgiacomo.travaglini@arm.com 48113996Sgiacomo.travaglini@arm.com using DispatchTable = std::unordered_map< 48213996Sgiacomo.travaglini@arm.com std::underlying_type<enum CommandType>::type, DispatchEntry>; 48313996Sgiacomo.travaglini@arm.com 48413996Sgiacomo.travaglini@arm.com static DispatchTable cmdDispatcher; 48513996Sgiacomo.travaglini@arm.com 48613996Sgiacomo.travaglini@arm.com static std::string commandName(uint32_t cmd); 48713996Sgiacomo.travaglini@arm.com 48813996Sgiacomo.travaglini@arm.com void main(Yield &yield) override; 48913996Sgiacomo.travaglini@arm.com 49013996Sgiacomo.travaglini@arm.com void readCommand(Yield &yield, CommandEntry &command); 49113996Sgiacomo.travaglini@arm.com void processCommand(Yield &yield, CommandEntry &command); 49213996Sgiacomo.travaglini@arm.com 49313996Sgiacomo.travaglini@arm.com // Commands 49413996Sgiacomo.travaglini@arm.com void clear(Yield &yield, CommandEntry &command); 49513996Sgiacomo.travaglini@arm.com void discard(Yield &yield, CommandEntry &command); 49613996Sgiacomo.travaglini@arm.com void mapc(Yield &yield, CommandEntry &command); 49713996Sgiacomo.travaglini@arm.com void mapd(Yield &yield, CommandEntry &command); 49813996Sgiacomo.travaglini@arm.com void mapi(Yield &yield, CommandEntry &command); 49913996Sgiacomo.travaglini@arm.com void mapti(Yield &yield, CommandEntry &command); 50013996Sgiacomo.travaglini@arm.com void movall(Yield &yield, CommandEntry &command); 50113996Sgiacomo.travaglini@arm.com void movi(Yield &yield, CommandEntry &command); 50213996Sgiacomo.travaglini@arm.com void sync(Yield &yield, CommandEntry &command); 50313996Sgiacomo.travaglini@arm.com void doInt(Yield &yield, CommandEntry &command); 50413996Sgiacomo.travaglini@arm.com void inv(Yield &yield, CommandEntry &command); 50513996Sgiacomo.travaglini@arm.com void invall(Yield &yield, CommandEntry &command); 50613996Sgiacomo.travaglini@arm.com void vinvall(Yield &yield, CommandEntry &command); 50713996Sgiacomo.travaglini@arm.com void vmapi(Yield &yield, CommandEntry &command); 50813996Sgiacomo.travaglini@arm.com void vmapp(Yield &yield, CommandEntry &command); 50913996Sgiacomo.travaglini@arm.com void vmapti(Yield &yield, CommandEntry &command); 51013996Sgiacomo.travaglini@arm.com void vmovi(Yield &yield, CommandEntry &command); 51113996Sgiacomo.travaglini@arm.com void vmovp(Yield &yield, CommandEntry &command); 51213996Sgiacomo.travaglini@arm.com void vsync(Yield &yield, CommandEntry &command); 51313996Sgiacomo.travaglini@arm.com 51413996Sgiacomo.travaglini@arm.com protected: // Helpers 51513996Sgiacomo.travaglini@arm.com bool idOutOfRange(CommandEntry &command, DTE dte) const 51613996Sgiacomo.travaglini@arm.com { 51713996Sgiacomo.travaglini@arm.com return its.idOutOfRange(command.eventId, dte.ittRange); 51813996Sgiacomo.travaglini@arm.com } 51913996Sgiacomo.travaglini@arm.com 52013996Sgiacomo.travaglini@arm.com bool deviceOutOfRange(CommandEntry &command) const 52113996Sgiacomo.travaglini@arm.com { 52213996Sgiacomo.travaglini@arm.com return its.deviceOutOfRange(command.deviceId); 52313996Sgiacomo.travaglini@arm.com } 52413996Sgiacomo.travaglini@arm.com 52513996Sgiacomo.travaglini@arm.com bool sizeOutOfRange(CommandEntry &command) const 52613996Sgiacomo.travaglini@arm.com { 52713996Sgiacomo.travaglini@arm.com const auto size = bits(command.raw[1], 4, 0); 52813996Sgiacomo.travaglini@arm.com const auto valid = bits(command.raw[2], 63); 52913996Sgiacomo.travaglini@arm.com if (valid) 53013996Sgiacomo.travaglini@arm.com return its.sizeOutOfRange(size); 53113996Sgiacomo.travaglini@arm.com else 53213996Sgiacomo.travaglini@arm.com return false; 53313996Sgiacomo.travaglini@arm.com } 53413996Sgiacomo.travaglini@arm.com 53513996Sgiacomo.travaglini@arm.com bool collectionOutOfRange(CommandEntry &command) const 53613996Sgiacomo.travaglini@arm.com { 53713996Sgiacomo.travaglini@arm.com return its.collectionOutOfRange(bits(command.raw[2], 15, 0)); 53813996Sgiacomo.travaglini@arm.com } 53913996Sgiacomo.travaglini@arm.com}; 54013996Sgiacomo.travaglini@arm.com 54113996Sgiacomo.travaglini@arm.com#endif 542