1*54fd6939SJiyong ParkException Handling Framework 2*54fd6939SJiyong Park============================ 3*54fd6939SJiyong Park 4*54fd6939SJiyong ParkThis document describes various aspects of handling exceptions by Runtime 5*54fd6939SJiyong ParkFirmware (BL31) that are targeted at EL3, other than SMCs. The |EHF| takes care 6*54fd6939SJiyong Parkof the following exceptions when targeted at EL3: 7*54fd6939SJiyong Park 8*54fd6939SJiyong Park- Interrupts 9*54fd6939SJiyong Park- Synchronous External Aborts 10*54fd6939SJiyong Park- Asynchronous External Aborts 11*54fd6939SJiyong Park 12*54fd6939SJiyong Park|TF-A|'s handling of synchronous ``SMC`` exceptions raised from lower ELs is 13*54fd6939SJiyong Parkdescribed in the :ref:`Firmware Design document <handling-an-smc>`. However, the 14*54fd6939SJiyong Park|EHF| changes the semantics of `Interrupt handling`_ and :ref:`synchronous 15*54fd6939SJiyong Parkexceptions <Effect on SMC calls>` other than SMCs. 16*54fd6939SJiyong Park 17*54fd6939SJiyong ParkThe |EHF| is selected by setting the build option ``EL3_EXCEPTION_HANDLING`` to 18*54fd6939SJiyong Park``1``, and is only available for AArch64 systems. 19*54fd6939SJiyong Park 20*54fd6939SJiyong ParkIntroduction 21*54fd6939SJiyong Park------------ 22*54fd6939SJiyong Park 23*54fd6939SJiyong ParkThrough various control bits in the ``SCR_EL3`` register, the Arm architecture 24*54fd6939SJiyong Parkallows for asynchronous exceptions to be routed to EL3. As described in the 25*54fd6939SJiyong Park:ref:`Interrupt Management Framework` document, depending on the chosen 26*54fd6939SJiyong Parkinterrupt routing model, TF-A appropriately sets the ``FIQ`` and ``IRQ`` bits of 27*54fd6939SJiyong Park``SCR_EL3`` register to effect this routing. For most use cases, other than for 28*54fd6939SJiyong Parkthe purpose of facilitating context switch between Normal and Secure worlds, 29*54fd6939SJiyong ParkFIQs and IRQs routed to EL3 are not required to be handled in EL3. 30*54fd6939SJiyong Park 31*54fd6939SJiyong ParkHowever, the evolving system and standards landscape demands that various 32*54fd6939SJiyong Parkexceptions are targeted at and handled in EL3. For instance: 33*54fd6939SJiyong Park 34*54fd6939SJiyong Park- Starting with ARMv8.2 architecture extension, many RAS features have been 35*54fd6939SJiyong Park introduced to the Arm architecture. With RAS features implemented, various 36*54fd6939SJiyong Park components of the system may use one of the asynchronous exceptions to signal 37*54fd6939SJiyong Park error conditions to PEs. These error conditions are of critical nature, and 38*54fd6939SJiyong Park it's imperative that corrective or remedial actions are taken at the earliest 39*54fd6939SJiyong Park opportunity. Therefore, a *Firmware-first Handling* approach is generally 40*54fd6939SJiyong Park followed in response to RAS events in the system. 41*54fd6939SJiyong Park 42*54fd6939SJiyong Park- The Arm `SDEI specification`_ defines interfaces through which Normal world 43*54fd6939SJiyong Park interacts with the Runtime Firmware in order to request notification of 44*54fd6939SJiyong Park system events. The |SDEI| specification requires that these events are 45*54fd6939SJiyong Park notified even when the Normal world executes with the exceptions masked. This 46*54fd6939SJiyong Park too implies that firmware-first handling is required, where the events are 47*54fd6939SJiyong Park first received by the EL3 firmware, and then dispatched to Normal world 48*54fd6939SJiyong Park through purely software mechanism. 49*54fd6939SJiyong Park 50*54fd6939SJiyong ParkFor |TF-A|, firmware-first handling means that asynchronous exceptions are 51*54fd6939SJiyong Parksuitably routed to EL3, and the Runtime Firmware (BL31) is extended to include 52*54fd6939SJiyong Parksoftware components that are capable of handling those exceptions that target 53*54fd6939SJiyong ParkEL3. These components—referred to as *dispatchers* [#spd]_ in general—may 54*54fd6939SJiyong Parkchoose to: 55*54fd6939SJiyong Park 56*54fd6939SJiyong Park.. _delegation-use-cases: 57*54fd6939SJiyong Park 58*54fd6939SJiyong Park- Receive and handle exceptions entirely in EL3, meaning the exceptions 59*54fd6939SJiyong Park handling terminates in EL3. 60*54fd6939SJiyong Park 61*54fd6939SJiyong Park- Receive exceptions, but handle part of the exception in EL3, and delegate the 62*54fd6939SJiyong Park rest of the handling to a dedicated software stack running at lower Secure 63*54fd6939SJiyong Park ELs. In this scheme, the handling spans various secure ELs. 64*54fd6939SJiyong Park 65*54fd6939SJiyong Park- Receive exceptions, but handle part of the exception in EL3, and delegate 66*54fd6939SJiyong Park processing of the error to dedicated software stack running at lower secure 67*54fd6939SJiyong Park ELs (as above); additionally, the Normal world may also be required to 68*54fd6939SJiyong Park participate in the handling, or be notified of such events (for example, as 69*54fd6939SJiyong Park an |SDEI| event). In this scheme, exception handling potentially and 70*54fd6939SJiyong Park maximally spans all ELs in both Secure and Normal worlds. 71*54fd6939SJiyong Park 72*54fd6939SJiyong ParkOn any given system, all of the above handling models may be employed 73*54fd6939SJiyong Parkindependently depending on platform choice and the nature of the exception 74*54fd6939SJiyong Parkreceived. 75*54fd6939SJiyong Park 76*54fd6939SJiyong Park.. [#spd] Not to be confused with :ref:`Secure Payload Dispatcher 77*54fd6939SJiyong Park <firmware_design_sel1_spd>`, which is an EL3 component that operates in EL3 78*54fd6939SJiyong Park on behalf of Secure OS. 79*54fd6939SJiyong Park 80*54fd6939SJiyong ParkThe role of Exception Handling Framework 81*54fd6939SJiyong Park---------------------------------------- 82*54fd6939SJiyong Park 83*54fd6939SJiyong ParkCorollary to the use cases cited above, the primary role of the |EHF| is to 84*54fd6939SJiyong Parkfacilitate firmware-first handling of exceptions on Arm systems. The |EHF| thus 85*54fd6939SJiyong Parkenables multiple exception dispatchers in runtime firmware to co-exist, register 86*54fd6939SJiyong Parkfor, and handle exceptions targeted at EL3. This section outlines the basics, 87*54fd6939SJiyong Parkand the rest of this document expands the various aspects of the |EHF|. 88*54fd6939SJiyong Park 89*54fd6939SJiyong ParkIn order to arbitrate exception handling among dispatchers, the |EHF| operation 90*54fd6939SJiyong Parkis based on a priority scheme. This priority scheme is closely tied to how the 91*54fd6939SJiyong ParkArm GIC architecture defines it, although it's applied to non-interrupt 92*54fd6939SJiyong Parkexceptions too (SErrors, for example). 93*54fd6939SJiyong Park 94*54fd6939SJiyong ParkThe platform is required to `partition`__ the Secure priority space into 95*54fd6939SJiyong Parkpriority levels as applicable for the Secure software stack. It then assigns the 96*54fd6939SJiyong Parkdispatchers to one or more priority levels. The dispatchers then register 97*54fd6939SJiyong Parkhandlers for the priority levels at runtime. A dispatcher can register handlers 98*54fd6939SJiyong Parkfor more than one priority level. 99*54fd6939SJiyong Park 100*54fd6939SJiyong Park.. __: `Partitioning priority levels`_ 101*54fd6939SJiyong Park 102*54fd6939SJiyong Park 103*54fd6939SJiyong Park.. _ehf-figure: 104*54fd6939SJiyong Park 105*54fd6939SJiyong Park.. image:: ../resources/diagrams/draw.io/ehf.svg 106*54fd6939SJiyong Park 107*54fd6939SJiyong ParkA priority level is *active* when a handler at that priority level is currently 108*54fd6939SJiyong Parkexecuting in EL3, or has delegated the execution to a lower EL. For interrupts, 109*54fd6939SJiyong Parkthis is implicit when an interrupt is targeted and acknowledged at EL3, and the 110*54fd6939SJiyong Parkpriority of the acknowledged interrupt is used to match its registered handler. 111*54fd6939SJiyong ParkThe priority level is likewise implicitly deactivated when the interrupt 112*54fd6939SJiyong Parkhandling concludes by EOIing the interrupt. 113*54fd6939SJiyong Park 114*54fd6939SJiyong ParkNon-interrupt exceptions (SErrors, for example) don't have a notion of priority. 115*54fd6939SJiyong ParkIn order for the priority arbitration to work, the |EHF| provides APIs in order 116*54fd6939SJiyong Parkfor these non-interrupt exceptions to assume a priority, and to interwork with 117*54fd6939SJiyong Parkinterrupts. Dispatchers handling such exceptions must therefore explicitly 118*54fd6939SJiyong Parkactivate and deactivate the respective priority level as and when they're 119*54fd6939SJiyong Parkhandled or delegated. 120*54fd6939SJiyong Park 121*54fd6939SJiyong ParkBecause priority activation and deactivation for interrupt handling is implicit 122*54fd6939SJiyong Parkand involves GIC priority masking, it's impossible for a lower priority 123*54fd6939SJiyong Parkinterrupt to preempt a higher priority one. By extension, this means that a 124*54fd6939SJiyong Parklower priority dispatcher cannot preempt a higher-priority one. Priority 125*54fd6939SJiyong Parkactivation and deactivation for non-interrupt exceptions, however, has to be 126*54fd6939SJiyong Parkexplicit. The |EHF| therefore disallows for lower priority level to be activated 127*54fd6939SJiyong Parkwhilst a higher priority level is active, and would result in a panic. 128*54fd6939SJiyong ParkLikewise, a panic would result if it's attempted to deactivate a lower priority 129*54fd6939SJiyong Parklevel when a higher priority level is active. 130*54fd6939SJiyong Park 131*54fd6939SJiyong ParkIn essence, priority level activation and deactivation conceptually works like a 132*54fd6939SJiyong Parkstack—priority levels stack up in strictly increasing fashion, and need to be 133*54fd6939SJiyong Parkunstacked in strictly the reverse order. For interrupts, the GIC ensures this is 134*54fd6939SJiyong Parkthe case; for non-interrupts, the |EHF| monitors and asserts this. See 135*54fd6939SJiyong Park`Transition of priority levels`_. 136*54fd6939SJiyong Park 137*54fd6939SJiyong Park.. _interrupt-handling: 138*54fd6939SJiyong Park 139*54fd6939SJiyong ParkInterrupt handling 140*54fd6939SJiyong Park------------------ 141*54fd6939SJiyong Park 142*54fd6939SJiyong ParkThe |EHF| is a client of *Interrupt Management Framework*, and registers the 143*54fd6939SJiyong Parktop-level handler for interrupts that target EL3, as described in the 144*54fd6939SJiyong Park:ref:`Interrupt Management Framework` document. This has the following 145*54fd6939SJiyong Parkimplications: 146*54fd6939SJiyong Park 147*54fd6939SJiyong Park- On GICv3 systems, when executing in S-EL1, pending Non-secure interrupts of 148*54fd6939SJiyong Park sufficient priority are signalled as FIQs, and therefore will be routed to 149*54fd6939SJiyong Park EL3. As a result, S-EL1 software cannot expect to handle Non-secure 150*54fd6939SJiyong Park interrupts at S-EL1. Essentially, this deprecates the routing mode described 151*54fd6939SJiyong Park as :ref:`CSS=0, TEL3=0 <EL3 interrupts>`. 152*54fd6939SJiyong Park 153*54fd6939SJiyong Park In order for S-EL1 software to handle Non-secure interrupts while having 154*54fd6939SJiyong Park |EHF| enabled, the dispatcher must adopt a model where Non-secure interrupts 155*54fd6939SJiyong Park are received at EL3, but are then :ref:`synchronously <sp-synchronous-int>` 156*54fd6939SJiyong Park handled over to S-EL1. 157*54fd6939SJiyong Park 158*54fd6939SJiyong Park- On GICv2 systems, it's required that the build option ``GICV2_G0_FOR_EL3`` is 159*54fd6939SJiyong Park set to ``1`` so that *Group 0* interrupts target EL3. 160*54fd6939SJiyong Park 161*54fd6939SJiyong Park- While executing in Secure world, |EHF| sets GIC Priority Mask Register to the 162*54fd6939SJiyong Park lowest Secure priority. This means that no Non-secure interrupts can preempt 163*54fd6939SJiyong Park Secure execution. See `Effect on SMC calls`_ for more details. 164*54fd6939SJiyong Park 165*54fd6939SJiyong ParkAs mentioned above, with |EHF|, the platform is required to partition *Group 0* 166*54fd6939SJiyong Parkinterrupts into distinct priority levels. A dispatcher that chooses to receive 167*54fd6939SJiyong Parkinterrupts can then *own* one or more priority levels, and register interrupt 168*54fd6939SJiyong Parkhandlers for them. A given priority level can be assigned to only one handler. A 169*54fd6939SJiyong Parkdispatcher may register more than one priority level. 170*54fd6939SJiyong Park 171*54fd6939SJiyong ParkDispatchers are assigned interrupt priority levels in two steps: 172*54fd6939SJiyong Park 173*54fd6939SJiyong Park.. _Partitioning priority levels: 174*54fd6939SJiyong Park 175*54fd6939SJiyong ParkPartitioning priority levels 176*54fd6939SJiyong Park~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 177*54fd6939SJiyong Park 178*54fd6939SJiyong ParkInterrupts are associated to dispatchers by way of grouping and assigning 179*54fd6939SJiyong Parkinterrupts to a priority level. In other words, all interrupts that are to 180*54fd6939SJiyong Parktarget a particular dispatcher should fall in a particular priority level. For 181*54fd6939SJiyong Parkpriority assignment: 182*54fd6939SJiyong Park 183*54fd6939SJiyong Park- Of the 8 bits of priority that Arm GIC architecture permits, bit 7 must be 0 184*54fd6939SJiyong Park (secure space). 185*54fd6939SJiyong Park 186*54fd6939SJiyong Park- Depending on the number of dispatchers to support, the platform must choose 187*54fd6939SJiyong Park to use the top *n* of the 7 remaining bits to identify and assign interrupts 188*54fd6939SJiyong Park to individual dispatchers. Choosing *n* bits supports up to 2\ :sup:`n` 189*54fd6939SJiyong Park distinct dispatchers. For example, by choosing 2 additional bits (i.e., bits 190*54fd6939SJiyong Park 6 and 5), the platform can partition into 4 secure priority ranges: ``0x0``, 191*54fd6939SJiyong Park ``0x20``, ``0x40``, and ``0x60``. See `Interrupt handling example`_. 192*54fd6939SJiyong Park 193*54fd6939SJiyong Park.. note:: 194*54fd6939SJiyong Park 195*54fd6939SJiyong Park The Arm GIC architecture requires that a GIC implementation that supports two 196*54fd6939SJiyong Park security states must implement at least 32 priority levels; i.e., at least 5 197*54fd6939SJiyong Park upper bits of the 8 bits are writeable. In the scheme described above, when 198*54fd6939SJiyong Park choosing *n* bits for priority range assignment, the platform must ensure 199*54fd6939SJiyong Park that at least ``n+1`` top bits of GIC priority are writeable. 200*54fd6939SJiyong Park 201*54fd6939SJiyong ParkThe priority thus assigned to an interrupt is also used to determine the 202*54fd6939SJiyong Parkpriority of delegated execution in lower ELs. Delegated execution in lower EL is 203*54fd6939SJiyong Parkassociated with a priority level chosen with ``ehf_activate_priority()`` API 204*54fd6939SJiyong Park(described `later`__). The chosen priority level also determines the interrupts 205*54fd6939SJiyong Parkmasked while executing in a lower EL, therefore controls preemption of delegated 206*54fd6939SJiyong Parkexecution. 207*54fd6939SJiyong Park 208*54fd6939SJiyong Park.. __: `ehf-apis`_ 209*54fd6939SJiyong Park 210*54fd6939SJiyong ParkThe platform expresses the chosen priority levels by declaring an array of 211*54fd6939SJiyong Parkpriority level descriptors. Each entry in the array is of type 212*54fd6939SJiyong Park``ehf_pri_desc_t``, and declares a priority level, and shall be populated by the 213*54fd6939SJiyong Park``EHF_PRI_DESC()`` macro. 214*54fd6939SJiyong Park 215*54fd6939SJiyong Park.. warning:: 216*54fd6939SJiyong Park 217*54fd6939SJiyong Park The macro ``EHF_PRI_DESC()`` installs the descriptors in the array at a 218*54fd6939SJiyong Park computed index, and not necessarily where the macro is placed in the array. 219*54fd6939SJiyong Park The size of the array might therefore be larger than what it appears to be. 220*54fd6939SJiyong Park The ``ARRAY_SIZE()`` macro therefore should be used to determine the size of 221*54fd6939SJiyong Park array. 222*54fd6939SJiyong Park 223*54fd6939SJiyong ParkFinally, this array of descriptors is exposed to |EHF| via the 224*54fd6939SJiyong Park``EHF_REGISTER_PRIORITIES()`` macro. 225*54fd6939SJiyong Park 226*54fd6939SJiyong ParkRefer to the `Interrupt handling example`_ for usage. See also: `Interrupt 227*54fd6939SJiyong ParkPrioritisation Considerations`_. 228*54fd6939SJiyong Park 229*54fd6939SJiyong ParkProgramming priority 230*54fd6939SJiyong Park~~~~~~~~~~~~~~~~~~~~ 231*54fd6939SJiyong Park 232*54fd6939SJiyong ParkThe text in `Partitioning priority levels`_ only describes how the platform 233*54fd6939SJiyong Parkexpresses the required levels of priority. It however doesn't choose interrupts 234*54fd6939SJiyong Parknor program the required priority in GIC. 235*54fd6939SJiyong Park 236*54fd6939SJiyong ParkThe :ref:`Firmware Design guide<configuring-secure-interrupts>` explains methods 237*54fd6939SJiyong Parkfor configuring secure interrupts. |EHF| requires the platform to enumerate 238*54fd6939SJiyong Parkinterrupt properties (as opposed to just numbers) of Secure interrupts. The 239*54fd6939SJiyong Parkpriority of secure interrupts must match that as determined in the 240*54fd6939SJiyong Park`Partitioning priority levels`_ section above. 241*54fd6939SJiyong Park 242*54fd6939SJiyong ParkSee `Limitations`_, and also refer to `Interrupt handling example`_ for 243*54fd6939SJiyong Parkillustration. 244*54fd6939SJiyong Park 245*54fd6939SJiyong ParkRegistering handler 246*54fd6939SJiyong Park------------------- 247*54fd6939SJiyong Park 248*54fd6939SJiyong ParkDispatchers register handlers for their priority levels through the following 249*54fd6939SJiyong ParkAPI: 250*54fd6939SJiyong Park 251*54fd6939SJiyong Park.. code:: c 252*54fd6939SJiyong Park 253*54fd6939SJiyong Park int ehf_register_priority_handler(int pri, ehf_handler_t handler) 254*54fd6939SJiyong Park 255*54fd6939SJiyong ParkThe API takes two arguments: 256*54fd6939SJiyong Park 257*54fd6939SJiyong Park- The priority level for which the handler is being registered; 258*54fd6939SJiyong Park 259*54fd6939SJiyong Park- The handler to be registered. The handler must be aligned to 4 bytes. 260*54fd6939SJiyong Park 261*54fd6939SJiyong ParkIf a dispatcher owns more than one priority levels, it has to call the API for 262*54fd6939SJiyong Parkeach of them. 263*54fd6939SJiyong Park 264*54fd6939SJiyong ParkThe API will succeed, and return ``0``, only if: 265*54fd6939SJiyong Park 266*54fd6939SJiyong Park- There exists a descriptor with the priority level requested. 267*54fd6939SJiyong Park 268*54fd6939SJiyong Park- There are no handlers already registered by a previous call to the API. 269*54fd6939SJiyong Park 270*54fd6939SJiyong ParkOtherwise, the API returns ``-1``. 271*54fd6939SJiyong Park 272*54fd6939SJiyong ParkThe interrupt handler should have the following signature: 273*54fd6939SJiyong Park 274*54fd6939SJiyong Park.. code:: c 275*54fd6939SJiyong Park 276*54fd6939SJiyong Park typedef int (*ehf_handler_t)(uint32_t intr_raw, uint32_t flags, void *handle, 277*54fd6939SJiyong Park void *cookie); 278*54fd6939SJiyong Park 279*54fd6939SJiyong ParkThe parameters are as obtained from the top-level :ref:`EL3 interrupt handler 280*54fd6939SJiyong Park<el3-runtime-firmware>`. 281*54fd6939SJiyong Park 282*54fd6939SJiyong ParkThe :ref:`SDEI dispatcher<SDEI: Software Delegated Exception Interface>`, for 283*54fd6939SJiyong Parkexample, expects the platform to allocate two different priority levels— 284*54fd6939SJiyong Park``PLAT_SDEI_CRITICAL_PRI``, and ``PLAT_SDEI_NORMAL_PRI`` —and registers the 285*54fd6939SJiyong Parksame handler to handle both levels. 286*54fd6939SJiyong Park 287*54fd6939SJiyong ParkInterrupt handling example 288*54fd6939SJiyong Park-------------------------- 289*54fd6939SJiyong Park 290*54fd6939SJiyong ParkThe following annotated snippet demonstrates how a platform might choose to 291*54fd6939SJiyong Parkassign interrupts to fictitious dispatchers: 292*54fd6939SJiyong Park 293*54fd6939SJiyong Park.. code:: c 294*54fd6939SJiyong Park 295*54fd6939SJiyong Park #include <common/interrupt_props.h> 296*54fd6939SJiyong Park #include <drivers/arm/gic_common.h> 297*54fd6939SJiyong Park #include <exception_mgmt.h> 298*54fd6939SJiyong Park 299*54fd6939SJiyong Park ... 300*54fd6939SJiyong Park 301*54fd6939SJiyong Park /* 302*54fd6939SJiyong Park * This platform uses 2 bits for interrupt association. In total, 3 upper 303*54fd6939SJiyong Park * bits are in use. 304*54fd6939SJiyong Park * 305*54fd6939SJiyong Park * 7 6 5 3 0 306*54fd6939SJiyong Park * .-.-.-.----------. 307*54fd6939SJiyong Park * |0|b|b| ..0.. | 308*54fd6939SJiyong Park * '-'-'-'----------' 309*54fd6939SJiyong Park */ 310*54fd6939SJiyong Park #define PLAT_PRI_BITS 2 311*54fd6939SJiyong Park 312*54fd6939SJiyong Park /* Priorities for individual dispatchers */ 313*54fd6939SJiyong Park #define DISP0_PRIO 0x00 /* Not used */ 314*54fd6939SJiyong Park #define DISP1_PRIO 0x20 315*54fd6939SJiyong Park #define DISP2_PRIO 0x40 316*54fd6939SJiyong Park #define DISP3_PRIO 0x60 317*54fd6939SJiyong Park 318*54fd6939SJiyong Park /* Install priority level descriptors for each dispatcher */ 319*54fd6939SJiyong Park ehf_pri_desc_t plat_exceptions[] = { 320*54fd6939SJiyong Park EHF_PRI_DESC(PLAT_PRI_BITS, DISP1_PRIO), 321*54fd6939SJiyong Park EHF_PRI_DESC(PLAT_PRI_BITS, DISP2_PRIO), 322*54fd6939SJiyong Park EHF_PRI_DESC(PLAT_PRI_BITS, DISP3_PRIO), 323*54fd6939SJiyong Park }; 324*54fd6939SJiyong Park 325*54fd6939SJiyong Park /* Expose priority descriptors to Exception Handling Framework */ 326*54fd6939SJiyong Park EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions), 327*54fd6939SJiyong Park PLAT_PRI_BITS); 328*54fd6939SJiyong Park 329*54fd6939SJiyong Park ... 330*54fd6939SJiyong Park 331*54fd6939SJiyong Park /* List interrupt properties for GIC driver. All interrupts target EL3 */ 332*54fd6939SJiyong Park const interrupt_prop_t plat_interrupts[] = { 333*54fd6939SJiyong Park /* Dispatcher 1 owns interrupts d1_0 and d1_1, so assigns priority DISP1_PRIO */ 334*54fd6939SJiyong Park INTR_PROP_DESC(d1_0, DISP1_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 335*54fd6939SJiyong Park INTR_PROP_DESC(d1_1, DISP1_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 336*54fd6939SJiyong Park 337*54fd6939SJiyong Park /* Dispatcher 2 owns interrupts d2_0 and d2_1, so assigns priority DISP2_PRIO */ 338*54fd6939SJiyong Park INTR_PROP_DESC(d2_0, DISP2_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 339*54fd6939SJiyong Park INTR_PROP_DESC(d2_1, DISP2_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 340*54fd6939SJiyong Park 341*54fd6939SJiyong Park /* Dispatcher 3 owns interrupts d3_0 and d3_1, so assigns priority DISP3_PRIO */ 342*54fd6939SJiyong Park INTR_PROP_DESC(d3_0, DISP3_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 343*54fd6939SJiyong Park INTR_PROP_DESC(d3_1, DISP3_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 344*54fd6939SJiyong Park }; 345*54fd6939SJiyong Park 346*54fd6939SJiyong Park ... 347*54fd6939SJiyong Park 348*54fd6939SJiyong Park /* Dispatcher 1 registers its handler */ 349*54fd6939SJiyong Park ehf_register_priority_handler(DISP1_PRIO, disp1_handler); 350*54fd6939SJiyong Park 351*54fd6939SJiyong Park /* Dispatcher 2 registers its handler */ 352*54fd6939SJiyong Park ehf_register_priority_handler(DISP2_PRIO, disp2_handler); 353*54fd6939SJiyong Park 354*54fd6939SJiyong Park /* Dispatcher 3 registers its handler */ 355*54fd6939SJiyong Park ehf_register_priority_handler(DISP3_PRIO, disp3_handler); 356*54fd6939SJiyong Park 357*54fd6939SJiyong Park ... 358*54fd6939SJiyong Park 359*54fd6939SJiyong ParkSee also the `Build-time flow`_ and the `Run-time flow`_. 360*54fd6939SJiyong Park 361*54fd6939SJiyong Park.. _Activating and Deactivating priorities: 362*54fd6939SJiyong Park 363*54fd6939SJiyong ParkActivating and Deactivating priorities 364*54fd6939SJiyong Park-------------------------------------- 365*54fd6939SJiyong Park 366*54fd6939SJiyong ParkA priority level is said to be *active* when an exception of that priority is 367*54fd6939SJiyong Parkbeing handled: for interrupts, this is implied when the interrupt is 368*54fd6939SJiyong Parkacknowledged; for non-interrupt exceptions, such as SErrors or :ref:`SDEI 369*54fd6939SJiyong Parkexplicit dispatches <explicit-dispatch-of-events>`, this has to be done via 370*54fd6939SJiyong Parkcalling ``ehf_activate_priority()``. See `Run-time flow`_. 371*54fd6939SJiyong Park 372*54fd6939SJiyong ParkConversely, when the dispatcher has reached a logical resolution for the cause 373*54fd6939SJiyong Parkof the exception, the corresponding priority level ought to be deactivated. As 374*54fd6939SJiyong Parkabove, for interrupts, this is implied when the interrupt is EOId in the GIC; 375*54fd6939SJiyong Parkfor other exceptions, this has to be done via calling 376*54fd6939SJiyong Park``ehf_deactivate_priority()``. 377*54fd6939SJiyong Park 378*54fd6939SJiyong ParkThanks to `different provisions`__ for exception delegation, there are 379*54fd6939SJiyong Parkpotentially more than one work flow for deactivation: 380*54fd6939SJiyong Park 381*54fd6939SJiyong Park.. __: `delegation-use-cases`_ 382*54fd6939SJiyong Park 383*54fd6939SJiyong Park.. _deactivation workflows: 384*54fd6939SJiyong Park 385*54fd6939SJiyong Park- The dispatcher has addressed the cause of the exception, and decided to take 386*54fd6939SJiyong Park no further action. In this case, the dispatcher's handler deactivates the 387*54fd6939SJiyong Park priority level before returning to the |EHF|. Runtime firmware, upon exit 388*54fd6939SJiyong Park through an ``ERET``, resumes execution before the interrupt occurred. 389*54fd6939SJiyong Park 390*54fd6939SJiyong Park- The dispatcher has to delegate the execution to lower ELs, and the cause of 391*54fd6939SJiyong Park the exception can be considered resolved only when the lower EL returns 392*54fd6939SJiyong Park signals complete (via an ``SMC``) at a future point in time. The following 393*54fd6939SJiyong Park sequence ensues: 394*54fd6939SJiyong Park 395*54fd6939SJiyong Park #. The dispatcher calls ``setjmp()`` to setup a jump point, and arranges to 396*54fd6939SJiyong Park enter a lower EL upon the next ``ERET``. 397*54fd6939SJiyong Park 398*54fd6939SJiyong Park #. Through the ensuing ``ERET`` from runtime firmware, execution is delegated 399*54fd6939SJiyong Park to a lower EL. 400*54fd6939SJiyong Park 401*54fd6939SJiyong Park #. The lower EL completes its execution, and signals completion via an 402*54fd6939SJiyong Park ``SMC``. 403*54fd6939SJiyong Park 404*54fd6939SJiyong Park #. The ``SMC`` is handled by the same dispatcher that handled the exception 405*54fd6939SJiyong Park previously. Noticing the conclusion of exception handling, the dispatcher 406*54fd6939SJiyong Park does ``longjmp()`` to resume beyond the previous jump point. 407*54fd6939SJiyong Park 408*54fd6939SJiyong ParkAs mentioned above, the |EHF| provides the following APIs for activating and 409*54fd6939SJiyong Parkdeactivating interrupt: 410*54fd6939SJiyong Park 411*54fd6939SJiyong Park.. _ehf-apis: 412*54fd6939SJiyong Park 413*54fd6939SJiyong Park- ``ehf_activate_priority()`` activates the supplied priority level, but only 414*54fd6939SJiyong Park if the current active priority is higher than the given one; otherwise 415*54fd6939SJiyong Park panics. Also, to prevent interruption by physical interrupts of lower 416*54fd6939SJiyong Park priority, the |EHF| programs the *Priority Mask Register* corresponding to 417*54fd6939SJiyong Park the PE to the priority being activated. Dispatchers typically only need to 418*54fd6939SJiyong Park call this when handling exceptions other than interrupts, and it needs to 419*54fd6939SJiyong Park delegate execution to a lower EL at a desired priority level. 420*54fd6939SJiyong Park 421*54fd6939SJiyong Park- ``ehf_deactivate_priority()`` deactivates a given priority, but only if the 422*54fd6939SJiyong Park current active priority is equal to the given one; otherwise panics. |EHF| 423*54fd6939SJiyong Park also restores the *Priority Mask Register* corresponding to the PE to the 424*54fd6939SJiyong Park priority before the call to ``ehf_activate_priority()``. Dispatchers 425*54fd6939SJiyong Park typically only need to call this after handling exceptions other than 426*54fd6939SJiyong Park interrupts. 427*54fd6939SJiyong Park 428*54fd6939SJiyong ParkThe calling of APIs are subject to allowed `transitions`__. See also the 429*54fd6939SJiyong Park`Run-time flow`_. 430*54fd6939SJiyong Park 431*54fd6939SJiyong Park.. __: `Transition of priority levels`_ 432*54fd6939SJiyong Park 433*54fd6939SJiyong ParkTransition of priority levels 434*54fd6939SJiyong Park----------------------------- 435*54fd6939SJiyong Park 436*54fd6939SJiyong ParkThe |EHF| APIs ``ehf_activate_priority()`` and ``ehf_deactivate_priority()`` can 437*54fd6939SJiyong Parkbe called to transition the current priority level on a PE. A given sequence of 438*54fd6939SJiyong Parkcalls to these APIs are subject to the following conditions: 439*54fd6939SJiyong Park 440*54fd6939SJiyong Park- For activation, the |EHF| only allows for the priority to increase (i.e. 441*54fd6939SJiyong Park numeric value decreases); 442*54fd6939SJiyong Park 443*54fd6939SJiyong Park- For deactivation, the |EHF| only allows for the priority to decrease (i.e. 444*54fd6939SJiyong Park numeric value increases). Additionally, the priority being deactivated is 445*54fd6939SJiyong Park required to be the current priority. 446*54fd6939SJiyong Park 447*54fd6939SJiyong ParkIf these are violated, a panic will result. 448*54fd6939SJiyong Park 449*54fd6939SJiyong Park.. _Effect on SMC calls: 450*54fd6939SJiyong Park 451*54fd6939SJiyong ParkEffect on SMC calls 452*54fd6939SJiyong Park------------------- 453*54fd6939SJiyong Park 454*54fd6939SJiyong ParkIn general, Secure execution is regarded as more important than Non-secure 455*54fd6939SJiyong Parkexecution. As discussed elsewhere in this document, EL3 execution, and any 456*54fd6939SJiyong Parkdelegated execution thereafter, has the effect of raising GIC's priority 457*54fd6939SJiyong Parkmask—either implicitly by acknowledging Secure interrupts, or when dispatchers 458*54fd6939SJiyong Parkcall ``ehf_activate_priority()``. As a result, Non-secure interrupts cannot 459*54fd6939SJiyong Parkpreempt any Secure execution. 460*54fd6939SJiyong Park 461*54fd6939SJiyong ParkSMCs from Non-secure world are synchronous exceptions, and are mechanisms for 462*54fd6939SJiyong ParkNon-secure world to request Secure services. They're broadly classified as 463*54fd6939SJiyong Park*Fast* or *Yielding* (see `SMCCC`__). 464*54fd6939SJiyong Park 465*54fd6939SJiyong Park.. __: https://developer.arm.com/docs/den0028/latest 466*54fd6939SJiyong Park 467*54fd6939SJiyong Park- *Fast* SMCs are atomic from the caller's point of view. I.e., they return 468*54fd6939SJiyong Park to the caller only when the Secure world has finished serving the request. 469*54fd6939SJiyong Park Any Non-secure interrupts that become pending meanwhile cannot preempt Secure 470*54fd6939SJiyong Park execution. 471*54fd6939SJiyong Park 472*54fd6939SJiyong Park- *Yielding* SMCs carry the semantics of a preemptible, lower-priority request. 473*54fd6939SJiyong Park A pending Non-secure interrupt can preempt Secure execution handling a 474*54fd6939SJiyong Park Yielding SMC. I.e., the caller might observe a Yielding SMC returning when 475*54fd6939SJiyong Park either: 476*54fd6939SJiyong Park 477*54fd6939SJiyong Park #. Secure world completes the request, and the caller would find ``SMC_OK`` 478*54fd6939SJiyong Park as the return code. 479*54fd6939SJiyong Park 480*54fd6939SJiyong Park #. A Non-secure interrupt preempts Secure execution. Non-secure interrupt is 481*54fd6939SJiyong Park handled, and Non-secure execution resumes after ``SMC`` instruction. 482*54fd6939SJiyong Park 483*54fd6939SJiyong Park The dispatcher handling a Yielding SMC must provide a different return code 484*54fd6939SJiyong Park to the Non-secure caller to distinguish the latter case. This return code, 485*54fd6939SJiyong Park however, is not standardised (unlike ``SMC_UNKNOWN`` or ``SMC_OK``, for 486*54fd6939SJiyong Park example), so will vary across dispatchers that handle the request. 487*54fd6939SJiyong Park 488*54fd6939SJiyong ParkFor the latter case above, dispatchers before |EHF| expect Non-secure interrupts 489*54fd6939SJiyong Parkto be taken to S-EL1 [#irq]_, so would get a chance to populate the designated 490*54fd6939SJiyong Parkpreempted error code before yielding to Non-secure world. 491*54fd6939SJiyong Park 492*54fd6939SJiyong ParkThe introduction of |EHF| changes the behaviour as described in `Interrupt 493*54fd6939SJiyong Parkhandling`_. 494*54fd6939SJiyong Park 495*54fd6939SJiyong ParkWhen |EHF| is enabled, in order to allow Non-secure interrupts to preempt 496*54fd6939SJiyong ParkYielding SMC handling, the dispatcher must call ``ehf_allow_ns_preemption()`` 497*54fd6939SJiyong ParkAPI. The API takes one argument, the error code to be returned to the Non-secure 498*54fd6939SJiyong Parkworld upon getting preempted. 499*54fd6939SJiyong Park 500*54fd6939SJiyong Park.. [#irq] In case of GICv2, Non-secure interrupts while in S-EL1 were signalled 501*54fd6939SJiyong Park as IRQs, and in case of GICv3, FIQs. 502*54fd6939SJiyong Park 503*54fd6939SJiyong ParkBuild-time flow 504*54fd6939SJiyong Park--------------- 505*54fd6939SJiyong Park 506*54fd6939SJiyong ParkPlease refer to the `figure`__ above. 507*54fd6939SJiyong Park 508*54fd6939SJiyong Park.. __: `ehf-figure`_ 509*54fd6939SJiyong Park 510*54fd6939SJiyong ParkThe build-time flow involves the following steps: 511*54fd6939SJiyong Park 512*54fd6939SJiyong Park#. Platform assigns priorities by installing priority level descriptors for 513*54fd6939SJiyong Park individual dispatchers, as described in `Partitioning priority levels`_. 514*54fd6939SJiyong Park 515*54fd6939SJiyong Park#. Platform provides interrupt properties to GIC driver, as described in 516*54fd6939SJiyong Park `Programming priority`_. 517*54fd6939SJiyong Park 518*54fd6939SJiyong Park#. Dispatcher calling ``ehf_register_priority_handler()`` to register an 519*54fd6939SJiyong Park interrupt handler. 520*54fd6939SJiyong Park 521*54fd6939SJiyong ParkAlso refer to the `Interrupt handling example`_. 522*54fd6939SJiyong Park 523*54fd6939SJiyong ParkRun-time flow 524*54fd6939SJiyong Park------------- 525*54fd6939SJiyong Park 526*54fd6939SJiyong Park.. _interrupt-flow: 527*54fd6939SJiyong Park 528*54fd6939SJiyong ParkThe following is an example flow for interrupts: 529*54fd6939SJiyong Park 530*54fd6939SJiyong Park#. The GIC driver, during initialization, iterates through the platform-supplied 531*54fd6939SJiyong Park interrupt properties (see `Programming priority`_), and configures the 532*54fd6939SJiyong Park interrupts. This programs the appropriate priority and group (Group 0) on 533*54fd6939SJiyong Park interrupts belonging to different dispatchers. 534*54fd6939SJiyong Park 535*54fd6939SJiyong Park#. The |EHF|, during its initialisation, registers a top-level interrupt handler 536*54fd6939SJiyong Park with the :ref:`Interrupt Management Framework<el3-runtime-firmware>` for EL3 537*54fd6939SJiyong Park interrupts. This also results in setting the routing bits in ``SCR_EL3``. 538*54fd6939SJiyong Park 539*54fd6939SJiyong Park#. When an interrupt belonging to a dispatcher fires, GIC raises an EL3/Group 0 540*54fd6939SJiyong Park interrupt, and is taken to EL3. 541*54fd6939SJiyong Park 542*54fd6939SJiyong Park#. The top-level EL3 interrupt handler executes. The handler acknowledges the 543*54fd6939SJiyong Park interrupt, reads its *Running Priority*, and from that, determines the 544*54fd6939SJiyong Park dispatcher handler. 545*54fd6939SJiyong Park 546*54fd6939SJiyong Park#. The |EHF| programs the *Priority Mask Register* of the PE to the priority of 547*54fd6939SJiyong Park the interrupt received. 548*54fd6939SJiyong Park 549*54fd6939SJiyong Park#. The |EHF| marks that priority level *active*, and jumps to the dispatcher 550*54fd6939SJiyong Park handler. 551*54fd6939SJiyong Park 552*54fd6939SJiyong Park#. Once the dispatcher handler finishes its job, it has to immediately 553*54fd6939SJiyong Park *deactivate* the priority level before returning to the |EHF|. See 554*54fd6939SJiyong Park `deactivation workflows`_. 555*54fd6939SJiyong Park 556*54fd6939SJiyong Park.. _non-interrupt-flow: 557*54fd6939SJiyong Park 558*54fd6939SJiyong ParkThe following is an example flow for exceptions that targets EL3 other than 559*54fd6939SJiyong Parkinterrupt: 560*54fd6939SJiyong Park 561*54fd6939SJiyong Park#. The platform provides handlers for the specific kind of exception. 562*54fd6939SJiyong Park 563*54fd6939SJiyong Park#. The exception arrives, and the corresponding handler is executed. 564*54fd6939SJiyong Park 565*54fd6939SJiyong Park#. The handler calls ``ehf_activate_priority()`` to activate the required 566*54fd6939SJiyong Park priority level. This also has the effect of raising GIC priority mask, thus 567*54fd6939SJiyong Park preventing interrupts of lower priority from preempting the handling. The 568*54fd6939SJiyong Park handler may choose to do the handling entirely in EL3 or delegate to a lower 569*54fd6939SJiyong Park EL. 570*54fd6939SJiyong Park 571*54fd6939SJiyong Park#. Once exception handling concludes, the handler calls 572*54fd6939SJiyong Park ``ehf_deactivate_priority()`` to deactivate the priority level activated 573*54fd6939SJiyong Park earlier. This also has the effect of lowering GIC priority mask to what it 574*54fd6939SJiyong Park was before. 575*54fd6939SJiyong Park 576*54fd6939SJiyong ParkInterrupt Prioritisation Considerations 577*54fd6939SJiyong Park--------------------------------------- 578*54fd6939SJiyong Park 579*54fd6939SJiyong ParkThe GIC priority scheme, by design, prioritises Secure interrupts over Normal 580*54fd6939SJiyong Parkworld ones. The platform further assigns relative priorities amongst Secure 581*54fd6939SJiyong Parkdispatchers through |EHF|. 582*54fd6939SJiyong Park 583*54fd6939SJiyong ParkAs mentioned in `Partitioning priority levels`_, interrupts targeting distinct 584*54fd6939SJiyong Parkdispatchers fall in distinct priority levels. Because they're routed via the 585*54fd6939SJiyong ParkGIC, interrupt delivery to the PE is subject to GIC prioritisation rules. In 586*54fd6939SJiyong Parkparticular, when an interrupt is being handled by the PE (i.e., the interrupt is 587*54fd6939SJiyong Parkin *Active* state), only interrupts of higher priority are signalled to the PE, 588*54fd6939SJiyong Parkeven if interrupts of same or lower priority are pending. This has the side 589*54fd6939SJiyong Parkeffect of one dispatcher being starved of interrupts by virtue of another 590*54fd6939SJiyong Parkdispatcher handling its (higher priority) interrupts. 591*54fd6939SJiyong Park 592*54fd6939SJiyong ParkThe |EHF| doesn't enforce a particular prioritisation policy, but the platform 593*54fd6939SJiyong Parkshould carefully consider the assignment of priorities to dispatchers integrated 594*54fd6939SJiyong Parkinto runtime firmware. The platform should sensibly delineate priority to 595*54fd6939SJiyong Parkvarious dispatchers according to their nature. In particular, dispatchers of 596*54fd6939SJiyong Parkcritical nature (RAS, for example) should be assigned higher priority than 597*54fd6939SJiyong Parkothers (|SDEI|, for example); and within |SDEI|, Critical priority 598*54fd6939SJiyong Park|SDEI| should be assigned higher priority than Normal ones. 599*54fd6939SJiyong Park 600*54fd6939SJiyong ParkLimitations 601*54fd6939SJiyong Park----------- 602*54fd6939SJiyong Park 603*54fd6939SJiyong ParkThe |EHF| has the following limitations: 604*54fd6939SJiyong Park 605*54fd6939SJiyong Park- Although there could be up to 128 Secure dispatchers supported by the GIC 606*54fd6939SJiyong Park priority scheme, the size of descriptor array exposed with 607*54fd6939SJiyong Park ``EHF_REGISTER_PRIORITIES()`` macro is currently limited to 32. This serves most 608*54fd6939SJiyong Park expected use cases. This may be expanded in the future, should use cases 609*54fd6939SJiyong Park demand so. 610*54fd6939SJiyong Park 611*54fd6939SJiyong Park- The platform must ensure that the priority assigned to the dispatcher in the 612*54fd6939SJiyong Park exception descriptor and the programmed priority of interrupts handled by the 613*54fd6939SJiyong Park dispatcher match. The |EHF| cannot verify that this has been followed. 614*54fd6939SJiyong Park 615*54fd6939SJiyong Park-------------- 616*54fd6939SJiyong Park 617*54fd6939SJiyong Park*Copyright (c) 2018-2020, Arm Limited and Contributors. All rights reserved.* 618*54fd6939SJiyong Park 619*54fd6939SJiyong Park.. _SDEI specification: http://infocenter.arm.com/help/topic/com.arm.doc.den0054a/ARM_DEN0054A_Software_Delegated_Exception_Interface.pdf 620