1 /* 2 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are met: 6 * 7 * Redistributions of source code must retain the above copyright notice, this 8 * list of conditions and the following disclaimer. 9 * 10 * Redistributions in binary form must reproduce the above copyright notice, 11 * this list of conditions and the following disclaimer in the documentation 12 * and/or other materials provided with the distribution. 13 * 14 * Neither the name of ARM nor the names of its contributors may be used 15 * to endorse or promote products derived from this software without specific 16 * prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include <arch.h> 32 #include <arch_helpers.h> 33 #include <assert.h> 34 #include <debug.h> 35 #include <gic_common.h> 36 #include <gicv2.h> 37 #include "../common/gic_common_private.h" 38 #include "gicv2_private.h" 39 40 static const gicv2_driver_data_t *driver_data; 41 42 /******************************************************************************* 43 * Enable secure interrupts and use FIQs to route them. Disable legacy bypass 44 * and set the priority mask register to allow all interrupts to trickle in. 45 ******************************************************************************/ 46 void gicv2_cpuif_enable(void) 47 { 48 unsigned int val; 49 50 assert(driver_data); 51 assert(driver_data->gicc_base); 52 53 /* 54 * Enable the Group 0 interrupts, FIQEn and disable Group 0/1 55 * bypass. 56 */ 57 val = CTLR_ENABLE_G0_BIT | FIQ_EN_BIT | FIQ_BYP_DIS_GRP0; 58 val |= IRQ_BYP_DIS_GRP0 | FIQ_BYP_DIS_GRP1 | IRQ_BYP_DIS_GRP1; 59 60 /* Program the idle priority in the PMR */ 61 gicc_write_pmr(driver_data->gicc_base, GIC_PRI_MASK); 62 gicc_write_ctlr(driver_data->gicc_base, val); 63 } 64 65 /******************************************************************************* 66 * Place the cpu interface in a state where it can never make a cpu exit wfi as 67 * as result of an asserted interrupt. This is critical for powering down a cpu 68 ******************************************************************************/ 69 void gicv2_cpuif_disable(void) 70 { 71 unsigned int val; 72 73 assert(driver_data); 74 assert(driver_data->gicc_base); 75 76 /* Disable secure, non-secure interrupts and disable their bypass */ 77 val = gicc_read_ctlr(driver_data->gicc_base); 78 val &= ~(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1_BIT); 79 val |= FIQ_BYP_DIS_GRP1 | FIQ_BYP_DIS_GRP0; 80 val |= IRQ_BYP_DIS_GRP0 | IRQ_BYP_DIS_GRP1; 81 gicc_write_ctlr(driver_data->gicc_base, val); 82 } 83 84 /******************************************************************************* 85 * Per cpu gic distributor setup which will be done by all cpus after a cold 86 * boot/hotplug. This marks out the secure SPIs and PPIs & enables them. 87 ******************************************************************************/ 88 void gicv2_pcpu_distif_init(void) 89 { 90 assert(driver_data); 91 assert(driver_data->gicd_base); 92 assert(driver_data->g0_interrupt_array); 93 94 gicv2_secure_ppi_sgi_setup(driver_data->gicd_base, 95 driver_data->g0_interrupt_num, 96 driver_data->g0_interrupt_array); 97 } 98 99 /******************************************************************************* 100 * Global gic distributor init which will be done by the primary cpu after a 101 * cold boot. It marks out the secure SPIs, PPIs & SGIs and enables them. It 102 * then enables the secure GIC distributor interface. 103 ******************************************************************************/ 104 void gicv2_distif_init(void) 105 { 106 unsigned int ctlr; 107 108 assert(driver_data); 109 assert(driver_data->gicd_base); 110 assert(driver_data->g0_interrupt_array); 111 112 /* Disable the distributor before going further */ 113 ctlr = gicd_read_ctlr(driver_data->gicd_base); 114 gicd_write_ctlr(driver_data->gicd_base, 115 ctlr & ~(CTLR_ENABLE_G0_BIT | CTLR_ENABLE_G1_BIT)); 116 117 /* Set the default attribute of all SPIs */ 118 gicv2_spis_configure_defaults(driver_data->gicd_base); 119 120 /* Configure the G0 SPIs */ 121 gicv2_secure_spis_configure(driver_data->gicd_base, 122 driver_data->g0_interrupt_num, 123 driver_data->g0_interrupt_array); 124 125 /* Re-enable the secure SPIs now that they have been configured */ 126 gicd_write_ctlr(driver_data->gicd_base, ctlr | CTLR_ENABLE_G0_BIT); 127 } 128 129 /******************************************************************************* 130 * Initialize the ARM GICv2 driver with the provided platform inputs 131 ******************************************************************************/ 132 void gicv2_driver_init(const gicv2_driver_data_t *plat_driver_data) 133 { 134 unsigned int gic_version; 135 assert(plat_driver_data); 136 assert(plat_driver_data->gicd_base); 137 assert(plat_driver_data->gicc_base); 138 139 /* 140 * The platform should provide a list of atleast one type of 141 * interrupts 142 */ 143 assert(plat_driver_data->g0_interrupt_array); 144 145 /* 146 * If there are no interrupts of a particular type, then the number of 147 * interrupts of that type should be 0 and vice-versa. 148 */ 149 assert(plat_driver_data->g0_interrupt_array ? 150 plat_driver_data->g0_interrupt_num : 151 plat_driver_data->g0_interrupt_num == 0); 152 153 /* Ensure that this is a GICv2 system */ 154 gic_version = gicd_read_pidr2(plat_driver_data->gicd_base); 155 gic_version = (gic_version >> PIDR2_ARCH_REV_SHIFT) 156 & PIDR2_ARCH_REV_MASK; 157 assert(gic_version == ARCH_REV_GICV2); 158 159 driver_data = plat_driver_data; 160 161 /* 162 * The GIC driver data is initialized by the primary CPU with caches 163 * enabled. When the secondary CPU boots up, it initializes the 164 * GICC/GICR interface with the caches disabled. Hence flush the 165 * driver_data to ensure coherency. This is not required if the 166 * platform has HW_ASSISTED_COHERENCY enabled. 167 */ 168 #if !HW_ASSISTED_COHERENCY 169 flush_dcache_range((uintptr_t) &driver_data, sizeof(driver_data)); 170 flush_dcache_range((uintptr_t) driver_data, sizeof(*driver_data)); 171 #endif 172 INFO("ARM GICv2 driver initialized\n"); 173 } 174 175 /****************************************************************************** 176 * This function returns whether FIQ is enabled in the GIC CPU interface. 177 *****************************************************************************/ 178 unsigned int gicv2_is_fiq_enabled(void) 179 { 180 unsigned int gicc_ctlr; 181 182 assert(driver_data); 183 assert(driver_data->gicc_base); 184 185 gicc_ctlr = gicc_read_ctlr(driver_data->gicc_base); 186 return (gicc_ctlr >> FIQ_EN_SHIFT) & 0x1; 187 } 188 189 /******************************************************************************* 190 * This function returns the type of the highest priority pending interrupt at 191 * the GIC cpu interface. The return values can be one of the following : 192 * PENDING_G1_INTID : The interrupt type is non secure Group 1. 193 * 0 - 1019 : The interrupt type is secure Group 0. 194 * GIC_SPURIOUS_INTERRUPT : there is no pending interrupt with 195 * sufficient priority to be signaled 196 ******************************************************************************/ 197 unsigned int gicv2_get_pending_interrupt_type(void) 198 { 199 assert(driver_data); 200 assert(driver_data->gicc_base); 201 202 return gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK; 203 } 204 205 /******************************************************************************* 206 * This function returns the id of the highest priority pending interrupt at 207 * the GIC cpu interface. GIC_SPURIOUS_INTERRUPT is returned when there is no 208 * interrupt pending. 209 ******************************************************************************/ 210 unsigned int gicv2_get_pending_interrupt_id(void) 211 { 212 unsigned int id; 213 214 assert(driver_data); 215 assert(driver_data->gicc_base); 216 217 id = gicc_read_hppir(driver_data->gicc_base) & INT_ID_MASK; 218 219 /* 220 * Find out which non-secure interrupt it is under the assumption that 221 * the GICC_CTLR.AckCtl bit is 0. 222 */ 223 if (id == PENDING_G1_INTID) 224 id = gicc_read_ahppir(driver_data->gicc_base) & INT_ID_MASK; 225 226 return id; 227 } 228 229 /******************************************************************************* 230 * This functions reads the GIC cpu interface Interrupt Acknowledge register 231 * to start handling the pending secure 0 interrupt. It returns the 232 * contents of the IAR. 233 ******************************************************************************/ 234 unsigned int gicv2_acknowledge_interrupt(void) 235 { 236 assert(driver_data); 237 assert(driver_data->gicc_base); 238 239 return gicc_read_IAR(driver_data->gicc_base); 240 } 241 242 /******************************************************************************* 243 * This functions writes the GIC cpu interface End Of Interrupt register with 244 * the passed value to finish handling the active secure group 0 interrupt. 245 ******************************************************************************/ 246 void gicv2_end_of_interrupt(unsigned int id) 247 { 248 assert(driver_data); 249 assert(driver_data->gicc_base); 250 251 gicc_write_EOIR(driver_data->gicc_base, id); 252 } 253 254 /******************************************************************************* 255 * This function returns the type of the interrupt id depending upon the group 256 * this interrupt has been configured under by the interrupt controller i.e. 257 * group0 secure or group1 non secure. It returns zero for Group 0 secure and 258 * one for Group 1 non secure interrupt. 259 ******************************************************************************/ 260 unsigned int gicv2_get_interrupt_group(unsigned int id) 261 { 262 assert(driver_data); 263 assert(driver_data->gicd_base); 264 265 return gicd_get_igroupr(driver_data->gicd_base, id); 266 } 267