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