gic_v3_redistributor.hh revision 13924:9e89b018ba6d
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; 40 41class Gicv3Redistributor : public Serializable 42{ 43 private: 44 45 friend class Gicv3CPUInterface; 46 friend class Gicv3Distributor; 47 48 protected: 49 50 Gicv3 * gic; 51 Gicv3Distributor * distributor; 52 Gicv3CPUInterface * cpuInterface; 53 uint32_t cpuId; 54 55 /* 56 * GICv3 defines 2 contiguous 64KB frames for each redistributor. 57 * Order of frames must be RD_base, SGI_base. 58 */ 59 static const uint32_t RD_base = 0x0; 60 static const uint32_t SGI_base = 0x10000; 61 62 enum { 63 // Control Register 64 GICR_CTLR = RD_base + 0x0000, 65 // Implementer Identification Register 66 GICR_IIDR = RD_base + 0x0004, 67 // Type Register 68 GICR_TYPER = RD_base + 0x0008, 69 // Wake Register 70 GICR_WAKER = RD_base + 0x0014, 71 // Peripheral ID0 Register 72 GICR_PIDR0 = RD_base + 0xffe0, 73 // Peripheral ID1 Register 74 GICR_PIDR1 = RD_base + 0xffe4, 75 // Peripheral ID2 Register 76 GICR_PIDR2 = RD_base + 0xffe8, 77 // Peripheral ID3 Register 78 GICR_PIDR3 = RD_base + 0xffec, 79 // Peripheral ID4 Register 80 GICR_PIDR4 = RD_base + 0xffd0, 81 // Peripheral ID5 Register 82 GICR_PIDR5 = RD_base + 0xffd4, 83 // Peripheral ID6 Register 84 GICR_PIDR6 = RD_base + 0xffd8, 85 // Peripheral ID7 Register 86 GICR_PIDR7 = RD_base + 0xffdc, 87 }; 88 89 static const uint32_t GICR_WAKER_ProcessorSleep = 1 << 1; 90 static const uint32_t GICR_WAKER_ChildrenAsleep = 1 << 2; 91 92 bool peInLowPowerState; 93 94 enum { 95 // Interrupt Group Register 0 96 GICR_IGROUPR0 = SGI_base + 0x0080, 97 // Interrupt Set-Enable Register 0 98 GICR_ISENABLER0 = SGI_base + 0x0100, 99 // Interrupt Clear-Enable Register 0 100 GICR_ICENABLER0 = SGI_base + 0x0180, 101 // Interrupt Set-Pending Register 0 102 GICR_ISPENDR0 = SGI_base + 0x0200, 103 // Interrupt Clear-Pending Register 0 104 GICR_ICPENDR0 = SGI_base + 0x0280, 105 // Interrupt Set-Active Register 0 106 GICR_ISACTIVER0 = SGI_base + 0x0300, 107 // Interrupt Clear-Active Register 0 108 GICR_ICACTIVER0 = SGI_base + 0x0380, 109 // SGI Configuration Register 110 GICR_ICFGR0 = SGI_base + 0x0c00, 111 // PPI Configuration Register 112 GICR_ICFGR1 = SGI_base + 0x0c04, 113 // Interrupt Group Modifier Register 0 114 GICR_IGRPMODR0 = SGI_base + 0x0d00, 115 // Non-secure Access Control Register 116 GICR_NSACR = SGI_base + 0x0e00, 117 }; 118 119 // Interrupt Priority Registers 120 static const AddrRange GICR_IPRIORITYR; 121 122 // GIC physical LPI Redistributor register 123 enum { 124 // Set LPI Pending Register 125 GICR_SETLPIR = RD_base + 0x0040, 126 // Clear LPI Pending Register 127 GICR_CLRLPIR = RD_base + 0x0048, 128 //Redistributor Properties Base Address Register 129 GICR_PROPBASER = RD_base + 0x0070, 130 // Redistributor LPI Pending Table Base Address Register 131 GICR_PENDBASER = RD_base + 0x0078, 132 // Redistributor Invalidate LPI Register 133 GICR_INVLPIR = RD_base + 0x00A0, 134 // Redistributor Invalidate All Register 135 GICR_INVALLR = RD_base + 0x00B0, 136 // Redistributor Synchronize Register 137 GICR_SYNCR = RD_base + 0x00C0, 138 }; 139 140 std::vector <uint8_t> irqGroup; 141 std::vector <bool> irqEnabled; 142 std::vector <bool> irqPending; 143 std::vector <bool> irqActive; 144 std::vector <uint8_t> irqPriority; 145 std::vector <Gicv3::IntTriggerType> irqConfig; 146 std::vector <uint8_t> irqGrpmod; 147 std::vector <uint8_t> irqNsacr; 148 149 bool DPG1S; 150 bool DPG1NS; 151 bool DPG0; 152 bool EnableLPIs; 153 154 Addr lpiConfigurationTablePtr; 155 uint8_t lpiIDBits; 156 Addr lpiPendingTablePtr; 157 158 BitUnion8(LPIConfigurationTableEntry) 159 Bitfield<7, 2> priority; 160 Bitfield<1> res1; 161 Bitfield<0> enable; 162 EndBitUnion(LPIConfigurationTableEntry) 163 164 static const uint32_t GICR_CTLR_ENABLE_LPIS = 1 << 0; 165 static const uint32_t GICR_CTLR_DPG0 = 1 << 24; 166 static const uint32_t GICR_CTLR_DPG1NS = 1 << 25; 167 static const uint32_t GICR_CTLR_DPG1S = 1 << 26; 168 169 public: 170 171 /* 172 * GICv3 defines only 2 64K consecutive frames for the redistributor 173 * (RD_base and SGI_base) but we are using 2 extra 64K stride frames 174 * to match GICv4 that defines 4 64K consecutive frames for them. 175 * Note this must match with DTB/DTS GIC node definition and boot 176 * loader code. 177 */ 178 const uint32_t addrRangeSize; 179 180 static const uint32_t SMALLEST_LPI_ID = 8192; 181 182 183 void activateIRQ(uint32_t int_id); 184 bool canBeSelectedFor1toNInterrupt(Gicv3::GroupId group) const; 185 void deactivateIRQ(uint32_t int_id); 186 187 inline Gicv3CPUInterface * 188 getCPUInterface() const 189 { 190 return cpuInterface; 191 } 192 193 uint32_t 194 processorNumber() const 195 { 196 return cpuId; 197 } 198 199 Gicv3::GroupId getIntGroup(int int_id) const; 200 Gicv3::IntStatus intStatus(uint32_t int_id) const; 201 uint8_t readEntryLPI(uint32_t intid); 202 void writeEntryLPI(uint32_t intid, uint8_t lpi_entry); 203 bool isPendingLPI(uint32_t intid); 204 void setClrLPI(uint64_t data, bool set); 205 void reset(); 206 void sendSGI(uint32_t int_id, Gicv3::GroupId group, bool ns); 207 void serialize(CheckpointOut & cp) const override; 208 void unserialize(CheckpointIn & cp) override; 209 void update(); 210 void updateAndInformCPUInterface(); 211 212 public: 213 214 Gicv3Redistributor(Gicv3 * gic, uint32_t cpu_id); 215 uint32_t getAffinity() const; 216 void init(); 217 void initState(); 218 uint64_t read(Addr addr, size_t size, bool is_secure_access); 219 void sendPPInt(uint32_t int_id); 220 void write(Addr addr, uint64_t data, size_t size, bool is_secure_access); 221}; 222 223#endif //__DEV_ARM_GICV3_REDISTRIBUTOR_H__ 224