xref: /rk3399_ARM-atf/docs/components/sdei.rst (revision 566d15e84aefb63f33933934059e024008ae70ad)
140d553cfSPaul BeesleySDEI: Software Delegated Exception Interface
240d553cfSPaul Beesley============================================
340d553cfSPaul Beesley
440d553cfSPaul BeesleyThis document provides an overview of the SDEI dispatcher implementation in
540d553cfSPaul BeesleyTrusted Firmware-A (TF-A).
640d553cfSPaul Beesley
740d553cfSPaul BeesleyIntroduction
840d553cfSPaul Beesley------------
940d553cfSPaul Beesley
1040d553cfSPaul Beesley`Software Delegated Exception Interface`_ (SDEI) is an Arm specification for
1140d553cfSPaul BeesleyNon-secure world to register handlers with firmware to receive notifications
1240d553cfSPaul Beesleyabout system events. Firmware will first receive the system events by way of
1340d553cfSPaul Beesleyasynchronous exceptions and, in response, arranges for the registered handler to
1440d553cfSPaul Beesleyexecute in the Non-secure EL.
1540d553cfSPaul Beesley
1640d553cfSPaul BeesleyNormal world software that interacts with the SDEI dispatcher (makes SDEI
1740d553cfSPaul Beesleyrequests and receives notifications) is referred to as the *SDEI Client*. A
1840d553cfSPaul Beesleyclient receives the event notification at the registered handler even when it
1940d553cfSPaul Beesleywas executing with exceptions masked. The list of SDEI events available to the
2040d553cfSPaul Beesleyclient are specific to the platform [#std-event]_. See also `Determining client
2140d553cfSPaul BeesleyEL`_.
2240d553cfSPaul Beesley
2340d553cfSPaul Beesley.. _general SDEI dispatch:
2440d553cfSPaul Beesley
2540d553cfSPaul BeesleyThe following figure depicts a general sequence involving SDEI client executing
2640d553cfSPaul Beesleyat EL2 and an event dispatch resulting from the triggering of a bound interrupt.
2740d553cfSPaul BeesleyA commentary is provided below:
2840d553cfSPaul Beesley
29a2c320a8SPaul Beesley.. image:: ../resources/diagrams/plantuml/sdei_general.svg
3040d553cfSPaul Beesley
3140d553cfSPaul BeesleyAs part of initialisation, the SDEI client binds a Non-secure interrupt [1], and
3240d553cfSPaul Beesleythe SDEI dispatcher returns a platform dynamic event number [2]. The client then
3340d553cfSPaul Beesleyregisters a handler for that event [3], enables the event [5], and unmasks all
3440d553cfSPaul Beesleyevents on the current PE [7]. This sequence is typical of an SDEI client, but it
3540d553cfSPaul Beesleymay involve additional SDEI calls.
3640d553cfSPaul Beesley
3740d553cfSPaul BeesleyAt a later point in time, when the bound interrupt triggers [9], it's trapped to
3840d553cfSPaul BeesleyEL3. The interrupt is handed over to the SDEI dispatcher, which then arranges to
3940d553cfSPaul Beesleyexecute the registered handler [10]. The client terminates its execution with
4040d553cfSPaul Beesley``SDEI_EVENT_COMPLETE`` [11], following which the dispatcher resumes the
4140d553cfSPaul Beesleyoriginal EL2 execution [13]. Note that the SDEI interrupt remains active until
4240d553cfSPaul Beesleythe client handler completes, at which point EL3 does EOI [12].
4340d553cfSPaul Beesley
44*566d15e8SJohn TsichritzisOther than events bound to interrupts, as depicted in the sequence above, SDEI
4540d553cfSPaul Beesleyevents can be explicitly dispatched in response to other exceptions, for
4640d553cfSPaul Beesleyexample, upon receiving an *SError* or *Synchronous External Abort*. See
4740d553cfSPaul Beesley`Explicit dispatch of events`_.
4840d553cfSPaul Beesley
4940d553cfSPaul BeesleyThe remainder of this document only discusses the design and implementation of
5040d553cfSPaul BeesleySDEI dispatcher in TF-A, and assumes that the reader is familiar with the SDEI
5140d553cfSPaul Beesleyspecification, the interfaces, and their requirements.
5240d553cfSPaul Beesley
5340d553cfSPaul Beesley.. [#std-event] Except event 0, which is defined by the SDEI specification as a
5440d553cfSPaul Beesley                standard event.
5540d553cfSPaul Beesley
5640d553cfSPaul BeesleyDefining events
5740d553cfSPaul Beesley---------------
5840d553cfSPaul Beesley
5940d553cfSPaul BeesleyA platform choosing to include the SDEI dispatcher must also define the events
6040d553cfSPaul Beesleyavailable on the platform, along with their attributes.
6140d553cfSPaul Beesley
6240d553cfSPaul BeesleyThe platform is expected to provide two arrays of event descriptors: one for
6340d553cfSPaul Beesleyprivate events, and another for shared events. The SDEI dispatcher provides
6440d553cfSPaul Beesley``SDEI_PRIVATE_EVENT()`` and ``SDEI_SHARED_EVENT()`` macros to populate the
6540d553cfSPaul Beesleyevent descriptors. Both macros take 3 arguments:
6640d553cfSPaul Beesley
6740d553cfSPaul Beesley-  The event number: this must be a positive 32-bit integer.
6840d553cfSPaul Beesley
6940d553cfSPaul Beesley-  For an event that has a backing interrupt, the interrupt number the event is
7040d553cfSPaul Beesley   bound to:
7140d553cfSPaul Beesley
7240d553cfSPaul Beesley   - If it's not applicable to an event, this shall be left as ``0``.
7340d553cfSPaul Beesley
7440d553cfSPaul Beesley   - If the event is dynamic, this should be specified as ``SDEI_DYN_IRQ``.
7540d553cfSPaul Beesley
7640d553cfSPaul Beesley-  A bit map of `Event flags`_.
7740d553cfSPaul Beesley
7840d553cfSPaul BeesleyTo define event 0, the macro ``SDEI_DEFINE_EVENT_0()`` should be used. This
7940d553cfSPaul Beesleymacro takes only one parameter: an SGI number to signal other PEs.
8040d553cfSPaul Beesley
8140d553cfSPaul BeesleyTo define an event that's meant to be `explicitly dispatched`__ (i.e., not as a
8240d553cfSPaul Beesleyresult of receiving an SDEI interrupt), the macro ``SDEI_EXPLICIT_EVENT()``
8340d553cfSPaul Beesleyshould be used. It accepts two parameters:
8440d553cfSPaul Beesley
8540d553cfSPaul Beesley.. __: `Explicit dispatch of events`_
8640d553cfSPaul Beesley
8740d553cfSPaul Beesley-  The event number (as above);
8840d553cfSPaul Beesley
8940d553cfSPaul Beesley-  Event priority: ``SDEI_MAPF_CRITICAL`` or ``SDEI_MAPF_NORMAL``, as described
9040d553cfSPaul Beesley   below.
9140d553cfSPaul Beesley
9240d553cfSPaul BeesleyOnce the event descriptor arrays are defined, they should be exported to the
9340d553cfSPaul BeesleySDEI dispatcher using the ``REGISTER_SDEI_MAP()`` macro, passing it the pointers
9440d553cfSPaul Beesleyto the private and shared event descriptor arrays, respectively. Note that the
9540d553cfSPaul Beesley``REGISTER_SDEI_MAP()`` macro must be used in the same file where the arrays are
9640d553cfSPaul Beesleydefined.
9740d553cfSPaul Beesley
9840d553cfSPaul BeesleyRegarding event descriptors:
9940d553cfSPaul Beesley
10040d553cfSPaul Beesley-  For Event 0:
10140d553cfSPaul Beesley
10240d553cfSPaul Beesley   - There must be exactly one descriptor in the private array, and none in the
10340d553cfSPaul Beesley     shared array.
10440d553cfSPaul Beesley
10540d553cfSPaul Beesley   - The event should be defined using ``SDEI_DEFINE_EVENT_0()``.
10640d553cfSPaul Beesley
10740d553cfSPaul Beesley   - Must be bound to a Secure SGI on the platform.
10840d553cfSPaul Beesley
10940d553cfSPaul Beesley-  Explicit events should only be used in the private array.
11040d553cfSPaul Beesley
11140d553cfSPaul Beesley-  Statically bound shared and private interrupts must be bound to shared and
11240d553cfSPaul Beesley   private interrupts on the platform, respectively. See the section on
11340d553cfSPaul Beesley   `interrupt configuration`__.
11440d553cfSPaul Beesley
11540d553cfSPaul Beesley   .. __: `Configuration within Exception Handling Framework`_
11640d553cfSPaul Beesley
11740d553cfSPaul Beesley-  Both arrays should be one-dimensional. The ``REGISTER_SDEI_MAP()`` macro
11840d553cfSPaul Beesley   takes care of replicating private events for each PE on the platform.
11940d553cfSPaul Beesley
12040d553cfSPaul Beesley-  Both arrays must be sorted in the increasing order of event number.
12140d553cfSPaul Beesley
12240d553cfSPaul BeesleyThe SDEI specification doesn't have provisions for discovery of available events
12340d553cfSPaul Beesleyon the platform. The list of events made available to the client, along with
12440d553cfSPaul Beesleytheir semantics, have to be communicated out of band; for example, through
12540d553cfSPaul BeesleyDevice Trees or firmware configuration tables.
12640d553cfSPaul Beesley
12740d553cfSPaul BeesleySee also `Event definition example`_.
12840d553cfSPaul Beesley
12940d553cfSPaul BeesleyEvent flags
13040d553cfSPaul Beesley~~~~~~~~~~~
13140d553cfSPaul Beesley
13240d553cfSPaul BeesleyEvent flags describe the properties of the event. They are bit maps that can be
13340d553cfSPaul Beesley``OR``\ ed to form parameters to macros that `define events`__.
13440d553cfSPaul Beesley
13540d553cfSPaul Beesley.. __: `Defining events`_
13640d553cfSPaul Beesley
13740d553cfSPaul Beesley-  ``SDEI_MAPF_DYNAMIC``: Marks the event as dynamic. Dynamic events can be
13840d553cfSPaul Beesley   bound to (or released from) any Non-secure interrupt at runtime via the
13940d553cfSPaul Beesley   ``SDEI_INTERRUPT_BIND`` and ``SDEI_INTERRUPT_RELEASE`` calls.
14040d553cfSPaul Beesley
14140d553cfSPaul Beesley-  ``SDEI_MAPF_BOUND``: Marks the event as statically bound to an interrupt.
14240d553cfSPaul Beesley   These events cannot be re-bound at runtime.
14340d553cfSPaul Beesley
14440d553cfSPaul Beesley-  ``SDEI_MAPF_NORMAL``: Marks the event as having *Normal* priority. This is
14540d553cfSPaul Beesley   the default priority.
14640d553cfSPaul Beesley
14740d553cfSPaul Beesley-  ``SDEI_MAPF_CRITICAL``: Marks the event as having *Critical* priority.
14840d553cfSPaul Beesley
14940d553cfSPaul BeesleyEvent definition example
15040d553cfSPaul Beesley------------------------
15140d553cfSPaul Beesley
15240d553cfSPaul Beesley.. code:: c
15340d553cfSPaul Beesley
15440d553cfSPaul Beesley   static sdei_ev_map_t plat_private_sdei[] = {
15540d553cfSPaul Beesley        /* Event 0 definition */
15640d553cfSPaul Beesley        SDEI_DEFINE_EVENT_0(8),
15740d553cfSPaul Beesley
15840d553cfSPaul Beesley        /* PPI */
15940d553cfSPaul Beesley        SDEI_PRIVATE_EVENT(8, 23, SDEI_MAPF_BOUND),
16040d553cfSPaul Beesley
16140d553cfSPaul Beesley        /* Dynamic private events */
16240d553cfSPaul Beesley        SDEI_PRIVATE_EVENT(100, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
16340d553cfSPaul Beesley        SDEI_PRIVATE_EVENT(101, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
16440d553cfSPaul Beesley
16540d553cfSPaul Beesley        /* Events for explicit dispatch */
16640d553cfSPaul Beesley        SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_NORMAL);
16740d553cfSPaul Beesley        SDEI_EXPLICIT_EVENT(2000, SDEI_MAPF_CRITICAL);
16840d553cfSPaul Beesley   };
16940d553cfSPaul Beesley
17040d553cfSPaul Beesley   /* Shared event mappings */
17140d553cfSPaul Beesley   static sdei_ev_map_t plat_shared_sdei[] = {
17240d553cfSPaul Beesley        SDEI_SHARED_EVENT(804, 0, SDEI_MAPF_DYNAMIC),
17340d553cfSPaul Beesley
17440d553cfSPaul Beesley        /* Dynamic shared events */
17540d553cfSPaul Beesley        SDEI_SHARED_EVENT(3000, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC),
17640d553cfSPaul Beesley        SDEI_SHARED_EVENT(3001, SDEI_DYN_IRQ, SDEI_MAPF_DYNAMIC)
17740d553cfSPaul Beesley   };
17840d553cfSPaul Beesley
17940d553cfSPaul Beesley   /* Export SDEI events */
18040d553cfSPaul Beesley   REGISTER_SDEI_MAP(plat_private_sdei, plat_shared_sdei);
18140d553cfSPaul Beesley
18240d553cfSPaul BeesleyConfiguration within Exception Handling Framework
18340d553cfSPaul Beesley-------------------------------------------------
18440d553cfSPaul Beesley
18540d553cfSPaul BeesleyThe SDEI dispatcher functions alongside the Exception Handling Framework. This
18640d553cfSPaul Beesleymeans that the platform must assign priorities to both Normal and Critical SDEI
18740d553cfSPaul Beesleyinterrupts for the platform:
18840d553cfSPaul Beesley
18940d553cfSPaul Beesley-  Install priority descriptors for Normal and Critical SDEI interrupts.
19040d553cfSPaul Beesley
19140d553cfSPaul Beesley-  For those interrupts that are statically bound (i.e. events defined as having
19240d553cfSPaul Beesley   the ``SDEI_MAPF_BOUND`` property), enumerate their properties for the GIC
19340d553cfSPaul Beesley   driver to configure interrupts accordingly.
19440d553cfSPaul Beesley
19540d553cfSPaul Beesley   The interrupts must be configured to target EL3. This means that they should
19640d553cfSPaul Beesley   be configured as *Group 0*.  Additionally, on GICv2 systems, the build option
19740d553cfSPaul Beesley   ``GICV2_G0_FOR_EL3`` must be set to ``1``.
19840d553cfSPaul Beesley
19940d553cfSPaul BeesleySee also `SDEI porting requirements`_.
20040d553cfSPaul Beesley
20140d553cfSPaul BeesleyDetermining client EL
20240d553cfSPaul Beesley---------------------
20340d553cfSPaul Beesley
20440d553cfSPaul BeesleyThe SDEI specification requires that the *physical* SDEI client executes in the
20540d553cfSPaul Beesleyhighest Non-secure EL implemented on the system. This means that the dispatcher
20640d553cfSPaul Beesleywill only allow SDEI calls to be made from:
20740d553cfSPaul Beesley
20840d553cfSPaul Beesley-  EL2, if EL2 is implemented. The Hypervisor is expected to implement a
20940d553cfSPaul Beesley   *virtual* SDEI dispatcher to support SDEI clients in Guest Operating Systems
21040d553cfSPaul Beesley   executing in Non-secure EL1.
21140d553cfSPaul Beesley
21240d553cfSPaul Beesley-  Non-secure EL1, if EL2 is not implemented or disabled.
21340d553cfSPaul Beesley
21440d553cfSPaul BeesleySee the function ``sdei_client_el()`` in ``sdei_private.h``.
21540d553cfSPaul Beesley
21640d553cfSPaul BeesleyExplicit dispatch of events
21740d553cfSPaul Beesley---------------------------
21840d553cfSPaul Beesley
21940d553cfSPaul BeesleyTypically, an SDEI event dispatch is caused by the PE receiving interrupts that
22040d553cfSPaul Beesleyare bound to an SDEI event. However, there are cases where the Secure world
22140d553cfSPaul Beesleyrequires dispatch of an SDEI event as a direct or indirect result of a past
22240d553cfSPaul Beesleyactivity, such as receiving a Secure interrupt or an exception.
22340d553cfSPaul Beesley
22440d553cfSPaul BeesleyThe SDEI dispatcher implementation provides ``sdei_dispatch_event()`` API for
22540d553cfSPaul Beesleythis purpose. The API has the following signature:
22640d553cfSPaul Beesley
22729c02529SPaul Beesley.. code:: c
22840d553cfSPaul Beesley
22940d553cfSPaul Beesley        int sdei_dispatch_event(int ev_num);
23040d553cfSPaul Beesley
23140d553cfSPaul BeesleyThe parameter ``ev_num`` is the event number to dispatch. The API returns ``0``
23240d553cfSPaul Beesleyon success, or ``-1`` on failure.
23340d553cfSPaul Beesley
23440d553cfSPaul BeesleyThe following figure depicts a scenario involving explicit dispatch of SDEI
23540d553cfSPaul Beesleyevent. A commentary is provided below:
23640d553cfSPaul Beesley
237a2c320a8SPaul Beesley.. image:: ../resources/diagrams/plantuml/sdei_explicit_dispatch.svg
23840d553cfSPaul Beesley
23940d553cfSPaul BeesleyAs part of initialisation, the SDEI client registers a handler for a platform
24040d553cfSPaul Beesleyevent [1], enables the event [3], and unmasks the current PE [5]. Note that,
24140d553cfSPaul Beesleyunlike in `general SDEI dispatch`_, this doesn't involve interrupt binding, as
24240d553cfSPaul Beesleybound or dynamic events can't be explicitly dispatched (see the section below).
24340d553cfSPaul Beesley
24440d553cfSPaul BeesleyAt a later point in time, a critical event [#critical-event]_ is trapped into
24540d553cfSPaul BeesleyEL3 [7]. EL3 performs a first-level triage of the event, and a RAS component
24640d553cfSPaul Beesleyassumes further handling [8]. The dispatch completes, but intends to involve
24740d553cfSPaul BeesleyNon-secure world in further handling, and therefore decides to explicitly
24840d553cfSPaul Beesleydispatch an event [10] (which the client had already registered for [1]). The
24940d553cfSPaul Beesleyrest of the sequence is similar to that in the `general SDEI dispatch`_: the
25040d553cfSPaul Beesleyrequested event is dispatched to the client (assuming all the conditions are
25140d553cfSPaul Beesleymet), and when the handler completes, the preempted execution resumes.
25240d553cfSPaul Beesley
25340d553cfSPaul Beesley.. [#critical-event] Examples of critical event are *SError*, *Synchronous
25440d553cfSPaul Beesley                     External Abort*, *Fault Handling interrupt*, or *Error
25540d553cfSPaul Beesley                     Recovery interrupt* from one of RAS nodes in the system.
25640d553cfSPaul Beesley
25740d553cfSPaul BeesleyConditions for event dispatch
25840d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
25940d553cfSPaul Beesley
26040d553cfSPaul BeesleyAll of the following requirements must be met for the API to return ``0`` and
26140d553cfSPaul Beesleyevent to be dispatched:
26240d553cfSPaul Beesley
26340d553cfSPaul Beesley-  SDEI events must be unmasked on the PE. I.e. the client must have called
26440d553cfSPaul Beesley   ``PE_UNMASK`` beforehand.
26540d553cfSPaul Beesley
26640d553cfSPaul Beesley-  Event 0 can't be dispatched.
26740d553cfSPaul Beesley
26840d553cfSPaul Beesley-  The event must be declared using the ``SDEI_EXPLICIT_EVENT()`` macro
26940d553cfSPaul Beesley   described above.
27040d553cfSPaul Beesley
27140d553cfSPaul Beesley-  The event must be private to the PE.
27240d553cfSPaul Beesley
27340d553cfSPaul Beesley-  The event must have been registered for and enabled.
27440d553cfSPaul Beesley
27540d553cfSPaul Beesley-  A dispatch for the same event must not be outstanding. I.e. it hasn't already
27640d553cfSPaul Beesley   been dispatched and is yet to be completed.
27740d553cfSPaul Beesley
27840d553cfSPaul Beesley-  The priority of the event (either Critical or Normal, as configured by the
27940d553cfSPaul Beesley   platform at build-time) shouldn't cause priority inversion. This means:
28040d553cfSPaul Beesley
28140d553cfSPaul Beesley   -  If it's of Normal priority, neither Normal nor Critical priority dispatch
28240d553cfSPaul Beesley      must be outstanding on the PE.
28340d553cfSPaul Beesley
28440d553cfSPaul Beesley   -  If it's of a Critical priority, no Critical priority dispatch must be
28540d553cfSPaul Beesley      outstanding on the PE.
28640d553cfSPaul Beesley
28740d553cfSPaul BeesleyFurther, the caller should be aware of the following assumptions made by the
28840d553cfSPaul Beesleydispatcher:
28940d553cfSPaul Beesley
29040d553cfSPaul Beesley-  The caller of the API is a component running in EL3; for example, a RAS
29140d553cfSPaul Beesley   driver.
29240d553cfSPaul Beesley
29340d553cfSPaul Beesley-  The requested dispatch will be permitted by the Exception Handling Framework.
29440d553cfSPaul Beesley   I.e. the caller must make sure that the requested dispatch has sufficient
29540d553cfSPaul Beesley   priority so as not to cause priority level inversion within Exception
29640d553cfSPaul Beesley   Handling Framework.
29740d553cfSPaul Beesley
29840d553cfSPaul Beesley-  The caller must be prepared for the SDEI dispatcher to restore the Non-secure
29940d553cfSPaul Beesley   context, and mark that the active context.
30040d553cfSPaul Beesley
30140d553cfSPaul Beesley-  The call will block until the SDEI client completes the event (i.e. when the
30240d553cfSPaul Beesley   client calls either ``SDEI_EVENT_COMPLETE`` or ``SDEI_COMPLETE_AND_RESUME``).
30340d553cfSPaul Beesley
30440d553cfSPaul Beesley-  The caller must be prepared for this API to return failure and handle
30540d553cfSPaul Beesley   accordingly.
30640d553cfSPaul Beesley
30740d553cfSPaul BeesleyPorting requirements
30840d553cfSPaul Beesley--------------------
30940d553cfSPaul Beesley
31040d553cfSPaul BeesleyThe porting requirements of the SDEI dispatcher are outlined in the `porting
31140d553cfSPaul Beesleyguide`__.
31240d553cfSPaul Beesley
31340d553cfSPaul Beesley.. __: `SDEI porting requirements`_
31440d553cfSPaul Beesley
31540d553cfSPaul BeesleyNote on writing SDEI event handlers
31640d553cfSPaul Beesley-----------------------------------
31740d553cfSPaul Beesley
31840d553cfSPaul Beesley*This section pertains to SDEI event handlers in general, not just when using
31940d553cfSPaul Beesleythe TF-A SDEI dispatcher.*
32040d553cfSPaul Beesley
32140d553cfSPaul BeesleyThe SDEI specification requires that event handlers preserve the contents of all
32240d553cfSPaul Beesleyregisters except ``x0`` to ``x17``. This has significance if event handler is
32340d553cfSPaul Beesleywritten in C: compilers typically adjust the stack frame at the beginning and
32440d553cfSPaul Beesleyend of C functions. For example, AArch64 GCC typically produces the following
32540d553cfSPaul Beesleyfunction prologue and epilogue:
32640d553cfSPaul Beesley
32740d553cfSPaul Beesley::
32840d553cfSPaul Beesley
32940d553cfSPaul Beesley        c_event_handler:
33040d553cfSPaul Beesley                stp     x29, x30, [sp,#-32]!
33140d553cfSPaul Beesley                mov     x29, sp
33240d553cfSPaul Beesley
33340d553cfSPaul Beesley                ...
33440d553cfSPaul Beesley
33540d553cfSPaul Beesley                bl      ...
33640d553cfSPaul Beesley
33740d553cfSPaul Beesley                ...
33840d553cfSPaul Beesley
33940d553cfSPaul Beesley                ldp     x29, x30, [sp],#32
34040d553cfSPaul Beesley                ret
34140d553cfSPaul Beesley
34240d553cfSPaul BeesleyThe register ``x29`` is used as frame pointer in the prologue. Because neither a
34340d553cfSPaul Beesleyvalid ``SDEI_EVENT_COMPLETE`` nor ``SDEI_EVENT_COMPLETE_AND_RESUME`` calls
34440d553cfSPaul Beesleyreturn to the handler, the epilogue never gets executed, and registers ``x29``
34540d553cfSPaul Beesleyand ``x30`` (in the case above) are inadvertently corrupted. This violates the
34640d553cfSPaul BeesleySDEI specification, and the normal execution thereafter will result in
34740d553cfSPaul Beesleyunexpected behaviour.
34840d553cfSPaul Beesley
34940d553cfSPaul BeesleyTo work this around, it's advised that the top-level event handlers are
35040d553cfSPaul Beesleyimplemented in assembly, following a similar pattern as below:
35140d553cfSPaul Beesley
35240d553cfSPaul Beesley::
35340d553cfSPaul Beesley
35440d553cfSPaul Beesley        asm_event_handler:
35540d553cfSPaul Beesley                /* Save link register whilst maintaining stack alignment */
35640d553cfSPaul Beesley                stp     xzr, x30, [sp, #-16]!
35740d553cfSPaul Beesley                bl      c_event_handler
35840d553cfSPaul Beesley
35940d553cfSPaul Beesley                /* Restore link register */
36040d553cfSPaul Beesley                ldp     xzr, x30, [sp], #16
36140d553cfSPaul Beesley
36240d553cfSPaul Beesley                /* Complete call */
36340d553cfSPaul Beesley                ldr     x0, =SDEI_EVENT_COMPLETE
36440d553cfSPaul Beesley                smc     #0
36540d553cfSPaul Beesley                b       .
36640d553cfSPaul Beesley
36740d553cfSPaul Beesley----
36840d553cfSPaul Beesley
36940d553cfSPaul Beesley*Copyright (c) 2017-2018, Arm Limited and Contributors. All rights reserved.*
37040d553cfSPaul Beesley
37140d553cfSPaul Beesley.. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf
37240d553cfSPaul Beesley.. _SDEI porting requirements: ../getting_started/porting-guide.rst#sdei-porting-requirements
373*566d15e8SJohn Tsichritzis.. _Software Delegated Exception Interface: `SDEI specification`_
374