1*91f16700Schasinglulu /* 2*91f16700Schasinglulu * Copyright (c) 2015-2023, Arm Limited and Contributors. All rights reserved. 3*91f16700Schasinglulu * Portions copyright (c) 2021-2022, ProvenRun S.A.S. All rights reserved. 4*91f16700Schasinglulu * 5*91f16700Schasinglulu * SPDX-License-Identifier: BSD-3-Clause 6*91f16700Schasinglulu */ 7*91f16700Schasinglulu 8*91f16700Schasinglulu #include <assert.h> 9*91f16700Schasinglulu #include <stdbool.h> 10*91f16700Schasinglulu 11*91f16700Schasinglulu #include <arch_helpers.h> 12*91f16700Schasinglulu #include <common/bl_common.h> 13*91f16700Schasinglulu #include <common/debug.h> 14*91f16700Schasinglulu #include <bl31/interrupt_mgmt.h> 15*91f16700Schasinglulu #include <drivers/arm/gic_common.h> 16*91f16700Schasinglulu #include <drivers/arm/gicv3.h> 17*91f16700Schasinglulu #include <lib/cassert.h> 18*91f16700Schasinglulu #include <plat/common/platform.h> 19*91f16700Schasinglulu 20*91f16700Schasinglulu #ifdef IMAGE_BL31 21*91f16700Schasinglulu 22*91f16700Schasinglulu /* 23*91f16700Schasinglulu * The following platform GIC functions are weakly defined. They 24*91f16700Schasinglulu * provide typical implementations that may be re-used by multiple 25*91f16700Schasinglulu * platforms but may also be overridden by a platform if required. 26*91f16700Schasinglulu */ 27*91f16700Schasinglulu #pragma weak plat_ic_get_pending_interrupt_id 28*91f16700Schasinglulu #pragma weak plat_ic_get_pending_interrupt_type 29*91f16700Schasinglulu #pragma weak plat_ic_acknowledge_interrupt 30*91f16700Schasinglulu #pragma weak plat_ic_get_interrupt_type 31*91f16700Schasinglulu #pragma weak plat_ic_end_of_interrupt 32*91f16700Schasinglulu #pragma weak plat_interrupt_type_to_line 33*91f16700Schasinglulu 34*91f16700Schasinglulu #pragma weak plat_ic_get_running_priority 35*91f16700Schasinglulu #pragma weak plat_ic_is_spi 36*91f16700Schasinglulu #pragma weak plat_ic_is_ppi 37*91f16700Schasinglulu #pragma weak plat_ic_is_sgi 38*91f16700Schasinglulu #pragma weak plat_ic_get_interrupt_active 39*91f16700Schasinglulu #pragma weak plat_ic_enable_interrupt 40*91f16700Schasinglulu #pragma weak plat_ic_disable_interrupt 41*91f16700Schasinglulu #pragma weak plat_ic_set_interrupt_priority 42*91f16700Schasinglulu #pragma weak plat_ic_set_interrupt_type 43*91f16700Schasinglulu #pragma weak plat_ic_raise_el3_sgi 44*91f16700Schasinglulu #pragma weak plat_ic_raise_ns_sgi 45*91f16700Schasinglulu #pragma weak plat_ic_raise_s_el1_sgi 46*91f16700Schasinglulu #pragma weak plat_ic_set_spi_routing 47*91f16700Schasinglulu #pragma weak plat_ic_set_interrupt_pending 48*91f16700Schasinglulu #pragma weak plat_ic_clear_interrupt_pending 49*91f16700Schasinglulu 50*91f16700Schasinglulu /* 51*91f16700Schasinglulu * This function returns the highest priority pending interrupt at 52*91f16700Schasinglulu * the Interrupt controller 53*91f16700Schasinglulu */ 54*91f16700Schasinglulu uint32_t plat_ic_get_pending_interrupt_id(void) 55*91f16700Schasinglulu { 56*91f16700Schasinglulu unsigned int irqnr; 57*91f16700Schasinglulu 58*91f16700Schasinglulu assert(IS_IN_EL3()); 59*91f16700Schasinglulu irqnr = gicv3_get_pending_interrupt_id(); 60*91f16700Schasinglulu return gicv3_is_intr_id_special_identifier(irqnr) ? 61*91f16700Schasinglulu INTR_ID_UNAVAILABLE : irqnr; 62*91f16700Schasinglulu } 63*91f16700Schasinglulu 64*91f16700Schasinglulu /* 65*91f16700Schasinglulu * This function returns the type of the highest priority pending interrupt 66*91f16700Schasinglulu * at the Interrupt controller. In the case of GICv3, the Highest Priority 67*91f16700Schasinglulu * Pending interrupt system register (`ICC_HPPIR0_EL1`) is read to determine 68*91f16700Schasinglulu * the id of the pending interrupt. The type of interrupt depends upon the 69*91f16700Schasinglulu * id value as follows. 70*91f16700Schasinglulu * 1. id = PENDING_G1S_INTID (1020) is reported as a S-EL1 interrupt 71*91f16700Schasinglulu * 2. id = PENDING_G1NS_INTID (1021) is reported as a Non-secure interrupt. 72*91f16700Schasinglulu * 3. id = GIC_SPURIOUS_INTERRUPT (1023) is reported as an invalid interrupt 73*91f16700Schasinglulu * type. 74*91f16700Schasinglulu * 4. All other interrupt id's are reported as EL3 interrupt. 75*91f16700Schasinglulu */ 76*91f16700Schasinglulu uint32_t plat_ic_get_pending_interrupt_type(void) 77*91f16700Schasinglulu { 78*91f16700Schasinglulu unsigned int irqnr; 79*91f16700Schasinglulu uint32_t type; 80*91f16700Schasinglulu 81*91f16700Schasinglulu assert(IS_IN_EL3()); 82*91f16700Schasinglulu irqnr = gicv3_get_pending_interrupt_type(); 83*91f16700Schasinglulu 84*91f16700Schasinglulu switch (irqnr) { 85*91f16700Schasinglulu case PENDING_G1S_INTID: 86*91f16700Schasinglulu type = INTR_TYPE_S_EL1; 87*91f16700Schasinglulu break; 88*91f16700Schasinglulu case PENDING_G1NS_INTID: 89*91f16700Schasinglulu type = INTR_TYPE_NS; 90*91f16700Schasinglulu break; 91*91f16700Schasinglulu case GIC_SPURIOUS_INTERRUPT: 92*91f16700Schasinglulu type = INTR_TYPE_INVAL; 93*91f16700Schasinglulu break; 94*91f16700Schasinglulu default: 95*91f16700Schasinglulu type = INTR_TYPE_EL3; 96*91f16700Schasinglulu break; 97*91f16700Schasinglulu } 98*91f16700Schasinglulu 99*91f16700Schasinglulu return type; 100*91f16700Schasinglulu } 101*91f16700Schasinglulu 102*91f16700Schasinglulu /* 103*91f16700Schasinglulu * This function returns the highest priority pending interrupt at 104*91f16700Schasinglulu * the Interrupt controller and indicates to the Interrupt controller 105*91f16700Schasinglulu * that the interrupt processing has started. 106*91f16700Schasinglulu */ 107*91f16700Schasinglulu uint32_t plat_ic_acknowledge_interrupt(void) 108*91f16700Schasinglulu { 109*91f16700Schasinglulu assert(IS_IN_EL3()); 110*91f16700Schasinglulu return gicv3_acknowledge_interrupt(); 111*91f16700Schasinglulu } 112*91f16700Schasinglulu 113*91f16700Schasinglulu /* 114*91f16700Schasinglulu * This function returns the type of the interrupt `id`, depending on how 115*91f16700Schasinglulu * the interrupt has been configured in the interrupt controller. 116*91f16700Schasinglulu */ 117*91f16700Schasinglulu uint32_t plat_ic_get_interrupt_type(uint32_t id) 118*91f16700Schasinglulu { 119*91f16700Schasinglulu unsigned int group; 120*91f16700Schasinglulu 121*91f16700Schasinglulu assert(IS_IN_EL3()); 122*91f16700Schasinglulu group = gicv3_get_interrupt_group(id, plat_my_core_pos()); 123*91f16700Schasinglulu 124*91f16700Schasinglulu switch (group) { 125*91f16700Schasinglulu case INTR_GROUP0: 126*91f16700Schasinglulu return INTR_TYPE_EL3; 127*91f16700Schasinglulu case INTR_GROUP1S: 128*91f16700Schasinglulu return INTR_TYPE_S_EL1; 129*91f16700Schasinglulu case INTR_GROUP1NS: 130*91f16700Schasinglulu return INTR_TYPE_NS; 131*91f16700Schasinglulu default: 132*91f16700Schasinglulu assert(false); /* Unreachable */ 133*91f16700Schasinglulu return INTR_TYPE_EL3; 134*91f16700Schasinglulu } 135*91f16700Schasinglulu } 136*91f16700Schasinglulu 137*91f16700Schasinglulu /* 138*91f16700Schasinglulu * This functions is used to indicate to the interrupt controller that 139*91f16700Schasinglulu * the processing of the interrupt corresponding to the `id` has 140*91f16700Schasinglulu * finished. 141*91f16700Schasinglulu */ 142*91f16700Schasinglulu void plat_ic_end_of_interrupt(uint32_t id) 143*91f16700Schasinglulu { 144*91f16700Schasinglulu assert(IS_IN_EL3()); 145*91f16700Schasinglulu gicv3_end_of_interrupt(id); 146*91f16700Schasinglulu } 147*91f16700Schasinglulu 148*91f16700Schasinglulu /* 149*91f16700Schasinglulu * An ARM processor signals interrupt exceptions through the IRQ and FIQ pins. 150*91f16700Schasinglulu * The interrupt controller knows which pin/line it uses to signal a type of 151*91f16700Schasinglulu * interrupt. It lets the interrupt management framework determine for a type of 152*91f16700Schasinglulu * interrupt and security state, which line should be used in the SCR_EL3 to 153*91f16700Schasinglulu * control its routing to EL3. The interrupt line is represented as the bit 154*91f16700Schasinglulu * position of the IRQ or FIQ bit in the SCR_EL3. 155*91f16700Schasinglulu */ 156*91f16700Schasinglulu uint32_t plat_interrupt_type_to_line(uint32_t type, 157*91f16700Schasinglulu uint32_t security_state) 158*91f16700Schasinglulu { 159*91f16700Schasinglulu assert((type == INTR_TYPE_S_EL1) || 160*91f16700Schasinglulu (type == INTR_TYPE_EL3) || 161*91f16700Schasinglulu (type == INTR_TYPE_NS)); 162*91f16700Schasinglulu 163*91f16700Schasinglulu assert(sec_state_is_valid(security_state)); 164*91f16700Schasinglulu assert(IS_IN_EL3()); 165*91f16700Schasinglulu 166*91f16700Schasinglulu switch (type) { 167*91f16700Schasinglulu case INTR_TYPE_S_EL1: 168*91f16700Schasinglulu /* 169*91f16700Schasinglulu * The S-EL1 interrupts are signaled as IRQ in S-EL0/1 contexts 170*91f16700Schasinglulu * and as FIQ in the NS-EL0/1/2 contexts 171*91f16700Schasinglulu */ 172*91f16700Schasinglulu if (security_state == SECURE) 173*91f16700Schasinglulu return __builtin_ctz(SCR_IRQ_BIT); 174*91f16700Schasinglulu else 175*91f16700Schasinglulu return __builtin_ctz(SCR_FIQ_BIT); 176*91f16700Schasinglulu assert(0); /* Unreachable */ 177*91f16700Schasinglulu case INTR_TYPE_NS: 178*91f16700Schasinglulu /* 179*91f16700Schasinglulu * The Non secure interrupts will be signaled as FIQ in S-EL0/1 180*91f16700Schasinglulu * contexts and as IRQ in the NS-EL0/1/2 contexts. 181*91f16700Schasinglulu */ 182*91f16700Schasinglulu if (security_state == SECURE) 183*91f16700Schasinglulu return __builtin_ctz(SCR_FIQ_BIT); 184*91f16700Schasinglulu else 185*91f16700Schasinglulu return __builtin_ctz(SCR_IRQ_BIT); 186*91f16700Schasinglulu assert(0); /* Unreachable */ 187*91f16700Schasinglulu case INTR_TYPE_EL3: 188*91f16700Schasinglulu /* 189*91f16700Schasinglulu * The EL3 interrupts are signaled as FIQ in both S-EL0/1 and 190*91f16700Schasinglulu * NS-EL0/1/2 contexts 191*91f16700Schasinglulu */ 192*91f16700Schasinglulu return __builtin_ctz(SCR_FIQ_BIT); 193*91f16700Schasinglulu default: 194*91f16700Schasinglulu panic(); 195*91f16700Schasinglulu } 196*91f16700Schasinglulu } 197*91f16700Schasinglulu 198*91f16700Schasinglulu unsigned int plat_ic_get_running_priority(void) 199*91f16700Schasinglulu { 200*91f16700Schasinglulu return gicv3_get_running_priority(); 201*91f16700Schasinglulu } 202*91f16700Schasinglulu 203*91f16700Schasinglulu int plat_ic_is_spi(unsigned int id) 204*91f16700Schasinglulu { 205*91f16700Schasinglulu return (id >= MIN_SPI_ID) && (id <= MAX_SPI_ID); 206*91f16700Schasinglulu } 207*91f16700Schasinglulu 208*91f16700Schasinglulu int plat_ic_is_ppi(unsigned int id) 209*91f16700Schasinglulu { 210*91f16700Schasinglulu return (id >= MIN_PPI_ID) && (id < MIN_SPI_ID); 211*91f16700Schasinglulu } 212*91f16700Schasinglulu 213*91f16700Schasinglulu int plat_ic_is_sgi(unsigned int id) 214*91f16700Schasinglulu { 215*91f16700Schasinglulu return (id >= MIN_SGI_ID) && (id < MIN_PPI_ID); 216*91f16700Schasinglulu } 217*91f16700Schasinglulu 218*91f16700Schasinglulu unsigned int plat_ic_get_interrupt_active(unsigned int id) 219*91f16700Schasinglulu { 220*91f16700Schasinglulu return gicv3_get_interrupt_active(id, plat_my_core_pos()); 221*91f16700Schasinglulu } 222*91f16700Schasinglulu 223*91f16700Schasinglulu void plat_ic_enable_interrupt(unsigned int id) 224*91f16700Schasinglulu { 225*91f16700Schasinglulu gicv3_enable_interrupt(id, plat_my_core_pos()); 226*91f16700Schasinglulu } 227*91f16700Schasinglulu 228*91f16700Schasinglulu void plat_ic_disable_interrupt(unsigned int id) 229*91f16700Schasinglulu { 230*91f16700Schasinglulu gicv3_disable_interrupt(id, plat_my_core_pos()); 231*91f16700Schasinglulu } 232*91f16700Schasinglulu 233*91f16700Schasinglulu void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority) 234*91f16700Schasinglulu { 235*91f16700Schasinglulu gicv3_set_interrupt_priority(id, plat_my_core_pos(), priority); 236*91f16700Schasinglulu } 237*91f16700Schasinglulu 238*91f16700Schasinglulu bool plat_ic_has_interrupt_type(unsigned int type) 239*91f16700Schasinglulu { 240*91f16700Schasinglulu if ((type == INTR_TYPE_EL3) || (type == INTR_TYPE_S_EL1) || 241*91f16700Schasinglulu (type == INTR_TYPE_NS)) { 242*91f16700Schasinglulu return true; 243*91f16700Schasinglulu } 244*91f16700Schasinglulu 245*91f16700Schasinglulu return false; 246*91f16700Schasinglulu } 247*91f16700Schasinglulu 248*91f16700Schasinglulu void plat_ic_set_interrupt_type(unsigned int id, unsigned int type) 249*91f16700Schasinglulu { 250*91f16700Schasinglulu unsigned int group; 251*91f16700Schasinglulu 252*91f16700Schasinglulu switch (type) { 253*91f16700Schasinglulu case INTR_TYPE_EL3: 254*91f16700Schasinglulu group = INTR_GROUP0; 255*91f16700Schasinglulu break; 256*91f16700Schasinglulu case INTR_TYPE_S_EL1: 257*91f16700Schasinglulu group = INTR_GROUP1S; 258*91f16700Schasinglulu break; 259*91f16700Schasinglulu case INTR_TYPE_NS: 260*91f16700Schasinglulu group = INTR_GROUP1NS; 261*91f16700Schasinglulu break; 262*91f16700Schasinglulu default: 263*91f16700Schasinglulu assert(false); /* Unreachable */ 264*91f16700Schasinglulu group = INTR_GROUP0; 265*91f16700Schasinglulu break; 266*91f16700Schasinglulu } 267*91f16700Schasinglulu 268*91f16700Schasinglulu gicv3_set_interrupt_group(id, plat_my_core_pos(), group); 269*91f16700Schasinglulu } 270*91f16700Schasinglulu 271*91f16700Schasinglulu void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target) 272*91f16700Schasinglulu { 273*91f16700Schasinglulu /* Target must be a valid MPIDR in the system */ 274*91f16700Schasinglulu assert(plat_core_pos_by_mpidr(target) >= 0); 275*91f16700Schasinglulu 276*91f16700Schasinglulu /* Verify that this is a secure EL3 SGI */ 277*91f16700Schasinglulu assert(plat_ic_get_interrupt_type((unsigned int)sgi_num) == 278*91f16700Schasinglulu INTR_TYPE_EL3); 279*91f16700Schasinglulu 280*91f16700Schasinglulu gicv3_raise_sgi((unsigned int)sgi_num, GICV3_G0, target); 281*91f16700Schasinglulu } 282*91f16700Schasinglulu 283*91f16700Schasinglulu void plat_ic_raise_ns_sgi(int sgi_num, u_register_t target) 284*91f16700Schasinglulu { 285*91f16700Schasinglulu /* Target must be a valid MPIDR in the system */ 286*91f16700Schasinglulu assert(plat_core_pos_by_mpidr(target) >= 0); 287*91f16700Schasinglulu 288*91f16700Schasinglulu /* Verify that this is a non-secure SGI */ 289*91f16700Schasinglulu assert(plat_ic_get_interrupt_type((unsigned int)sgi_num) == 290*91f16700Schasinglulu INTR_TYPE_NS); 291*91f16700Schasinglulu 292*91f16700Schasinglulu gicv3_raise_sgi((unsigned int)sgi_num, GICV3_G1NS, target); 293*91f16700Schasinglulu } 294*91f16700Schasinglulu 295*91f16700Schasinglulu void plat_ic_raise_s_el1_sgi(int sgi_num, u_register_t target) 296*91f16700Schasinglulu { 297*91f16700Schasinglulu /* Target must be a valid MPIDR in the system */ 298*91f16700Schasinglulu assert(plat_core_pos_by_mpidr(target) >= 0); 299*91f16700Schasinglulu 300*91f16700Schasinglulu /* Verify that this is a secure EL1 SGI */ 301*91f16700Schasinglulu assert(plat_ic_get_interrupt_type((unsigned int)sgi_num) == 302*91f16700Schasinglulu INTR_TYPE_S_EL1); 303*91f16700Schasinglulu 304*91f16700Schasinglulu gicv3_raise_sgi((unsigned int)sgi_num, GICV3_G1S, target); 305*91f16700Schasinglulu } 306*91f16700Schasinglulu 307*91f16700Schasinglulu void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode, 308*91f16700Schasinglulu u_register_t mpidr) 309*91f16700Schasinglulu { 310*91f16700Schasinglulu unsigned int irm = 0; 311*91f16700Schasinglulu 312*91f16700Schasinglulu switch (routing_mode) { 313*91f16700Schasinglulu case INTR_ROUTING_MODE_PE: 314*91f16700Schasinglulu assert(plat_core_pos_by_mpidr(mpidr) >= 0); 315*91f16700Schasinglulu irm = GICV3_IRM_PE; 316*91f16700Schasinglulu break; 317*91f16700Schasinglulu case INTR_ROUTING_MODE_ANY: 318*91f16700Schasinglulu irm = GICV3_IRM_ANY; 319*91f16700Schasinglulu break; 320*91f16700Schasinglulu default: 321*91f16700Schasinglulu assert(0); /* Unreachable */ 322*91f16700Schasinglulu break; 323*91f16700Schasinglulu } 324*91f16700Schasinglulu 325*91f16700Schasinglulu gicv3_set_spi_routing(id, irm, mpidr); 326*91f16700Schasinglulu } 327*91f16700Schasinglulu 328*91f16700Schasinglulu void plat_ic_set_interrupt_pending(unsigned int id) 329*91f16700Schasinglulu { 330*91f16700Schasinglulu /* Disallow setting SGIs pending */ 331*91f16700Schasinglulu assert(id >= MIN_PPI_ID); 332*91f16700Schasinglulu gicv3_set_interrupt_pending(id, plat_my_core_pos()); 333*91f16700Schasinglulu } 334*91f16700Schasinglulu 335*91f16700Schasinglulu void plat_ic_clear_interrupt_pending(unsigned int id) 336*91f16700Schasinglulu { 337*91f16700Schasinglulu /* Disallow setting SGIs pending */ 338*91f16700Schasinglulu assert(id >= MIN_PPI_ID); 339*91f16700Schasinglulu gicv3_clear_interrupt_pending(id, plat_my_core_pos()); 340*91f16700Schasinglulu } 341*91f16700Schasinglulu 342*91f16700Schasinglulu unsigned int plat_ic_set_priority_mask(unsigned int mask) 343*91f16700Schasinglulu { 344*91f16700Schasinglulu return gicv3_set_pmr(mask); 345*91f16700Schasinglulu } 346*91f16700Schasinglulu 347*91f16700Schasinglulu unsigned int plat_ic_get_interrupt_id(unsigned int raw) 348*91f16700Schasinglulu { 349*91f16700Schasinglulu unsigned int id = raw & INT_ID_MASK; 350*91f16700Schasinglulu 351*91f16700Schasinglulu return gicv3_is_intr_id_special_identifier(id) ? 352*91f16700Schasinglulu INTR_ID_UNAVAILABLE : id; 353*91f16700Schasinglulu } 354*91f16700Schasinglulu #endif 355*91f16700Schasinglulu #ifdef IMAGE_BL32 356*91f16700Schasinglulu 357*91f16700Schasinglulu #pragma weak plat_ic_get_pending_interrupt_id 358*91f16700Schasinglulu #pragma weak plat_ic_acknowledge_interrupt 359*91f16700Schasinglulu #pragma weak plat_ic_end_of_interrupt 360*91f16700Schasinglulu 361*91f16700Schasinglulu /* In AArch32, the secure group1 interrupts are targeted to Secure PL1 */ 362*91f16700Schasinglulu #ifndef __aarch64__ 363*91f16700Schasinglulu #define IS_IN_EL1() IS_IN_SECURE() 364*91f16700Schasinglulu #endif 365*91f16700Schasinglulu 366*91f16700Schasinglulu /* 367*91f16700Schasinglulu * This function returns the highest priority pending interrupt at 368*91f16700Schasinglulu * the Interrupt controller 369*91f16700Schasinglulu */ 370*91f16700Schasinglulu uint32_t plat_ic_get_pending_interrupt_id(void) 371*91f16700Schasinglulu { 372*91f16700Schasinglulu unsigned int irqnr; 373*91f16700Schasinglulu 374*91f16700Schasinglulu assert(IS_IN_EL1()); 375*91f16700Schasinglulu irqnr = gicv3_get_pending_interrupt_id_sel1(); 376*91f16700Schasinglulu return (irqnr == GIC_SPURIOUS_INTERRUPT) ? 377*91f16700Schasinglulu INTR_ID_UNAVAILABLE : irqnr; 378*91f16700Schasinglulu } 379*91f16700Schasinglulu 380*91f16700Schasinglulu /* 381*91f16700Schasinglulu * This function returns the highest priority pending interrupt at 382*91f16700Schasinglulu * the Interrupt controller and indicates to the Interrupt controller 383*91f16700Schasinglulu * that the interrupt processing has started. 384*91f16700Schasinglulu */ 385*91f16700Schasinglulu uint32_t plat_ic_acknowledge_interrupt(void) 386*91f16700Schasinglulu { 387*91f16700Schasinglulu assert(IS_IN_EL1()); 388*91f16700Schasinglulu return gicv3_acknowledge_interrupt_sel1(); 389*91f16700Schasinglulu } 390*91f16700Schasinglulu 391*91f16700Schasinglulu /* 392*91f16700Schasinglulu * This functions is used to indicate to the interrupt controller that 393*91f16700Schasinglulu * the processing of the interrupt corresponding to the `id` has 394*91f16700Schasinglulu * finished. 395*91f16700Schasinglulu */ 396*91f16700Schasinglulu void plat_ic_end_of_interrupt(uint32_t id) 397*91f16700Schasinglulu { 398*91f16700Schasinglulu assert(IS_IN_EL1()); 399*91f16700Schasinglulu gicv3_end_of_interrupt_sel1(id); 400*91f16700Schasinglulu } 401*91f16700Schasinglulu #endif 402