xref: /arm-trusted-firmware/docs/components/platform-interrupt-controller-API.rst (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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