1 /* 2 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <arch.h> 8 #include <arch_helpers.h> 9 #include <assert.h> 10 #include <debug.h> 11 #include <gic_common.h> 12 #include <gicv2.h> 13 #include <interrupt_props.h> 14 #include "../common/gic_common_private.h" 15 #include "gicv2_private.h" 16 17 /* 18 * Accessor to read the GIC Distributor ITARGETSR corresponding to the 19 * interrupt `id`, 4 interrupt IDs at a time. 20 */ 21 unsigned int gicd_read_itargetsr(uintptr_t base, unsigned int id) 22 { 23 unsigned n = id >> ITARGETSR_SHIFT; 24 return mmio_read_32(base + GICD_ITARGETSR + (n << 2)); 25 } 26 27 /* 28 * Accessor to read the GIC Distributor CPENDSGIR corresponding to the 29 * interrupt `id`, 4 interrupt IDs at a time. 30 */ 31 unsigned int gicd_read_cpendsgir(uintptr_t base, unsigned int id) 32 { 33 unsigned n = id >> CPENDSGIR_SHIFT; 34 return mmio_read_32(base + GICD_CPENDSGIR + (n << 2)); 35 } 36 37 /* 38 * Accessor to read the GIC Distributor SPENDSGIR corresponding to the 39 * interrupt `id`, 4 interrupt IDs at a time. 40 */ 41 unsigned int gicd_read_spendsgir(uintptr_t base, unsigned int id) 42 { 43 unsigned n = id >> SPENDSGIR_SHIFT; 44 return mmio_read_32(base + GICD_SPENDSGIR + (n << 2)); 45 } 46 47 /* 48 * Accessor to write the GIC Distributor ITARGETSR corresponding to the 49 * interrupt `id`, 4 interrupt IDs at a time. 50 */ 51 void gicd_write_itargetsr(uintptr_t base, unsigned int id, unsigned int val) 52 { 53 unsigned n = id >> ITARGETSR_SHIFT; 54 mmio_write_32(base + GICD_ITARGETSR + (n << 2), val); 55 } 56 57 /* 58 * Accessor to write the GIC Distributor CPENDSGIR corresponding to the 59 * interrupt `id`, 4 interrupt IDs at a time. 60 */ 61 void gicd_write_cpendsgir(uintptr_t base, unsigned int id, unsigned int val) 62 { 63 unsigned n = id >> CPENDSGIR_SHIFT; 64 mmio_write_32(base + GICD_CPENDSGIR + (n << 2), val); 65 } 66 67 /* 68 * Accessor to write the GIC Distributor SPENDSGIR corresponding to the 69 * interrupt `id`, 4 interrupt IDs at a time. 70 */ 71 void gicd_write_spendsgir(uintptr_t base, unsigned int id, unsigned int val) 72 { 73 unsigned n = id >> SPENDSGIR_SHIFT; 74 mmio_write_32(base + GICD_SPENDSGIR + (n << 2), val); 75 } 76 77 /******************************************************************************* 78 * Get the current CPU bit mask from GICD_ITARGETSR0 79 ******************************************************************************/ 80 unsigned int gicv2_get_cpuif_id(uintptr_t base) 81 { 82 unsigned int val; 83 84 val = gicd_read_itargetsr(base, 0); 85 return val & GIC_TARGET_CPU_MASK; 86 } 87 88 /******************************************************************************* 89 * Helper function to configure the default attributes of SPIs. 90 ******************************************************************************/ 91 void gicv2_spis_configure_defaults(uintptr_t gicd_base) 92 { 93 unsigned int index, num_ints; 94 95 num_ints = gicd_read_typer(gicd_base); 96 num_ints &= TYPER_IT_LINES_NO_MASK; 97 num_ints = (num_ints + 1U) << 5; 98 99 /* 100 * Treat all SPIs as G1NS by default. The number of interrupts is 101 * calculated as 32 * (IT_LINES + 1). We do 32 at a time. 102 */ 103 for (index = MIN_SPI_ID; index < num_ints; index += 32U) 104 gicd_write_igroupr(gicd_base, index, ~0U); 105 106 /* Setup the default SPI priorities doing four at a time */ 107 for (index = MIN_SPI_ID; index < num_ints; index += 4U) 108 gicd_write_ipriorityr(gicd_base, 109 index, 110 GICD_IPRIORITYR_DEF_VAL); 111 112 /* Treat all SPIs as level triggered by default, 16 at a time */ 113 for (index = MIN_SPI_ID; index < num_ints; index += 16U) 114 gicd_write_icfgr(gicd_base, index, 0U); 115 } 116 117 #if !ERROR_DEPRECATED 118 /******************************************************************************* 119 * Helper function to configure secure G0 SPIs. 120 ******************************************************************************/ 121 void gicv2_secure_spis_configure(uintptr_t gicd_base, 122 unsigned int num_ints, 123 const unsigned int *sec_intr_list) 124 { 125 unsigned int index, irq_num; 126 127 /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ 128 if (num_ints != 0U) 129 assert(sec_intr_list != NULL); 130 131 for (index = 0; index < num_ints; index++) { 132 irq_num = sec_intr_list[index]; 133 if (irq_num >= MIN_SPI_ID) { 134 /* Configure this interrupt as a secure interrupt */ 135 gicd_clr_igroupr(gicd_base, irq_num); 136 137 /* Set the priority of this interrupt */ 138 gicd_set_ipriorityr(gicd_base, 139 irq_num, 140 GIC_HIGHEST_SEC_PRIORITY); 141 142 /* Target the secure interrupts to primary CPU */ 143 gicd_set_itargetsr(gicd_base, irq_num, 144 gicv2_get_cpuif_id(gicd_base)); 145 146 /* Enable this interrupt */ 147 gicd_set_isenabler(gicd_base, irq_num); 148 } 149 } 150 151 } 152 #endif 153 154 /******************************************************************************* 155 * Helper function to configure properties of secure G0 SPIs. 156 ******************************************************************************/ 157 void gicv2_secure_spis_configure_props(uintptr_t gicd_base, 158 const interrupt_prop_t *interrupt_props, 159 unsigned int interrupt_props_num) 160 { 161 unsigned int i; 162 const interrupt_prop_t *prop_desc; 163 164 /* Make sure there's a valid property array */ 165 if (interrupt_props_num != 0U) 166 assert(interrupt_props != NULL); 167 168 for (i = 0; i < interrupt_props_num; i++) { 169 prop_desc = &interrupt_props[i]; 170 171 if (prop_desc->intr_num < MIN_SPI_ID) 172 continue; 173 174 /* Configure this interrupt as a secure interrupt */ 175 assert(prop_desc->intr_grp == GICV2_INTR_GROUP0); 176 gicd_clr_igroupr(gicd_base, prop_desc->intr_num); 177 178 /* Set the priority of this interrupt */ 179 gicd_set_ipriorityr(gicd_base, prop_desc->intr_num, 180 prop_desc->intr_pri); 181 182 /* Target the secure interrupts to primary CPU */ 183 gicd_set_itargetsr(gicd_base, prop_desc->intr_num, 184 gicv2_get_cpuif_id(gicd_base)); 185 186 /* Set interrupt configuration */ 187 gicd_set_icfgr(gicd_base, prop_desc->intr_num, 188 prop_desc->intr_cfg); 189 190 /* Enable this interrupt */ 191 gicd_set_isenabler(gicd_base, prop_desc->intr_num); 192 } 193 } 194 195 #if !ERROR_DEPRECATED 196 /******************************************************************************* 197 * Helper function to configure secure G0 SGIs and PPIs. 198 ******************************************************************************/ 199 void gicv2_secure_ppi_sgi_setup(uintptr_t gicd_base, 200 unsigned int num_ints, 201 const unsigned int *sec_intr_list) 202 { 203 unsigned int index, irq_num, sec_ppi_sgi_mask = 0; 204 205 /* If `num_ints` is not 0, ensure that `sec_intr_list` is not NULL */ 206 assert(num_ints ? (uintptr_t)sec_intr_list : 1); 207 208 /* 209 * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a 210 * more scalable approach as it avoids clearing the enable bits in the 211 * GICD_CTLR. 212 */ 213 gicd_write_icenabler(gicd_base, 0, ~0); 214 215 /* Setup the default PPI/SGI priorities doing four at a time */ 216 for (index = 0; index < MIN_SPI_ID; index += 4) 217 gicd_write_ipriorityr(gicd_base, 218 index, 219 GICD_IPRIORITYR_DEF_VAL); 220 221 for (index = 0; index < num_ints; index++) { 222 irq_num = sec_intr_list[index]; 223 if (irq_num < MIN_SPI_ID) { 224 /* We have an SGI or a PPI. They are Group0 at reset */ 225 sec_ppi_sgi_mask |= 1U << irq_num; 226 227 /* Set the priority of this interrupt */ 228 gicd_set_ipriorityr(gicd_base, 229 irq_num, 230 GIC_HIGHEST_SEC_PRIORITY); 231 } 232 } 233 234 /* 235 * Invert the bitmask to create a mask for non-secure PPIs and 236 * SGIs. Program the GICD_IGROUPR0 with this bit mask. 237 */ 238 gicd_write_igroupr(gicd_base, 0, ~sec_ppi_sgi_mask); 239 240 /* Enable the Group 0 SGIs and PPIs */ 241 gicd_write_isenabler(gicd_base, 0, sec_ppi_sgi_mask); 242 } 243 #endif 244 245 /******************************************************************************* 246 * Helper function to configure properties of secure G0 SGIs and PPIs. 247 ******************************************************************************/ 248 void gicv2_secure_ppi_sgi_setup_props(uintptr_t gicd_base, 249 const interrupt_prop_t *interrupt_props, 250 unsigned int interrupt_props_num) 251 { 252 unsigned int i; 253 uint32_t sec_ppi_sgi_mask = 0; 254 const interrupt_prop_t *prop_desc; 255 256 /* Make sure there's a valid property array */ 257 if (interrupt_props_num != 0U) 258 assert(interrupt_props != NULL); 259 260 /* 261 * Disable all SGIs (imp. def.)/PPIs before configuring them. This is a 262 * more scalable approach as it avoids clearing the enable bits in the 263 * GICD_CTLR. 264 */ 265 gicd_write_icenabler(gicd_base, 0U, ~0U); 266 267 /* Setup the default PPI/SGI priorities doing four at a time */ 268 for (i = 0U; i < MIN_SPI_ID; i += 4U) 269 gicd_write_ipriorityr(gicd_base, i, GICD_IPRIORITYR_DEF_VAL); 270 271 for (i = 0U; i < interrupt_props_num; i++) { 272 prop_desc = &interrupt_props[i]; 273 274 if (prop_desc->intr_num >= MIN_SPI_ID) 275 continue; 276 277 /* Configure this interrupt as a secure interrupt */ 278 assert(prop_desc->intr_grp == GICV2_INTR_GROUP0); 279 280 /* 281 * Set interrupt configuration for PPIs. Configuration for SGIs 282 * are ignored. 283 */ 284 if ((prop_desc->intr_num >= MIN_PPI_ID) && 285 (prop_desc->intr_num < MIN_SPI_ID)) { 286 gicd_set_icfgr(gicd_base, prop_desc->intr_num, 287 prop_desc->intr_cfg); 288 } 289 290 /* We have an SGI or a PPI. They are Group0 at reset */ 291 sec_ppi_sgi_mask |= (1u << prop_desc->intr_num); 292 293 /* Set the priority of this interrupt */ 294 gicd_set_ipriorityr(gicd_base, prop_desc->intr_num, 295 prop_desc->intr_pri); 296 } 297 298 /* 299 * Invert the bitmask to create a mask for non-secure PPIs and SGIs. 300 * Program the GICD_IGROUPR0 with this bit mask. 301 */ 302 gicd_write_igroupr(gicd_base, 0, ~sec_ppi_sgi_mask); 303 304 /* Enable the Group 0 SGIs and PPIs */ 305 gicd_write_isenabler(gicd_base, 0, sec_ppi_sgi_mask); 306 } 307