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