gic_v3_its.hh revision 14187
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) 19913996Sgiacomo.travaglini@arm.com Bitfield<37> vmovp; 20013996Sgiacomo.travaglini@arm.com Bitfield<36> cil; 20113996Sgiacomo.travaglini@arm.com Bitfield<35, 32> cidBits; 20213996Sgiacomo.travaglini@arm.com Bitfield<31, 24> hcc; 20313996Sgiacomo.travaglini@arm.com Bitfield<19> pta; 20413996Sgiacomo.travaglini@arm.com Bitfield<18> seis; 20513996Sgiacomo.travaglini@arm.com Bitfield<17, 13> devBits; 20613996Sgiacomo.travaglini@arm.com Bitfield<12, 8> idBits; 20713996Sgiacomo.travaglini@arm.com Bitfield<7, 4> ittEntrySize; 20813996Sgiacomo.travaglini@arm.com Bitfield<2> cct; 20913996Sgiacomo.travaglini@arm.com Bitfield<1> _virtual; 21013996Sgiacomo.travaglini@arm.com Bitfield<0> physical; 21113996Sgiacomo.travaglini@arm.com EndBitUnion(TYPER) 21213996Sgiacomo.travaglini@arm.com 21313996Sgiacomo.travaglini@arm.com CTLR gitsControl; 21413996Sgiacomo.travaglini@arm.com TYPER gitsTyper; 21513996Sgiacomo.travaglini@arm.com CBASER gitsCbaser; 21613996Sgiacomo.travaglini@arm.com CRDWR gitsCreadr; 21713996Sgiacomo.travaglini@arm.com CRDWR gitsCwriter; 21813996Sgiacomo.travaglini@arm.com uint32_t gitsIidr; 21913996Sgiacomo.travaglini@arm.com uint32_t gitsTranslater; 22013996Sgiacomo.travaglini@arm.com 22113996Sgiacomo.travaglini@arm.com std::vector<BASER> tableBases; 22213996Sgiacomo.travaglini@arm.com 22313996Sgiacomo.travaglini@arm.com /** 22413996Sgiacomo.travaglini@arm.com * Returns TRUE if the eventID supplied has bits above the implemented 22513996Sgiacomo.travaglini@arm.com * size or above the itt_range 22613996Sgiacomo.travaglini@arm.com */ 22713996Sgiacomo.travaglini@arm.com bool idOutOfRange(uint32_t event_id, uint8_t itt_range) const; 22813996Sgiacomo.travaglini@arm.com 22913996Sgiacomo.travaglini@arm.com /** 23013996Sgiacomo.travaglini@arm.com * Returns TRUE if the value supplied has bits above the implemented range 23113996Sgiacomo.travaglini@arm.com * or if the value supplied exceeds the maximum configured size in the 23213996Sgiacomo.travaglini@arm.com * appropriate GITS_BASER<n> 23313996Sgiacomo.travaglini@arm.com */ 23413996Sgiacomo.travaglini@arm.com bool deviceOutOfRange(uint32_t device_id) const; 23513996Sgiacomo.travaglini@arm.com 23613996Sgiacomo.travaglini@arm.com /** 23713996Sgiacomo.travaglini@arm.com * Returns TRUE if the value (size) supplied exceeds the maximum 23813996Sgiacomo.travaglini@arm.com * allowed by GITS_TYPER.ID_bits. Size is the parameter which is 23913996Sgiacomo.travaglini@arm.com * passed to the ITS via the MAPD command and is stored in the 24013996Sgiacomo.travaglini@arm.com * DTE.ittRange field. 24113996Sgiacomo.travaglini@arm.com */ 24213996Sgiacomo.travaglini@arm.com bool sizeOutOfRange(uint32_t size) const; 24313996Sgiacomo.travaglini@arm.com 24413996Sgiacomo.travaglini@arm.com /** 24513996Sgiacomo.travaglini@arm.com * Returns TRUE if the value supplied has bits above the implemented range 24613996Sgiacomo.travaglini@arm.com * or if the value exceeds the total number of collections supported in 24713996Sgiacomo.travaglini@arm.com * hardware and external memory 24813996Sgiacomo.travaglini@arm.com */ 24913996Sgiacomo.travaglini@arm.com bool collectionOutOfRange(uint32_t collection_id) const; 25013996Sgiacomo.travaglini@arm.com 25113996Sgiacomo.travaglini@arm.com /** 25213996Sgiacomo.travaglini@arm.com * Returns TRUE if the value supplied is larger than that permitted by 25313996Sgiacomo.travaglini@arm.com * GICD_TYPER.IDbits or not in the LPI range and is not 1023 25413996Sgiacomo.travaglini@arm.com */ 25513996Sgiacomo.travaglini@arm.com bool lpiOutOfRange(uint32_t intid) const; 25613996Sgiacomo.travaglini@arm.com 25713996Sgiacomo.travaglini@arm.com private: // Command 25813996Sgiacomo.travaglini@arm.com void checkCommandQueue(); 25913996Sgiacomo.travaglini@arm.com void incrementReadPointer(); 26013996Sgiacomo.travaglini@arm.com 26113996Sgiacomo.travaglini@arm.com public: // TableWalk 26213996Sgiacomo.travaglini@arm.com BitUnion64(DTE) 26313996Sgiacomo.travaglini@arm.com Bitfield<57, 53> ittRange; 26413996Sgiacomo.travaglini@arm.com Bitfield<52, 1> ittAddress; 26513996Sgiacomo.travaglini@arm.com Bitfield<0> valid; 26613996Sgiacomo.travaglini@arm.com EndBitUnion(DTE) 26713996Sgiacomo.travaglini@arm.com 26813996Sgiacomo.travaglini@arm.com BitUnion64(ITTE) 26913996Sgiacomo.travaglini@arm.com Bitfield<59, 46> vpeid; 27013996Sgiacomo.travaglini@arm.com Bitfield<45, 30> icid; 27113996Sgiacomo.travaglini@arm.com Bitfield<29, 16> intNumHyp; 27213996Sgiacomo.travaglini@arm.com Bitfield<15, 2> intNum; 27313996Sgiacomo.travaglini@arm.com Bitfield<1> intType; 27413996Sgiacomo.travaglini@arm.com Bitfield<0> valid; 27513996Sgiacomo.travaglini@arm.com EndBitUnion(ITTE) 27613996Sgiacomo.travaglini@arm.com 27713996Sgiacomo.travaglini@arm.com BitUnion64(CTE) 27813996Sgiacomo.travaglini@arm.com Bitfield<40, 1> rdBase; 27913996Sgiacomo.travaglini@arm.com Bitfield<0> valid; 28013996Sgiacomo.travaglini@arm.com EndBitUnion(CTE) 28113996Sgiacomo.travaglini@arm.com 28213996Sgiacomo.travaglini@arm.com enum InterruptType 28313996Sgiacomo.travaglini@arm.com { 28413996Sgiacomo.travaglini@arm.com VIRTUAL_INTERRUPT = 0, 28513996Sgiacomo.travaglini@arm.com PHYSICAL_INTERRUPT = 1 28613996Sgiacomo.travaglini@arm.com }; 28713996Sgiacomo.travaglini@arm.com 28813996Sgiacomo.travaglini@arm.com private: 28913996Sgiacomo.travaglini@arm.com Gicv3Redistributor* getRedistributor(uint64_t rd_base); 29013996Sgiacomo.travaglini@arm.com Gicv3Redistributor* getRedistributor(CTE cte) 29113996Sgiacomo.travaglini@arm.com { 29213996Sgiacomo.travaglini@arm.com return getRedistributor(cte.rdBase); 29313996Sgiacomo.travaglini@arm.com } 29413996Sgiacomo.travaglini@arm.com 29513996Sgiacomo.travaglini@arm.com ItsAction runProcess(ItsProcess *proc, PacketPtr pkt); 29613996Sgiacomo.travaglini@arm.com ItsAction runProcessTiming(ItsProcess *proc, PacketPtr pkt); 29713996Sgiacomo.travaglini@arm.com ItsAction runProcessAtomic(ItsProcess *proc, PacketPtr pkt); 29813996Sgiacomo.travaglini@arm.com 29913996Sgiacomo.travaglini@arm.com enum ItsTables 30013996Sgiacomo.travaglini@arm.com { 30113996Sgiacomo.travaglini@arm.com DEVICE_TABLE = 1, 30213996Sgiacomo.travaglini@arm.com VPE_TABLE = 2, 30313996Sgiacomo.travaglini@arm.com TRANSLATION_TABLE = 3, 30413996Sgiacomo.travaglini@arm.com COLLECTION_TABLE = 4 30513996Sgiacomo.travaglini@arm.com }; 30613996Sgiacomo.travaglini@arm.com 30713996Sgiacomo.travaglini@arm.com enum PageSize 30813996Sgiacomo.travaglini@arm.com { 30913996Sgiacomo.travaglini@arm.com SIZE_4K, 31013996Sgiacomo.travaglini@arm.com SIZE_16K, 31113996Sgiacomo.travaglini@arm.com SIZE_64K 31213996Sgiacomo.travaglini@arm.com }; 31313996Sgiacomo.travaglini@arm.com 31413996Sgiacomo.travaglini@arm.com Addr pageAddress(enum ItsTables table); 31513996Sgiacomo.travaglini@arm.com 31613996Sgiacomo.travaglini@arm.com void moveAllPendingState( 31713996Sgiacomo.travaglini@arm.com Gicv3Redistributor *rd1, Gicv3Redistributor *rd2); 31813996Sgiacomo.travaglini@arm.com 31913996Sgiacomo.travaglini@arm.com private: 32013996Sgiacomo.travaglini@arm.com std::queue<ItsAction> packetsToRetry; 32113996Sgiacomo.travaglini@arm.com uint32_t masterId; 32213996Sgiacomo.travaglini@arm.com Gicv3 *gic; 32313996Sgiacomo.travaglini@arm.com EventFunctionWrapper commandEvent; 32413996Sgiacomo.travaglini@arm.com 32513996Sgiacomo.travaglini@arm.com bool pendingCommands; 32613996Sgiacomo.travaglini@arm.com uint32_t pendingTranslations; 32713996Sgiacomo.travaglini@arm.com}; 32813996Sgiacomo.travaglini@arm.com 32913996Sgiacomo.travaglini@arm.com/** 33013996Sgiacomo.travaglini@arm.com * ItsProcess is a base coroutine wrapper which is spawned by 33113996Sgiacomo.travaglini@arm.com * the Gicv3Its module when the latter needs to perform different 33213996Sgiacomo.travaglini@arm.com * actions, like translating a peripheral's MSI into an LPI 33313996Sgiacomo.travaglini@arm.com * (See derived ItsTranslation) or processing a Command from the 33413996Sgiacomo.travaglini@arm.com * ITS queue (ItsCommand). 33513996Sgiacomo.travaglini@arm.com * The action to take is implemented by the method: 33613996Sgiacomo.travaglini@arm.com * 33713996Sgiacomo.travaglini@arm.com * virtual void main(Yield &yield) = 0; 33813996Sgiacomo.travaglini@arm.com * It's inheriting from Packet::SenderState since the generic process 33913996Sgiacomo.travaglini@arm.com * will be stopped (we are using coroutines) and sent with the packet 34013996Sgiacomo.travaglini@arm.com * to memory when doing table walks. 34113996Sgiacomo.travaglini@arm.com * When Gicv3Its receives a response, it will resume the coroutine from 34213996Sgiacomo.travaglini@arm.com * the point it stopped when yielding. 34313996Sgiacomo.travaglini@arm.com */ 34413996Sgiacomo.travaglini@arm.comclass ItsProcess : public Packet::SenderState 34513996Sgiacomo.travaglini@arm.com{ 34613996Sgiacomo.travaglini@arm.com public: 34713996Sgiacomo.travaglini@arm.com using DTE = Gicv3Its::DTE; 34813996Sgiacomo.travaglini@arm.com using ITTE = Gicv3Its::ITTE; 34913996Sgiacomo.travaglini@arm.com using CTE = Gicv3Its::CTE; 35013996Sgiacomo.travaglini@arm.com using Coroutine = m5::Coroutine<PacketPtr, ItsAction>; 35113996Sgiacomo.travaglini@arm.com using Yield = Coroutine::CallerType; 35213996Sgiacomo.travaglini@arm.com 35313996Sgiacomo.travaglini@arm.com ItsProcess(Gicv3Its &_its); 35413996Sgiacomo.travaglini@arm.com virtual ~ItsProcess(); 35513996Sgiacomo.travaglini@arm.com 35613996Sgiacomo.travaglini@arm.com /** Returns the Gicv3Its name. Mainly used for DPRINTS */ 35713996Sgiacomo.travaglini@arm.com const std::string name() const; 35813996Sgiacomo.travaglini@arm.com 35913996Sgiacomo.travaglini@arm.com ItsAction run(PacketPtr pkt); 36013996Sgiacomo.travaglini@arm.com 36113996Sgiacomo.travaglini@arm.com protected: 36213996Sgiacomo.travaglini@arm.com void reinit(); 36313996Sgiacomo.travaglini@arm.com virtual void main(Yield &yield) = 0; 36413996Sgiacomo.travaglini@arm.com 36513996Sgiacomo.travaglini@arm.com void writeDeviceTable(Yield &yield, uint32_t device_id, DTE dte); 36613996Sgiacomo.travaglini@arm.com 36713996Sgiacomo.travaglini@arm.com void writeIrqTranslationTable( 36813996Sgiacomo.travaglini@arm.com Yield &yield, const Addr itt_base, uint32_t event_id, ITTE itte); 36913996Sgiacomo.travaglini@arm.com 37013996Sgiacomo.travaglini@arm.com void writeIrqCollectionTable( 37113996Sgiacomo.travaglini@arm.com Yield &yield, uint32_t collection_id, CTE cte); 37213996Sgiacomo.travaglini@arm.com 37313996Sgiacomo.travaglini@arm.com uint64_t readDeviceTable( 37413996Sgiacomo.travaglini@arm.com Yield &yield, uint32_t device_id); 37513996Sgiacomo.travaglini@arm.com 37613996Sgiacomo.travaglini@arm.com uint64_t readIrqTranslationTable( 37713996Sgiacomo.travaglini@arm.com Yield &yield, const Addr itt_base, uint32_t event_id); 37813996Sgiacomo.travaglini@arm.com 37913996Sgiacomo.travaglini@arm.com uint64_t readIrqCollectionTable(Yield &yield, uint32_t collection_id); 38013996Sgiacomo.travaglini@arm.com 38113996Sgiacomo.travaglini@arm.com void doRead(Yield &yield, Addr addr, void *ptr, size_t size); 38213996Sgiacomo.travaglini@arm.com void doWrite(Yield &yield, Addr addr, void *ptr, size_t size); 38313996Sgiacomo.travaglini@arm.com void terminate(Yield &yield); 38413996Sgiacomo.travaglini@arm.com 38513996Sgiacomo.travaglini@arm.com protected: 38613996Sgiacomo.travaglini@arm.com Gicv3Its &its; 38713996Sgiacomo.travaglini@arm.com 38813996Sgiacomo.travaglini@arm.com private: 38913996Sgiacomo.travaglini@arm.com std::unique_ptr<Coroutine> coroutine; 39013996Sgiacomo.travaglini@arm.com}; 39113996Sgiacomo.travaglini@arm.com 39213996Sgiacomo.travaglini@arm.com/** 39313996Sgiacomo.travaglini@arm.com * An ItsTranslation is created whenever a peripheral writes a message in 39413996Sgiacomo.travaglini@arm.com * GITS_TRANSLATER (MSI). In this case main will simply do the table walks 39513996Sgiacomo.travaglini@arm.com * until it gets a redistributor and an INTID. It will then raise the 39613996Sgiacomo.travaglini@arm.com * LPI interrupt to the target redistributor. 39713996Sgiacomo.travaglini@arm.com */ 39813996Sgiacomo.travaglini@arm.comclass ItsTranslation : public ItsProcess 39913996Sgiacomo.travaglini@arm.com{ 40013996Sgiacomo.travaglini@arm.com public: 40113996Sgiacomo.travaglini@arm.com ItsTranslation(Gicv3Its &_its); 40213996Sgiacomo.travaglini@arm.com ~ItsTranslation(); 40313996Sgiacomo.travaglini@arm.com 40413996Sgiacomo.travaglini@arm.com protected: 40513996Sgiacomo.travaglini@arm.com void main(Yield &yield) override; 40613996Sgiacomo.travaglini@arm.com 40713996Sgiacomo.travaglini@arm.com std::pair<uint32_t, Gicv3Redistributor *> 40813996Sgiacomo.travaglini@arm.com translateLPI(Yield &yield, uint32_t device_id, uint32_t event_id); 40913996Sgiacomo.travaglini@arm.com}; 41013996Sgiacomo.travaglini@arm.com 41113996Sgiacomo.travaglini@arm.com/** 41213996Sgiacomo.travaglini@arm.com * An ItsCommand is created whenever there is a new command in the command 41313996Sgiacomo.travaglini@arm.com * queue. Only one command can be executed per time. 41413996Sgiacomo.travaglini@arm.com * main will firstly read the command from memory and then it will process 41513996Sgiacomo.travaglini@arm.com * it. 41613996Sgiacomo.travaglini@arm.com */ 41713996Sgiacomo.travaglini@arm.comclass ItsCommand : public ItsProcess 41813996Sgiacomo.travaglini@arm.com{ 41913996Sgiacomo.travaglini@arm.com public: 42013996Sgiacomo.travaglini@arm.com union CommandEntry 42113996Sgiacomo.travaglini@arm.com { 42213996Sgiacomo.travaglini@arm.com struct 42313996Sgiacomo.travaglini@arm.com { 42413996Sgiacomo.travaglini@arm.com uint32_t type; 42513996Sgiacomo.travaglini@arm.com uint32_t deviceId; 42613996Sgiacomo.travaglini@arm.com uint32_t eventId; 42713996Sgiacomo.travaglini@arm.com uint32_t pintId; 42813996Sgiacomo.travaglini@arm.com 42913996Sgiacomo.travaglini@arm.com uint32_t data[4]; 43013996Sgiacomo.travaglini@arm.com }; 43113996Sgiacomo.travaglini@arm.com uint64_t raw[4]; 43213996Sgiacomo.travaglini@arm.com }; 43313996Sgiacomo.travaglini@arm.com 43413996Sgiacomo.travaglini@arm.com enum CommandType : uint32_t 43513996Sgiacomo.travaglini@arm.com { 43613996Sgiacomo.travaglini@arm.com CLEAR = 0x04, 43713996Sgiacomo.travaglini@arm.com DISCARD = 0x0F, 43813996Sgiacomo.travaglini@arm.com INT = 0x03, 43913996Sgiacomo.travaglini@arm.com INV = 0x0C, 44013996Sgiacomo.travaglini@arm.com INVALL = 0x0D, 44113996Sgiacomo.travaglini@arm.com MAPC = 0x09, 44213996Sgiacomo.travaglini@arm.com MAPD = 0x08, 44313996Sgiacomo.travaglini@arm.com MAPI = 0x0B, 44413996Sgiacomo.travaglini@arm.com MAPTI = 0x0A, 44513996Sgiacomo.travaglini@arm.com MOVALL = 0x0E, 44613996Sgiacomo.travaglini@arm.com MOVI = 0x01, 44713996Sgiacomo.travaglini@arm.com SYNC = 0x05, 44813996Sgiacomo.travaglini@arm.com VINVALL = 0x2D, 44913996Sgiacomo.travaglini@arm.com VMAPI = 0x2B, 45013996Sgiacomo.travaglini@arm.com VMAPP = 0x29, 45113996Sgiacomo.travaglini@arm.com VMAPTI = 0x2A, 45213996Sgiacomo.travaglini@arm.com VMOVI = 0x21, 45313996Sgiacomo.travaglini@arm.com VMOVP = 0x22, 45413996Sgiacomo.travaglini@arm.com VSYNC = 0x25 45513996Sgiacomo.travaglini@arm.com }; 45613996Sgiacomo.travaglini@arm.com 45713996Sgiacomo.travaglini@arm.com ItsCommand(Gicv3Its &_its); 45813996Sgiacomo.travaglini@arm.com ~ItsCommand(); 45913996Sgiacomo.travaglini@arm.com 46013996Sgiacomo.travaglini@arm.com protected: 46113996Sgiacomo.travaglini@arm.com /** 46213996Sgiacomo.travaglini@arm.com * Dispatch entry is a metadata struct which contains information about 46313996Sgiacomo.travaglini@arm.com * the command (like the name) and the function object implementing 46413996Sgiacomo.travaglini@arm.com * the command. 46513996Sgiacomo.travaglini@arm.com */ 46613996Sgiacomo.travaglini@arm.com struct DispatchEntry 46713996Sgiacomo.travaglini@arm.com { 46813996Sgiacomo.travaglini@arm.com using ExecFn = std::function<void(ItsCommand*, Yield&, CommandEntry&)>; 46913996Sgiacomo.travaglini@arm.com 47013996Sgiacomo.travaglini@arm.com DispatchEntry(std::string _name, ExecFn _exec) 47113996Sgiacomo.travaglini@arm.com : name(_name), exec(_exec) 47213996Sgiacomo.travaglini@arm.com {} 47313996Sgiacomo.travaglini@arm.com 47413996Sgiacomo.travaglini@arm.com std::string name; 47513996Sgiacomo.travaglini@arm.com ExecFn exec; 47613996Sgiacomo.travaglini@arm.com }; 47713996Sgiacomo.travaglini@arm.com 47813996Sgiacomo.travaglini@arm.com using DispatchTable = std::unordered_map< 47913996Sgiacomo.travaglini@arm.com std::underlying_type<enum CommandType>::type, DispatchEntry>; 48013996Sgiacomo.travaglini@arm.com 48113996Sgiacomo.travaglini@arm.com static DispatchTable cmdDispatcher; 48213996Sgiacomo.travaglini@arm.com 48313996Sgiacomo.travaglini@arm.com static std::string commandName(uint32_t cmd); 48413996Sgiacomo.travaglini@arm.com 48513996Sgiacomo.travaglini@arm.com void main(Yield &yield) override; 48613996Sgiacomo.travaglini@arm.com 48713996Sgiacomo.travaglini@arm.com void readCommand(Yield &yield, CommandEntry &command); 48813996Sgiacomo.travaglini@arm.com void processCommand(Yield &yield, CommandEntry &command); 48913996Sgiacomo.travaglini@arm.com 49013996Sgiacomo.travaglini@arm.com // Commands 49113996Sgiacomo.travaglini@arm.com void clear(Yield &yield, CommandEntry &command); 49213996Sgiacomo.travaglini@arm.com void discard(Yield &yield, CommandEntry &command); 49313996Sgiacomo.travaglini@arm.com void mapc(Yield &yield, CommandEntry &command); 49413996Sgiacomo.travaglini@arm.com void mapd(Yield &yield, CommandEntry &command); 49513996Sgiacomo.travaglini@arm.com void mapi(Yield &yield, CommandEntry &command); 49613996Sgiacomo.travaglini@arm.com void mapti(Yield &yield, CommandEntry &command); 49713996Sgiacomo.travaglini@arm.com void movall(Yield &yield, CommandEntry &command); 49813996Sgiacomo.travaglini@arm.com void movi(Yield &yield, CommandEntry &command); 49913996Sgiacomo.travaglini@arm.com void sync(Yield &yield, CommandEntry &command); 50013996Sgiacomo.travaglini@arm.com void doInt(Yield &yield, CommandEntry &command); 50113996Sgiacomo.travaglini@arm.com void inv(Yield &yield, CommandEntry &command); 50213996Sgiacomo.travaglini@arm.com void invall(Yield &yield, CommandEntry &command); 50313996Sgiacomo.travaglini@arm.com void vinvall(Yield &yield, CommandEntry &command); 50413996Sgiacomo.travaglini@arm.com void vmapi(Yield &yield, CommandEntry &command); 50513996Sgiacomo.travaglini@arm.com void vmapp(Yield &yield, CommandEntry &command); 50613996Sgiacomo.travaglini@arm.com void vmapti(Yield &yield, CommandEntry &command); 50713996Sgiacomo.travaglini@arm.com void vmovi(Yield &yield, CommandEntry &command); 50813996Sgiacomo.travaglini@arm.com void vmovp(Yield &yield, CommandEntry &command); 50913996Sgiacomo.travaglini@arm.com void vsync(Yield &yield, CommandEntry &command); 51013996Sgiacomo.travaglini@arm.com 51113996Sgiacomo.travaglini@arm.com protected: // Helpers 51213996Sgiacomo.travaglini@arm.com bool idOutOfRange(CommandEntry &command, DTE dte) const 51313996Sgiacomo.travaglini@arm.com { 51413996Sgiacomo.travaglini@arm.com return its.idOutOfRange(command.eventId, dte.ittRange); 51513996Sgiacomo.travaglini@arm.com } 51613996Sgiacomo.travaglini@arm.com 51713996Sgiacomo.travaglini@arm.com bool deviceOutOfRange(CommandEntry &command) const 51813996Sgiacomo.travaglini@arm.com { 51913996Sgiacomo.travaglini@arm.com return its.deviceOutOfRange(command.deviceId); 52013996Sgiacomo.travaglini@arm.com } 52113996Sgiacomo.travaglini@arm.com 52213996Sgiacomo.travaglini@arm.com bool sizeOutOfRange(CommandEntry &command) const 52313996Sgiacomo.travaglini@arm.com { 52413996Sgiacomo.travaglini@arm.com const auto size = bits(command.raw[1], 4, 0); 52513996Sgiacomo.travaglini@arm.com const auto valid = bits(command.raw[2], 63); 52613996Sgiacomo.travaglini@arm.com if (valid) 52713996Sgiacomo.travaglini@arm.com return its.sizeOutOfRange(size); 52813996Sgiacomo.travaglini@arm.com else 52913996Sgiacomo.travaglini@arm.com return false; 53013996Sgiacomo.travaglini@arm.com } 53113996Sgiacomo.travaglini@arm.com 53213996Sgiacomo.travaglini@arm.com bool collectionOutOfRange(CommandEntry &command) const 53313996Sgiacomo.travaglini@arm.com { 53413996Sgiacomo.travaglini@arm.com return its.collectionOutOfRange(bits(command.raw[2], 15, 0)); 53513996Sgiacomo.travaglini@arm.com } 53613996Sgiacomo.travaglini@arm.com}; 53713996Sgiacomo.travaglini@arm.com 53813996Sgiacomo.travaglini@arm.com#endif 539