platform-interrupt-controller-API.rst 10.7 KB
Newer Older
Paul Beesley's avatar
Paul Beesley committed
1
2
Platform Interrupt Controller API
=================================
3
4
5
6
7

This document lists the optional platform interrupt controller API that
abstracts the runtime configuration and control of interrupt controller from the
generic code. The mandatory APIs are described in the `porting guide`__.

8
.. __: ../getting_started/porting-guide.rst#interrupt-management-framework-in-bl31
9
10
11
12
13
14
15
16
17
18
19

Function: unsigned int plat_ic_get_running_priority(void); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : void
    Return   : unsigned int

This API should return the priority of the interrupt the PE is currently
servicing. This must be be called only after an interrupt has already been
20
acknowledged via ``plat_ic_acknowledge_interrupt``.
21

Dan Handley's avatar
Dan Handley committed
22
In the case of Arm standard platforms using GIC, the *Running Priority Register*
23
24
is read to determine the priority of the interrupt.

25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
Function: int plat_ic_is_spi(unsigned int id); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Return   : int

The API should return whether the interrupt ID (first parameter) is categorized
as a Shared Peripheral Interrupt. Shared Peripheral Interrupts are typically
associated to system-wide peripherals, and these interrupts can target any PE in
the system.

Function: int plat_ic_is_ppi(unsigned int id); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Return   : int

The API should return whether the interrupt ID (first parameter) is categorized
as a Private Peripheral Interrupt. Private Peripheral Interrupts are typically
associated with peripherals that are private to each PE. Interrupts from private
peripherals target to that PE only.

Function: int plat_ic_is_sgi(unsigned int id); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Return   : int

The API should return whether the interrupt ID (first parameter) is categorized
as a Software Generated Interrupt. Software Generated Interrupts are raised by
explicit programming by software, and are typically used in inter-PE
communication. Secure SGIs are reserved for use by Secure world software.

64
65
66
67
68
69
70
71
72
73
74
Function: unsigned int plat_ic_get_interrupt_active(unsigned int id); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Return   : int

This API should return the *active* status of the interrupt ID specified by the
first parameter, ``id``.

Dan Handley's avatar
Dan Handley committed
75
In case of Arm standard platforms using GIC, the implementation of the API reads
76
77
78
the GIC *Set Active Register* to read and return the active status of the
interrupt.

79
80
81
82
83
84
85
86
87
88
89
Function: void plat_ic_enable_interrupt(unsigned int id); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Return   : void

This API should enable the interrupt ID specified by the first parameter,
``id``. PEs in the system are expected to receive only enabled interrupts.

Dan Handley's avatar
Dan Handley committed
90
In case of Arm standard platforms using GIC, the implementation of the API
91
92
93
94
95
96
97
98
99
100
101
102
103
104
inserts barrier to make memory updates visible before enabling interrupt, and
then writes to GIC *Set Enable Register* to enable the interrupt.

Function: void plat_ic_disable_interrupt(unsigned int id); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Return   : void

This API should disable the interrupt ID specified by the first parameter,
``id``. PEs in the system are not expected to receive disabled interrupts.

Dan Handley's avatar
Dan Handley committed
105
In case of Arm standard platforms using GIC, the implementation of the API
106
107
108
writes to GIC *Clear Enable Register* to disable the interrupt, and inserts
barrier to make memory updates visible afterwards.

109
110
111
112
113
114
115
116
117
118
119
120
Function: void plat_ic_set_interrupt_priority(unsigned int id, unsigned int priority); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Argument : unsigned int
    Return   : void

This API should set the priority of the interrupt specified by first parameter
``id`` to the value set by the second parameter ``priority``.

Dan Handley's avatar
Dan Handley committed
121
In case of Arm standard platforms using GIC, the implementation of the API
122
123
writes to GIC *Priority Register* set interrupt priority.

124
125
126
127
128
129
130
131
132
133
134
135
Function: int plat_ic_has_interrupt_type(unsigned int type); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Return   : int

This API should return whether the platform supports a given interrupt type. The
parameter ``type`` shall be one of ``INTR_TYPE_EL3``, ``INTR_TYPE_S_EL1``, or
``INTR_TYPE_NS``.

Dan Handley's avatar
Dan Handley committed
136
In case of Arm standard platforms using GICv3, the implementation of the API
137
138
returns ``1`` for all interrupt types.

Dan Handley's avatar
Dan Handley committed
139
In case of Arm standard platforms using GICv2, the API always return ``1`` for
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
``INTR_TYPE_NS``. Return value for other types depends on the value of build
option ``GICV2_G0_FOR_EL3``:

- For interrupt type ``INTR_TYPE_EL3``:

  - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns ``0``, indicating no support
    for EL3 interrupts.

  - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns ``1``, indicating support for
    EL3 interrupts.

- For interrupt type ``INTR_TYPE_S_EL1``:

  - When ``GICV2_G0_FOR_EL3`` is ``0``, it returns ``1``, indicating support for
    Secure EL1 interrupts.

  - When ``GICV2_G0_FOR_EL3`` is ``1``, it returns ``0``, indicating no support
    for Secure EL1 interrupts.

