gic_v3_redistributor.hh revision 14231:222f6512335e
1/* 2 * Copyright (c) 2018 Metempsy Technology Consulting 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * Authors: Jairo Balart 29 */ 30 31#ifndef __DEV_ARM_GICV3_REDISTRIBUTOR_H__ 32#define __DEV_ARM_GICV3_REDISTRIBUTOR_H__ 33 34#include "base/addr_range.hh" 35#include "dev/arm/gic_v3.hh" 36#include "sim/serialize.hh" 37 38class Gicv3CPUInterface; 39class Gicv3Distributor; 40class Gicv3Its; 41 42class Gicv3Redistributor : public Serializable 43{ 44 private: 45 46 friend class Gicv3CPUInterface; 47 friend class Gicv3Distributor; 48 friend class Gicv3Its; 49 50 protected: 51 52 Gicv3 * gic; 53 Gicv3Distributor * distributor; 54 Gicv3CPUInterface * cpuInterface; 55 uint32_t cpuId; 56 PortProxy * memProxy; 57 58 /* 59 * GICv3 defines 2 contiguous 64KB frames for each redistributor. 60 * Order of frames must be RD_base, SGI_base. 61 */ 62 static const uint32_t RD_base = 0x0; 63 static const uint32_t SGI_base = 0x10000; 64 65 enum { 66 // Control Register 67 GICR_CTLR = RD_base + 0x0000, 68 // Implementer Identification Register 69 GICR_IIDR = RD_base + 0x0004, 70 // Type Register 71 GICR_TYPER = RD_base + 0x0008, 72 // Wake Register 73 GICR_WAKER = RD_base + 0x0014, 74 // Peripheral ID0 Register 75 GICR_PIDR0 = RD_base + 0xffe0, 76 // Peripheral ID1 Register 77 GICR_PIDR1 = RD_base + 0xffe4, 78 // Peripheral ID2 Register 79 GICR_PIDR2 = RD_base + 0xffe8, 80 // Peripheral ID3 Register 81 GICR_PIDR3 = RD_base + 0xffec, 82 // Peripheral ID4 Register 83 GICR_PIDR4 = RD_base + 0xffd0, 84 // Peripheral ID5 Register 85 GICR_PIDR5 = RD_base + 0xffd4, 86 // Peripheral ID6 Register 87 GICR_PIDR6 = RD_base + 0xffd8, 88 // Peripheral ID7 Register 89 GICR_PIDR7 = RD_base + 0xffdc, 90 }; 91 92 static const uint32_t GICR_WAKER_ProcessorSleep = 1 << 1; 93 static const uint32_t GICR_WAKER_ChildrenAsleep = 1 << 2; 94 95 bool peInLowPowerState; 96 97 enum { 98 // Interrupt Group Register 0 99 GICR_IGROUPR0 = SGI_base + 0x0080, 100 // Interrupt Set-Enable Register 0 101 GICR_ISENABLER0 = SGI_base + 0x0100, 102 // Interrupt Clear-Enable Register 0 103 GICR_ICENABLER0 = SGI_base + 0x0180, 104 // Interrupt Set-Pending Register 0 105 GICR_ISPENDR0 = SGI_base + 0x0200, 106 // Interrupt Clear-Pending Register 0 107 GICR_ICPENDR0 = SGI_base + 0x0280, 108 // Interrupt Set-Active Register 0 109 GICR_ISACTIVER0 = SGI_base + 0x0300, 110 // Interrupt Clear-Active Register 0 111 GICR_ICACTIVER0 = SGI_base + 0x0380, 112 // SGI Configuration Register 113 GICR_ICFGR0 = SGI_base + 0x0c00, 114 // PPI Configuration Register 115 GICR_ICFGR1 = SGI_base + 0x0c04, 116 // Interrupt Group Modifier Register 0 117 GICR_IGRPMODR0 = SGI_base + 0x0d00, 118 // Non-secure Access Control Register 119 GICR_NSACR = SGI_base + 0x0e00, 120 }; 121 122 // Interrupt Priority Registers 123 static const AddrRange GICR_IPRIORITYR; 124 125 // GIC physical LPI Redistributor register 126 enum { 127 // Set LPI Pending Register 128 GICR_SETLPIR = RD_base + 0x0040, 129 // Clear LPI Pending Register 130 GICR_CLRLPIR = RD_base + 0x0048, 131 //Redistributor Properties Base Address Register 132 GICR_PROPBASER = RD_base + 0x0070, 133 // Redistributor LPI Pending Table Base Address Register 134 GICR_PENDBASER = RD_base + 0x0078, 135 // Redistributor Invalidate LPI Register 136 GICR_INVLPIR = RD_base + 0x00A0, 137 // Redistributor Invalidate All Register 138 GICR_INVALLR = RD_base + 0x00B0, 139 // Redistributor Synchronize Register 140 GICR_SYNCR = RD_base + 0x00C0, 141 }; 142 143 std::vector <uint8_t> irqGroup; 144 std::vector <bool> irqEnabled; 145 std::vector <bool> irqPending; 146 std::vector <bool> irqActive; 147 std::vector <uint8_t> irqPriority; 148 std::vector <Gicv3::IntTriggerType> irqConfig; 149 std::vector <uint8_t> irqGrpmod; 150 std::vector <uint8_t> irqNsacr; 151 152 bool DPG1S; 153 bool DPG1NS; 154 bool DPG0; 155 bool EnableLPIs; 156 157 Addr lpiConfigurationTablePtr; 158 uint8_t lpiIDBits; 159 Addr lpiPendingTablePtr; 160 161 BitUnion8(LPIConfigurationTableEntry) 162 Bitfield<7, 2> priority; 163 Bitfield<1> res1; 164 Bitfield<0> enable; 165 EndBitUnion(LPIConfigurationTableEntry) 166 167 static const uint32_t GICR_CTLR_ENABLE_LPIS = 1 << 0; 168 static const uint32_t GICR_CTLR_DPG0 = 1 << 24; 169 static const uint32_t GICR_CTLR_DPG1NS = 1 << 25; 170 static const uint32_t GICR_CTLR_DPG1S = 1 << 26; 171 172 public: 173 174 /* 175 * GICv3 defines only 2 64K consecutive frames for the redistributor 176 * (RD_base and SGI_base) but we are using 2 extra 64K stride frames 177 * to match GICv4 that defines 4 64K consecutive frames for them. 178 * Note this must match with DTB/DTS GIC node definition and boot 179 * loader code. 180 */ 181 const uint32_t addrRangeSize; 182 183 static const uint32_t SMALLEST_LPI_ID = 8192; 184 185 186 void activateIRQ(uint32_t int_id); 187 bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const; 188 void deactivateIRQ(uint32_t int_id); 189 190 inline Gicv3CPUInterface * 191 getCPUInterface() const 192 { 193 return cpuInterface; 194 } 195 196 uint32_t 197 processorNumber() const 198 { 199 return cpuId; 200 } 201 202 Gicv3::GroupId getIntGroup(int int_id) const; 203 Gicv3::IntStatus intStatus(uint32_t int_id) const; 204 uint8_t readEntryLPI(uint32_t intid); 205 void writeEntryLPI(uint32_t intid, uint8_t lpi_entry); 206 bool isPendingLPI(uint32_t intid); 207 void setClrLPI(uint64_t data, bool set); 208 void reset(); 209 void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns); 210 void serialize(CheckpointOut & cp) const override; 211 void unserialize(CheckpointIn & cp) override; 212 void update(); 213 void updateDistributor(); 214 215 public: 216 217 Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id); 218 uint32_t getAffinity() const; 219 void init(); 220 void initState(); 221 uint64_t read(Addr addr, size_t size, bool is_secure_access); 222 void sendPPInt(uint32_t int_id); 223 void write(Addr addr, uint64_t data, size_t size, bool is_secure_access); 224}; 225 226#endif //__DEV_ARM_GICV3_REDISTRIBUTOR_H__ 227