1*91f16700SchasingluluPlatform Interrupt Controller API 2*91f16700Schasinglulu================================= 3*91f16700Schasinglulu 4*91f16700SchasingluluThis document lists the optional platform interrupt controller API that 5*91f16700Schasingluluabstracts the runtime configuration and control of interrupt controller from the 6*91f16700Schasinglulugeneric code. The mandatory APIs are described in the 7*91f16700Schasinglulu:ref:`Porting Guide <porting_guide_imf_in_bl31>`. 8*91f16700Schasinglulu 9*91f16700SchasingluluFunction: unsigned int plat_ic_get_running_priority(void); [optional] 10*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 11*91f16700Schasinglulu 12*91f16700Schasinglulu:: 13*91f16700Schasinglulu 14*91f16700Schasinglulu Argument : void 15*91f16700Schasinglulu Return : unsigned int 16*91f16700Schasinglulu 17*91f16700SchasingluluThis API should return the priority of the interrupt the PE is currently 18*91f16700Schasingluluservicing. This must be be called only after an interrupt has already been 19*91f16700Schasingluluacknowledged via ``plat_ic_acknowledge_interrupt``. 20*91f16700Schasinglulu 21*91f16700SchasingluluIn the case of Arm standard platforms using GIC, the *Running Priority Register* 22*91f16700Schasingluluis read to determine the priority of the interrupt. 23*91f16700Schasinglulu 24*91f16700SchasingluluFunction: int plat_ic_is_spi(unsigned int id); [optional] 25*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 26*91f16700Schasinglulu 27*91f16700Schasinglulu:: 28*91f16700Schasinglulu 29*91f16700Schasinglulu Argument : unsigned int 30*91f16700Schasinglulu Return : int 31*91f16700Schasinglulu 32*91f16700SchasingluluThe API should return whether the interrupt ID (first parameter) is categorized 33*91f16700Schasingluluas a Shared Peripheral Interrupt. Shared Peripheral Interrupts are typically 34*91f16700Schasingluluassociated to system-wide peripherals, and these interrupts can target any PE in 35*91f16700Schasingluluthe system. 36*91f16700Schasinglulu 37*91f16700SchasingluluFunction: int plat_ic_is_ppi(unsigned int id); [optional] 38*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 39*91f16700Schasinglulu 40*91f16700Schasinglulu:: 41*91f16700Schasinglulu 42*91f16700Schasinglulu Argument : unsigned int 43*91f16700Schasinglulu Return : int 44*91f16700Schasinglulu 45*91f16700SchasingluluThe API should return whether the interrupt ID (first parameter) is categorized 46*91f16700Schasingluluas a Private Peripheral Interrupt. Private Peripheral Interrupts are typically 47*91f16700Schasingluluassociated with peripherals that are private to each PE. Interrupts from private 48*91f16700Schasingluluperipherals target to that PE only. 49*91f16700Schasinglulu 50*91f16700SchasingluluFunction: int plat_ic_is_sgi(unsigned int id); [optional] 51*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 52*91f16700Schasinglulu 53*91f16700Schasinglulu:: 54*91f16700Schasinglulu 55*91f16700Schasinglulu Argument : unsigned int 56*91f16700Schasinglulu Return : int 57*91f16700Schasinglulu 58*91f16700SchasingluluThe API should return whether the interrupt ID (first parameter) is categorized 59*91f16700Schasingluluas a Software Generated Interrupt. Software Generated Interrupts are raised by 60*91f16700Schasingluluexplicit programming by software, and are typically used in inter-PE 61*91f16700Schasinglulucommunication. Secure SGIs are reserved for use by Secure world software. 62*91f16700Schasinglulu 63*91f16700SchasingluluFunction: unsigned int plat_ic_get_interrupt_active(unsigned int id); [optional] 64*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 65*91f16700Schasinglulu 66*91f16700Schasinglulu:: 67*91f16700Schasinglulu 68*91f16700Schasinglulu Argument : unsigned int 69*91f16700Schasinglulu Return : int 70*91f16700Schasinglulu 71*91f16700SchasingluluThis API should return the *active* status of the interrupt ID specified by the 72*91f16700Schasinglulufirst parameter, ``id``. 73*91f16700Schasinglulu 74*91f16700SchasingluluIn case of Arm standard platforms using GIC, the implementation of the API reads 75*91f16700Schasingluluthe GIC *Set Active Register* to read and return the active status of the 76*91f16700Schasingluluinterrupt. 77*91f16700Schasinglulu 78*91f16700SchasingluluFunction: void plat_ic_enable_interrupt(unsigned int id); [optional] 79*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 80*91f16700Schasinglulu 81*91f16700Schasinglulu:: 82*91f16700Schasinglulu 83*91f16700Schasinglulu Argument : unsigned int 84*91f16700Schasinglulu Return : void 85*91f16700Schasinglulu 86*91f16700SchasingluluThis API should enable the interrupt ID specified by the first parameter, 87*91f16700Schasinglulu``id``. PEs in the system are expected to receive only enabled interrupts. 88*91f16700Schasinglulu 89*91f16700SchasingluluIn case of Arm standard platforms using GIC, the implementation of the API 90*91f16700Schasingluluinserts barrier to make memory updates visible before enabling interrupt, and 91*91f16700Schasingluluthen writes to GIC *Set Enable Register* to enable the interrupt. 92*91f16700Schasinglulu 93*91f16700SchasingluluFunction: void plat_ic_disable_interrupt(unsigned int id); [optional] 94*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 95*91f16700Schasinglulu 96*91f16700Schasinglulu:: 97*91f16700Schasinglulu 98*91f16700Schasinglulu Argument : unsigned int 99*91f16700Schasinglulu Return : void 100*91f16700Schasinglulu 101*91f16700SchasingluluThis API should disable the interrupt ID specified by the first parameter, 102*91f16700Schasinglulu``id``. PEs in the system are not expected to receive disabled interrupts. 103*91f16700Schasinglulu 104*91f16700SchasingluluIn case of Arm standard platforms using GIC, the implementation of the API 105*91f16700Schasingluluwrites to GIC *Clear Enable Register* to disable the interrupt, and inserts 106*91f16700Schasinglulubarrier to make memory updates visible afterwards. 107*91f16700Schasinglulu 108*91f16700SchasingluluFunction: void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority); [optional] 109*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 110*91f16700Schasinglulu 111*91f16700Schasinglulu:: 112*91f16700Schasinglulu 113*91f16700Schasinglulu Argument : unsigned int 114*91f16700Schasinglulu Argument : unsigned int 115*91f16700Schasinglulu Return : void 116*91f16700Schasinglulu 117*91f16700SchasingluluThis API should set the priority of the interrupt specified by first parameter 118*91f16700Schasinglulu``id`` to the value set by the second parameter ``priority``. 119*91f16700Schasinglulu 120*91f16700SchasingluluIn case of Arm standard platforms using GIC, the implementation of the API 121*91f16700Schasingluluwrites to GIC *Priority Register* set interrupt priority. 122*91f16700Schasinglulu 123*91f16700SchasingluluFunction: bool plat_ic_has_interrupt_type(unsigned int type); [optional] 124*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 125*91f16700Schasinglulu 126*91f16700Schasinglulu:: 127*91f16700Schasinglulu 128*91f16700Schasinglulu Argument : unsigned int 129*91f16700Schasinglulu Return : bool 130*91f16700Schasinglulu 131*91f16700SchasingluluThis API should return whether the platform supports a given interrupt type. The 132*91f16700Schasingluluparameter ``type`` shall be one of ``INTR_TYPE_EL3``, ``INTR_TYPE_S_EL1``, or 133*91f16700Schasinglulu``INTR_TYPE_NS``. 134*91f16700Schasinglulu 135*91f16700SchasingluluIn case of Arm standard platforms using GICv3, the implementation of the API 136*91f16700Schasinglulureturns *true* for all interrupt types. 137*91f16700Schasinglulu 138*91f16700SchasingluluIn case of Arm standard platforms using GICv2, the API always return *true* for 139*91f16700Schasinglulu``INTR_TYPE_NS``. Return value for other types depends on the value of build 140*91f16700Schasingluluoption ``GICV2_G0_FOR_EL3``: 141*91f16700Schasinglulu 142*91f16700Schasinglulu- For interrupt type ``INTR_TYPE_EL3``: 143*91f16700Schasinglulu 144*91f16700Schasinglulu - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns *false*, indicating no support 145*91f16700Schasinglulu for EL3 interrupts. 146*91f16700Schasinglulu 147*91f16700Schasinglulu - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns *true*, indicating support for 148*91f16700Schasinglulu EL3 interrupts. 149*91f16700Schasinglulu 150*91f16700Schasinglulu- For interrupt type ``INTR_TYPE_S_EL1``: 151*91f16700Schasinglulu 152*91f16700Schasinglulu - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns *true*, indicating support for 153*91f16700Schasinglulu Secure EL1 interrupts. 154*91f16700Schasinglulu 155*91f16700Schasinglulu - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns *false*, indicating no support 156*91f16700Schasinglulu for Secure EL1 interrupts. 157*91f16700Schasinglulu 158*91f16700SchasingluluFunction: void plat_ic_set_interrupt_type(unsigned int id, unsigned int type); [optional] 159*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 160*91f16700Schasinglulu 161*91f16700Schasinglulu:: 162*91f16700Schasinglulu 163*91f16700Schasinglulu Argument : unsigned int 164*91f16700Schasinglulu Argument : unsigned int 165*91f16700Schasinglulu Return : void 166*91f16700Schasinglulu 167*91f16700SchasingluluThis API should set the interrupt specified by first parameter ``id`` to the 168*91f16700Schasinglulutype specified by second parameter ``type``. The ``type`` parameter can be 169*91f16700Schasingluluone of: 170*91f16700Schasinglulu 171*91f16700Schasinglulu- ``INTR_TYPE_NS``: interrupt is meant to be consumed by the Non-secure world. 172*91f16700Schasinglulu 173*91f16700Schasinglulu- ``INTR_TYPE_S_EL1``: interrupt is meant to be consumed by Secure EL1. 174*91f16700Schasinglulu 175*91f16700Schasinglulu- ``INTR_TYPE_EL3``: interrupt is meant to be consumed by EL3. 176*91f16700Schasinglulu 177*91f16700SchasingluluIn case of Arm standard platforms using GIC, the implementation of the API 178*91f16700Schasingluluwrites to the GIC *Group Register* and *Group Modifier Register* (only GICv3) to 179*91f16700Schasingluluassign the interrupt to the right group. 180*91f16700Schasinglulu 181*91f16700SchasingluluFor GICv3: 182*91f16700Schasinglulu 183*91f16700Schasinglulu- ``INTR_TYPE_NS`` maps to Group 1 interrupt. 184*91f16700Schasinglulu 185*91f16700Schasinglulu- ``INTR_TYPE_S_EL1`` maps to Secure Group 1 interrupt. 186*91f16700Schasinglulu 187*91f16700Schasinglulu- ``INTR_TYPE_EL3`` maps to Secure Group 0 interrupt. 188*91f16700Schasinglulu 189*91f16700SchasingluluFor GICv2: 190*91f16700Schasinglulu 191*91f16700Schasinglulu- ``INTR_TYPE_NS`` maps to Group 1 interrupt. 192*91f16700Schasinglulu 193*91f16700Schasinglulu- When the build option ``GICV2_G0_FOR_EL3`` is set to ``0`` (the default), 194*91f16700Schasinglulu ``INTR_TYPE_S_EL1`` maps to Group 0. Otherwise, ``INTR_TYPE_EL3`` maps to 195*91f16700Schasinglulu Group 0 interrupt. 196*91f16700Schasinglulu 197*91f16700SchasingluluFunction: void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target); [optional] 198*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 199*91f16700Schasinglulu 200*91f16700Schasinglulu:: 201*91f16700Schasinglulu 202*91f16700Schasinglulu Argument : int 203*91f16700Schasinglulu Argument : u_register_t 204*91f16700Schasinglulu Return : void 205*91f16700Schasinglulu 206*91f16700SchasingluluThis API should raise an EL3 SGI. The first parameter, ``sgi_num``, specifies 207*91f16700Schasingluluthe ID of the SGI. The second parameter, ``target``, must be the MPIDR of the 208*91f16700Schasinglulutarget PE. 209*91f16700Schasinglulu 210*91f16700SchasingluluIn case of Arm standard platforms using GIC, the implementation of the API 211*91f16700Schasingluluinserts barrier to make memory updates visible before raising SGI, then writes 212*91f16700Schasingluluto appropriate *SGI Register* in order to raise the EL3 SGI. 213*91f16700Schasinglulu 214*91f16700SchasingluluFunction: void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode, u_register_t mpidr); [optional] 215*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 216*91f16700Schasinglulu 217*91f16700Schasinglulu:: 218*91f16700Schasinglulu 219*91f16700Schasinglulu Argument : unsigned int 220*91f16700Schasinglulu Argument : unsigned int 221*91f16700Schasinglulu Argument : u_register_t 222*91f16700Schasinglulu Return : void 223*91f16700Schasinglulu 224*91f16700SchasingluluThis API should set the routing mode of Share Peripheral Interrupt (SPI) 225*91f16700Schasingluluspecified by first parameter ``id`` to that specified by the second parameter 226*91f16700Schasinglulu``routing_mode``. 227*91f16700Schasinglulu 228*91f16700SchasingluluThe ``routing_mode`` parameter can be one of: 229*91f16700Schasinglulu 230*91f16700Schasinglulu- ``INTR_ROUTING_MODE_ANY`` means the interrupt can be routed to any PE in the 231*91f16700Schasinglulu system. The ``mpidr`` parameter is ignored in this case. 232*91f16700Schasinglulu 233*91f16700Schasinglulu- ``INTR_ROUTING_MODE_PE`` means the interrupt is routed to the PE whose MPIDR 234*91f16700Schasinglulu value is specified by the parameter ``mpidr``. 235*91f16700Schasinglulu 236*91f16700SchasingluluIn case of Arm standard platforms using GIC, the implementation of the API 237*91f16700Schasingluluwrites to the GIC *Target Register* (GICv2) or *Route Register* (GICv3) to set 238*91f16700Schasingluluthe routing. 239*91f16700Schasinglulu 240*91f16700SchasingluluFunction: void plat_ic_set_interrupt_pending(unsigned int id); [optional] 241*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 242*91f16700Schasinglulu 243*91f16700Schasinglulu:: 244*91f16700Schasinglulu 245*91f16700Schasinglulu Argument : unsigned int 246*91f16700Schasinglulu Return : void 247*91f16700Schasinglulu 248*91f16700SchasingluluThis API should set the interrupt specified by first parameter ``id`` to 249*91f16700Schasinglulu*Pending*. 250*91f16700Schasinglulu 251*91f16700SchasingluluIn case of Arm standard platforms using GIC, the implementation of the API 252*91f16700Schasingluluinserts barrier to make memory updates visible before setting interrupt pending, 253*91f16700Schasingluluand writes to the GIC *Set Pending Register* to set the interrupt pending 254*91f16700Schasinglulustatus. 255*91f16700Schasinglulu 256*91f16700SchasingluluFunction: void plat_ic_clear_interrupt_pending(unsigned int id); [optional] 257*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 258*91f16700Schasinglulu 259*91f16700Schasinglulu:: 260*91f16700Schasinglulu 261*91f16700Schasinglulu Argument : unsigned int 262*91f16700Schasinglulu Return : void 263*91f16700Schasinglulu 264*91f16700SchasingluluThis API should clear the *Pending* status of the interrupt specified by first 265*91f16700Schasingluluparameter ``id``. 266*91f16700Schasinglulu 267*91f16700SchasingluluIn case of Arm standard platforms using GIC, the implementation of the API 268*91f16700Schasingluluwrites to the GIC *Clear Pending Register* to clear the interrupt pending 269*91f16700Schasinglulustatus, and inserts barrier to make memory updates visible afterwards. 270*91f16700Schasinglulu 271*91f16700SchasingluluFunction: unsigned int plat_ic_set_priority_mask(unsigned int id); [optional] 272*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 273*91f16700Schasinglulu 274*91f16700Schasinglulu:: 275*91f16700Schasinglulu 276*91f16700Schasinglulu Argument : unsigned int 277*91f16700Schasinglulu Return : int 278*91f16700Schasinglulu 279*91f16700SchasingluluThis API should set the priority mask (first parameter) in the interrupt 280*91f16700Schasinglulucontroller such that only interrupts of higher priority than the supplied one 281*91f16700Schasinglulumay be signalled to the PE. The API should return the current priority value 282*91f16700Schasingluluthat it's overwriting. 283*91f16700Schasinglulu 284*91f16700SchasingluluIn case of Arm standard platforms using GIC, the implementation of the API 285*91f16700Schasingluluinserts to order memory updates before updating mask, then writes to the GIC 286*91f16700Schasinglulu*Priority Mask Register*, and make sure memory updates are visible before 287*91f16700Schasinglulupotential trigger due to mask update. 288*91f16700Schasinglulu 289*91f16700Schasinglulu.. _plat_ic_get_interrupt_id: 290*91f16700Schasinglulu 291*91f16700SchasingluluFunction: unsigned int plat_ic_get_interrupt_id(unsigned int raw); [optional] 292*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 293*91f16700Schasinglulu 294*91f16700Schasinglulu:: 295*91f16700Schasinglulu 296*91f16700Schasinglulu Argument : unsigned int 297*91f16700Schasinglulu Return : unsigned int 298*91f16700Schasinglulu 299*91f16700SchasingluluThis API should extract and return the interrupt number from the raw value 300*91f16700Schasingluluobtained by the acknowledging the interrupt (read using 301*91f16700Schasinglulu``plat_ic_acknowledge_interrupt()``). If the interrupt ID is invalid, this API 302*91f16700Schasinglulushould return ``INTR_ID_UNAVAILABLE``. 303*91f16700Schasinglulu 304*91f16700SchasingluluIn case of Arm standard platforms using GIC, the implementation of the API 305*91f16700Schasinglulumasks out the interrupt ID field from the acknowledged value from GIC. 306*91f16700Schasinglulu 307*91f16700Schasinglulu-------------- 308*91f16700Schasinglulu 309*91f16700Schasinglulu*Copyright (c) 2017-2023, Arm Limited and Contributors. All rights reserved.* 310