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