18aa05055SPaul BeesleyInterrupt Management Framework 28aa05055SPaul Beesley============================== 340d553cfSPaul Beesley 440d553cfSPaul BeesleyThis framework is responsible for managing interrupts routed to EL3. It also 540d553cfSPaul Beesleyallows EL3 software to configure the interrupt routing behavior. Its main 640d553cfSPaul Beesleyobjective is to implement the following two requirements. 740d553cfSPaul Beesley 840d553cfSPaul Beesley#. It should be possible to route interrupts meant to be handled by secure 940d553cfSPaul Beesley software (Secure interrupts) to EL3, when execution is in non-secure state 1040d553cfSPaul Beesley (normal world). The framework should then take care of handing control of 1140d553cfSPaul Beesley the interrupt to either software in EL3 or Secure-EL1 depending upon the 1240d553cfSPaul Beesley software configuration and the GIC implementation. This requirement ensures 1340d553cfSPaul Beesley that secure interrupts are under the control of the secure software with 1440d553cfSPaul Beesley respect to their delivery and handling without the possibility of 1540d553cfSPaul Beesley intervention from non-secure software. 1640d553cfSPaul Beesley 1740d553cfSPaul Beesley#. It should be possible to route interrupts meant to be handled by 1840d553cfSPaul Beesley non-secure software (Non-secure interrupts) to the last executed exception 1940d553cfSPaul Beesley level in the normal world when the execution is in secure world at 2040d553cfSPaul Beesley exception levels lower than EL3. This could be done with or without the 2140d553cfSPaul Beesley knowledge of software executing in Secure-EL1/Secure-EL0. The choice of 2240d553cfSPaul Beesley approach should be governed by the secure software. This requirement 2340d553cfSPaul Beesley ensures that non-secure software is able to execute in tandem with the 2440d553cfSPaul Beesley secure software without overriding it. 2540d553cfSPaul Beesley 2640d553cfSPaul BeesleyConcepts 2740d553cfSPaul Beesley-------- 2840d553cfSPaul Beesley 2940d553cfSPaul BeesleyInterrupt types 3040d553cfSPaul Beesley~~~~~~~~~~~~~~~ 3140d553cfSPaul Beesley 3240d553cfSPaul BeesleyThe framework categorises an interrupt to be one of the following depending upon 3340d553cfSPaul Beesleythe exception level(s) it is handled in. 3440d553cfSPaul Beesley 3540d553cfSPaul Beesley#. Secure EL1 interrupt. This type of interrupt can be routed to EL3 or 3640d553cfSPaul Beesley Secure-EL1 depending upon the security state of the current execution 3740d553cfSPaul Beesley context. It is always handled in Secure-EL1. 3840d553cfSPaul Beesley 3940d553cfSPaul Beesley#. Non-secure interrupt. This type of interrupt can be routed to EL3, 4040d553cfSPaul Beesley Secure-EL1, Non-secure EL1 or EL2 depending upon the security state of the 4140d553cfSPaul Beesley current execution context. It is always handled in either Non-secure EL1 4240d553cfSPaul Beesley or EL2. 4340d553cfSPaul Beesley 4440d553cfSPaul Beesley#. EL3 interrupt. This type of interrupt can be routed to EL3 or Secure-EL1 4540d553cfSPaul Beesley depending upon the security state of the current execution context. It is 4640d553cfSPaul Beesley always handled in EL3. 4740d553cfSPaul Beesley 4840d553cfSPaul BeesleyThe following constants define the various interrupt types in the framework 4940d553cfSPaul Beesleyimplementation. 5040d553cfSPaul Beesley 5129c02529SPaul Beesley.. code:: c 5240d553cfSPaul Beesley 5340d553cfSPaul Beesley #define INTR_TYPE_S_EL1 0 5440d553cfSPaul Beesley #define INTR_TYPE_EL3 1 5540d553cfSPaul Beesley #define INTR_TYPE_NS 2 5640d553cfSPaul Beesley 5740d553cfSPaul BeesleyRouting model 5840d553cfSPaul Beesley~~~~~~~~~~~~~ 5940d553cfSPaul Beesley 6040d553cfSPaul BeesleyA type of interrupt can be either generated as an FIQ or an IRQ. The target 6140d553cfSPaul Beesleyexception level of an interrupt type is configured through the FIQ and IRQ bits 6240d553cfSPaul Beesleyin the Secure Configuration Register at EL3 (``SCR_EL3.FIQ`` and ``SCR_EL3.IRQ`` 6340d553cfSPaul Beesleybits). When ``SCR_EL3.FIQ``\ =1, FIQs are routed to EL3. Otherwise they are routed 6440d553cfSPaul Beesleyto the First Exception Level (FEL) capable of handling interrupts. When 6540d553cfSPaul Beesley``SCR_EL3.IRQ``\ =1, IRQs are routed to EL3. Otherwise they are routed to the 6640d553cfSPaul BeesleyFEL. This register is configured independently by EL3 software for each security 6740d553cfSPaul Beesleystate prior to entry into a lower exception level in that security state. 6840d553cfSPaul Beesley 6940d553cfSPaul BeesleyA routing model for a type of interrupt (generated as FIQ or IRQ) is defined as 7040d553cfSPaul Beesleyits target exception level for each security state. It is represented by a 7140d553cfSPaul Beesleysingle bit for each security state. A value of ``0`` means that the interrupt 7240d553cfSPaul Beesleyshould be routed to the FEL. A value of ``1`` means that the interrupt should be 7340d553cfSPaul Beesleyrouted to EL3. A routing model is applicable only when execution is not in EL3. 7440d553cfSPaul Beesley 7540d553cfSPaul BeesleyThe default routing model for an interrupt type is to route it to the FEL in 7640d553cfSPaul Beesleyeither security state. 7740d553cfSPaul Beesley 7840d553cfSPaul BeesleyValid routing models 7940d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~ 8040d553cfSPaul Beesley 8140d553cfSPaul BeesleyThe framework considers certain routing models for each type of interrupt to be 8240d553cfSPaul Beesleyincorrect as they conflict with the requirements mentioned in Section 1. The 8340d553cfSPaul Beesleyfollowing sub-sections describe all the possible routing models and specify 8440d553cfSPaul Beesleywhich ones are valid or invalid. EL3 interrupts are currently supported only 8540d553cfSPaul Beesleyfor GIC version 3.0 (Arm GICv3) and only the Secure-EL1 and Non-secure interrupt 8640d553cfSPaul Beesleytypes are supported for GIC version 2.0 (Arm GICv2) (see `Assumptions in 8740d553cfSPaul BeesleyInterrupt Management Framework`_). The terminology used in the following 8840d553cfSPaul Beesleysub-sections is explained below. 8940d553cfSPaul Beesley 9040d553cfSPaul Beesley#. **CSS**. Current Security State. ``0`` when secure and ``1`` when non-secure 9140d553cfSPaul Beesley 9240d553cfSPaul Beesley#. **TEL3**. Target Exception Level 3. ``0`` when targeted to the FEL. ``1`` when 9340d553cfSPaul Beesley targeted to EL3. 9440d553cfSPaul Beesley 9540d553cfSPaul BeesleySecure-EL1 interrupts 9640d553cfSPaul Beesley^^^^^^^^^^^^^^^^^^^^^ 9740d553cfSPaul Beesley 9840d553cfSPaul Beesley#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in 9940d553cfSPaul Beesley secure state. This is a valid routing model as secure software is in 10040d553cfSPaul Beesley control of handling secure interrupts. 10140d553cfSPaul Beesley 10240d553cfSPaul Beesley#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in secure 10340d553cfSPaul Beesley state. This is a valid routing model as secure software in EL3 can 10440d553cfSPaul Beesley handover the interrupt to Secure-EL1 for handling. 10540d553cfSPaul Beesley 10640d553cfSPaul Beesley#. **CSS=1, TEL3=0**. Interrupt is routed to the FEL when execution is in 10740d553cfSPaul Beesley non-secure state. This is an invalid routing model as a secure interrupt 10840d553cfSPaul Beesley is not visible to the secure software which violates the motivation behind 10940d553cfSPaul Beesley the Arm Security Extensions. 11040d553cfSPaul Beesley 11140d553cfSPaul Beesley#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in 11240d553cfSPaul Beesley non-secure state. This is a valid routing model as secure software in EL3 11340d553cfSPaul Beesley can handover the interrupt to Secure-EL1 for handling. 11440d553cfSPaul Beesley 11540d553cfSPaul BeesleyNon-secure interrupts 11640d553cfSPaul Beesley^^^^^^^^^^^^^^^^^^^^^ 11740d553cfSPaul Beesley 11840d553cfSPaul Beesley#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in 11940d553cfSPaul Beesley secure state. This allows the secure software to trap non-secure 12040d553cfSPaul Beesley interrupts, perform its book-keeping and hand the interrupt to the 12140d553cfSPaul Beesley non-secure software through EL3. This is a valid routing model as secure 12240d553cfSPaul Beesley software is in control of how its execution is preempted by non-secure 12340d553cfSPaul Beesley interrupts. 12440d553cfSPaul Beesley 12540d553cfSPaul Beesley#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in secure 12640d553cfSPaul Beesley state. This is a valid routing model as secure software in EL3 can save 12740d553cfSPaul Beesley the state of software in Secure-EL1/Secure-EL0 before handing the 12840d553cfSPaul Beesley interrupt to non-secure software. This model requires additional 12940d553cfSPaul Beesley coordination between Secure-EL1 and EL3 software to ensure that the 13040d553cfSPaul Beesley former's state is correctly saved by the latter. 13140d553cfSPaul Beesley 13240d553cfSPaul Beesley#. **CSS=1, TEL3=0**. Interrupt is routed to FEL when execution is in 13340d553cfSPaul Beesley non-secure state. This is a valid routing model as a non-secure interrupt 13440d553cfSPaul Beesley is handled by non-secure software. 13540d553cfSPaul Beesley 13640d553cfSPaul Beesley#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in 13740d553cfSPaul Beesley non-secure state. This is an invalid routing model as there is no valid 13840d553cfSPaul Beesley reason to route the interrupt to EL3 software and then hand it back to 13940d553cfSPaul Beesley non-secure software for handling. 14040d553cfSPaul Beesley 14140d553cfSPaul BeesleyEL3 interrupts 14240d553cfSPaul Beesley^^^^^^^^^^^^^^ 14340d553cfSPaul Beesley 14440d553cfSPaul Beesley#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in 14540d553cfSPaul Beesley Secure-EL1/Secure-EL0. This is a valid routing model as secure software 14640d553cfSPaul Beesley in Secure-EL1/Secure-EL0 is in control of how its execution is preempted 14740d553cfSPaul Beesley by EL3 interrupt and can handover the interrupt to EL3 for handling. 14840d553cfSPaul Beesley 14940d553cfSPaul Beesley However, when ``EL3_EXCEPTION_HANDLING`` is ``1``, this routing model is 15040d553cfSPaul Beesley invalid as EL3 interrupts are unconditionally routed to EL3, and EL3 15140d553cfSPaul Beesley interrupts will always preempt Secure EL1/EL0 execution. See `exception 15240d553cfSPaul Beesley handling`__ documentation. 15340d553cfSPaul Beesley 15440d553cfSPaul Beesley .. __: exception-handling.rst#interrupt-handling 15540d553cfSPaul Beesley 15640d553cfSPaul Beesley#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in 15740d553cfSPaul Beesley Secure-EL1/Secure-EL0. This is a valid routing model as secure software 15840d553cfSPaul Beesley in EL3 can handle the interrupt. 15940d553cfSPaul Beesley 16040d553cfSPaul Beesley#. **CSS=1, TEL3=0**. Interrupt is routed to the FEL when execution is in 16140d553cfSPaul Beesley non-secure state. This is an invalid routing model as a secure interrupt 16240d553cfSPaul Beesley is not visible to the secure software which violates the motivation behind 16340d553cfSPaul Beesley the Arm Security Extensions. 16440d553cfSPaul Beesley 16540d553cfSPaul Beesley#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in 16640d553cfSPaul Beesley non-secure state. This is a valid routing model as secure software in EL3 16740d553cfSPaul Beesley can handle the interrupt. 16840d553cfSPaul Beesley 16940d553cfSPaul BeesleyMapping of interrupt type to signal 17040d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 17140d553cfSPaul Beesley 17240d553cfSPaul BeesleyThe framework is meant to work with any interrupt controller implemented by a 17340d553cfSPaul Beesleyplatform. A interrupt controller could generate a type of interrupt as either an 17440d553cfSPaul BeesleyFIQ or IRQ signal to the CPU depending upon the current security state. The 17540d553cfSPaul Beesleymapping between the type and signal is known only to the platform. The framework 17640d553cfSPaul Beesleyuses this information to determine whether the IRQ or the FIQ bit should be 17740d553cfSPaul Beesleyprogrammed in ``SCR_EL3`` while applying the routing model for a type of 17840d553cfSPaul Beesleyinterrupt. The platform provides this information through the 17940d553cfSPaul Beesley``plat_interrupt_type_to_line()`` API (described in the 18034760951SPaul Beesley:ref:`Porting Guide`). For example, on the FVP port when the platform uses an 18134760951SPaul BeesleyArm GICv2 interrupt controller, Secure-EL1 interrupts are signaled through the 18234760951SPaul BeesleyFIQ signal while Non-secure interrupts are signaled through the IRQ signal. 18334760951SPaul BeesleyThis applies when execution is in either security state. 18440d553cfSPaul Beesley 18540d553cfSPaul BeesleyEffect of mapping of several interrupt types to one signal 18640d553cfSPaul Beesley^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 18740d553cfSPaul Beesley 18840d553cfSPaul BeesleyIt should be noted that if more than one interrupt type maps to a single 18940d553cfSPaul Beesleyinterrupt signal, and if any one of the interrupt type sets **TEL3=1** for a 19040d553cfSPaul Beesleyparticular security state, then interrupt signal will be routed to EL3 when in 19140d553cfSPaul Beesleythat security state. This means that all the other interrupt types using the 19240d553cfSPaul Beesleysame interrupt signal will be forced to the same routing model. This should be 19340d553cfSPaul Beesleyborne in mind when choosing the routing model for an interrupt type. 19440d553cfSPaul Beesley 19540d553cfSPaul BeesleyFor example, in Arm GICv3, when the execution context is Secure-EL1/ 19640d553cfSPaul BeesleySecure-EL0, both the EL3 and the non secure interrupt types map to the FIQ 19740d553cfSPaul Beesleysignal. So if either one of the interrupt type sets the routing model so 19840d553cfSPaul Beesleythat **TEL3=1** when **CSS=0**, the FIQ bit in ``SCR_EL3`` will be programmed to 19940d553cfSPaul Beesleyroute the FIQ signal to EL3 when executing in Secure-EL1/Secure-EL0, thereby 20040d553cfSPaul Beesleyeffectively routing the other interrupt type also to EL3. 20140d553cfSPaul Beesley 20240d553cfSPaul BeesleyAssumptions in Interrupt Management Framework 20340d553cfSPaul Beesley--------------------------------------------- 20440d553cfSPaul Beesley 20540d553cfSPaul BeesleyThe framework makes the following assumptions to simplify its implementation. 20640d553cfSPaul Beesley 20740d553cfSPaul Beesley#. Although the framework has support for 2 types of secure interrupts (EL3 20840d553cfSPaul Beesley and Secure-EL1 interrupt), only interrupt controller architectures 20940d553cfSPaul Beesley like Arm GICv3 has architectural support for EL3 interrupts in the form of 21040d553cfSPaul Beesley Group 0 interrupts. In Arm GICv2, all secure interrupts are assumed to be 21140d553cfSPaul Beesley handled in Secure-EL1. They can be delivered to Secure-EL1 via EL3 but they 21240d553cfSPaul Beesley cannot be handled in EL3. 21340d553cfSPaul Beesley 21440d553cfSPaul Beesley#. Interrupt exceptions (``PSTATE.I`` and ``F`` bits) are masked during execution 21540d553cfSPaul Beesley in EL3. 21640d553cfSPaul Beesley 21740d553cfSPaul Beesley#. Interrupt management: the following sections describe how interrupts are 21840d553cfSPaul Beesley managed by the interrupt handling framework. This entails: 21940d553cfSPaul Beesley 22040d553cfSPaul Beesley #. Providing an interface to allow registration of a handler and 22140d553cfSPaul Beesley specification of the routing model for a type of interrupt. 22240d553cfSPaul Beesley 22340d553cfSPaul Beesley #. Implementing support to hand control of an interrupt type to its 22440d553cfSPaul Beesley registered handler when the interrupt is generated. 22540d553cfSPaul Beesley 22640d553cfSPaul BeesleyBoth aspects of interrupt management involve various components in the secure 22740d553cfSPaul Beesleysoftware stack spanning from EL3 to Secure-EL1. These components are described 22840d553cfSPaul Beesleyin the section `Software components`_. The framework stores information 22940d553cfSPaul Beesleyassociated with each type of interrupt in the following data structure. 23040d553cfSPaul Beesley 23140d553cfSPaul Beesley.. code:: c 23240d553cfSPaul Beesley 23340d553cfSPaul Beesley typedef struct intr_type_desc { 23440d553cfSPaul Beesley interrupt_type_handler_t handler; 23540d553cfSPaul Beesley uint32_t flags; 23640d553cfSPaul Beesley uint32_t scr_el3[2]; 23740d553cfSPaul Beesley } intr_type_desc_t; 23840d553cfSPaul Beesley 23940d553cfSPaul BeesleyThe ``flags`` field stores the routing model for the interrupt type in 24040d553cfSPaul Beesleybits[1:0]. Bit[0] stores the routing model when execution is in the secure 24140d553cfSPaul Beesleystate. Bit[1] stores the routing model when execution is in the non-secure 24240d553cfSPaul Beesleystate. As mentioned in Section `Routing model`_, a value of ``0`` implies that 24340d553cfSPaul Beesleythe interrupt should be targeted to the FEL. A value of ``1`` implies that it 24440d553cfSPaul Beesleyshould be targeted to EL3. The remaining bits are reserved and SBZ. The helper 24540d553cfSPaul Beesleymacro ``set_interrupt_rm_flag()`` should be used to set the bits in the 24640d553cfSPaul Beesley``flags`` parameter. 24740d553cfSPaul Beesley 24840d553cfSPaul BeesleyThe ``scr_el3[2]`` field also stores the routing model but as a mapping of the 24940d553cfSPaul Beesleymodel in the ``flags`` field to the corresponding bit in the ``SCR_EL3`` for each 25040d553cfSPaul Beesleysecurity state. 25140d553cfSPaul Beesley 25240d553cfSPaul BeesleyThe framework also depends upon the platform port to configure the interrupt 25340d553cfSPaul Beesleycontroller to distinguish between secure and non-secure interrupts. The platform 25440d553cfSPaul Beesleyis expected to be aware of the secure devices present in the system and their 25540d553cfSPaul Beesleyassociated interrupt numbers. It should configure the interrupt controller to 25640d553cfSPaul Beesleyenable the secure interrupts, ensure that their priority is always higher than 25740d553cfSPaul Beesleythe non-secure interrupts and target them to the primary CPU. It should also 25834760951SPaul Beesleyexport the interface described in the :ref:`Porting Guide` to enable 25940d553cfSPaul Beesleyhandling of interrupts. 26040d553cfSPaul Beesley 26140d553cfSPaul BeesleyIn the remainder of this document, for the sake of simplicity a Arm GICv2 system 26240d553cfSPaul Beesleyis considered and it is assumed that the FIQ signal is used to generate Secure-EL1 26340d553cfSPaul Beesleyinterrupts and the IRQ signal is used to generate non-secure interrupts in either 26440d553cfSPaul Beesleysecurity state. EL3 interrupts are not considered. 26540d553cfSPaul Beesley 26640d553cfSPaul BeesleySoftware components 26740d553cfSPaul Beesley------------------- 26840d553cfSPaul Beesley 26940d553cfSPaul BeesleyRoles and responsibilities for interrupt management are sub-divided between the 27040d553cfSPaul Beesleyfollowing components of software running in EL3 and Secure-EL1. Each component is 27140d553cfSPaul Beesleybriefly described below. 27240d553cfSPaul Beesley 27340d553cfSPaul Beesley#. EL3 Runtime Firmware. This component is common to all ports of TF-A. 27440d553cfSPaul Beesley 27540d553cfSPaul Beesley#. Secure Payload Dispatcher (SPD) service. This service interfaces with the 27640d553cfSPaul Beesley Secure Payload (SP) software which runs in Secure-EL1/Secure-EL0 and is 27740d553cfSPaul Beesley responsible for switching execution between secure and non-secure states. 27840d553cfSPaul Beesley A switch is triggered by a Secure Monitor Call and it uses the APIs 27940d553cfSPaul Beesley exported by the Context management library to implement this functionality. 28040d553cfSPaul Beesley Switching execution between the two security states is a requirement for 28140d553cfSPaul Beesley interrupt management as well. This results in a significant dependency on 28240d553cfSPaul Beesley the SPD service. TF-A implements an example Test Secure Payload Dispatcher 28340d553cfSPaul Beesley (TSPD) service. 28440d553cfSPaul Beesley 28540d553cfSPaul Beesley An SPD service plugs into the EL3 runtime firmware and could be common to 28640d553cfSPaul Beesley some ports of TF-A. 28740d553cfSPaul Beesley 28840d553cfSPaul Beesley#. Secure Payload (SP). On a production system, the Secure Payload corresponds 28940d553cfSPaul Beesley to a Secure OS which runs in Secure-EL1/Secure-EL0. It interfaces with the 29040d553cfSPaul Beesley SPD service to manage communication with non-secure software. TF-A 29140d553cfSPaul Beesley implements an example secure payload called Test Secure Payload (TSP) 29240d553cfSPaul Beesley which runs only in Secure-EL1. 29340d553cfSPaul Beesley 29440d553cfSPaul Beesley A Secure payload implementation could be common to some ports of TF-A, 29540d553cfSPaul Beesley just like the SPD service. 29640d553cfSPaul Beesley 29740d553cfSPaul BeesleyInterrupt registration 29840d553cfSPaul Beesley---------------------- 29940d553cfSPaul Beesley 30040d553cfSPaul BeesleyThis section describes in detail the role of each software component (see 30140d553cfSPaul Beesley`Software components`_) during the registration of a handler for an interrupt 30240d553cfSPaul Beesleytype. 30340d553cfSPaul Beesley 30440d553cfSPaul BeesleyEL3 runtime firmware 30540d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~ 30640d553cfSPaul Beesley 30740d553cfSPaul BeesleyThis component declares the following prototype for a handler of an interrupt type. 30840d553cfSPaul Beesley 30940d553cfSPaul Beesley.. code:: c 31040d553cfSPaul Beesley 31140d553cfSPaul Beesley typedef uint64_t (*interrupt_type_handler_t)(uint32_t id, 31240d553cfSPaul Beesley uint32_t flags, 31340d553cfSPaul Beesley void *handle, 31440d553cfSPaul Beesley void *cookie); 31540d553cfSPaul Beesley 31640d553cfSPaul BeesleyThe ``id`` is parameter is reserved and could be used in the future for passing 31740d553cfSPaul Beesleythe interrupt id of the highest pending interrupt only if there is a foolproof 31840d553cfSPaul Beesleyway of determining the id. Currently it contains ``INTR_ID_UNAVAILABLE``. 31940d553cfSPaul Beesley 32040d553cfSPaul BeesleyThe ``flags`` parameter contains miscellaneous information as follows. 32140d553cfSPaul Beesley 32240d553cfSPaul Beesley#. Security state, bit[0]. This bit indicates the security state of the lower 32340d553cfSPaul Beesley exception level when the interrupt was generated. A value of ``1`` means 32440d553cfSPaul Beesley that it was in the non-secure state. A value of ``0`` indicates that it was 32540d553cfSPaul Beesley in the secure state. This bit can be used by the handler to ensure that 32640d553cfSPaul Beesley interrupt was generated and routed as per the routing model specified 32740d553cfSPaul Beesley during registration. 32840d553cfSPaul Beesley 32940d553cfSPaul Beesley#. Reserved, bits[31:1]. The remaining bits are reserved for future use. 33040d553cfSPaul Beesley 33140d553cfSPaul BeesleyThe ``handle`` parameter points to the ``cpu_context`` structure of the current CPU 33240d553cfSPaul Beesleyfor the security state specified in the ``flags`` parameter. 33340d553cfSPaul Beesley 33440d553cfSPaul BeesleyOnce the handler routine completes, execution will return to either the secure 33540d553cfSPaul Beesleyor non-secure state. The handler routine must return a pointer to 33640d553cfSPaul Beesley``cpu_context`` structure of the current CPU for the target security state. On 33740d553cfSPaul BeesleyAArch64, this return value is currently ignored by the caller as the 33840d553cfSPaul Beesleyappropriate ``cpu_context`` to be used is expected to be set by the handler 33940d553cfSPaul Beesleyvia the context management library APIs. 34040d553cfSPaul BeesleyA portable interrupt handler implementation must set the target context both in 34140d553cfSPaul Beesleythe structure pointed to by the returned pointer and via the context management 34240d553cfSPaul Beesleylibrary APIs. The handler should treat all error conditions as critical errors 34340d553cfSPaul Beesleyand take appropriate action within its implementation e.g. use assertion 34440d553cfSPaul Beesleyfailures. 34540d553cfSPaul Beesley 34640d553cfSPaul BeesleyThe runtime firmware provides the following API for registering a handler for a 34740d553cfSPaul Beesleyparticular type of interrupt. A Secure Payload Dispatcher service should use 34840d553cfSPaul Beesleythis API to register a handler for Secure-EL1 and optionally for non-secure 34940d553cfSPaul Beesleyinterrupts. This API also requires the caller to specify the routing model for 35040d553cfSPaul Beesleythe type of interrupt. 35140d553cfSPaul Beesley 35240d553cfSPaul Beesley.. code:: c 35340d553cfSPaul Beesley 35440d553cfSPaul Beesley int32_t register_interrupt_type_handler(uint32_t type, 35540d553cfSPaul Beesley interrupt_type_handler handler, 35640d553cfSPaul Beesley uint64_t flags); 35740d553cfSPaul Beesley 35840d553cfSPaul BeesleyThe ``type`` parameter can be one of the three interrupt types listed above i.e. 35940d553cfSPaul Beesley``INTR_TYPE_S_EL1``, ``INTR_TYPE_NS`` & ``INTR_TYPE_EL3``. The ``flags`` parameter 36040d553cfSPaul Beesleyis as described in Section 2. 36140d553cfSPaul Beesley 36240d553cfSPaul BeesleyThe function will return ``0`` upon a successful registration. It will return 36340d553cfSPaul Beesley``-EALREADY`` in case a handler for the interrupt type has already been 36440d553cfSPaul Beesleyregistered. If the ``type`` is unrecognised or the ``flags`` or the ``handler`` are 36540d553cfSPaul Beesleyinvalid it will return ``-EINVAL``. 36640d553cfSPaul Beesley 36740d553cfSPaul BeesleyInterrupt routing is governed by the configuration of the ``SCR_EL3.FIQ/IRQ`` bits 36840d553cfSPaul Beesleyprior to entry into a lower exception level in either security state. The 36940d553cfSPaul Beesleycontext management library maintains a copy of the ``SCR_EL3`` system register for 37040d553cfSPaul Beesleyeach security state in the ``cpu_context`` structure of each CPU. It exports the 37140d553cfSPaul Beesleyfollowing APIs to let EL3 Runtime Firmware program and retrieve the routing 37240d553cfSPaul Beesleymodel for each security state for the current CPU. The value of ``SCR_EL3`` stored 37340d553cfSPaul Beesleyin the ``cpu_context`` is used by the ``el3_exit()`` function to program the 37440d553cfSPaul Beesley``SCR_EL3`` register prior to returning from the EL3 exception level. 37540d553cfSPaul Beesley 37640d553cfSPaul Beesley.. code:: c 37740d553cfSPaul Beesley 37840d553cfSPaul Beesley uint32_t cm_get_scr_el3(uint32_t security_state); 37940d553cfSPaul Beesley void cm_write_scr_el3_bit(uint32_t security_state, 38040d553cfSPaul Beesley uint32_t bit_pos, 38140d553cfSPaul Beesley uint32_t value); 38240d553cfSPaul Beesley 38340d553cfSPaul Beesley``cm_get_scr_el3()`` returns the value of the ``SCR_EL3`` register for the specified 38436a5acfdSPeng Donglinsecurity state of the current CPU. ``cm_write_scr_el3_bit()`` writes a ``0`` or ``1`` 38536a5acfdSPeng Donglinto the bit specified by ``bit_pos``. ``register_interrupt_type_handler()`` invokes 38640d553cfSPaul Beesley``set_routing_model()`` API which programs the ``SCR_EL3`` according to the routing 38740d553cfSPaul Beesleymodel using the ``cm_get_scr_el3()`` and ``cm_write_scr_el3_bit()`` APIs. 38840d553cfSPaul Beesley 38940d553cfSPaul BeesleyIt is worth noting that in the current implementation of the framework, the EL3 39040d553cfSPaul Beesleyruntime firmware is responsible for programming the routing model. The SPD is 39140d553cfSPaul Beesleyresponsible for ensuring that the routing model has been adhered to upon 39240d553cfSPaul Beesleyreceiving an interrupt. 39340d553cfSPaul Beesley 39440d553cfSPaul Beesley.. _spd-int-registration: 39540d553cfSPaul Beesley 39640d553cfSPaul BeesleySecure payload dispatcher 39740d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~~~~~~ 39840d553cfSPaul Beesley 39940d553cfSPaul BeesleyA SPD service is responsible for determining and maintaining the interrupt 40040d553cfSPaul Beesleyrouting model supported by itself and the Secure Payload. It is also responsible 40140d553cfSPaul Beesleyfor ferrying interrupts between secure and non-secure software depending upon 40240d553cfSPaul Beesleythe routing model. It could determine the routing model at build time or at 40340d553cfSPaul Beesleyruntime. It must use this information to register a handler for each interrupt 40440d553cfSPaul Beesleytype using the ``register_interrupt_type_handler()`` API in EL3 runtime firmware. 40540d553cfSPaul Beesley 40640d553cfSPaul BeesleyIf the routing model is not known to the SPD service at build time, then it must 40740d553cfSPaul Beesleybe provided by the SP as the result of its initialisation. The SPD should 40840d553cfSPaul Beesleyprogram the routing model only after SP initialisation has completed e.g. in the 40940d553cfSPaul BeesleySPD initialisation function pointed to by the ``bl32_init`` variable. 41040d553cfSPaul Beesley 41140d553cfSPaul BeesleyThe SPD should determine the mechanism to pass control to the Secure Payload 41240d553cfSPaul Beesleyafter receiving an interrupt from the EL3 runtime firmware. This information 41340d553cfSPaul Beesleycould either be provided to the SPD service at build time or by the SP at 41440d553cfSPaul Beesleyruntime. 41540d553cfSPaul Beesley 41640d553cfSPaul BeesleyTest secure payload dispatcher behavior 41740d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 41840d553cfSPaul Beesley 419e1c5026aSPaul Beesley.. note:: 420e1c5026aSPaul Beesley Where this document discusses ``TSP_NS_INTR_ASYNC_PREEMPT`` as being 42140d553cfSPaul Beesley ``1``, the same results also apply when ``EL3_EXCEPTION_HANDLING`` is ``1``. 42240d553cfSPaul Beesley 42340d553cfSPaul BeesleyThe TSPD only handles Secure-EL1 interrupts and is provided with the following 42440d553cfSPaul Beesleyrouting model at build time. 42540d553cfSPaul Beesley 42640d553cfSPaul Beesley- Secure-EL1 interrupts are routed to EL3 when execution is in non-secure 42740d553cfSPaul Beesley state and are routed to the FEL when execution is in the secure state 42840d553cfSPaul Beesley i.e **CSS=0, TEL3=0** & **CSS=1, TEL3=1** for Secure-EL1 interrupts 42940d553cfSPaul Beesley 43040d553cfSPaul Beesley- When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is zero, the default routing 43140d553cfSPaul Beesley model is used for non-secure interrupts. They are routed to the FEL in 43240d553cfSPaul Beesley either security state i.e **CSS=0, TEL3=0** & **CSS=1, TEL3=0** for 43340d553cfSPaul Beesley Non-secure interrupts. 43440d553cfSPaul Beesley 43540d553cfSPaul Beesley- When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is defined to 1, then the 43640d553cfSPaul Beesley non secure interrupts are routed to EL3 when execution is in secure state 43740d553cfSPaul Beesley i.e **CSS=0, TEL3=1** for non-secure interrupts. This effectively preempts 43840d553cfSPaul Beesley Secure-EL1. The default routing model is used for non secure interrupts in 43940d553cfSPaul Beesley non-secure state. i.e **CSS=1, TEL3=0**. 44040d553cfSPaul Beesley 44140d553cfSPaul BeesleyIt performs the following actions in the ``tspd_init()`` function to fulfill the 44240d553cfSPaul Beesleyrequirements mentioned earlier. 44340d553cfSPaul Beesley 44440d553cfSPaul Beesley#. It passes control to the Test Secure Payload to perform its 44540d553cfSPaul Beesley initialisation. The TSP provides the address of the vector table 44640d553cfSPaul Beesley ``tsp_vectors`` in the SP which also includes the handler for Secure-EL1 44740d553cfSPaul Beesley interrupts in the ``sel1_intr_entry`` field. The TSPD passes control to the TSP at 44840d553cfSPaul Beesley this address when it receives a Secure-EL1 interrupt. 44940d553cfSPaul Beesley 45040d553cfSPaul Beesley The handover agreement between the TSP and the TSPD requires that the TSPD 45140d553cfSPaul Beesley masks all interrupts (``PSTATE.DAIF`` bits) when it calls 45240d553cfSPaul Beesley ``tsp_sel1_intr_entry()``. The TSP has to preserve the callee saved general 45340d553cfSPaul Beesley purpose, SP_EL1/Secure-EL0, LR, VFP and system registers. It can use 45440d553cfSPaul Beesley ``x0-x18`` to enable its C runtime. 45540d553cfSPaul Beesley 45640d553cfSPaul Beesley#. The TSPD implements a handler function for Secure-EL1 interrupts. This 45740d553cfSPaul Beesley function is registered with the EL3 runtime firmware using the 45840d553cfSPaul Beesley ``register_interrupt_type_handler()`` API as follows 45940d553cfSPaul Beesley 46040d553cfSPaul Beesley .. code:: c 46140d553cfSPaul Beesley 46240d553cfSPaul Beesley /* Forward declaration */ 46340d553cfSPaul Beesley interrupt_type_handler tspd_secure_el1_interrupt_handler; 46440d553cfSPaul Beesley int32_t rc, flags = 0; 46540d553cfSPaul Beesley set_interrupt_rm_flag(flags, NON_SECURE); 46640d553cfSPaul Beesley rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, 46740d553cfSPaul Beesley tspd_secure_el1_interrupt_handler, 46840d553cfSPaul Beesley flags); 46940d553cfSPaul Beesley if (rc) 47040d553cfSPaul Beesley panic(); 47140d553cfSPaul Beesley 47240d553cfSPaul Beesley#. When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is defined to 1, the TSPD 47340d553cfSPaul Beesley implements a handler function for non-secure interrupts. This function is 47440d553cfSPaul Beesley registered with the EL3 runtime firmware using the 47540d553cfSPaul Beesley ``register_interrupt_type_handler()`` API as follows 47640d553cfSPaul Beesley 47740d553cfSPaul Beesley .. code:: c 47840d553cfSPaul Beesley 47940d553cfSPaul Beesley /* Forward declaration */ 48040d553cfSPaul Beesley interrupt_type_handler tspd_ns_interrupt_handler; 48140d553cfSPaul Beesley int32_t rc, flags = 0; 48240d553cfSPaul Beesley set_interrupt_rm_flag(flags, SECURE); 48340d553cfSPaul Beesley rc = register_interrupt_type_handler(INTR_TYPE_NS, 48440d553cfSPaul Beesley tspd_ns_interrupt_handler, 48540d553cfSPaul Beesley flags); 48640d553cfSPaul Beesley if (rc) 48740d553cfSPaul Beesley panic(); 48840d553cfSPaul Beesley 48940d553cfSPaul Beesley.. _sp-int-registration: 49040d553cfSPaul Beesley 49140d553cfSPaul BeesleySecure payload 49240d553cfSPaul Beesley~~~~~~~~~~~~~~ 49340d553cfSPaul Beesley 49440d553cfSPaul BeesleyA Secure Payload must implement an interrupt handling framework at Secure-EL1 49540d553cfSPaul Beesley(Secure-EL1 IHF) to support its chosen interrupt routing model. Secure payload 49640d553cfSPaul Beesleyexecution will alternate between the below cases. 49740d553cfSPaul Beesley 49840d553cfSPaul Beesley#. In the code where IRQ, FIQ or both interrupts are enabled, if an interrupt 49940d553cfSPaul Beesley type is targeted to the FEL, then it will be routed to the Secure-EL1 50040d553cfSPaul Beesley exception vector table. This is defined as the **asynchronous mode** of 50140d553cfSPaul Beesley handling interrupts. This mode applies to both Secure-EL1 and non-secure 50240d553cfSPaul Beesley interrupts. 50340d553cfSPaul Beesley 50440d553cfSPaul Beesley#. In the code where both interrupts are disabled, if an interrupt type is 50540d553cfSPaul Beesley targeted to the FEL, then execution will eventually migrate to the 50640d553cfSPaul Beesley non-secure state. Any non-secure interrupts will be handled as described 50740d553cfSPaul Beesley in the routing model where **CSS=1 and TEL3=0**. Secure-EL1 interrupts 50840d553cfSPaul Beesley will be routed to EL3 (as per the routing model where **CSS=1 and 50940d553cfSPaul Beesley TEL3=1**) where the SPD service will hand them to the SP. This is defined 51040d553cfSPaul Beesley as the **synchronous mode** of handling interrupts. 51140d553cfSPaul Beesley 51240d553cfSPaul BeesleyThe interrupt handling framework implemented by the SP should support one or 51340d553cfSPaul Beesleyboth these interrupt handling models depending upon the chosen routing model. 51440d553cfSPaul Beesley 51540d553cfSPaul BeesleyThe following list briefly describes how the choice of a valid routing model 51640d553cfSPaul Beesley(see `Valid routing models`_) effects the implementation of the Secure-EL1 51740d553cfSPaul BeesleyIHF. If the choice of the interrupt routing model is not known to the SPD 51840d553cfSPaul Beesleyservice at compile time, then the SP should pass this information to the SPD 51940d553cfSPaul Beesleyservice at runtime during its initialisation phase. 52040d553cfSPaul Beesley 52140d553cfSPaul BeesleyAs mentioned earlier, an Arm GICv2 system is considered and it is assumed that 52240d553cfSPaul Beesleythe FIQ signal is used to generate Secure-EL1 interrupts and the IRQ signal 52340d553cfSPaul Beesleyis used to generate non-secure interrupts in either security state. 52440d553cfSPaul Beesley 52540d553cfSPaul BeesleySecure payload IHF design w.r.t secure-EL1 interrupts 52640d553cfSPaul Beesley^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 52740d553cfSPaul Beesley 52840d553cfSPaul Beesley#. **CSS=0, TEL3=0**. If ``PSTATE.F=0``, Secure-EL1 interrupts will be 52940d553cfSPaul Beesley triggered at one of the Secure-EL1 FIQ exception vectors. The Secure-EL1 53040d553cfSPaul Beesley IHF should implement support for handling FIQ interrupts asynchronously. 53140d553cfSPaul Beesley 53240d553cfSPaul Beesley If ``PSTATE.F=1`` then Secure-EL1 interrupts will be handled as per the 53340d553cfSPaul Beesley synchronous interrupt handling model. The SP could implement this scenario 53440d553cfSPaul Beesley by exporting a separate entrypoint for Secure-EL1 interrupts to the SPD 53540d553cfSPaul Beesley service during the registration phase. The SPD service would also need to 53640d553cfSPaul Beesley know the state of the system, general purpose and the ``PSTATE`` registers 53740d553cfSPaul Beesley in which it should arrange to return execution to the SP. The SP should 53840d553cfSPaul Beesley provide this information in an implementation defined way during the 53940d553cfSPaul Beesley registration phase if it is not known to the SPD service at build time. 54040d553cfSPaul Beesley 54140d553cfSPaul Beesley#. **CSS=1, TEL3=1**. Interrupts are routed to EL3 when execution is in 54240d553cfSPaul Beesley non-secure state. They should be handled through the synchronous interrupt 54340d553cfSPaul Beesley handling model as described in 1. above. 54440d553cfSPaul Beesley 54540d553cfSPaul Beesley#. **CSS=0, TEL3=1**. Secure-EL1 interrupts are routed to EL3 when execution 54640d553cfSPaul Beesley is in secure state. They will not be visible to the SP. The ``PSTATE.F`` bit 54740d553cfSPaul Beesley in Secure-EL1/Secure-EL0 will not mask FIQs. The EL3 runtime firmware will 54840d553cfSPaul Beesley call the handler registered by the SPD service for Secure-EL1 interrupts. 54940d553cfSPaul Beesley Secure-EL1 IHF should then handle all Secure-EL1 interrupt through the 55040d553cfSPaul Beesley synchronous interrupt handling model described in 1. above. 55140d553cfSPaul Beesley 55240d553cfSPaul BeesleySecure payload IHF design w.r.t non-secure interrupts 55340d553cfSPaul Beesley^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 55440d553cfSPaul Beesley 55540d553cfSPaul Beesley#. **CSS=0, TEL3=0**. If ``PSTATE.I=0``, non-secure interrupts will be 55640d553cfSPaul Beesley triggered at one of the Secure-EL1 IRQ exception vectors . The Secure-EL1 55740d553cfSPaul Beesley IHF should co-ordinate with the SPD service to transfer execution to the 55840d553cfSPaul Beesley non-secure state where the interrupt should be handled e.g the SP could 55940d553cfSPaul Beesley allocate a function identifier to issue a SMC64 or SMC32 to the SPD 56040d553cfSPaul Beesley service which indicates that the SP execution has been preempted by a 56140d553cfSPaul Beesley non-secure interrupt. If this function identifier is not known to the SPD 56240d553cfSPaul Beesley service at compile time then the SP could provide it during the 56340d553cfSPaul Beesley registration phase. 56440d553cfSPaul Beesley 56540d553cfSPaul Beesley If ``PSTATE.I=1`` then the non-secure interrupt will pend until execution 56640d553cfSPaul Beesley resumes in the non-secure state. 56740d553cfSPaul Beesley 56840d553cfSPaul Beesley#. **CSS=0, TEL3=1**. Non-secure interrupts are routed to EL3. They will not 56940d553cfSPaul Beesley be visible to the SP. The ``PSTATE.I`` bit in Secure-EL1/Secure-EL0 will 57040d553cfSPaul Beesley have not effect. The SPD service should register a non-secure interrupt 57140d553cfSPaul Beesley handler which should save the SP state correctly and resume execution in 57240d553cfSPaul Beesley the non-secure state where the interrupt will be handled. The Secure-EL1 57340d553cfSPaul Beesley IHF does not need to take any action. 57440d553cfSPaul Beesley 57540d553cfSPaul Beesley#. **CSS=1, TEL3=0**. Non-secure interrupts are handled in the FEL in 57640d553cfSPaul Beesley non-secure state (EL1/EL2) and are not visible to the SP. This routing 57740d553cfSPaul Beesley model does not affect the SP behavior. 57840d553cfSPaul Beesley 57940d553cfSPaul BeesleyA Secure Payload must also ensure that all Secure-EL1 interrupts are correctly 58040d553cfSPaul Beesleyconfigured at the interrupt controller by the platform port of the EL3 runtime 58140d553cfSPaul Beesleyfirmware. It should configure any additional Secure-EL1 interrupts which the EL3 58240d553cfSPaul Beesleyruntime firmware is not aware of through its platform port. 58340d553cfSPaul Beesley 58440d553cfSPaul BeesleyTest secure payload behavior 58540d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 58640d553cfSPaul Beesley 58740d553cfSPaul BeesleyThe routing model for Secure-EL1 and non-secure interrupts chosen by the TSP is 58840d553cfSPaul Beesleydescribed in Section `Secure Payload Dispatcher`__. It is known to the TSPD 58940d553cfSPaul Beesleyservice at build time. 59040d553cfSPaul Beesley 59140d553cfSPaul Beesley.. __: #spd-int-registration 59240d553cfSPaul Beesley 59340d553cfSPaul BeesleyThe TSP implements an entrypoint (``tsp_sel1_intr_entry()``) for handling Secure-EL1 59440d553cfSPaul Beesleyinterrupts taken in non-secure state and routed through the TSPD service 59540d553cfSPaul Beesley(synchronous handling model). It passes the reference to this entrypoint via 59640d553cfSPaul Beesley``tsp_vectors`` to the TSPD service. 59740d553cfSPaul Beesley 59840d553cfSPaul BeesleyThe TSP also replaces the default exception vector table referenced through the 59940d553cfSPaul Beesley``early_exceptions`` variable, with a vector table capable of handling FIQ and IRQ 60040d553cfSPaul Beesleyexceptions taken at the same (Secure-EL1) exception level. This table is 60140d553cfSPaul Beesleyreferenced through the ``tsp_exceptions`` variable and programmed into the 60240d553cfSPaul BeesleyVBAR_EL1. It caters for the asynchronous handling model. 60340d553cfSPaul Beesley 60440d553cfSPaul BeesleyThe TSP also programs the Secure Physical Timer in the Arm Generic Timer block 60540d553cfSPaul Beesleyto raise a periodic interrupt (every half a second) for the purpose of testing 60640d553cfSPaul Beesleyinterrupt management across all the software components listed in `Software 60740d553cfSPaul Beesleycomponents`_. 60840d553cfSPaul Beesley 60940d553cfSPaul BeesleyInterrupt handling 61040d553cfSPaul Beesley------------------ 61140d553cfSPaul Beesley 61240d553cfSPaul BeesleyThis section describes in detail the role of each software component (see 61340d553cfSPaul BeesleySection `Software components`_) in handling an interrupt of a particular type. 61440d553cfSPaul Beesley 61540d553cfSPaul BeesleyEL3 runtime firmware 61640d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~ 61740d553cfSPaul Beesley 61840d553cfSPaul BeesleyThe EL3 runtime firmware populates the IRQ and FIQ exception vectors referenced 61940d553cfSPaul Beesleyby the ``runtime_exceptions`` variable as follows. 62040d553cfSPaul Beesley 62140d553cfSPaul Beesley#. IRQ and FIQ exceptions taken from the current exception level with 62240d553cfSPaul Beesley ``SP_EL0`` or ``SP_EL3`` are reported as irrecoverable error conditions. As 62340d553cfSPaul Beesley mentioned earlier, EL3 runtime firmware always executes with the 62440d553cfSPaul Beesley ``PSTATE.I`` and ``PSTATE.F`` bits set. 62540d553cfSPaul Beesley 62640d553cfSPaul Beesley#. The following text describes how the IRQ and FIQ exceptions taken from a 62740d553cfSPaul Beesley lower exception level using AArch64 or AArch32 are handled. 62840d553cfSPaul Beesley 62940d553cfSPaul BeesleyWhen an interrupt is generated, the vector for each interrupt type is 63040d553cfSPaul Beesleyresponsible for: 63140d553cfSPaul Beesley 63240d553cfSPaul Beesley#. Saving the entire general purpose register context (x0-x30) immediately 63340d553cfSPaul Beesley upon exception entry. The registers are saved in the per-cpu ``cpu_context`` 63440d553cfSPaul Beesley data structure referenced by the ``SP_EL3``\ register. 63540d553cfSPaul Beesley 63640d553cfSPaul Beesley#. Saving the ``ELR_EL3``, ``SP_EL0`` and ``SPSR_EL3`` system registers in the 63740d553cfSPaul Beesley per-cpu ``cpu_context`` data structure referenced by the ``SP_EL3`` register. 63840d553cfSPaul Beesley 63940d553cfSPaul Beesley#. Switching to the C runtime stack by restoring the ``CTX_RUNTIME_SP`` value 64040d553cfSPaul Beesley from the per-cpu ``cpu_context`` data structure in ``SP_EL0`` and 64140d553cfSPaul Beesley executing the ``msr spsel, #0`` instruction. 64240d553cfSPaul Beesley 64340d553cfSPaul Beesley#. Determining the type of interrupt. Secure-EL1 interrupts will be signaled 64440d553cfSPaul Beesley at the FIQ vector. Non-secure interrupts will be signaled at the IRQ 64540d553cfSPaul Beesley vector. The platform should implement the following API to determine the 64640d553cfSPaul Beesley type of the pending interrupt. 64740d553cfSPaul Beesley 64840d553cfSPaul Beesley .. code:: c 64940d553cfSPaul Beesley 65040d553cfSPaul Beesley uint32_t plat_ic_get_interrupt_type(void); 65140d553cfSPaul Beesley 65240d553cfSPaul Beesley It should return either ``INTR_TYPE_S_EL1`` or ``INTR_TYPE_NS``. 65340d553cfSPaul Beesley 65440d553cfSPaul Beesley#. Determining the handler for the type of interrupt that has been generated. 65540d553cfSPaul Beesley The following API has been added for this purpose. 65640d553cfSPaul Beesley 65740d553cfSPaul Beesley .. code:: c 65840d553cfSPaul Beesley 65940d553cfSPaul Beesley interrupt_type_handler get_interrupt_type_handler(uint32_t interrupt_type); 66040d553cfSPaul Beesley 66140d553cfSPaul Beesley It returns the reference to the registered handler for this interrupt 66240d553cfSPaul Beesley type. The ``handler`` is retrieved from the ``intr_type_desc_t`` structure as 66340d553cfSPaul Beesley described in Section 2. ``NULL`` is returned if no handler has been 66440d553cfSPaul Beesley registered for this type of interrupt. This scenario is reported as an 66540d553cfSPaul Beesley irrecoverable error condition. 66640d553cfSPaul Beesley 66740d553cfSPaul Beesley#. Calling the registered handler function for the interrupt type generated. 66840d553cfSPaul Beesley The ``id`` parameter is set to ``INTR_ID_UNAVAILABLE`` currently. The id along 66940d553cfSPaul Beesley with the current security state and a reference to the ``cpu_context_t`` 67040d553cfSPaul Beesley structure for the current security state are passed to the handler function 67140d553cfSPaul Beesley as its arguments. 67240d553cfSPaul Beesley 67340d553cfSPaul Beesley The handler function returns a reference to the per-cpu ``cpu_context_t`` 67440d553cfSPaul Beesley structure for the target security state. 67540d553cfSPaul Beesley 67640d553cfSPaul Beesley#. Calling ``el3_exit()`` to return from EL3 into a lower exception level in 67740d553cfSPaul Beesley the security state determined by the handler routine. The ``el3_exit()`` 67840d553cfSPaul Beesley function is responsible for restoring the register context from the 67940d553cfSPaul Beesley ``cpu_context_t`` data structure for the target security state. 68040d553cfSPaul Beesley 68140d553cfSPaul BeesleySecure payload dispatcher 68240d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~~~~~~ 68340d553cfSPaul Beesley 68440d553cfSPaul BeesleyInterrupt entry 68540d553cfSPaul Beesley^^^^^^^^^^^^^^^ 68640d553cfSPaul Beesley 68740d553cfSPaul BeesleyThe SPD service begins handling an interrupt when the EL3 runtime firmware calls 68840d553cfSPaul Beesleythe handler function for that type of interrupt. The SPD service is responsible 68940d553cfSPaul Beesleyfor the following: 69040d553cfSPaul Beesley 69140d553cfSPaul Beesley#. Validating the interrupt. This involves ensuring that the interrupt was 69240d553cfSPaul Beesley generated according to the interrupt routing model specified by the SPD 69340d553cfSPaul Beesley service during registration. It should use the security state of the 69440d553cfSPaul Beesley exception level (passed in the ``flags`` parameter of the handler) where 69540d553cfSPaul Beesley the interrupt was taken from to determine this. If the interrupt is not 69640d553cfSPaul Beesley recognised then the handler should treat it as an irrecoverable error 69740d553cfSPaul Beesley condition. 69840d553cfSPaul Beesley 69940d553cfSPaul Beesley An SPD service can register a handler for Secure-EL1 and/or Non-secure 70040d553cfSPaul Beesley interrupts. A non-secure interrupt should never be routed to EL3 from 70140d553cfSPaul Beesley from non-secure state. Also if a routing model is chosen where Secure-EL1 70240d553cfSPaul Beesley interrupts are routed to S-EL1 when execution is in Secure state, then a 70340d553cfSPaul Beesley S-EL1 interrupt should never be routed to EL3 from secure state. The handler 70440d553cfSPaul Beesley could use the security state flag to check this. 70540d553cfSPaul Beesley 70640d553cfSPaul Beesley#. Determining whether a context switch is required. This depends upon the 70740d553cfSPaul Beesley routing model and interrupt type. For non secure and S-EL1 interrupt, 70840d553cfSPaul Beesley if the security state of the execution context where the interrupt was 70940d553cfSPaul Beesley generated is not the same as the security state required for handling 71040d553cfSPaul Beesley the interrupt, a context switch is required. The following 2 cases 71140d553cfSPaul Beesley require a context switch from secure to non-secure or vice-versa: 71240d553cfSPaul Beesley 71340d553cfSPaul Beesley #. A Secure-EL1 interrupt taken from the non-secure state should be 71440d553cfSPaul Beesley routed to the Secure Payload. 71540d553cfSPaul Beesley 71640d553cfSPaul Beesley #. A non-secure interrupt taken from the secure state should be routed 71740d553cfSPaul Beesley to the last known non-secure exception level. 71840d553cfSPaul Beesley 71940d553cfSPaul Beesley The SPD service must save the system register context of the current 72040d553cfSPaul Beesley security state. It must then restore the system register context of the 72140d553cfSPaul Beesley target security state. It should use the ``cm_set_next_eret_context()`` API 72240d553cfSPaul Beesley to ensure that the next ``cpu_context`` to be restored is of the target 72340d553cfSPaul Beesley security state. 72440d553cfSPaul Beesley 72540d553cfSPaul Beesley If the target state is secure then execution should be handed to the SP as 72640d553cfSPaul Beesley per the synchronous interrupt handling model it implements. A Secure-EL1 72740d553cfSPaul Beesley interrupt can be routed to EL3 while execution is in the SP. This implies 72840d553cfSPaul Beesley that SP execution can be preempted while handling an interrupt by a 72940d553cfSPaul Beesley another higher priority Secure-EL1 interrupt or a EL3 interrupt. The SPD 73040d553cfSPaul Beesley service should be able to handle this preemption or manage secure interrupt 73140d553cfSPaul Beesley priorities before handing control to the SP. 73240d553cfSPaul Beesley 73340d553cfSPaul Beesley#. Setting the return value of the handler to the per-cpu ``cpu_context`` if 73440d553cfSPaul Beesley the interrupt has been successfully validated and ready to be handled at a 73540d553cfSPaul Beesley lower exception level. 73640d553cfSPaul Beesley 73740d553cfSPaul BeesleyThe routing model allows non-secure interrupts to interrupt Secure-EL1 when in 73840d553cfSPaul Beesleysecure state if it has been configured to do so. The SPD service and the SP 73940d553cfSPaul Beesleyshould implement a mechanism for routing these interrupts to the last known 74040d553cfSPaul Beesleyexception level in the non-secure state. The former should save the SP context, 74140d553cfSPaul Beesleyrestore the non-secure context and arrange for entry into the non-secure state 74240d553cfSPaul Beesleyso that the interrupt can be handled. 74340d553cfSPaul Beesley 74440d553cfSPaul BeesleyInterrupt exit 74540d553cfSPaul Beesley^^^^^^^^^^^^^^ 74640d553cfSPaul Beesley 74740d553cfSPaul BeesleyWhen the Secure Payload has finished handling a Secure-EL1 interrupt, it could 74840d553cfSPaul Beesleyreturn control back to the SPD service through a SMC32 or SMC64. The SPD service 74940d553cfSPaul Beesleyshould handle this secure monitor call so that execution resumes in the 75040d553cfSPaul Beesleyexception level and the security state from where the Secure-EL1 interrupt was 75140d553cfSPaul Beesleyoriginally taken. 75240d553cfSPaul Beesley 75340d553cfSPaul BeesleyTest secure payload dispatcher Secure-EL1 interrupt handling 75440d553cfSPaul Beesley^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 75540d553cfSPaul Beesley 75640d553cfSPaul BeesleyThe example TSPD service registers a handler for Secure-EL1 interrupts taken 75740d553cfSPaul Beesleyfrom the non-secure state. During execution in S-EL1, the TSPD expects that the 75840d553cfSPaul BeesleySecure-EL1 interrupts are handled in S-EL1 by TSP. Its handler 75940d553cfSPaul Beesley``tspd_secure_el1_interrupt_handler()`` expects only to be invoked for Secure-EL1 76040d553cfSPaul Beesleyoriginating from the non-secure state. It takes the following actions upon being 76140d553cfSPaul Beesleyinvoked. 76240d553cfSPaul Beesley 76340d553cfSPaul Beesley#. It uses the security state provided in the ``flags`` parameter to ensure 76440d553cfSPaul Beesley that the secure interrupt originated from the non-secure state. It asserts 76540d553cfSPaul Beesley if this is not the case. 76640d553cfSPaul Beesley 76740d553cfSPaul Beesley#. It saves the system register context for the non-secure state by calling 76840d553cfSPaul Beesley ``cm_el1_sysregs_context_save(NON_SECURE);``. 76940d553cfSPaul Beesley 77040d553cfSPaul Beesley#. It sets the ``ELR_EL3`` system register to ``tsp_sel1_intr_entry`` and sets the 77140d553cfSPaul Beesley ``SPSR_EL3.DAIF`` bits in the secure CPU context. It sets ``x0`` to 77240d553cfSPaul Beesley ``TSP_HANDLE_SEL1_INTR_AND_RETURN``. If the TSP was preempted earlier by a non 77340d553cfSPaul Beesley secure interrupt during ``yielding`` SMC processing, save the registers that 77440d553cfSPaul Beesley will be trashed, which is the ``ELR_EL3`` and ``SPSR_EL3``, in order to be able 77540d553cfSPaul Beesley to re-enter TSP for Secure-EL1 interrupt processing. It does not need to 77640d553cfSPaul Beesley save any other secure context since the TSP is expected to preserve it 77740d553cfSPaul Beesley (see section `Test secure payload dispatcher behavior`_). 77840d553cfSPaul Beesley 77940d553cfSPaul Beesley#. It restores the system register context for the secure state by calling 78040d553cfSPaul Beesley ``cm_el1_sysregs_context_restore(SECURE);``. 78140d553cfSPaul Beesley 78240d553cfSPaul Beesley#. It ensures that the secure CPU context is used to program the next 78340d553cfSPaul Beesley exception return from EL3 by calling ``cm_set_next_eret_context(SECURE);``. 78440d553cfSPaul Beesley 78540d553cfSPaul Beesley#. It returns the per-cpu ``cpu_context`` to indicate that the interrupt can 78640d553cfSPaul Beesley now be handled by the SP. ``x1`` is written with the value of ``elr_el3`` 78740d553cfSPaul Beesley register for the non-secure state. This information is used by the SP for 78840d553cfSPaul Beesley debugging purposes. 78940d553cfSPaul Beesley 79040d553cfSPaul BeesleyThe figure below describes how the interrupt handling is implemented by the TSPD 79140d553cfSPaul Beesleywhen a Secure-EL1 interrupt is generated when execution is in the non-secure 79240d553cfSPaul Beesleystate. 79340d553cfSPaul Beesley 79440d553cfSPaul Beesley|Image 1| 79540d553cfSPaul Beesley 79640d553cfSPaul BeesleyThe TSP issues an SMC with ``TSP_HANDLED_S_EL1_INTR`` as the function identifier to 79740d553cfSPaul Beesleysignal completion of interrupt handling. 79840d553cfSPaul Beesley 79940d553cfSPaul BeesleyThe TSPD service takes the following actions in ``tspd_smc_handler()`` function 80040d553cfSPaul Beesleyupon receiving an SMC with ``TSP_HANDLED_S_EL1_INTR`` as the function identifier: 80140d553cfSPaul Beesley 80240d553cfSPaul Beesley#. It ensures that the call originated from the secure state otherwise 80340d553cfSPaul Beesley execution returns to the non-secure state with ``SMC_UNK`` in ``x0``. 80440d553cfSPaul Beesley 80540d553cfSPaul Beesley#. It restores the saved ``ELR_EL3`` and ``SPSR_EL3`` system registers back to 80640d553cfSPaul Beesley the secure CPU context (see step 3 above) in case the TSP had been preempted 80740d553cfSPaul Beesley by a non secure interrupt earlier. 80840d553cfSPaul Beesley 80940d553cfSPaul Beesley#. It restores the system register context for the non-secure state by 81040d553cfSPaul Beesley calling ``cm_el1_sysregs_context_restore(NON_SECURE)``. 81140d553cfSPaul Beesley 81240d553cfSPaul Beesley#. It ensures that the non-secure CPU context is used to program the next 81340d553cfSPaul Beesley exception return from EL3 by calling ``cm_set_next_eret_context(NON_SECURE)``. 81440d553cfSPaul Beesley 81540d553cfSPaul Beesley#. ``tspd_smc_handler()`` returns a reference to the non-secure ``cpu_context`` 81640d553cfSPaul Beesley as the return value. 81740d553cfSPaul Beesley 81840d553cfSPaul BeesleyTest secure payload dispatcher non-secure interrupt handling 81940d553cfSPaul Beesley^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 82040d553cfSPaul Beesley 82140d553cfSPaul BeesleyThe TSP in Secure-EL1 can be preempted by a non-secure interrupt during 82240d553cfSPaul Beesley``yielding`` SMC processing or by a higher priority EL3 interrupt during 82340d553cfSPaul BeesleySecure-EL1 interrupt processing. When ``EL3_EXCEPTION_HANDLING`` is ``0``, only 82440d553cfSPaul Beesleynon-secure interrupts can cause preemption of TSP since there are no EL3 82540d553cfSPaul Beesleyinterrupts in the system. With ``EL3_EXCEPTION_HANDLING=1`` however, any EL3 82640d553cfSPaul Beesleyinterrupt may preempt Secure execution. 82740d553cfSPaul Beesley 82840d553cfSPaul BeesleyIt should be noted that while TSP is preempted, the TSPD only allows entry into 82940d553cfSPaul Beesleythe TSP either for Secure-EL1 interrupt handling or for resuming the preempted 83040d553cfSPaul Beesley``yielding`` SMC in response to the ``TSP_FID_RESUME`` SMC from the normal world. 83140d553cfSPaul Beesley(See Section `Implication of preempted SMC on Non-Secure Software`_). 83240d553cfSPaul Beesley 83340d553cfSPaul BeesleyThe non-secure interrupt triggered in Secure-EL1 during ``yielding`` SMC 83440d553cfSPaul Beesleyprocessing can be routed to either EL3 or Secure-EL1 and is controlled by build 83540d553cfSPaul Beesleyoption ``TSP_NS_INTR_ASYNC_PREEMPT`` (see Section `Test secure payload 83640d553cfSPaul Beesleydispatcher behavior`_). If the build option is set, the TSPD will set the 83740d553cfSPaul Beesleyrouting model for the non-secure interrupt to be routed to EL3 from secure state 83840d553cfSPaul Beesleyi.e. **TEL3=1, CSS=0** and registers ``tspd_ns_interrupt_handler()`` as the 83940d553cfSPaul Beesleynon-secure interrupt handler. The ``tspd_ns_interrupt_handler()`` on being 84040d553cfSPaul Beesleyinvoked ensures that the interrupt originated from the secure state and disables 84140d553cfSPaul Beesleyrouting of non-secure interrupts from secure state to EL3. This is to prevent 84240d553cfSPaul Beesleyfurther preemption (by a non-secure interrupt) when TSP is reentered for 84340d553cfSPaul Beesleyhandling Secure-EL1 interrupts that triggered while execution was in the normal 84440d553cfSPaul Beesleyworld. The ``tspd_ns_interrupt_handler()`` then invokes 84540d553cfSPaul Beesley``tspd_handle_sp_preemption()`` for further handling. 84640d553cfSPaul Beesley 84740d553cfSPaul BeesleyIf the ``TSP_NS_INTR_ASYNC_PREEMPT`` build option is zero (default), the default 84840d553cfSPaul Beesleyrouting model for non-secure interrupt in secure state is in effect 84940d553cfSPaul Beesleyi.e. **TEL3=0, CSS=0**. During ``yielding`` SMC processing, the IRQ 85040d553cfSPaul Beesleyexceptions are unmasked i.e. ``PSTATE.I=0``, and a non-secure interrupt will 85140d553cfSPaul Beesleytrigger at Secure-EL1 IRQ exception vector. The TSP saves the general purpose 85240d553cfSPaul Beesleyregister context and issues an SMC with ``TSP_PREEMPTED`` as the function 85340d553cfSPaul Beesleyidentifier to signal preemption of TSP. The TSPD SMC handler, 85440d553cfSPaul Beesley``tspd_smc_handler()``, ensures that the SMC call originated from the 85540d553cfSPaul Beesleysecure state otherwise execution returns to the non-secure state with 85640d553cfSPaul Beesley``SMC_UNK`` in ``x0``. It then invokes ``tspd_handle_sp_preemption()`` for 85740d553cfSPaul Beesleyfurther handling. 85840d553cfSPaul Beesley 85940d553cfSPaul BeesleyThe ``tspd_handle_sp_preemption()`` takes the following actions upon being 86040d553cfSPaul Beesleyinvoked: 86140d553cfSPaul Beesley 86240d553cfSPaul Beesley#. It saves the system register context for the secure state by calling 86340d553cfSPaul Beesley ``cm_el1_sysregs_context_save(SECURE)``. 86440d553cfSPaul Beesley 86540d553cfSPaul Beesley#. It restores the system register context for the non-secure state by 86640d553cfSPaul Beesley calling ``cm_el1_sysregs_context_restore(NON_SECURE)``. 86740d553cfSPaul Beesley 86840d553cfSPaul Beesley#. It ensures that the non-secure CPU context is used to program the next 86940d553cfSPaul Beesley exception return from EL3 by calling ``cm_set_next_eret_context(NON_SECURE)``. 87040d553cfSPaul Beesley 87140d553cfSPaul Beesley#. ``SMC_PREEMPTED`` is set in x0 and return to non secure state after 87240d553cfSPaul Beesley restoring non secure context. 87340d553cfSPaul Beesley 87440d553cfSPaul BeesleyThe Normal World is expected to resume the TSP after the ``yielding`` SMC 87540d553cfSPaul Beesleypreemption by issuing an SMC with ``TSP_FID_RESUME`` as the function identifier 87640d553cfSPaul Beesley(see section `Implication of preempted SMC on Non-Secure Software`_). The TSPD 87740d553cfSPaul Beesleyservice takes the following actions in ``tspd_smc_handler()`` function upon 87840d553cfSPaul Beesleyreceiving this SMC: 87940d553cfSPaul Beesley 88040d553cfSPaul Beesley#. It ensures that the call originated from the non secure state. An 88140d553cfSPaul Beesley assertion is raised otherwise. 88240d553cfSPaul Beesley 88340d553cfSPaul Beesley#. Checks whether the TSP needs a resume i.e check if it was preempted. It 88440d553cfSPaul Beesley then saves the system register context for the non-secure state by calling 88540d553cfSPaul Beesley ``cm_el1_sysregs_context_save(NON_SECURE)``. 88640d553cfSPaul Beesley 88740d553cfSPaul Beesley#. Restores the secure context by calling 88840d553cfSPaul Beesley ``cm_el1_sysregs_context_restore(SECURE)`` 88940d553cfSPaul Beesley 89040d553cfSPaul Beesley#. It ensures that the secure CPU context is used to program the next 89140d553cfSPaul Beesley exception return from EL3 by calling ``cm_set_next_eret_context(SECURE)``. 89240d553cfSPaul Beesley 89340d553cfSPaul Beesley#. ``tspd_smc_handler()`` returns a reference to the secure ``cpu_context`` as the 89440d553cfSPaul Beesley return value. 89540d553cfSPaul Beesley 89640d553cfSPaul BeesleyThe figure below describes how the TSP/TSPD handle a non-secure interrupt when 89740d553cfSPaul Beesleyit is generated during execution in the TSP with ``PSTATE.I`` = 0 when the 89840d553cfSPaul Beesley``TSP_NS_INTR_ASYNC_PREEMPT`` build flag is 0. 89940d553cfSPaul Beesley 90040d553cfSPaul Beesley|Image 2| 90140d553cfSPaul Beesley 90240d553cfSPaul BeesleySecure payload 90340d553cfSPaul Beesley~~~~~~~~~~~~~~ 90440d553cfSPaul Beesley 90540d553cfSPaul BeesleyThe SP should implement one or both of the synchronous and asynchronous 90640d553cfSPaul Beesleyinterrupt handling models depending upon the interrupt routing model it has 90740d553cfSPaul Beesleychosen (as described in section `Secure Payload`__). 90840d553cfSPaul Beesley 90940d553cfSPaul Beesley.. __: #sp-int-registration 91040d553cfSPaul Beesley 91140d553cfSPaul BeesleyIn the synchronous model, it should begin handling a Secure-EL1 interrupt after 91240d553cfSPaul Beesleyreceiving control from the SPD service at an entrypoint agreed upon during build 91340d553cfSPaul Beesleytime or during the registration phase. Before handling the interrupt, the SP 91440d553cfSPaul Beesleyshould save any Secure-EL1 system register context which is needed for resuming 91540d553cfSPaul Beesleynormal execution in the SP later e.g. ``SPSR_EL1``, ``ELR_EL1``. After handling 91640d553cfSPaul Beesleythe interrupt, the SP could return control back to the exception level and 91740d553cfSPaul Beesleysecurity state where the interrupt was originally taken from. The SP should use 91840d553cfSPaul Beesleyan SMC32 or SMC64 to ask the SPD service to do this. 91940d553cfSPaul Beesley 92040d553cfSPaul BeesleyIn the asynchronous model, the Secure Payload is responsible for handling 92140d553cfSPaul Beesleynon-secure and Secure-EL1 interrupts at the IRQ and FIQ vectors in its exception 92240d553cfSPaul Beesleyvector table when ``PSTATE.I`` and ``PSTATE.F`` bits are 0. As described earlier, 92340d553cfSPaul Beesleywhen a non-secure interrupt is generated, the SP should coordinate with the SPD 92440d553cfSPaul Beesleyservice to pass control back to the non-secure state in the last known exception 92540d553cfSPaul Beesleylevel. This will allow the non-secure interrupt to be handled in the non-secure 92640d553cfSPaul Beesleystate. 92740d553cfSPaul Beesley 92840d553cfSPaul BeesleyTest secure payload behavior 92940d553cfSPaul Beesley^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 93040d553cfSPaul Beesley 93140d553cfSPaul BeesleyThe TSPD hands control of a Secure-EL1 interrupt to the TSP at the 93240d553cfSPaul Beesley``tsp_sel1_intr_entry()``. The TSP handles the interrupt while ensuring that the 93340d553cfSPaul Beesleyhandover agreement described in Section `Test secure payload dispatcher 93440d553cfSPaul Beesleybehavior`_ is maintained. It updates some statistics by calling 93540d553cfSPaul Beesley``tsp_update_sync_sel1_intr_stats()``. It then calls 93640d553cfSPaul Beesley``tsp_common_int_handler()`` which. 93740d553cfSPaul Beesley 93840d553cfSPaul Beesley#. Checks whether the interrupt is the secure physical timer interrupt. It 93940d553cfSPaul Beesley uses the platform API ``plat_ic_get_pending_interrupt_id()`` to get the 94040d553cfSPaul Beesley interrupt number. If it is not the secure physical timer interrupt, then 94140d553cfSPaul Beesley that means that a higher priority interrupt has preempted it. Invoke 94240d553cfSPaul Beesley ``tsp_handle_preemption()`` to handover control back to EL3 by issuing 94340d553cfSPaul Beesley an SMC with ``TSP_PREEMPTED`` as the function identifier. 94440d553cfSPaul Beesley 94540d553cfSPaul Beesley#. Handles the secure timer interrupt interrupt by acknowledging it using the 94640d553cfSPaul Beesley ``plat_ic_acknowledge_interrupt()`` platform API, calling 94740d553cfSPaul Beesley ``tsp_generic_timer_handler()`` to reprogram the secure physical generic 94840d553cfSPaul Beesley timer and calling the ``plat_ic_end_of_interrupt()`` platform API to signal 94940d553cfSPaul Beesley end of interrupt processing. 95040d553cfSPaul Beesley 95140d553cfSPaul BeesleyThe TSP passes control back to the TSPD by issuing an SMC64 with 95240d553cfSPaul Beesley``TSP_HANDLED_S_EL1_INTR`` as the function identifier. 95340d553cfSPaul Beesley 95440d553cfSPaul BeesleyThe TSP handles interrupts under the asynchronous model as follows. 95540d553cfSPaul Beesley 95640d553cfSPaul Beesley#. Secure-EL1 interrupts are handled by calling the ``tsp_common_int_handler()`` 95740d553cfSPaul Beesley function. The function has been described above. 95840d553cfSPaul Beesley 95940d553cfSPaul Beesley#. Non-secure interrupts are handled by calling the ``tsp_common_int_handler()`` 96040d553cfSPaul Beesley function which ends up invoking ``tsp_handle_preemption()`` and issuing an 96140d553cfSPaul Beesley SMC64 with ``TSP_PREEMPTED`` as the function identifier. Execution resumes at 96240d553cfSPaul Beesley the instruction that follows this SMC instruction when the TSPD hands control 96340d553cfSPaul Beesley to the TSP in response to an SMC with ``TSP_FID_RESUME`` as the function 96440d553cfSPaul Beesley identifier from the non-secure state (see section `Test secure payload 96540d553cfSPaul Beesley dispatcher non-secure interrupt handling`_). 96640d553cfSPaul Beesley 96740d553cfSPaul BeesleyOther considerations 96840d553cfSPaul Beesley-------------------- 96940d553cfSPaul Beesley 97040d553cfSPaul BeesleyImplication of preempted SMC on Non-Secure Software 97140d553cfSPaul Beesley~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 97240d553cfSPaul Beesley 97340d553cfSPaul BeesleyA ``yielding`` SMC call to Secure payload can be preempted by a non-secure 97440d553cfSPaul Beesleyinterrupt and the execution can return to the non-secure world for handling 97540d553cfSPaul Beesleythe interrupt (For details on ``yielding`` SMC refer `SMC calling convention`_). 97640d553cfSPaul BeesleyIn this case, the SMC call has not completed its execution and the execution 97740d553cfSPaul Beesleymust return back to the secure payload to resume the preempted SMC call. 97840d553cfSPaul BeesleyThis can be achieved by issuing an SMC call which instructs to resume the 97940d553cfSPaul Beesleypreempted SMC. 98040d553cfSPaul Beesley 98140d553cfSPaul BeesleyA ``fast`` SMC cannot be preempted and hence this case will not happen for 98240d553cfSPaul Beesleya fast SMC call. 98340d553cfSPaul Beesley 98440d553cfSPaul BeesleyIn the Test Secure Payload implementation, ``TSP_FID_RESUME`` is designated 98540d553cfSPaul Beesleyas the resume SMC FID. It is important to note that ``TSP_FID_RESUME`` is a 98640d553cfSPaul Beesley``yielding`` SMC which means it too can be be preempted. The typical non 98740d553cfSPaul Beesleysecure software sequence for issuing a ``yielding`` SMC would look like this, 98840d553cfSPaul Beesleyassuming ``P.STATE.I=0`` in the non secure state : 98940d553cfSPaul Beesley 99040d553cfSPaul Beesley.. code:: c 99140d553cfSPaul Beesley 99240d553cfSPaul Beesley int rc; 99340d553cfSPaul Beesley rc = smc(TSP_YIELD_SMC_FID, ...); /* Issue a Yielding SMC call */ 99440d553cfSPaul Beesley /* The pending non-secure interrupt is handled by the interrupt handler 99540d553cfSPaul Beesley and returns back here. */ 99640d553cfSPaul Beesley while (rc == SMC_PREEMPTED) { /* Check if the SMC call is preempted */ 99740d553cfSPaul Beesley rc = smc(TSP_FID_RESUME); /* Issue resume SMC call */ 99840d553cfSPaul Beesley } 99940d553cfSPaul Beesley 100040d553cfSPaul BeesleyThe ``TSP_YIELD_SMC_FID`` is any ``yielding`` SMC function identifier and the smc() 100140d553cfSPaul Beesleyfunction invokes a SMC call with the required arguments. The pending non-secure 100240d553cfSPaul Beesleyinterrupt causes an IRQ exception and the IRQ handler registered at the 100340d553cfSPaul Beesleyexception vector handles the non-secure interrupt and returns. The return value 100440d553cfSPaul Beesleyfrom the SMC call is tested for ``SMC_PREEMPTED`` to check whether it is 100540d553cfSPaul Beesleypreempted. If it is, then the resume SMC call ``TSP_FID_RESUME`` is issued. The 100640d553cfSPaul Beesleyreturn value of the SMC call is tested again to check if it is preempted. 100740d553cfSPaul BeesleyThis is done in a loop till the SMC call succeeds or fails. If a ``yielding`` 100840d553cfSPaul BeesleySMC is preempted, until it is resumed using ``TSP_FID_RESUME`` SMC and 100940d553cfSPaul Beesleycompleted, the current TSPD prevents any other SMC call from re-entering 101040d553cfSPaul BeesleyTSP by returning ``SMC_UNK`` error. 101140d553cfSPaul Beesley 101240d553cfSPaul Beesley-------------- 101340d553cfSPaul Beesley 1014*3ba55a3cSlaurenw-arm*Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.* 101540d553cfSPaul Beesley 1016*3ba55a3cSlaurenw-arm.. _SMC calling convention: https://developer.arm.com/docs/den0028/latest 101740d553cfSPaul Beesley 1018a2c320a8SPaul Beesley.. |Image 1| image:: ../resources/diagrams/sec-int-handling.png 1019a2c320a8SPaul Beesley.. |Image 2| image:: ../resources/diagrams/non-sec-int-handling.png 1020