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