blob: aca1ccb06d7afa8b1eedc5ebd4643254d3231b6b [file] [log] [blame]
Paul Beesleyea225122019-02-11 17:54:45 +00001SDEI: Software Delegated Exception Interface
2============================================
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +01003
4.. contents::
5 :depth: 2
6
Dan Handley610e7e12018-03-01 18:44:00 +00007This document provides an overview of the SDEI dispatcher implementation in
8Trusted Firmware-A (TF-A).
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +01009
10Introduction
11------------
12
Dan Handley610e7e12018-03-01 18:44:00 +000013`Software Delegated Exception Interface`_ (SDEI) is an Arm specification for
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010014Non-secure world to register handlers with firmware to receive notifications
15about system events. Firmware will first receive the system events by way of
16asynchronous exceptions and, in response, arranges for the registered handler to
17execute in the Non-secure EL.
18
19Normal world software that interacts with the SDEI dispatcher (makes SDEI
20requests and receives notifications) is referred to as the *SDEI Client*. A
21client receives the event notification at the registered handler even when it
22was executing with exceptions masked. The list of SDEI events available to the
23client are specific to the platform [#std-event]_. See also `Determining client
24EL`_.
25
26.. _general SDEI dispatch:
27
28The following figure depicts a general sequence involving SDEI client executing
29at EL2 and an event dispatch resulting from the triggering of a bound interrupt.
30A commentary is provided below:
31
Paul Beesleyea225122019-02-11 17:54:45 +000032.. image:: ../plantuml/sdei_general.svg
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010033
34As part of initialisation, the SDEI client binds a Non-secure interrupt [1], and
35the SDEI dispatcher returns a platform dynamic event number [2]. The client then
36registers a handler for that event [3], enables the event [5], and unmasks all
37events on the current PE [7]. This sequence is typical of an SDEI client, but it
38may involve additional SDEI calls.
39
40At a later point in time, when the bound interrupt triggers [9], it's trapped to
41EL3. The interrupt is handed over to the SDEI dispatcher, which then arranges to
42execute the registered handler [10]. The client terminates its execution with
43``SDEI_EVENT_COMPLETE`` [11], following which the dispatcher resumes the
44original EL2 execution [13]. Note that the SDEI interrupt remains active until
45the client handler completes, at which point EL3 does EOI [12].
46
Jeenu Viswambharan34392302018-01-17 12:30:11 +000047Other than events bound to interrupts (as depicted in the sequence above, SDEI
48events can be explicitly dispatched in response to other exceptions, for
49example, upon receiving an *SError* or *Synchronous External Abort*. See
50`Explicit dispatch of events`_.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010051
52The remainder of this document only discusses the design and implementation of
Dan Handley610e7e12018-03-01 18:44:00 +000053SDEI dispatcher in TF-A, and assumes that the reader is familiar with the SDEI
54specification, the interfaces, and their requirements.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010055
56.. [#std-event] Except event 0, which is defined by the SDEI specification as a
57 standard event.
58
59Defining events
60---------------
61
62A platform choosing to include the SDEI dispatcher must also define the events
63available on the platform, along with their attributes.
64
65The platform is expected to provide two arrays of event descriptors: one for
66private events, and another for shared events. The SDEI dispatcher provides
67``SDEI_PRIVATE_EVENT()`` and ``SDEI_SHARED_EVENT()`` macros to populate the
68event descriptors. Both macros take 3 arguments:
69
70- The event number: this must be a positive 32-bit integer.
71
Jeenu Viswambharan34392302018-01-17 12:30:11 +000072- For an event that has a backing interrupt, the interrupt number the event is
73 bound to:
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010074
75 - If it's not applicable to an event, this shall be left as ``0``.
76
77 - If the event is dynamic, this should be specified as ``SDEI_DYN_IRQ``.
78
79- A bit map of `Event flags`_.
80
81To define event 0, the macro ``SDEI_DEFINE_EVENT_0()`` should be used. This
82macro takes only one parameter: an SGI number to signal other PEs.
83
Jeenu Viswambharan34392302018-01-17 12:30:11 +000084To define an event that's meant to be `explicitly dispatched`__ (i.e., not as a
85result of receiving an SDEI interrupt), the macro ``SDEI_EXPLICIT_EVENT()``
86should be used. It accepts two parameters:
87
88.. __: `Explicit dispatch of events`_
89
90- The event number (as above);
91
92- Event priority: ``SDEI_MAPF_CRITICAL`` or ``SDEI_MAPF_NORMAL``, as described
93 below.
94
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +010095Once the event descriptor arrays are defined, they should be exported to the
96SDEI dispatcher using the ``REGISTER_SDEI_MAP()`` macro, passing it the pointers
97to the private and shared event descriptor arrays, respectively. Note that the
98``REGISTER_SDEI_MAP()`` macro must be used in the same file where the arrays are
99defined.
100
101Regarding event descriptors:
102
103- For Event 0:
104
105 - There must be exactly one descriptor in the private array, and none in the
106 shared array.
107
108 - The event should be defined using ``SDEI_DEFINE_EVENT_0()``.
109
110 - Must be bound to a Secure SGI on the platform.
111
Jeenu Viswambharan34392302018-01-17 12:30:11 +0000112- Explicit events should only be used in the private array.
113
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100114- Statically bound shared and private interrupts must be bound to shared and
115 private interrupts on the platform, respectively. See the section on
116 `interrupt configuration`__.
117
118 .. __: `Configuration within Exception Handling Framework`_
119
120- Both arrays should be one-dimensional. The ``REGISTER_SDEI_MAP()`` macro
121 takes care of replicating private events for each PE on the platform.
122
123- Both arrays must be sorted in the increasing order of event number.
124
125The SDEI specification doesn't have provisions for discovery of available events
126on the platform. The list of events made available to the client, along with
127their semantics, have to be communicated out of band; for example, through
128Device Trees or firmware configuration tables.
129
130See also `Event definition example`_.
131
132Event flags
133~~~~~~~~~~~
134
135Event flags describe the properties of the event. They are bit maps that can be
136``OR``\ ed to form parameters to macros that `define events`__.
137
138.. __: `Defining events`_
139
140- ``SDEI_MAPF_DYNAMIC``: Marks the event as dynamic. Dynamic events can be
Antonio Nino Diaz56b68ad2019-02-28 13:35:21 +0000141 bound to (or released from) any Non-secure interrupt at runtime via the
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100142 ``SDEI_INTERRUPT_BIND`` and ``SDEI_INTERRUPT_RELEASE`` calls.
143
144- ``SDEI_MAPF_BOUND``: Marks the event as statically bound to an interrupt.
145 These events cannot be re-bound at runtime.
146
Jeenu Viswambharan34392302018-01-17 12:30:11 +0000147- ``SDEI_MAPF_NORMAL``: Marks the event as having *Normal* priority. This is
148 the default priority.
149
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100150- ``SDEI_MAPF_CRITICAL``: Marks the event as having *Critical* priority.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100151
152Event definition example
153------------------------
154
155.. code:: c
156
157 static sdei_ev_map_t plat_private_sdei[] = {
158 /* Event 0 definition */
159 SDEI_DEFINE_EVENT_0(8),
160
161 /* PPI */
162 SDEI_PRIVATE_EVENT(8, 23, SDEI_MAPF_BOUND),
163
164 /* Dynamic private events */
165 SDEI_PRIVATE_EVENT(100, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
166 SDEI_PRIVATE_EVENT(101, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
Jeenu Viswambharan34392302018-01-17 12:30:11 +0000167
168 /* Events for explicit dispatch */
169 SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_NORMAL);
170 SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_CRITICAL);
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100171 };
172
173 /* Shared event mappings */
174 static sdei_ev_map_t plat_shared_sdei[] = {
175 SDEI_SHARED_EVENT(804, 0, SDEI_MAPF_DYNAMIC),
176
177 /* Dynamic shared events */
178 SDEI_SHARED_EVENT(3000, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
179 SDEI_SHARED_EVENT(3001, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
180 };
181
182 /* Export SDEI events */
183 REGISTER_SDEI_MAP(plat_private_sdei, plat_shared_sdei);
184
185Configuration within Exception Handling Framework
186-------------------------------------------------
187
188The SDEI dispatcher functions alongside the Exception Handling Framework. This
189means that the platform must assign priorities to both Normal and Critical SDEI
190interrupts for the platform:
191
192- Install priority descriptors for Normal and Critical SDEI interrupts.
193
194- For those interrupts that are statically bound (i.e. events defined as having
195 the ``SDEI_MAPF_BOUND`` property), enumerate their properties for the GIC
196 driver to configure interrupts accordingly.
197
198 The interrupts must be configured to target EL3. This means that they should
199 be configured as *Group 0*. Additionally, on GICv2 systems, the build option
200 ``GICV2_G0_FOR_EL3`` must be set to ``1``.
201
202See also `SDEI porting requirements`_.
203
204Determining client EL
205---------------------
206
207The SDEI specification requires that the *physical* SDEI client executes in the
208highest Non-secure EL implemented on the system. This means that the dispatcher
209will only allow SDEI calls to be made from:
210
211- EL2, if EL2 is implemented. The Hypervisor is expected to implement a
212 *virtual* SDEI dispatcher to support SDEI clients in Guest Operating Systems
213 executing in Non-secure EL1.
214
215- Non-secure EL1, if EL2 is not implemented or disabled.
216
217See the function ``sdei_client_el()`` in ``sdei_private.h``.
218
219Explicit dispatch of events
220---------------------------
221
222Typically, an SDEI event dispatch is caused by the PE receiving interrupts that
223are bound to an SDEI event. However, there are cases where the Secure world
224requires dispatch of an SDEI event as a direct or indirect result of a past
Antonio Nino Diaz56b68ad2019-02-28 13:35:21 +0000225activity, such as receiving a Secure interrupt or an exception.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100226
227The SDEI dispatcher implementation provides ``sdei_dispatch_event()`` API for
228this purpose. The API has the following signature:
229
230::
231
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000232 int sdei_dispatch_event(int ev_num);
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100233
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000234The parameter ``ev_num`` is the event number to dispatch. The API returns ``0``
235on success, or ``-1`` on failure.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100236
237The following figure depicts a scenario involving explicit dispatch of SDEI
238event. A commentary is provided below:
239
Paul Beesleyea225122019-02-11 17:54:45 +0000240.. image:: ../plantuml/sdei_explicit_dispatch.svg
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100241
242As part of initialisation, the SDEI client registers a handler for a platform
243event [1], enables the event [3], and unmasks the current PE [5]. Note that,
244unlike in `general SDEI dispatch`_, this doesn't involve interrupt binding, as
245bound or dynamic events can't be explicitly dispatched (see the section below).
246
247At a later point in time, a critical event [#critical-event]_ is trapped into
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000248EL3 [7]. EL3 performs a first-level triage of the event, and a RAS component
249assumes further handling [8]. The dispatch completes, but intends to involve
250Non-secure world in further handling, and therefore decides to explicitly
251dispatch an event [10] (which the client had already registered for [1]). The
252rest of the sequence is similar to that in the `general SDEI dispatch`_: the
253requested event is dispatched to the client (assuming all the conditions are
254met), and when the handler completes, the preempted execution resumes.
Jeenu Viswambharan9a62fd12017-11-16 12:34:15 +0000255
256.. [#critical-event] Examples of critical event are *SError*, *Synchronous
257 External Abort*, *Fault Handling interrupt*, or *Error
258 Recovery interrupt* from one of RAS nodes in the system.
259
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100260Conditions for event dispatch
261~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
262
263All of the following requirements must be met for the API to return ``0`` and
264event to be dispatched:
265
266- SDEI events must be unmasked on the PE. I.e. the client must have called
267 ``PE_UNMASK`` beforehand.
268
269- Event 0 can't be dispatched.
270
Jeenu Viswambharan34392302018-01-17 12:30:11 +0000271- The event must be declared using the ``SDEI_EXPLICIT_EVENT()`` macro
272 described above.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100273
274- The event must be private to the PE.
275
276- The event must have been registered for and enabled.
277
278- A dispatch for the same event must not be outstanding. I.e. it hasn't already
279 been dispatched and is yet to be completed.
280
281- The priority of the event (either Critical or Normal, as configured by the
282 platform at build-time) shouldn't cause priority inversion. This means:
283
284 - If it's of Normal priority, neither Normal nor Critical priority dispatch
285 must be outstanding on the PE.
286
287 - If it's of a Critical priority, no Critical priority dispatch must be
288 outstanding on the PE.
289
290Further, the caller should be aware of the following assumptions made by the
291dispatcher:
292
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000293- The caller of the API is a component running in EL3; for example, a RAS
294 driver.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100295
296- The requested dispatch will be permitted by the Exception Handling Framework.
297 I.e. the caller must make sure that the requested dispatch has sufficient
298 priority so as not to cause priority level inversion within Exception
299 Handling Framework.
300
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000301- The caller must be prepared for the SDEI dispatcher to restore the Non-secure
302 context, and mark that the active context.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100303
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000304- The call will block until the SDEI client completes the event (i.e. when the
305 client calls either ``SDEI_EVENT_COMPLETE`` or ``SDEI_COMPLETE_AND_RESUME``).
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100306
Jeenu Viswambharan8b7e6bc2018-02-16 12:07:48 +0000307- The caller must be prepared for this API to return failure and handle
308 accordingly.
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100309
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100310Porting requirements
311--------------------
312
313The porting requirements of the SDEI dispatcher are outlined in the `porting
314guide`__.
315
316.. __: `SDEI porting requirements`_
317
318Note on writing SDEI event handlers
319-----------------------------------
320
321*This section pertains to SDEI event handlers in general, not just when using
Dan Handley610e7e12018-03-01 18:44:00 +0000322the TF-A SDEI dispatcher.*
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100323
324The SDEI specification requires that event handlers preserve the contents of all
325registers except ``x0`` to ``x17``. This has significance if event handler is
326written in C: compilers typically adjust the stack frame at the beginning and
327end of C functions. For example, AArch64 GCC typically produces the following
328function prologue and epilogue:
329
330::
331
332 c_event_handler:
333 stp x29, x30, [sp,#-32]!
334 mov x29, sp
335
336 ...
337
338 bl ...
339
340 ...
341
342 ldp x29, x30, [sp],#32
343 ret
344
345The register ``x29`` is used as frame pointer in the prologue. Because neither a
346valid ``SDEI_EVENT_COMPLETE`` nor ``SDEI_EVENT_COMPLETE_AND_RESUME`` calls
347return to the handler, the epilogue never gets executed, and registers ``x29``
348and ``x30`` (in the case above) are inadvertently corrupted. This violates the
349SDEI specification, and the normal execution thereafter will result in
350unexpected behaviour.
351
352To work this around, it's advised that the top-level event handlers are
353implemented in assembly, following a similar pattern as below:
354
355::
356
357 asm_event_handler:
358 /* Save link register whilst maintaining stack alignment */
359 stp xzr, x30, [sp, #-16]!
360 bl c_event_handler
361
362 /* Restore link register */
363 ldp xzr, x30, [sp], #16
364
365 /* Complete call */
366 ldr x0, =SDEI_EVENT_COMPLETE
367 smc #0
368 b .
369
370----
371
Dan Handley610e7e12018-03-01 18:44:00 +0000372*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
Jeenu Viswambharandb5e12e2017-10-18 14:35:20 +0100373
374.. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
Paul Beesleyea225122019-02-11 17:54:45 +0000375.. _SDEI porting requirements: ../getting_started/porting-guide.rst#sdei-porting-requirements