1 /* 2 * Copyright (c) 2019 Stephanos Ioannidis <root@stephanos.io> 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 /** 8 * @file 9 * @brief Driver for ARM Generic Interrupt Controller 10 * 11 * The Generic Interrupt Controller (GIC) is the default interrupt controller 12 * for the ARM A and R profile cores. This driver is used by the ARM arch 13 * implementation to handle interrupts. 14 */ 15 16 #ifndef ZEPHYR_INCLUDE_DRIVERS_GIC_H_ 17 #define ZEPHYR_INCLUDE_DRIVERS_GIC_H_ 18 19 /* 20 * GIC Register Interface Base Addresses 21 */ 22 23 #define GIC_DIST_BASE DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 0) 24 #define GIC_CPU_BASE DT_REG_ADDR_BY_IDX(DT_INST(0, arm_gic), 1) 25 26 /* 27 * GIC Distributor Interface 28 */ 29 30 /* 31 * 0x000 Distributor Control Register 32 * v1 ICDDCR 33 * v2/v3 GICD_CTLR 34 */ 35 #define GICD_CTLR (GIC_DIST_BASE + 0x0) 36 37 /* 38 * 0x004 Interrupt Controller Type Register 39 * v1 ICDICTR 40 * v2/v3 GICD_TYPER 41 */ 42 #define GICD_TYPER (GIC_DIST_BASE + 0x4) 43 44 /* 45 * 0x008 Distributor Implementer Identification Register 46 * v1 ICDIIDR 47 * v2/v3 GICD_IIDR 48 */ 49 #define GICD_IIDR (GIC_DIST_BASE + 0x8) 50 51 /* 52 * 0x080 Interrupt Group Registers 53 * v1 ICDISRn 54 * v2/v3 GICD_IGROUPRn 55 */ 56 #define GICD_IGROUPRn (GIC_DIST_BASE + 0x80) 57 58 /* 59 * 0x100 Interrupt Set-Enable Reigsters 60 * v1 ICDISERn 61 * v2/v3 GICD_ISENABLERn 62 */ 63 #define GICD_ISENABLERn (GIC_DIST_BASE + 0x100) 64 65 /* 66 * 0x180 Interrupt Clear-Enable Registers 67 * v1 ICDICERn 68 * v2/v3 GICD_ICENABLERn 69 */ 70 #define GICD_ICENABLERn (GIC_DIST_BASE + 0x180) 71 72 /* 73 * 0x200 Interrupt Set-Pending Registers 74 * v1 ICDISPRn 75 * v2/v3 GICD_ISPENDRn 76 */ 77 #define GICD_ISPENDRn (GIC_DIST_BASE + 0x200) 78 79 /* 80 * 0x280 Interrupt Clear-Pending Registers 81 * v1 ICDICPRn 82 * v2/v3 GICD_ICPENDRn 83 */ 84 #define GICD_ICPENDRn (GIC_DIST_BASE + 0x280) 85 86 /* 87 * 0x300 Interrupt Set-Active Registers 88 * v1 ICDABRn 89 * v2/v3 GICD_ISACTIVERn 90 */ 91 #define GICD_ISACTIVERn (GIC_DIST_BASE + 0x300) 92 93 #if CONFIG_GIC_VER >= 2 94 /* 95 * 0x380 Interrupt Clear-Active Registers 96 * v2/v3 GICD_ICACTIVERn 97 */ 98 #define GICD_ICACTIVERn (GIC_DIST_BASE + 0x380) 99 #endif 100 101 /* 102 * 0x400 Interrupt Priority Registers 103 * v1 ICDIPRn 104 * v2/v3 GICD_IPRIORITYRn 105 */ 106 #define GICD_IPRIORITYRn (GIC_DIST_BASE + 0x400) 107 108 /* 109 * 0x800 Interrupt Processor Targets Registers 110 * v1 ICDIPTRn 111 * v2/v3 GICD_ITARGETSRn 112 */ 113 #define GICD_ITARGETSRn (GIC_DIST_BASE + 0x800) 114 115 /* 116 * 0xC00 Interrupt Configuration Registers 117 * v1 ICDICRn 118 * v2/v3 GICD_ICFGRn 119 */ 120 #define GICD_ICFGRn (GIC_DIST_BASE + 0xc00) 121 122 /* 123 * 0xF00 Software Generated Interrupt Register 124 * v1 ICDSGIR 125 * v2/v3 GICD_SGIR 126 */ 127 #define GICD_SGIR (GIC_DIST_BASE + 0xf00) 128 129 /* 130 * GIC CPU Interface 131 */ 132 133 #if CONFIG_GIC_VER <= 2 134 135 /* 136 * 0x0000 CPU Interface Control Register 137 * v1 ICCICR 138 * v2/v3 GICC_CTLR 139 */ 140 #define GICC_CTLR (GIC_CPU_BASE + 0x0) 141 142 /* 143 * 0x0004 Interrupt Priority Mask Register 144 * v1 ICCPMR 145 * v2/v3 GICC_PMR 146 */ 147 #define GICC_PMR (GIC_CPU_BASE + 0x4) 148 149 /* 150 * 0x0008 Binary Point Register 151 * v1 ICCBPR 152 * v2/v3 GICC_BPR 153 */ 154 #define GICC_BPR (GIC_CPU_BASE + 0x8) 155 156 /* 157 * 0x000C Interrupt Acknowledge Register 158 * v1 ICCIAR 159 * v2/v3 GICC_IAR 160 */ 161 #define GICC_IAR (GIC_CPU_BASE + 0xc) 162 163 /* 164 * 0x0010 End of Interrupt Register 165 * v1 ICCEOIR 166 * v2/v3 GICC_EOIR 167 */ 168 #define GICC_EOIR (GIC_CPU_BASE + 0x10) 169 170 171 /* 172 * Helper Constants 173 */ 174 175 /* GICC_CTLR */ 176 #define GICC_CTLR_ENABLEGRP0 BIT(0) 177 #define GICC_CTLR_ENABLEGRP1 BIT(1) 178 179 #define GICC_CTLR_ENABLE_MASK (GICC_CTLR_ENABLEGRP0 | GICC_CTLR_ENABLEGRP1) 180 181 #if defined(CONFIG_GIC_V2) 182 183 #define GICC_CTLR_FIQBYPDISGRP0 BIT(5) 184 #define GICC_CTLR_IRQBYPDISGRP0 BIT(6) 185 #define GICC_CTLR_FIQBYPDISGRP1 BIT(7) 186 #define GICC_CTLR_IRQBYPDISGRP1 BIT(8) 187 188 #define GICC_CTLR_BYPASS_MASK (GICC_CTLR_FIQBYPDISGRP0 | \ 189 GICC_CTLR_IRQBYPDISGRP1 | \ 190 GICC_CTLR_FIQBYPDISGRP1 | \ 191 GICC_CTLR_IRQBYPDISGRP1) 192 193 #endif /* CONFIG_GIC_V2 */ 194 195 /* GICD_SGIR */ 196 #define GICD_SGIR_TGTFILT(x) ((x) << 24) 197 #define GICD_SGIR_TGTFILT_CPULIST GICD_SGIR_TGTFILT(0b00) 198 #define GICD_SGIR_TGTFILT_ALLBUTREQ GICD_SGIR_TGTFILT(0b01) 199 #define GICD_SGIR_TGTFILT_REQONLY GICD_SGIR_TGTFILT(0b10) 200 201 #define GICD_SGIR_CPULIST(x) ((x) << 16) 202 #define GICD_SGIR_CPULIST_CPU(n) GICD_SGIR_CPULIST(BIT(n)) 203 #define GICD_SGIR_CPULIST_MASK 0xff 204 205 #define GICD_SGIR_NSATT BIT(15) 206 207 #define GICD_SGIR_SGIINTID(x) (x) 208 209 #endif /* CONFIG_GIC_VER <= 2 */ 210 211 212 /* GICD_ICFGR */ 213 #define GICD_ICFGR_MASK BIT_MASK(2) 214 #define GICD_ICFGR_TYPE BIT(1) 215 216 /* GICD_TYPER.ITLinesNumber 0:4 */ 217 #define GICD_TYPER_ITLINESNUM_MASK 0x1f 218 219 /* 220 * Common Helper Constants 221 */ 222 #define GIC_SGI_INT_BASE 0 223 #define GIC_PPI_INT_BASE 16 224 225 #define GIC_IS_SGI(intid) (((intid) >= GIC_SGI_INT_BASE) && \ 226 ((intid) < GIC_PPI_INT_BASE)) 227 228 229 #define GIC_SPI_INT_BASE 32 230 231 #define GIC_SPI_MAX_INTID 1019 232 233 #define GIC_IS_SPI(intid) (((intid) >= GIC_SPI_INT_BASE) && \ 234 ((intid) <= GIC_SPI_MAX_INTID)) 235 236 #define GIC_NUM_INTR_PER_REG 32 237 238 #define GIC_NUM_CFG_PER_REG 16 239 240 #define GIC_NUM_PRI_PER_REG 4 241 242 /* GIC idle priority : value '0xff' will allow all interrupts */ 243 #define GIC_IDLE_PRIO 0xff 244 245 /* Priority levels 0:255 */ 246 #define GIC_PRI_MASK 0xff 247 248 /* 249 * '0xa0'is used to initialize each interrtupt default priority. 250 * This is an arbitrary value in current context. 251 * Any value '0x80' to '0xff' will work for both NS and S state. 252 * The values of individual interrupt and default has to be chosen 253 * carefully if PMR and BPR based nesting and preemption has to be done. 254 */ 255 #define GIC_INT_DEF_PRI_X4 0xa0a0a0a0 256 257 /* GIC special interrupt id */ 258 #define GIC_INTID_SPURIOUS 1023 259 260 /* Fixme: update from platform specific define or dt */ 261 #define GIC_NUM_CPU_IF CONFIG_MP_NUM_CPUS 262 263 #ifndef _ASMLANGUAGE 264 265 #include <zephyr/types.h> 266 #include <device.h> 267 268 /* 269 * GIC Driver Interface Functions 270 */ 271 272 /** 273 * @brief Enable interrupt 274 * 275 * @param irq interrupt ID 276 */ 277 void arm_gic_irq_enable(unsigned int irq); 278 279 /** 280 * @brief Disable interrupt 281 * 282 * @param irq interrupt ID 283 */ 284 void arm_gic_irq_disable(unsigned int irq); 285 286 /** 287 * @brief Check if an interrupt is enabled 288 * 289 * @param irq interrupt ID 290 * @return Returns true if interrupt is enabled, false otherwise 291 */ 292 bool arm_gic_irq_is_enabled(unsigned int irq); 293 294 /** 295 * @brief Set interrupt priority 296 * 297 * @param irq interrupt ID 298 * @param prio interrupt priority 299 * @param flags interrupt flags 300 */ 301 void arm_gic_irq_set_priority( 302 unsigned int irq, unsigned int prio, unsigned int flags); 303 304 /** 305 * @brief Get active interrupt ID 306 * 307 * @return Returns the ID of an active interrupt 308 */ 309 unsigned int arm_gic_get_active(void); 310 311 /** 312 * @brief Signal end-of-interrupt 313 * 314 * @param irq interrupt ID 315 */ 316 void arm_gic_eoi(unsigned int irq); 317 318 #ifdef CONFIG_SMP 319 /** 320 * @brief Initialize GIC of secondary cores 321 */ 322 void arm_gic_secondary_init(void); 323 #endif 324 325 /** 326 * @brief raise SGI to target cores 327 * 328 * @param sgi_id SGI ID 0 to 15 329 * @param target_aff target affinity in mpidr form. 330 * Aff level 1 2 3 will be extracted by api. 331 * @param target_list bitmask of target cores 332 */ 333 void gic_raise_sgi(unsigned int sgi_id, uint64_t target_aff, 334 uint16_t target_list); 335 336 #endif /* !_ASMLANGUAGE */ 337 338 #endif /* ZEPHYR_INCLUDE_DRIVERS_GIC_H_ */ 339