113531Sjairo.balart@metempsy.com/* 214258Sgiacomo.travaglini@arm.com * Copyright (c) 2019 ARM Limited 314258Sgiacomo.travaglini@arm.com * All rights reserved 414258Sgiacomo.travaglini@arm.com * 514258Sgiacomo.travaglini@arm.com * The license below extends only to copyright in the software and shall 614258Sgiacomo.travaglini@arm.com * not be construed as granting a license to any other intellectual 714258Sgiacomo.travaglini@arm.com * property including but not limited to intellectual property relating 814258Sgiacomo.travaglini@arm.com * to a hardware implementation of the functionality of the software 914258Sgiacomo.travaglini@arm.com * licensed hereunder. You may use the software subject to the license 1014258Sgiacomo.travaglini@arm.com * terms below provided that you ensure that this notice is replicated 1114258Sgiacomo.travaglini@arm.com * unmodified and in its entirety in all distributions of the software, 1214258Sgiacomo.travaglini@arm.com * modified or unmodified, in source code or in binary form. 1314258Sgiacomo.travaglini@arm.com * 1413531Sjairo.balart@metempsy.com * Copyright (c) 2018 Metempsy Technology Consulting 1513531Sjairo.balart@metempsy.com * All rights reserved. 1613531Sjairo.balart@metempsy.com * 1713531Sjairo.balart@metempsy.com * Redistribution and use in source and binary forms, with or without 1813531Sjairo.balart@metempsy.com * modification, are permitted provided that the following conditions are 1913531Sjairo.balart@metempsy.com * met: redistributions of source code must retain the above copyright 2013531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer; 2113531Sjairo.balart@metempsy.com * redistributions in binary form must reproduce the above copyright 2213531Sjairo.balart@metempsy.com * notice, this list of conditions and the following disclaimer in the 2313531Sjairo.balart@metempsy.com * documentation and/or other materials provided with the distribution; 2413531Sjairo.balart@metempsy.com * neither the name of the copyright holders nor the names of its 2513531Sjairo.balart@metempsy.com * contributors may be used to endorse or promote products derived from 2613531Sjairo.balart@metempsy.com * this software without specific prior written permission. 2713531Sjairo.balart@metempsy.com * 2813531Sjairo.balart@metempsy.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 2913531Sjairo.balart@metempsy.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3013531Sjairo.balart@metempsy.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3113531Sjairo.balart@metempsy.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3213531Sjairo.balart@metempsy.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3313531Sjairo.balart@metempsy.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3413531Sjairo.balart@metempsy.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3513531Sjairo.balart@metempsy.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3613531Sjairo.balart@metempsy.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3713531Sjairo.balart@metempsy.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3813531Sjairo.balart@metempsy.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 3913531Sjairo.balart@metempsy.com * 4013531Sjairo.balart@metempsy.com * Authors: Jairo Balart 4113531Sjairo.balart@metempsy.com */ 4213531Sjairo.balart@metempsy.com 4313531Sjairo.balart@metempsy.com#ifndef __DEV_ARM_GICV3_REDISTRIBUTOR_H__ 4413531Sjairo.balart@metempsy.com#define __DEV_ARM_GICV3_REDISTRIBUTOR_H__ 4513531Sjairo.balart@metempsy.com 4613531Sjairo.balart@metempsy.com#include "base/addr_range.hh" 4713531Sjairo.balart@metempsy.com#include "dev/arm/gic_v3.hh" 4813531Sjairo.balart@metempsy.com#include "sim/serialize.hh" 4913531Sjairo.balart@metempsy.com 5013756Sjairo.balart@metempsy.comclass Gicv3CPUInterface; 5113531Sjairo.balart@metempsy.comclass Gicv3Distributor; 5213996Sgiacomo.travaglini@arm.comclass Gicv3Its; 5313531Sjairo.balart@metempsy.com 5413531Sjairo.balart@metempsy.comclass Gicv3Redistributor : public Serializable 5513531Sjairo.balart@metempsy.com{ 5613531Sjairo.balart@metempsy.com private: 5713531Sjairo.balart@metempsy.com 5813531Sjairo.balart@metempsy.com friend class Gicv3CPUInterface; 5913531Sjairo.balart@metempsy.com friend class Gicv3Distributor; 6013996Sgiacomo.travaglini@arm.com friend class Gicv3Its; 6113531Sjairo.balart@metempsy.com 6213531Sjairo.balart@metempsy.com protected: 6313531Sjairo.balart@metempsy.com 6413531Sjairo.balart@metempsy.com Gicv3 * gic; 6513531Sjairo.balart@metempsy.com Gicv3Distributor * distributor; 6613531Sjairo.balart@metempsy.com Gicv3CPUInterface * cpuInterface; 6713531Sjairo.balart@metempsy.com uint32_t cpuId; 6813928Sgiacomo.travaglini@arm.com PortProxy * memProxy; 6913531Sjairo.balart@metempsy.com 7013531Sjairo.balart@metempsy.com /* 7113531Sjairo.balart@metempsy.com * GICv3 defines 2 contiguous 64KB frames for each redistributor. 7213531Sjairo.balart@metempsy.com * Order of frames must be RD_base, SGI_base. 7313531Sjairo.balart@metempsy.com */ 7413756Sjairo.balart@metempsy.com static const uint32_t RD_base = 0x0; 7513531Sjairo.balart@metempsy.com static const uint32_t SGI_base = 0x10000; 7613531Sjairo.balart@metempsy.com 7713531Sjairo.balart@metempsy.com enum { 7813531Sjairo.balart@metempsy.com // Control Register 7913531Sjairo.balart@metempsy.com GICR_CTLR = RD_base + 0x0000, 8013531Sjairo.balart@metempsy.com // Implementer Identification Register 8113756Sjairo.balart@metempsy.com GICR_IIDR = RD_base + 0x0004, 8213531Sjairo.balart@metempsy.com // Type Register 8313531Sjairo.balart@metempsy.com GICR_TYPER = RD_base + 0x0008, 8413531Sjairo.balart@metempsy.com // Wake Register 8513531Sjairo.balart@metempsy.com GICR_WAKER = RD_base + 0x0014, 8613531Sjairo.balart@metempsy.com // Peripheral ID0 Register 8713531Sjairo.balart@metempsy.com GICR_PIDR0 = RD_base + 0xffe0, 8813531Sjairo.balart@metempsy.com // Peripheral ID1 Register 8913531Sjairo.balart@metempsy.com GICR_PIDR1 = RD_base + 0xffe4, 9013531Sjairo.balart@metempsy.com // Peripheral ID2 Register 9113531Sjairo.balart@metempsy.com GICR_PIDR2 = RD_base + 0xffe8, 9213531Sjairo.balart@metempsy.com // Peripheral ID3 Register 9313531Sjairo.balart@metempsy.com GICR_PIDR3 = RD_base + 0xffec, 9413531Sjairo.balart@metempsy.com // Peripheral ID4 Register 9513531Sjairo.balart@metempsy.com GICR_PIDR4 = RD_base + 0xffd0, 9613531Sjairo.balart@metempsy.com // Peripheral ID5 Register 9713531Sjairo.balart@metempsy.com GICR_PIDR5 = RD_base + 0xffd4, 9813531Sjairo.balart@metempsy.com // Peripheral ID6 Register 9913531Sjairo.balart@metempsy.com GICR_PIDR6 = RD_base + 0xffd8, 10013531Sjairo.balart@metempsy.com // Peripheral ID7 Register 10113531Sjairo.balart@metempsy.com GICR_PIDR7 = RD_base + 0xffdc, 10213531Sjairo.balart@metempsy.com }; 10313531Sjairo.balart@metempsy.com 10413531Sjairo.balart@metempsy.com static const uint32_t GICR_WAKER_ProcessorSleep = 1 << 1; 10513531Sjairo.balart@metempsy.com static const uint32_t GICR_WAKER_ChildrenAsleep = 1 << 2; 10613531Sjairo.balart@metempsy.com 10713531Sjairo.balart@metempsy.com bool peInLowPowerState; 10813531Sjairo.balart@metempsy.com 10913531Sjairo.balart@metempsy.com enum { 11013531Sjairo.balart@metempsy.com // Interrupt Group Register 0 11113531Sjairo.balart@metempsy.com GICR_IGROUPR0 = SGI_base + 0x0080, 11213531Sjairo.balart@metempsy.com // Interrupt Set-Enable Register 0 11313531Sjairo.balart@metempsy.com GICR_ISENABLER0 = SGI_base + 0x0100, 11413531Sjairo.balart@metempsy.com // Interrupt Clear-Enable Register 0 11513531Sjairo.balart@metempsy.com GICR_ICENABLER0 = SGI_base + 0x0180, 11613531Sjairo.balart@metempsy.com // Interrupt Set-Pending Register 0 11713756Sjairo.balart@metempsy.com GICR_ISPENDR0 = SGI_base + 0x0200, 11813531Sjairo.balart@metempsy.com // Interrupt Clear-Pending Register 0 11913756Sjairo.balart@metempsy.com GICR_ICPENDR0 = SGI_base + 0x0280, 12013531Sjairo.balart@metempsy.com // Interrupt Set-Active Register 0 12113531Sjairo.balart@metempsy.com GICR_ISACTIVER0 = SGI_base + 0x0300, 12213531Sjairo.balart@metempsy.com // Interrupt Clear-Active Register 0 12313531Sjairo.balart@metempsy.com GICR_ICACTIVER0 = SGI_base + 0x0380, 12413531Sjairo.balart@metempsy.com // SGI Configuration Register 12513756Sjairo.balart@metempsy.com GICR_ICFGR0 = SGI_base + 0x0c00, 12613531Sjairo.balart@metempsy.com // PPI Configuration Register 12713756Sjairo.balart@metempsy.com GICR_ICFGR1 = SGI_base + 0x0c04, 12813531Sjairo.balart@metempsy.com // Interrupt Group Modifier Register 0 12913756Sjairo.balart@metempsy.com GICR_IGRPMODR0 = SGI_base + 0x0d00, 13013531Sjairo.balart@metempsy.com // Non-secure Access Control Register 13113756Sjairo.balart@metempsy.com GICR_NSACR = SGI_base + 0x0e00, 13213531Sjairo.balart@metempsy.com }; 13313531Sjairo.balart@metempsy.com 13413531Sjairo.balart@metempsy.com // Interrupt Priority Registers 13513531Sjairo.balart@metempsy.com static const AddrRange GICR_IPRIORITYR; 13613531Sjairo.balart@metempsy.com 13713690Sjairo.balart@metempsy.com // GIC physical LPI Redistributor register 13813690Sjairo.balart@metempsy.com enum { 13913690Sjairo.balart@metempsy.com // Set LPI Pending Register 14013690Sjairo.balart@metempsy.com GICR_SETLPIR = RD_base + 0x0040, 14113690Sjairo.balart@metempsy.com // Clear LPI Pending Register 14213690Sjairo.balart@metempsy.com GICR_CLRLPIR = RD_base + 0x0048, 14313690Sjairo.balart@metempsy.com //Redistributor Properties Base Address Register 14413690Sjairo.balart@metempsy.com GICR_PROPBASER = RD_base + 0x0070, 14513690Sjairo.balart@metempsy.com // Redistributor LPI Pending Table Base Address Register 14613690Sjairo.balart@metempsy.com GICR_PENDBASER = RD_base + 0x0078, 14713690Sjairo.balart@metempsy.com // Redistributor Invalidate LPI Register 14813690Sjairo.balart@metempsy.com GICR_INVLPIR = RD_base + 0x00A0, 14913690Sjairo.balart@metempsy.com // Redistributor Invalidate All Register 15013690Sjairo.balart@metempsy.com GICR_INVALLR = RD_base + 0x00B0, 15113690Sjairo.balart@metempsy.com // Redistributor Synchronize Register 15213690Sjairo.balart@metempsy.com GICR_SYNCR = RD_base + 0x00C0, 15313690Sjairo.balart@metempsy.com }; 15413690Sjairo.balart@metempsy.com 15513531Sjairo.balart@metempsy.com std::vector <uint8_t> irqGroup; 15613531Sjairo.balart@metempsy.com std::vector <bool> irqEnabled; 15713531Sjairo.balart@metempsy.com std::vector <bool> irqPending; 15813531Sjairo.balart@metempsy.com std::vector <bool> irqActive; 15913531Sjairo.balart@metempsy.com std::vector <uint8_t> irqPriority; 16013531Sjairo.balart@metempsy.com std::vector <Gicv3::IntTriggerType> irqConfig; 16113531Sjairo.balart@metempsy.com std::vector <uint8_t> irqGrpmod; 16213531Sjairo.balart@metempsy.com std::vector <uint8_t> irqNsacr; 16313531Sjairo.balart@metempsy.com 16413531Sjairo.balart@metempsy.com bool DPG1S; 16513531Sjairo.balart@metempsy.com bool DPG1NS; 16613531Sjairo.balart@metempsy.com bool DPG0; 16713690Sjairo.balart@metempsy.com bool EnableLPIs; 16813531Sjairo.balart@metempsy.com 16913690Sjairo.balart@metempsy.com Addr lpiConfigurationTablePtr; 17013690Sjairo.balart@metempsy.com uint8_t lpiIDBits; 17113690Sjairo.balart@metempsy.com Addr lpiPendingTablePtr; 17213690Sjairo.balart@metempsy.com 17313690Sjairo.balart@metempsy.com BitUnion8(LPIConfigurationTableEntry) 17413690Sjairo.balart@metempsy.com Bitfield<7, 2> priority; 17513690Sjairo.balart@metempsy.com Bitfield<1> res1; 17613690Sjairo.balart@metempsy.com Bitfield<0> enable; 17713690Sjairo.balart@metempsy.com EndBitUnion(LPIConfigurationTableEntry) 17813690Sjairo.balart@metempsy.com 17913690Sjairo.balart@metempsy.com static const uint32_t GICR_CTLR_ENABLE_LPIS = 1 << 0; 18013756Sjairo.balart@metempsy.com static const uint32_t GICR_CTLR_DPG0 = 1 << 24; 18113531Sjairo.balart@metempsy.com static const uint32_t GICR_CTLR_DPG1NS = 1 << 25; 18213756Sjairo.balart@metempsy.com static const uint32_t GICR_CTLR_DPG1S = 1 << 26; 18313531Sjairo.balart@metempsy.com 18413531Sjairo.balart@metempsy.com public: 18513531Sjairo.balart@metempsy.com 18613531Sjairo.balart@metempsy.com /* 18713531Sjairo.balart@metempsy.com * GICv3 defines only 2 64K consecutive frames for the redistributor 18813531Sjairo.balart@metempsy.com * (RD_base and SGI_base) but we are using 2 extra 64K stride frames 18913531Sjairo.balart@metempsy.com * to match GICv4 that defines 4 64K consecutive frames for them. 19013531Sjairo.balart@metempsy.com * Note this must match with DTB/DTS GIC node definition and boot 19113531Sjairo.balart@metempsy.com * loader code. 19213531Sjairo.balart@metempsy.com */ 19313878Sgiacomo.travaglini@arm.com const uint32_t addrRangeSize; 19413531Sjairo.balart@metempsy.com 19513690Sjairo.balart@metempsy.com static const uint32_t SMALLEST_LPI_ID = 8192; 19613690Sjairo.balart@metempsy.com 19713531Sjairo.balart@metempsy.com 19813756Sjairo.balart@metempsy.com void activateIRQ(uint32_t int_id); 19913756Sjairo.balart@metempsy.com bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const; 20013756Sjairo.balart@metempsy.com void deactivateIRQ(uint32_t int_id); 20113531Sjairo.balart@metempsy.com 20213756Sjairo.balart@metempsy.com inline Gicv3CPUInterface * 20313531Sjairo.balart@metempsy.com getCPUInterface() const 20413531Sjairo.balart@metempsy.com { 20513531Sjairo.balart@metempsy.com return cpuInterface; 20613531Sjairo.balart@metempsy.com } 20713531Sjairo.balart@metempsy.com 20813924Sgiacomo.travaglini@arm.com uint32_t 20913924Sgiacomo.travaglini@arm.com processorNumber() const 21013924Sgiacomo.travaglini@arm.com { 21113924Sgiacomo.travaglini@arm.com return cpuId; 21213924Sgiacomo.travaglini@arm.com } 21313924Sgiacomo.travaglini@arm.com 21413756Sjairo.balart@metempsy.com Gicv3::GroupId getIntGroup(int int_id) const; 21513756Sjairo.balart@metempsy.com Gicv3::IntStatus intStatus(uint32_t int_id) const; 21613924Sgiacomo.travaglini@arm.com uint8_t readEntryLPI(uint32_t intid); 21713924Sgiacomo.travaglini@arm.com void writeEntryLPI(uint32_t intid, uint8_t lpi_entry); 21813924Sgiacomo.travaglini@arm.com bool isPendingLPI(uint32_t intid); 21913690Sjairo.balart@metempsy.com void setClrLPI(uint64_t data, bool set); 22013756Sjairo.balart@metempsy.com void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns); 22113756Sjairo.balart@metempsy.com void serialize(CheckpointOut & cp) const override; 22213756Sjairo.balart@metempsy.com void unserialize(CheckpointIn & cp) override; 22313531Sjairo.balart@metempsy.com void update(); 22414231Sgiacomo.travaglini@arm.com void updateDistributor(); 22513756Sjairo.balart@metempsy.com 22613756Sjairo.balart@metempsy.com public: 22713756Sjairo.balart@metempsy.com 22813756Sjairo.balart@metempsy.com Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id); 22913756Sjairo.balart@metempsy.com uint32_t getAffinity() const; 23013756Sjairo.balart@metempsy.com void init(); 23113756Sjairo.balart@metempsy.com uint64_t read(Addr addr, size_t size, bool is_secure_access); 23213756Sjairo.balart@metempsy.com void sendPPInt(uint32_t int_id); 23313756Sjairo.balart@metempsy.com void write(Addr addr, uint64_t data, size_t size, bool is_secure_access); 23413531Sjairo.balart@metempsy.com}; 23513531Sjairo.balart@metempsy.com 23613531Sjairo.balart@metempsy.com#endif //__DEV_ARM_GICV3_REDISTRIBUTOR_H__ 237