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