18aa05055SPaul BeesleyException Handling Framework 28aa05055SPaul Beesley============================ 340d553cfSPaul Beesley 440d553cfSPaul BeesleyThis document describes various aspects of handling exceptions by Runtime 540d553cfSPaul BeesleyFirmware (BL31) that are targeted at EL3, other than SMCs. The |EHF| takes care 640d553cfSPaul Beesleyof the following exceptions when targeted at EL3: 740d553cfSPaul Beesley 840d553cfSPaul Beesley- Interrupts 940d553cfSPaul Beesley- Synchronous External Aborts 1040d553cfSPaul Beesley- Asynchronous External Aborts 1140d553cfSPaul Beesley 1240d553cfSPaul Beesley|TF-A|'s handling of synchronous ``SMC`` exceptions raised from lower ELs is 136844c347SMadhukar Pappireddydescribed in the :ref:`Firmware Design document <handling-an-smc>`. However, the 146844c347SMadhukar Pappireddy|EHF| changes the semantics of `Interrupt handling`_ and :ref:`synchronous 156844c347SMadhukar Pappireddyexceptions <Effect on SMC calls>` other than SMCs. 1640d553cfSPaul Beesley 1740d553cfSPaul BeesleyThe |EHF| is selected by setting the build option ``EL3_EXCEPTION_HANDLING`` to 1840d553cfSPaul Beesley``1``, and is only available for AArch64 systems. 1940d553cfSPaul Beesley 2040d553cfSPaul BeesleyIntroduction 2140d553cfSPaul Beesley------------ 2240d553cfSPaul Beesley 2340d553cfSPaul BeesleyThrough various control bits in the ``SCR_EL3`` register, the Arm architecture 2440d553cfSPaul Beesleyallows for asynchronous exceptions to be routed to EL3. As described in the 2534760951SPaul Beesley:ref:`Interrupt Management Framework` document, depending on the chosen 2634760951SPaul Beesleyinterrupt routing model, TF-A appropriately sets the ``FIQ`` and ``IRQ`` bits of 2740d553cfSPaul Beesley``SCR_EL3`` register to effect this routing. For most use cases, other than for 2840d553cfSPaul Beesleythe purpose of facilitating context switch between Normal and Secure worlds, 2940d553cfSPaul BeesleyFIQs and IRQs routed to EL3 are not required to be handled in EL3. 3040d553cfSPaul Beesley 3140d553cfSPaul BeesleyHowever, the evolving system and standards landscape demands that various 3240d553cfSPaul Beesleyexceptions are targeted at and handled in EL3. For instance: 3340d553cfSPaul Beesley 3440d553cfSPaul Beesley- Starting with ARMv8.2 architecture extension, many RAS features have been 3540d553cfSPaul Beesley introduced to the Arm architecture. With RAS features implemented, various 3640d553cfSPaul Beesley components of the system may use one of the asynchronous exceptions to signal 3740d553cfSPaul Beesley error conditions to PEs. These error conditions are of critical nature, and 3840d553cfSPaul Beesley it's imperative that corrective or remedial actions are taken at the earliest 3940d553cfSPaul Beesley opportunity. Therefore, a *Firmware-first Handling* approach is generally 4040d553cfSPaul Beesley followed in response to RAS events in the system. 4140d553cfSPaul Beesley 4240d553cfSPaul Beesley- The Arm `SDEI specification`_ defines interfaces through which Normal world 4340d553cfSPaul Beesley interacts with the Runtime Firmware in order to request notification of 448f62ca7bSPaul Beesley system events. The |SDEI| specification requires that these events are 458f62ca7bSPaul Beesley notified even when the Normal world executes with the exceptions masked. This 468f62ca7bSPaul Beesley too implies that firmware-first handling is required, where the events are 478f62ca7bSPaul Beesley first received by the EL3 firmware, and then dispatched to Normal world 488f62ca7bSPaul Beesley through purely software mechanism. 4940d553cfSPaul Beesley 5040d553cfSPaul BeesleyFor |TF-A|, firmware-first handling means that asynchronous exceptions are 5140d553cfSPaul Beesleysuitably routed to EL3, and the Runtime Firmware (BL31) is extended to include 5240d553cfSPaul Beesleysoftware components that are capable of handling those exceptions that target 5340d553cfSPaul BeesleyEL3. These components—referred to as *dispatchers* [#spd]_ in general—may 5440d553cfSPaul Beesleychoose to: 5540d553cfSPaul Beesley 5640d553cfSPaul Beesley.. _delegation-use-cases: 5740d553cfSPaul Beesley 5840d553cfSPaul Beesley- Receive and handle exceptions entirely in EL3, meaning the exceptions 5940d553cfSPaul Beesley handling terminates in EL3. 6040d553cfSPaul Beesley 6140d553cfSPaul Beesley- Receive exceptions, but handle part of the exception in EL3, and delegate the 6240d553cfSPaul Beesley rest of the handling to a dedicated software stack running at lower Secure 6340d553cfSPaul Beesley ELs. In this scheme, the handling spans various secure ELs. 6440d553cfSPaul Beesley 6540d553cfSPaul Beesley- Receive exceptions, but handle part of the exception in EL3, and delegate 6640d553cfSPaul Beesley processing of the error to dedicated software stack running at lower secure 6740d553cfSPaul Beesley ELs (as above); additionally, the Normal world may also be required to 6840d553cfSPaul Beesley participate in the handling, or be notified of such events (for example, as 698f62ca7bSPaul Beesley an |SDEI| event). In this scheme, exception handling potentially and 708f62ca7bSPaul Beesley maximally spans all ELs in both Secure and Normal worlds. 7140d553cfSPaul Beesley 7240d553cfSPaul BeesleyOn any given system, all of the above handling models may be employed 7340d553cfSPaul Beesleyindependently depending on platform choice and the nature of the exception 7440d553cfSPaul Beesleyreceived. 7540d553cfSPaul Beesley 766844c347SMadhukar Pappireddy.. [#spd] Not to be confused with :ref:`Secure Payload Dispatcher 776844c347SMadhukar Pappireddy <firmware_design_sel1_spd>`, which is an EL3 component that operates in EL3 786844c347SMadhukar Pappireddy on behalf of Secure OS. 7940d553cfSPaul Beesley 8040d553cfSPaul BeesleyThe role of Exception Handling Framework 8140d553cfSPaul Beesley---------------------------------------- 8240d553cfSPaul Beesley 8340d553cfSPaul BeesleyCorollary to the use cases cited above, the primary role of the |EHF| is to 8440d553cfSPaul Beesleyfacilitate firmware-first handling of exceptions on Arm systems. The |EHF| thus 8540d553cfSPaul Beesleyenables multiple exception dispatchers in runtime firmware to co-exist, register 8640d553cfSPaul Beesleyfor, and handle exceptions targeted at EL3. This section outlines the basics, 8740d553cfSPaul Beesleyand the rest of this document expands the various aspects of the |EHF|. 8840d553cfSPaul Beesley 8940d553cfSPaul BeesleyIn order to arbitrate exception handling among dispatchers, the |EHF| operation 9040d553cfSPaul Beesleyis based on a priority scheme. This priority scheme is closely tied to how the 9140d553cfSPaul BeesleyArm GIC architecture defines it, although it's applied to non-interrupt 9240d553cfSPaul Beesleyexceptions too (SErrors, for example). 9340d553cfSPaul Beesley 9440d553cfSPaul BeesleyThe platform is required to `partition`__ the Secure priority space into 9540d553cfSPaul Beesleypriority levels as applicable for the Secure software stack. It then assigns the 9640d553cfSPaul Beesleydispatchers to one or more priority levels. The dispatchers then register 9740d553cfSPaul Beesleyhandlers for the priority levels at runtime. A dispatcher can register handlers 9840d553cfSPaul Beesleyfor more than one priority level. 9940d553cfSPaul Beesley 10040d553cfSPaul Beesley.. __: `Partitioning priority levels`_ 10140d553cfSPaul Beesley 10240d553cfSPaul Beesley 10340d553cfSPaul Beesley.. _ehf-figure: 10440d553cfSPaul Beesley 105a2c320a8SPaul Beesley.. image:: ../resources/diagrams/draw.io/ehf.svg 10640d553cfSPaul Beesley 10740d553cfSPaul BeesleyA priority level is *active* when a handler at that priority level is currently 10840d553cfSPaul Beesleyexecuting in EL3, or has delegated the execution to a lower EL. For interrupts, 10940d553cfSPaul Beesleythis is implicit when an interrupt is targeted and acknowledged at EL3, and the 11040d553cfSPaul Beesleypriority of the acknowledged interrupt is used to match its registered handler. 11140d553cfSPaul BeesleyThe priority level is likewise implicitly deactivated when the interrupt 11240d553cfSPaul Beesleyhandling concludes by EOIing the interrupt. 11340d553cfSPaul Beesley 11440d553cfSPaul BeesleyNon-interrupt exceptions (SErrors, for example) don't have a notion of priority. 11540d553cfSPaul BeesleyIn order for the priority arbitration to work, the |EHF| provides APIs in order 11640d553cfSPaul Beesleyfor these non-interrupt exceptions to assume a priority, and to interwork with 11740d553cfSPaul Beesleyinterrupts. Dispatchers handling such exceptions must therefore explicitly 11840d553cfSPaul Beesleyactivate and deactivate the respective priority level as and when they're 11940d553cfSPaul Beesleyhandled or delegated. 12040d553cfSPaul Beesley 12140d553cfSPaul BeesleyBecause priority activation and deactivation for interrupt handling is implicit 12240d553cfSPaul Beesleyand involves GIC priority masking, it's impossible for a lower priority 12340d553cfSPaul Beesleyinterrupt to preempt a higher priority one. By extension, this means that a 12440d553cfSPaul Beesleylower priority dispatcher cannot preempt a higher-priority one. Priority 12540d553cfSPaul Beesleyactivation and deactivation for non-interrupt exceptions, however, has to be 12640d553cfSPaul Beesleyexplicit. The |EHF| therefore disallows for lower priority level to be activated 12740d553cfSPaul Beesleywhilst a higher priority level is active, and would result in a panic. 12840d553cfSPaul BeesleyLikewise, a panic would result if it's attempted to deactivate a lower priority 12940d553cfSPaul Beesleylevel when a higher priority level is active. 13040d553cfSPaul Beesley 13140d553cfSPaul BeesleyIn essence, priority level activation and deactivation conceptually works like a 13240d553cfSPaul Beesleystack—priority levels stack up in strictly increasing fashion, and need to be 13340d553cfSPaul Beesleyunstacked in strictly the reverse order. For interrupts, the GIC ensures this is 13440d553cfSPaul Beesleythe case; for non-interrupts, the |EHF| monitors and asserts this. See 13540d553cfSPaul Beesley`Transition of priority levels`_. 13640d553cfSPaul Beesley 1376844c347SMadhukar Pappireddy.. _interrupt-handling: 1386844c347SMadhukar Pappireddy 13940d553cfSPaul BeesleyInterrupt handling 14040d553cfSPaul Beesley------------------ 14140d553cfSPaul Beesley 14240d553cfSPaul BeesleyThe |EHF| is a client of *Interrupt Management Framework*, and registers the 14334760951SPaul Beesleytop-level handler for interrupts that target EL3, as described in the 14434760951SPaul Beesley:ref:`Interrupt Management Framework` document. This has the following 14534760951SPaul Beesleyimplications: 14640d553cfSPaul Beesley 14740d553cfSPaul Beesley- On GICv3 systems, when executing in S-EL1, pending Non-secure interrupts of 14840d553cfSPaul Beesley sufficient priority are signalled as FIQs, and therefore will be routed to 14940d553cfSPaul Beesley EL3. As a result, S-EL1 software cannot expect to handle Non-secure 15040d553cfSPaul Beesley interrupts at S-EL1. Essentially, this deprecates the routing mode described 1516844c347SMadhukar Pappireddy as :ref:`CSS=0, TEL3=0 <EL3 interrupts>`. 15240d553cfSPaul Beesley 15340d553cfSPaul Beesley In order for S-EL1 software to handle Non-secure interrupts while having 15440d553cfSPaul Beesley |EHF| enabled, the dispatcher must adopt a model where Non-secure interrupts 1556844c347SMadhukar Pappireddy are received at EL3, but are then :ref:`synchronously <sp-synchronous-int>` 1566844c347SMadhukar Pappireddy handled over to S-EL1. 15740d553cfSPaul Beesley 15840d553cfSPaul Beesley- On GICv2 systems, it's required that the build option ``GICV2_G0_FOR_EL3`` is 15940d553cfSPaul Beesley set to ``1`` so that *Group 0* interrupts target EL3. 16040d553cfSPaul Beesley 16140d553cfSPaul Beesley- While executing in Secure world, |EHF| sets GIC Priority Mask Register to the 16240d553cfSPaul Beesley lowest Secure priority. This means that no Non-secure interrupts can preempt 16340d553cfSPaul Beesley Secure execution. See `Effect on SMC calls`_ for more details. 16440d553cfSPaul Beesley 16540d553cfSPaul BeesleyAs mentioned above, with |EHF|, the platform is required to partition *Group 0* 16640d553cfSPaul Beesleyinterrupts into distinct priority levels. A dispatcher that chooses to receive 16740d553cfSPaul Beesleyinterrupts can then *own* one or more priority levels, and register interrupt 16840d553cfSPaul Beesleyhandlers for them. A given priority level can be assigned to only one handler. A 16940d553cfSPaul Beesleydispatcher may register more than one priority level. 17040d553cfSPaul Beesley 17140d553cfSPaul BeesleyDispatchers are assigned interrupt priority levels in two steps: 17240d553cfSPaul Beesley 173c3233c11SManish Pandey.. _Partitioning priority levels: 174c3233c11SManish Pandey 17540d553cfSPaul BeesleyPartitioning priority levels 17640d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 17740d553cfSPaul Beesley 17840d553cfSPaul BeesleyInterrupts are associated to dispatchers by way of grouping and assigning 17940d553cfSPaul Beesleyinterrupts to a priority level. In other words, all interrupts that are to 18040d553cfSPaul Beesleytarget a particular dispatcher should fall in a particular priority level. For 18140d553cfSPaul Beesleypriority assignment: 18240d553cfSPaul Beesley 18340d553cfSPaul Beesley- Of the 8 bits of priority that Arm GIC architecture permits, bit 7 must be 0 18440d553cfSPaul Beesley (secure space). 18540d553cfSPaul Beesley 18640d553cfSPaul Beesley- Depending on the number of dispatchers to support, the platform must choose 18740d553cfSPaul Beesley to use the top *n* of the 7 remaining bits to identify and assign interrupts 18840d553cfSPaul Beesley to individual dispatchers. Choosing *n* bits supports up to 2\ :sup:`n` 18940d553cfSPaul Beesley distinct dispatchers. For example, by choosing 2 additional bits (i.e., bits 19040d553cfSPaul Beesley 6 and 5), the platform can partition into 4 secure priority ranges: ``0x0``, 19140d553cfSPaul Beesley ``0x20``, ``0x40``, and ``0x60``. See `Interrupt handling example`_. 19240d553cfSPaul Beesley 193e1c5026aSPaul Beesley.. note:: 19440d553cfSPaul Beesley 19540d553cfSPaul Beesley The Arm GIC architecture requires that a GIC implementation that supports two 19640d553cfSPaul Beesley security states must implement at least 32 priority levels; i.e., at least 5 19740d553cfSPaul Beesley upper bits of the 8 bits are writeable. In the scheme described above, when 19840d553cfSPaul Beesley choosing *n* bits for priority range assignment, the platform must ensure 19940d553cfSPaul Beesley that at least ``n+1`` top bits of GIC priority are writeable. 20040d553cfSPaul Beesley 20140d553cfSPaul BeesleyThe priority thus assigned to an interrupt is also used to determine the 20240d553cfSPaul Beesleypriority of delegated execution in lower ELs. Delegated execution in lower EL is 20340d553cfSPaul Beesleyassociated with a priority level chosen with ``ehf_activate_priority()`` API 20440d553cfSPaul Beesley(described `later`__). The chosen priority level also determines the interrupts 20540d553cfSPaul Beesleymasked while executing in a lower EL, therefore controls preemption of delegated 20640d553cfSPaul Beesleyexecution. 20740d553cfSPaul Beesley 20840d553cfSPaul Beesley.. __: `ehf-apis`_ 20940d553cfSPaul Beesley 21040d553cfSPaul BeesleyThe platform expresses the chosen priority levels by declaring an array of 21140d553cfSPaul Beesleypriority level descriptors. Each entry in the array is of type 21240d553cfSPaul Beesley``ehf_pri_desc_t``, and declares a priority level, and shall be populated by the 21340d553cfSPaul Beesley``EHF_PRI_DESC()`` macro. 21440d553cfSPaul Beesley 215e1c5026aSPaul Beesley.. warning:: 21640d553cfSPaul Beesley 21740d553cfSPaul Beesley The macro ``EHF_PRI_DESC()`` installs the descriptors in the array at a 21840d553cfSPaul Beesley computed index, and not necessarily where the macro is placed in the array. 21940d553cfSPaul Beesley The size of the array might therefore be larger than what it appears to be. 22040d553cfSPaul Beesley The ``ARRAY_SIZE()`` macro therefore should be used to determine the size of 22140d553cfSPaul Beesley array. 22240d553cfSPaul Beesley 22340d553cfSPaul BeesleyFinally, this array of descriptors is exposed to |EHF| via the 22440d553cfSPaul Beesley``EHF_REGISTER_PRIORITIES()`` macro. 22540d553cfSPaul Beesley 22640d553cfSPaul BeesleyRefer to the `Interrupt handling example`_ for usage. See also: `Interrupt 22740d553cfSPaul BeesleyPrioritisation Considerations`_. 22840d553cfSPaul Beesley 22940d553cfSPaul BeesleyProgramming priority 23040d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~ 23140d553cfSPaul Beesley 23240d553cfSPaul BeesleyThe text in `Partitioning priority levels`_ only describes how the platform 23340d553cfSPaul Beesleyexpresses the required levels of priority. It however doesn't choose interrupts 23440d553cfSPaul Beesleynor program the required priority in GIC. 23540d553cfSPaul Beesley 236a4075bb5SMadhukar PappireddyThe :ref:`Firmware Design guide<configuring-secure-interrupts>` explains methods 237a4075bb5SMadhukar Pappireddyfor configuring secure interrupts. |EHF| requires the platform to enumerate 238a4075bb5SMadhukar Pappireddyinterrupt properties (as opposed to just numbers) of Secure interrupts. The 239a4075bb5SMadhukar Pappireddypriority of secure interrupts must match that as determined in the 240a4075bb5SMadhukar Pappireddy`Partitioning priority levels`_ section above. 24140d553cfSPaul Beesley 24240d553cfSPaul BeesleySee `Limitations`_, and also refer to `Interrupt handling example`_ for 24340d553cfSPaul Beesleyillustration. 24440d553cfSPaul Beesley 24540d553cfSPaul BeesleyRegistering handler 24640d553cfSPaul Beesley------------------- 24740d553cfSPaul Beesley 24840d553cfSPaul BeesleyDispatchers register handlers for their priority levels through the following 24940d553cfSPaul BeesleyAPI: 25040d553cfSPaul Beesley 25140d553cfSPaul Beesley.. code:: c 25240d553cfSPaul Beesley 25340d553cfSPaul Beesley int ehf_register_priority_handler(int pri, ehf_handler_t handler) 25440d553cfSPaul Beesley 25540d553cfSPaul BeesleyThe API takes two arguments: 25640d553cfSPaul Beesley 25740d553cfSPaul Beesley- The priority level for which the handler is being registered; 25840d553cfSPaul Beesley 25940d553cfSPaul Beesley- The handler to be registered. The handler must be aligned to 4 bytes. 26040d553cfSPaul Beesley 26140d553cfSPaul BeesleyIf a dispatcher owns more than one priority levels, it has to call the API for 26240d553cfSPaul Beesleyeach of them. 26340d553cfSPaul Beesley 26440d553cfSPaul BeesleyThe API will succeed, and return ``0``, only if: 26540d553cfSPaul Beesley 26640d553cfSPaul Beesley- There exists a descriptor with the priority level requested. 26740d553cfSPaul Beesley 26840d553cfSPaul Beesley- There are no handlers already registered by a previous call to the API. 26940d553cfSPaul Beesley 27040d553cfSPaul BeesleyOtherwise, the API returns ``-1``. 27140d553cfSPaul Beesley 27240d553cfSPaul BeesleyThe interrupt handler should have the following signature: 27340d553cfSPaul Beesley 27440d553cfSPaul Beesley.. code:: c 27540d553cfSPaul Beesley 27640d553cfSPaul Beesley typedef int (*ehf_handler_t)(uint32_t intr_raw, uint32_t flags, void *handle, 27740d553cfSPaul Beesley void *cookie); 27840d553cfSPaul Beesley 2796844c347SMadhukar PappireddyThe parameters are as obtained from the top-level :ref:`EL3 interrupt handler 2806844c347SMadhukar Pappireddy<el3-runtime-firmware>`. 28140d553cfSPaul Beesley 2826844c347SMadhukar PappireddyThe :ref:`SDEI dispatcher<SDEI: Software Delegated Exception Interface>`, for 2836844c347SMadhukar Pappireddyexample, expects the platform to allocate two different priority levels— 2846844c347SMadhukar Pappireddy``PLAT_SDEI_CRITICAL_PRI``, and ``PLAT_SDEI_NORMAL_PRI`` —and registers the 2856844c347SMadhukar Pappireddysame handler to handle both levels. 28640d553cfSPaul Beesley 28740d553cfSPaul BeesleyInterrupt handling example 28840d553cfSPaul Beesley-------------------------- 28940d553cfSPaul Beesley 29040d553cfSPaul BeesleyThe following annotated snippet demonstrates how a platform might choose to 29140d553cfSPaul Beesleyassign interrupts to fictitious dispatchers: 29240d553cfSPaul Beesley 29340d553cfSPaul Beesley.. code:: c 29440d553cfSPaul Beesley 29540d553cfSPaul Beesley #include <common/interrupt_props.h> 29640d553cfSPaul Beesley #include <drivers/arm/gic_common.h> 29740d553cfSPaul Beesley #include <exception_mgmt.h> 29840d553cfSPaul Beesley 29940d553cfSPaul Beesley ... 30040d553cfSPaul Beesley 30140d553cfSPaul Beesley /* 30240d553cfSPaul Beesley * This platform uses 2 bits for interrupt association. In total, 3 upper 30340d553cfSPaul Beesley * bits are in use. 30440d553cfSPaul Beesley * 30540d553cfSPaul Beesley * 7 6 5 3 0 30640d553cfSPaul Beesley * .-.-.-.----------. 30740d553cfSPaul Beesley * |0|b|b| ..0.. | 30840d553cfSPaul Beesley * '-'-'-'----------' 30940d553cfSPaul Beesley */ 31040d553cfSPaul Beesley #define PLAT_PRI_BITS 2 31140d553cfSPaul Beesley 31240d553cfSPaul Beesley /* Priorities for individual dispatchers */ 31340d553cfSPaul Beesley #define DISP0_PRIO 0x00 /* Not used */ 31440d553cfSPaul Beesley #define DISP1_PRIO 0x20 31540d553cfSPaul Beesley #define DISP2_PRIO 0x40 31640d553cfSPaul Beesley #define DISP3_PRIO 0x60 31740d553cfSPaul Beesley 31840d553cfSPaul Beesley /* Install priority level descriptors for each dispatcher */ 31940d553cfSPaul Beesley ehf_pri_desc_t plat_exceptions[] = { 32040d553cfSPaul Beesley EHF_PRI_DESC(PLAT_PRI_BITS, DISP1_PRIO), 32140d553cfSPaul Beesley EHF_PRI_DESC(PLAT_PRI_BITS, DISP2_PRIO), 32240d553cfSPaul Beesley EHF_PRI_DESC(PLAT_PRI_BITS, DISP3_PRIO), 32340d553cfSPaul Beesley }; 32440d553cfSPaul Beesley 32540d553cfSPaul Beesley /* Expose priority descriptors to Exception Handling Framework */ 32640d553cfSPaul Beesley EHF_REGISTER_PRIORITIES(plat_exceptions, ARRAY_SIZE(plat_exceptions), 32740d553cfSPaul Beesley PLAT_PRI_BITS); 32840d553cfSPaul Beesley 32940d553cfSPaul Beesley ... 33040d553cfSPaul Beesley 33140d553cfSPaul Beesley /* List interrupt properties for GIC driver. All interrupts target EL3 */ 33240d553cfSPaul Beesley const interrupt_prop_t plat_interrupts[] = { 33340d553cfSPaul Beesley /* Dispatcher 1 owns interrupts d1_0 and d1_1, so assigns priority DISP1_PRIO */ 33440d553cfSPaul Beesley INTR_PROP_DESC(d1_0, DISP1_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 33540d553cfSPaul Beesley INTR_PROP_DESC(d1_1, DISP1_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 33640d553cfSPaul Beesley 33740d553cfSPaul Beesley /* Dispatcher 2 owns interrupts d2_0 and d2_1, so assigns priority DISP2_PRIO */ 33840d553cfSPaul Beesley INTR_PROP_DESC(d2_0, DISP2_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 33940d553cfSPaul Beesley INTR_PROP_DESC(d2_1, DISP2_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 34040d553cfSPaul Beesley 34140d553cfSPaul Beesley /* Dispatcher 3 owns interrupts d3_0 and d3_1, so assigns priority DISP3_PRIO */ 34240d553cfSPaul Beesley INTR_PROP_DESC(d3_0, DISP3_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 34340d553cfSPaul Beesley INTR_PROP_DESC(d3_1, DISP3_PRIO, INTR_TYPE_EL3, GIC_INTR_CFG_LEVEL), 34440d553cfSPaul Beesley }; 34540d553cfSPaul Beesley 34640d553cfSPaul Beesley ... 34740d553cfSPaul Beesley 34840d553cfSPaul Beesley /* Dispatcher 1 registers its handler */ 34940d553cfSPaul Beesley ehf_register_priority_handler(DISP1_PRIO, disp1_handler); 35040d553cfSPaul Beesley 35140d553cfSPaul Beesley /* Dispatcher 2 registers its handler */ 35240d553cfSPaul Beesley ehf_register_priority_handler(DISP2_PRIO, disp2_handler); 35340d553cfSPaul Beesley 35440d553cfSPaul Beesley /* Dispatcher 3 registers its handler */ 35540d553cfSPaul Beesley ehf_register_priority_handler(DISP3_PRIO, disp3_handler); 35640d553cfSPaul Beesley 35740d553cfSPaul Beesley ... 35840d553cfSPaul Beesley 35940d553cfSPaul BeesleySee also the `Build-time flow`_ and the `Run-time flow`_. 36040d553cfSPaul Beesley 361c3233c11SManish Pandey.. _Activating and Deactivating priorities: 362c3233c11SManish Pandey 36340d553cfSPaul BeesleyActivating and Deactivating priorities 36440d553cfSPaul Beesley-------------------------------------- 36540d553cfSPaul Beesley 36640d553cfSPaul BeesleyA priority level is said to be *active* when an exception of that priority is 36740d553cfSPaul Beesleybeing handled: for interrupts, this is implied when the interrupt is 3686844c347SMadhukar Pappireddyacknowledged; for non-interrupt exceptions, such as SErrors or :ref:`SDEI 3696844c347SMadhukar Pappireddyexplicit dispatches <explicit-dispatch-of-events>`, this has to be done via 3706844c347SMadhukar Pappireddycalling ``ehf_activate_priority()``. See `Run-time flow`_. 37140d553cfSPaul Beesley 37240d553cfSPaul BeesleyConversely, when the dispatcher has reached a logical resolution for the cause 37340d553cfSPaul Beesleyof the exception, the corresponding priority level ought to be deactivated. As 37440d553cfSPaul Beesleyabove, for interrupts, this is implied when the interrupt is EOId in the GIC; 37540d553cfSPaul Beesleyfor other exceptions, this has to be done via calling 37640d553cfSPaul Beesley``ehf_deactivate_priority()``. 37740d553cfSPaul Beesley 37840d553cfSPaul BeesleyThanks to `different provisions`__ for exception delegation, there are 37940d553cfSPaul Beesleypotentially more than one work flow for deactivation: 38040d553cfSPaul Beesley 38140d553cfSPaul Beesley.. __: `delegation-use-cases`_ 38240d553cfSPaul Beesley 38340d553cfSPaul Beesley.. _deactivation workflows: 38440d553cfSPaul Beesley 38540d553cfSPaul Beesley- The dispatcher has addressed the cause of the exception, and decided to take 38640d553cfSPaul Beesley no further action. In this case, the dispatcher's handler deactivates the 38740d553cfSPaul Beesley priority level before returning to the |EHF|. Runtime firmware, upon exit 38840d553cfSPaul Beesley through an ``ERET``, resumes execution before the interrupt occurred. 38940d553cfSPaul Beesley 39040d553cfSPaul Beesley- The dispatcher has to delegate the execution to lower ELs, and the cause of 39140d553cfSPaul Beesley the exception can be considered resolved only when the lower EL returns 39240d553cfSPaul Beesley signals complete (via an ``SMC``) at a future point in time. The following 39340d553cfSPaul Beesley sequence ensues: 39440d553cfSPaul Beesley 39540d553cfSPaul Beesley #. The dispatcher calls ``setjmp()`` to setup a jump point, and arranges to 39640d553cfSPaul Beesley enter a lower EL upon the next ``ERET``. 39740d553cfSPaul Beesley 39840d553cfSPaul Beesley #. Through the ensuing ``ERET`` from runtime firmware, execution is delegated 39940d553cfSPaul Beesley to a lower EL. 40040d553cfSPaul Beesley 40140d553cfSPaul Beesley #. The lower EL completes its execution, and signals completion via an 40240d553cfSPaul Beesley ``SMC``. 40340d553cfSPaul Beesley 40440d553cfSPaul Beesley #. The ``SMC`` is handled by the same dispatcher that handled the exception 40540d553cfSPaul Beesley previously. Noticing the conclusion of exception handling, the dispatcher 40640d553cfSPaul Beesley does ``longjmp()`` to resume beyond the previous jump point. 40740d553cfSPaul Beesley 40840d553cfSPaul BeesleyAs mentioned above, the |EHF| provides the following APIs for activating and 40940d553cfSPaul Beesleydeactivating interrupt: 41040d553cfSPaul Beesley 41140d553cfSPaul Beesley.. _ehf-apis: 41240d553cfSPaul Beesley 41340d553cfSPaul Beesley- ``ehf_activate_priority()`` activates the supplied priority level, but only 41440d553cfSPaul Beesley if the current active priority is higher than the given one; otherwise 41540d553cfSPaul Beesley panics. Also, to prevent interruption by physical interrupts of lower 41640d553cfSPaul Beesley priority, the |EHF| programs the *Priority Mask Register* corresponding to 41740d553cfSPaul Beesley the PE to the priority being activated. Dispatchers typically only need to 41840d553cfSPaul Beesley call this when handling exceptions other than interrupts, and it needs to 41940d553cfSPaul Beesley delegate execution to a lower EL at a desired priority level. 42040d553cfSPaul Beesley 42140d553cfSPaul Beesley- ``ehf_deactivate_priority()`` deactivates a given priority, but only if the 42240d553cfSPaul Beesley current active priority is equal to the given one; otherwise panics. |EHF| 42340d553cfSPaul Beesley also restores the *Priority Mask Register* corresponding to the PE to the 42440d553cfSPaul Beesley priority before the call to ``ehf_activate_priority()``. Dispatchers 42540d553cfSPaul Beesley typically only need to call this after handling exceptions other than 42640d553cfSPaul Beesley interrupts. 42740d553cfSPaul Beesley 42840d553cfSPaul BeesleyThe calling of APIs are subject to allowed `transitions`__. See also the 42940d553cfSPaul Beesley`Run-time flow`_. 43040d553cfSPaul Beesley 43140d553cfSPaul Beesley.. __: `Transition of priority levels`_ 43240d553cfSPaul Beesley 43340d553cfSPaul BeesleyTransition of priority levels 43440d553cfSPaul Beesley----------------------------- 43540d553cfSPaul Beesley 43640d553cfSPaul BeesleyThe |EHF| APIs ``ehf_activate_priority()`` and ``ehf_deactivate_priority()`` can 43740d553cfSPaul Beesleybe called to transition the current priority level on a PE. A given sequence of 43840d553cfSPaul Beesleycalls to these APIs are subject to the following conditions: 43940d553cfSPaul Beesley 44040d553cfSPaul Beesley- For activation, the |EHF| only allows for the priority to increase (i.e. 44140d553cfSPaul Beesley numeric value decreases); 44240d553cfSPaul Beesley 44340d553cfSPaul Beesley- For deactivation, the |EHF| only allows for the priority to decrease (i.e. 44440d553cfSPaul Beesley numeric value increases). Additionally, the priority being deactivated is 44540d553cfSPaul Beesley required to be the current priority. 44640d553cfSPaul Beesley 44740d553cfSPaul BeesleyIf these are violated, a panic will result. 44840d553cfSPaul Beesley 4496844c347SMadhukar Pappireddy.. _Effect on SMC calls: 4506844c347SMadhukar Pappireddy 45140d553cfSPaul BeesleyEffect on SMC calls 45240d553cfSPaul Beesley------------------- 45340d553cfSPaul Beesley 45440d553cfSPaul BeesleyIn general, Secure execution is regarded as more important than Non-secure 45540d553cfSPaul Beesleyexecution. As discussed elsewhere in this document, EL3 execution, and any 45640d553cfSPaul Beesleydelegated execution thereafter, has the effect of raising GIC's priority 45740d553cfSPaul Beesleymask—either implicitly by acknowledging Secure interrupts, or when dispatchers 45840d553cfSPaul Beesleycall ``ehf_activate_priority()``. As a result, Non-secure interrupts cannot 45940d553cfSPaul Beesleypreempt any Secure execution. 46040d553cfSPaul Beesley 46140d553cfSPaul BeesleySMCs from Non-secure world are synchronous exceptions, and are mechanisms for 46240d553cfSPaul BeesleyNon-secure world to request Secure services. They're broadly classified as 46340d553cfSPaul Beesley*Fast* or *Yielding* (see `SMCCC`__). 46440d553cfSPaul Beesley 4653ba55a3cSlaurenw-arm.. __: https://developer.arm.com/docs/den0028/latest 46640d553cfSPaul Beesley 46740d553cfSPaul Beesley- *Fast* SMCs are atomic from the caller's point of view. I.e., they return 46840d553cfSPaul Beesley to the caller only when the Secure world has finished serving the request. 46940d553cfSPaul Beesley Any Non-secure interrupts that become pending meanwhile cannot preempt Secure 47040d553cfSPaul Beesley execution. 47140d553cfSPaul Beesley 47240d553cfSPaul Beesley- *Yielding* SMCs carry the semantics of a preemptible, lower-priority request. 47340d553cfSPaul Beesley A pending Non-secure interrupt can preempt Secure execution handling a 47440d553cfSPaul Beesley Yielding SMC. I.e., the caller might observe a Yielding SMC returning when 47540d553cfSPaul Beesley either: 47640d553cfSPaul Beesley 47740d553cfSPaul Beesley #. Secure world completes the request, and the caller would find ``SMC_OK`` 47840d553cfSPaul Beesley as the return code. 47940d553cfSPaul Beesley 48040d553cfSPaul Beesley #. A Non-secure interrupt preempts Secure execution. Non-secure interrupt is 48140d553cfSPaul Beesley handled, and Non-secure execution resumes after ``SMC`` instruction. 48240d553cfSPaul Beesley 48340d553cfSPaul Beesley The dispatcher handling a Yielding SMC must provide a different return code 48440d553cfSPaul Beesley to the Non-secure caller to distinguish the latter case. This return code, 48540d553cfSPaul Beesley however, is not standardised (unlike ``SMC_UNKNOWN`` or ``SMC_OK``, for 48640d553cfSPaul Beesley example), so will vary across dispatchers that handle the request. 48740d553cfSPaul Beesley 48840d553cfSPaul BeesleyFor the latter case above, dispatchers before |EHF| expect Non-secure interrupts 48940d553cfSPaul Beesleyto be taken to S-EL1 [#irq]_, so would get a chance to populate the designated 49040d553cfSPaul Beesleypreempted error code before yielding to Non-secure world. 49140d553cfSPaul Beesley 49240d553cfSPaul BeesleyThe introduction of |EHF| changes the behaviour as described in `Interrupt 49340d553cfSPaul Beesleyhandling`_. 49440d553cfSPaul Beesley 49540d553cfSPaul BeesleyWhen |EHF| is enabled, in order to allow Non-secure interrupts to preempt 49640d553cfSPaul BeesleyYielding SMC handling, the dispatcher must call ``ehf_allow_ns_preemption()`` 49740d553cfSPaul BeesleyAPI. The API takes one argument, the error code to be returned to the Non-secure 49840d553cfSPaul Beesleyworld upon getting preempted. 49940d553cfSPaul Beesley 50040d553cfSPaul Beesley.. [#irq] In case of GICv2, Non-secure interrupts while in S-EL1 were signalled 50140d553cfSPaul Beesley as IRQs, and in case of GICv3, FIQs. 50240d553cfSPaul Beesley 50340d553cfSPaul BeesleyBuild-time flow 50440d553cfSPaul Beesley--------------- 50540d553cfSPaul Beesley 50640d553cfSPaul BeesleyPlease refer to the `figure`__ above. 50740d553cfSPaul Beesley 50840d553cfSPaul Beesley.. __: `ehf-figure`_ 50940d553cfSPaul Beesley 51040d553cfSPaul BeesleyThe build-time flow involves the following steps: 51140d553cfSPaul Beesley 51240d553cfSPaul Beesley#. Platform assigns priorities by installing priority level descriptors for 51340d553cfSPaul Beesley individual dispatchers, as described in `Partitioning priority levels`_. 51440d553cfSPaul Beesley 51540d553cfSPaul Beesley#. Platform provides interrupt properties to GIC driver, as described in 51640d553cfSPaul Beesley `Programming priority`_. 51740d553cfSPaul Beesley 51840d553cfSPaul Beesley#. Dispatcher calling ``ehf_register_priority_handler()`` to register an 51940d553cfSPaul Beesley interrupt handler. 52040d553cfSPaul Beesley 52140d553cfSPaul BeesleyAlso refer to the `Interrupt handling example`_. 52240d553cfSPaul Beesley 52340d553cfSPaul BeesleyRun-time flow 52440d553cfSPaul Beesley------------- 52540d553cfSPaul Beesley 52640d553cfSPaul Beesley.. _interrupt-flow: 52740d553cfSPaul Beesley 52840d553cfSPaul BeesleyThe following is an example flow for interrupts: 52940d553cfSPaul Beesley 53040d553cfSPaul Beesley#. The GIC driver, during initialization, iterates through the platform-supplied 53140d553cfSPaul Beesley interrupt properties (see `Programming priority`_), and configures the 53240d553cfSPaul Beesley interrupts. This programs the appropriate priority and group (Group 0) on 53340d553cfSPaul Beesley interrupts belonging to different dispatchers. 53440d553cfSPaul Beesley 53540d553cfSPaul Beesley#. The |EHF|, during its initialisation, registers a top-level interrupt handler 5366844c347SMadhukar Pappireddy with the :ref:`Interrupt Management Framework<el3-runtime-firmware>` for EL3 5376844c347SMadhukar Pappireddy interrupts. This also results in setting the routing bits in ``SCR_EL3``. 53840d553cfSPaul Beesley 53940d553cfSPaul Beesley#. When an interrupt belonging to a dispatcher fires, GIC raises an EL3/Group 0 54040d553cfSPaul Beesley interrupt, and is taken to EL3. 54140d553cfSPaul Beesley 54240d553cfSPaul Beesley#. The top-level EL3 interrupt handler executes. The handler acknowledges the 54340d553cfSPaul Beesley interrupt, reads its *Running Priority*, and from that, determines the 54440d553cfSPaul Beesley dispatcher handler. 54540d553cfSPaul Beesley 54640d553cfSPaul Beesley#. The |EHF| programs the *Priority Mask Register* of the PE to the priority of 54740d553cfSPaul Beesley the interrupt received. 54840d553cfSPaul Beesley 54940d553cfSPaul Beesley#. The |EHF| marks that priority level *active*, and jumps to the dispatcher 55040d553cfSPaul Beesley handler. 55140d553cfSPaul Beesley 55240d553cfSPaul Beesley#. Once the dispatcher handler finishes its job, it has to immediately 55340d553cfSPaul Beesley *deactivate* the priority level before returning to the |EHF|. See 55440d553cfSPaul Beesley `deactivation workflows`_. 55540d553cfSPaul Beesley 55640d553cfSPaul Beesley.. _non-interrupt-flow: 55740d553cfSPaul Beesley 55840d553cfSPaul BeesleyThe following is an example flow for exceptions that targets EL3 other than 55940d553cfSPaul Beesleyinterrupt: 56040d553cfSPaul Beesley 56140d553cfSPaul Beesley#. The platform provides handlers for the specific kind of exception. 56240d553cfSPaul Beesley 56340d553cfSPaul Beesley#. The exception arrives, and the corresponding handler is executed. 56440d553cfSPaul Beesley 56540d553cfSPaul Beesley#. The handler calls ``ehf_activate_priority()`` to activate the required 56640d553cfSPaul Beesley priority level. This also has the effect of raising GIC priority mask, thus 56740d553cfSPaul Beesley preventing interrupts of lower priority from preempting the handling. The 56840d553cfSPaul Beesley handler may choose to do the handling entirely in EL3 or delegate to a lower 56940d553cfSPaul Beesley EL. 57040d553cfSPaul Beesley 57140d553cfSPaul Beesley#. Once exception handling concludes, the handler calls 57240d553cfSPaul Beesley ``ehf_deactivate_priority()`` to deactivate the priority level activated 57340d553cfSPaul Beesley earlier. This also has the effect of lowering GIC priority mask to what it 57440d553cfSPaul Beesley was before. 57540d553cfSPaul Beesley 57640d553cfSPaul BeesleyInterrupt Prioritisation Considerations 57740d553cfSPaul Beesley--------------------------------------- 57840d553cfSPaul Beesley 57940d553cfSPaul BeesleyThe GIC priority scheme, by design, prioritises Secure interrupts over Normal 58040d553cfSPaul Beesleyworld ones. The platform further assigns relative priorities amongst Secure 58140d553cfSPaul Beesleydispatchers through |EHF|. 58240d553cfSPaul Beesley 58340d553cfSPaul BeesleyAs mentioned in `Partitioning priority levels`_, interrupts targeting distinct 58440d553cfSPaul Beesleydispatchers fall in distinct priority levels. Because they're routed via the 58540d553cfSPaul BeesleyGIC, interrupt delivery to the PE is subject to GIC prioritisation rules. In 58640d553cfSPaul Beesleyparticular, when an interrupt is being handled by the PE (i.e., the interrupt is 58740d553cfSPaul Beesleyin *Active* state), only interrupts of higher priority are signalled to the PE, 58840d553cfSPaul Beesleyeven if interrupts of same or lower priority are pending. This has the side 58940d553cfSPaul Beesleyeffect of one dispatcher being starved of interrupts by virtue of another 59040d553cfSPaul Beesleydispatcher handling its (higher priority) interrupts. 59140d553cfSPaul Beesley 59240d553cfSPaul BeesleyThe |EHF| doesn't enforce a particular prioritisation policy, but the platform 59340d553cfSPaul Beesleyshould carefully consider the assignment of priorities to dispatchers integrated 59440d553cfSPaul Beesleyinto runtime firmware. The platform should sensibly delineate priority to 59540d553cfSPaul Beesleyvarious dispatchers according to their nature. In particular, dispatchers of 59640d553cfSPaul Beesleycritical nature (RAS, for example) should be assigned higher priority than 5978f62ca7bSPaul Beesleyothers (|SDEI|, for example); and within |SDEI|, Critical priority 5988f62ca7bSPaul Beesley|SDEI| should be assigned higher priority than Normal ones. 59940d553cfSPaul Beesley 60040d553cfSPaul BeesleyLimitations 60140d553cfSPaul Beesley----------- 60240d553cfSPaul Beesley 60340d553cfSPaul BeesleyThe |EHF| has the following limitations: 60440d553cfSPaul Beesley 60540d553cfSPaul Beesley- Although there could be up to 128 Secure dispatchers supported by the GIC 60640d553cfSPaul Beesley priority scheme, the size of descriptor array exposed with 60740d553cfSPaul Beesley ``EHF_REGISTER_PRIORITIES()`` macro is currently limited to 32. This serves most 60840d553cfSPaul Beesley expected use cases. This may be expanded in the future, should use cases 60940d553cfSPaul Beesley demand so. 61040d553cfSPaul Beesley 61140d553cfSPaul Beesley- The platform must ensure that the priority assigned to the dispatcher in the 61240d553cfSPaul Beesley exception descriptor and the programmed priority of interrupts handled by the 61340d553cfSPaul Beesley dispatcher match. The |EHF| cannot verify that this has been followed. 61440d553cfSPaul Beesley 61534760951SPaul Beesley-------------- 61640d553cfSPaul Beesley 617*854d199bSGovindraj Raja*Copyright (c) 2018-2025, Arm Limited and Contributors. All rights reserved.* 61840d553cfSPaul Beesley 619*854d199bSGovindraj Raja.. _SDEI specification: https://developer.arm.com/documentation/den0054