Function: void plat_ic_set_interrupt_type(unsigned int id, unsigned int type); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Argument : unsigned int
    Return   : void

This API should set the interrupt specified by first parameter ``id`` to the
type specified by second parameter ``type``. The ``type`` parameter can be
one of:

- ``INTR_TYPE_NS``: interrupt is meant to be consumed by the Non-secure world.

- ``INTR_TYPE_S_EL1``: interrupt is meant to be consumed by Secure EL1.

- ``INTR_TYPE_EL3``: interrupt is meant to be consumed by EL3.

Dan Handley's avatar
Dan Handley committed
178
In case of Arm standard platforms using GIC, the implementation of the API
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
writes to the GIC *Group Register* and *Group Modifier Register* (only GICv3) to
assign the interrupt to the right group.

For GICv3:

- ``INTR_TYPE_NS`` maps to Group 1 interrupt.

- ``INTR_TYPE_S_EL1`` maps to Secure Group 1 interrupt.

- ``INTR_TYPE_EL3`` maps to Secure Group 0 interrupt.

For GICv2:

- ``INTR_TYPE_NS`` maps to Group 1 interrupt.

- When the build option ``GICV2_G0_FOR_EL3`` is set to ``0`` (the default),
  ``INTR_TYPE_S_EL1`` maps to Group 0. Otherwise, ``INTR_TYPE_EL3`` maps to
  Group 0 interrupt.

198
199
200
201
202
203
204
205
206
207
208
209
210
Function: void plat_ic_raise_el3_sgi(int sgi_num, u_register_t target); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : int
    Argument : u_register_t
    Return   : void

This API should raise an EL3 SGI. The first parameter, ``sgi_num``, specifies
the ID of the SGI. The second parameter, ``target``, must be the MPIDR of the
target PE.

Dan Handley's avatar
Dan Handley committed
211
In case of Arm standard platforms using GIC, the implementation of the API
212
213
214
inserts barrier to make memory updates visible before raising SGI, then writes
to appropriate *SGI Register* in order to raise the EL3 SGI.

215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
Function: void plat_ic_set_spi_routing(unsigned int id, unsigned int routing_mode, u_register_t mpidr); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Argument : unsigned int
    Argument : u_register_t
    Return   : void

This API should set the routing mode of Share Peripheral Interrupt (SPI)
specified by first parameter ``id`` to that specified by the second parameter
``routing_mode``.

The ``routing_mode`` parameter can be one of:

- ``INTR_ROUTING_MODE_ANY`` means the interrupt can be routed to any PE in the
  system. The ``mpidr`` parameter is ignored in this case.

- ``INTR_ROUTING_MODE_PE`` means the interrupt is routed to the PE whose MPIDR
  value is specified by the parameter ``mpidr``.

Dan Handley's avatar
Dan Handley committed
237
In case of Arm standard platforms using GIC, the implementation of the API
238
239
240
writes to the GIC *Target Register* (GICv2) or *Route Register* (GICv3) to set
the routing.

241
242
243
244
245
246
247
248
249
250
251
Function: void plat_ic_set_interrupt_pending(unsigned int id); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Return   : void

This API should set the interrupt specified by first parameter ``id`` to
*Pending*.

Dan Handley's avatar
Dan Handley committed
252
In case of Arm standard platforms using GIC, the implementation of the API
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
inserts barrier to make memory updates visible before setting interrupt pending,
and writes to the GIC *Set Pending Register* to set the interrupt pending
status.

Function: void plat_ic_clear_interrupt_pending(unsigned int id); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Return   : void

This API should clear the *Pending* status of the interrupt specified by first
parameter ``id``.

Dan Handley's avatar
Dan Handley committed
268
In case of Arm standard platforms using GIC, the implementation of the API
269
270
271
writes to the GIC *Clear Pending Register* to clear the interrupt pending
status, and inserts barrier to make memory updates visible afterwards.

272
273
274
275
276
277
278
279
280
281
282
283
284
Function: unsigned int plat_ic_set_priority_mask(unsigned int id); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Return   : int

This API should set the priority mask (first parameter) in the interrupt
controller such that only interrupts of higher priority than the supplied one
may be signalled to the PE. The API should return the current priority value
that it's overwriting.

Dan Handley's avatar
Dan Handley committed
285
In case of Arm standard platforms using GIC, the implementation of the API
286
287
288
289
inserts to order memory updates before updating mask, then writes to the GIC
*Priority Mask Register*, and make sure memory updates are visible before
potential trigger due to mask update.

290
291
292
293
294
295
296
297
298
299
300
301
302
Function: unsigned int plat_ic_get_interrupt_id(unsigned int raw); [optional]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

::

    Argument : unsigned int
    Return   : unsigned int

This API should extract and return the interrupt number from the raw value
obtained by the acknowledging the interrupt (read using
``plat_ic_acknowledge_interrupt()``). If the interrupt ID is invalid, this API
should return ``INTR_ID_UNAVAILABLE``.

Dan Handley's avatar
Dan Handley committed
303
In case of Arm standard platforms using GIC, the implementation of the API
304
305
masks out the interrupt ID field from the acknowledged value from GIC.

306
307
----

Dan Handley's avatar
Dan Handley committed
308
*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*