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