1*91f16700SchasingluluInterrupt Management Framework 2*91f16700Schasinglulu============================== 3*91f16700Schasinglulu 4*91f16700SchasingluluThis framework is responsible for managing interrupts routed to EL3. It also 5*91f16700Schasingluluallows EL3 software to configure the interrupt routing behavior. Its main 6*91f16700Schasingluluobjective is to implement the following two requirements. 7*91f16700Schasinglulu 8*91f16700Schasinglulu#. It should be possible to route interrupts meant to be handled by secure 9*91f16700Schasinglulu software (Secure interrupts) to EL3, when execution is in non-secure state 10*91f16700Schasinglulu (normal world). The framework should then take care of handing control of 11*91f16700Schasinglulu the interrupt to either software in EL3 or Secure-EL1 depending upon the 12*91f16700Schasinglulu software configuration and the GIC implementation. This requirement ensures 13*91f16700Schasinglulu that secure interrupts are under the control of the secure software with 14*91f16700Schasinglulu respect to their delivery and handling without the possibility of 15*91f16700Schasinglulu intervention from non-secure software. 16*91f16700Schasinglulu 17*91f16700Schasinglulu#. It should be possible to route interrupts meant to be handled by 18*91f16700Schasinglulu non-secure software (Non-secure interrupts) to the last executed exception 19*91f16700Schasinglulu level in the normal world when the execution is in secure world at 20*91f16700Schasinglulu exception levels lower than EL3. This could be done with or without the 21*91f16700Schasinglulu knowledge of software executing in Secure-EL1/Secure-EL0. The choice of 22*91f16700Schasinglulu approach should be governed by the secure software. This requirement 23*91f16700Schasinglulu ensures that non-secure software is able to execute in tandem with the 24*91f16700Schasinglulu secure software without overriding it. 25*91f16700Schasinglulu 26*91f16700SchasingluluConcepts 27*91f16700Schasinglulu-------- 28*91f16700Schasinglulu 29*91f16700SchasingluluInterrupt types 30*91f16700Schasinglulu~~~~~~~~~~~~~~~ 31*91f16700Schasinglulu 32*91f16700SchasingluluThe framework categorises an interrupt to be one of the following depending upon 33*91f16700Schasingluluthe exception level(s) it is handled in. 34*91f16700Schasinglulu 35*91f16700Schasinglulu#. Secure EL1 interrupt. This type of interrupt can be routed to EL3 or 36*91f16700Schasinglulu Secure-EL1 depending upon the security state of the current execution 37*91f16700Schasinglulu context. It is always handled in Secure-EL1. 38*91f16700Schasinglulu 39*91f16700Schasinglulu#. Non-secure interrupt. This type of interrupt can be routed to EL3, 40*91f16700Schasinglulu Secure-EL1, Non-secure EL1 or EL2 depending upon the security state of the 41*91f16700Schasinglulu current execution context. It is always handled in either Non-secure EL1 42*91f16700Schasinglulu or EL2. 43*91f16700Schasinglulu 44*91f16700Schasinglulu#. EL3 interrupt. This type of interrupt can be routed to EL3 or Secure-EL1 45*91f16700Schasinglulu depending upon the security state of the current execution context. It is 46*91f16700Schasinglulu always handled in EL3. 47*91f16700Schasinglulu 48*91f16700SchasingluluThe following constants define the various interrupt types in the framework 49*91f16700Schasingluluimplementation. 50*91f16700Schasinglulu 51*91f16700Schasinglulu.. code:: c 52*91f16700Schasinglulu 53*91f16700Schasinglulu #define INTR_TYPE_S_EL1 0 54*91f16700Schasinglulu #define INTR_TYPE_EL3 1 55*91f16700Schasinglulu #define INTR_TYPE_NS 2 56*91f16700Schasinglulu 57*91f16700SchasingluluRouting model 58*91f16700Schasinglulu~~~~~~~~~~~~~ 59*91f16700Schasinglulu 60*91f16700SchasingluluA type of interrupt can be either generated as an FIQ or an IRQ. The target 61*91f16700Schasingluluexception level of an interrupt type is configured through the FIQ and IRQ bits 62*91f16700Schasingluluin the Secure Configuration Register at EL3 (``SCR_EL3.FIQ`` and ``SCR_EL3.IRQ`` 63*91f16700Schasinglulubits). When ``SCR_EL3.FIQ``\ =1, FIQs are routed to EL3. Otherwise they are routed 64*91f16700Schasingluluto the First Exception Level (FEL) capable of handling interrupts. When 65*91f16700Schasinglulu``SCR_EL3.IRQ``\ =1, IRQs are routed to EL3. Otherwise they are routed to the 66*91f16700SchasingluluFEL. This register is configured independently by EL3 software for each security 67*91f16700Schasinglulustate prior to entry into a lower exception level in that security state. 68*91f16700Schasinglulu 69*91f16700SchasingluluA routing model for a type of interrupt (generated as FIQ or IRQ) is defined as 70*91f16700Schasingluluits target exception level for each security state. It is represented by a 71*91f16700Schasinglulusingle bit for each security state. A value of ``0`` means that the interrupt 72*91f16700Schasinglulushould be routed to the FEL. A value of ``1`` means that the interrupt should be 73*91f16700Schasinglulurouted to EL3. A routing model is applicable only when execution is not in EL3. 74*91f16700Schasinglulu 75*91f16700SchasingluluThe default routing model for an interrupt type is to route it to the FEL in 76*91f16700Schasinglulueither security state. 77*91f16700Schasinglulu 78*91f16700SchasingluluValid routing models 79*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~ 80*91f16700Schasinglulu 81*91f16700SchasingluluThe framework considers certain routing models for each type of interrupt to be 82*91f16700Schasingluluincorrect as they conflict with the requirements mentioned in Section 1. The 83*91f16700Schasinglulufollowing sub-sections describe all the possible routing models and specify 84*91f16700Schasingluluwhich ones are valid or invalid. EL3 interrupts are currently supported only 85*91f16700Schasinglulufor GIC version 3.0 (Arm GICv3) and only the Secure-EL1 and Non-secure interrupt 86*91f16700Schasinglulutypes are supported for GIC version 2.0 (Arm GICv2) (see `Assumptions in 87*91f16700SchasingluluInterrupt Management Framework`_). The terminology used in the following 88*91f16700Schasinglulusub-sections is explained below. 89*91f16700Schasinglulu 90*91f16700Schasinglulu#. **CSS**. Current Security State. ``0`` when secure and ``1`` when non-secure 91*91f16700Schasinglulu 92*91f16700Schasinglulu#. **TEL3**. Target Exception Level 3. ``0`` when targeted to the FEL. ``1`` when 93*91f16700Schasinglulu targeted to EL3. 94*91f16700Schasinglulu 95*91f16700SchasingluluSecure-EL1 interrupts 96*91f16700Schasinglulu^^^^^^^^^^^^^^^^^^^^^ 97*91f16700Schasinglulu 98*91f16700Schasinglulu#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in 99*91f16700Schasinglulu secure state. This is a valid routing model as secure software is in 100*91f16700Schasinglulu control of handling secure interrupts. 101*91f16700Schasinglulu 102*91f16700Schasinglulu#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in secure 103*91f16700Schasinglulu state. This is a valid routing model as secure software in EL3 can 104*91f16700Schasinglulu handover the interrupt to Secure-EL1 for handling. 105*91f16700Schasinglulu 106*91f16700Schasinglulu#. **CSS=1, TEL3=0**. Interrupt is routed to the FEL when execution is in 107*91f16700Schasinglulu non-secure state. This is an invalid routing model as a secure interrupt 108*91f16700Schasinglulu is not visible to the secure software which violates the motivation behind 109*91f16700Schasinglulu the Arm Security Extensions. 110*91f16700Schasinglulu 111*91f16700Schasinglulu#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in 112*91f16700Schasinglulu non-secure state. This is a valid routing model as secure software in EL3 113*91f16700Schasinglulu can handover the interrupt to Secure-EL1 for handling. 114*91f16700Schasinglulu 115*91f16700SchasingluluNon-secure interrupts 116*91f16700Schasinglulu^^^^^^^^^^^^^^^^^^^^^ 117*91f16700Schasinglulu 118*91f16700Schasinglulu#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in 119*91f16700Schasinglulu secure state. This allows the secure software to trap non-secure 120*91f16700Schasinglulu interrupts, perform its book-keeping and hand the interrupt to the 121*91f16700Schasinglulu non-secure software through EL3. This is a valid routing model as secure 122*91f16700Schasinglulu software is in control of how its execution is preempted by non-secure 123*91f16700Schasinglulu interrupts. 124*91f16700Schasinglulu 125*91f16700Schasinglulu#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in secure 126*91f16700Schasinglulu state. This is a valid routing model as secure software in EL3 can save 127*91f16700Schasinglulu the state of software in Secure-EL1/Secure-EL0 before handing the 128*91f16700Schasinglulu interrupt to non-secure software. This model requires additional 129*91f16700Schasinglulu coordination between Secure-EL1 and EL3 software to ensure that the 130*91f16700Schasinglulu former's state is correctly saved by the latter. 131*91f16700Schasinglulu 132*91f16700Schasinglulu#. **CSS=1, TEL3=0**. Interrupt is routed to FEL when execution is in 133*91f16700Schasinglulu non-secure state. This is a valid routing model as a non-secure interrupt 134*91f16700Schasinglulu is handled by non-secure software. 135*91f16700Schasinglulu 136*91f16700Schasinglulu#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in 137*91f16700Schasinglulu non-secure state. This is an invalid routing model as there is no valid 138*91f16700Schasinglulu reason to route the interrupt to EL3 software and then hand it back to 139*91f16700Schasinglulu non-secure software for handling. 140*91f16700Schasinglulu 141*91f16700Schasinglulu.. _EL3 interrupts: 142*91f16700Schasinglulu 143*91f16700SchasingluluEL3 interrupts 144*91f16700Schasinglulu^^^^^^^^^^^^^^ 145*91f16700Schasinglulu 146*91f16700Schasinglulu#. **CSS=0, TEL3=0**. Interrupt is routed to the FEL when execution is in 147*91f16700Schasinglulu Secure-EL1/Secure-EL0. This is a valid routing model as secure software 148*91f16700Schasinglulu in Secure-EL1/Secure-EL0 is in control of how its execution is preempted 149*91f16700Schasinglulu by EL3 interrupt and can handover the interrupt to EL3 for handling. 150*91f16700Schasinglulu 151*91f16700Schasinglulu However, when ``EL3_EXCEPTION_HANDLING`` is ``1``, this routing model is 152*91f16700Schasinglulu invalid as EL3 interrupts are unconditionally routed to EL3, and EL3 153*91f16700Schasinglulu interrupts will always preempt Secure EL1/EL0 execution. See :ref:`exception 154*91f16700Schasinglulu handling<interrupt-handling>` documentation. 155*91f16700Schasinglulu 156*91f16700Schasinglulu#. **CSS=0, TEL3=1**. Interrupt is routed to EL3 when execution is in 157*91f16700Schasinglulu Secure-EL1/Secure-EL0. This is a valid routing model as secure software 158*91f16700Schasinglulu in EL3 can handle the interrupt. 159*91f16700Schasinglulu 160*91f16700Schasinglulu#. **CSS=1, TEL3=0**. Interrupt is routed to the FEL when execution is in 161*91f16700Schasinglulu non-secure state. This is an invalid routing model as a secure interrupt 162*91f16700Schasinglulu is not visible to the secure software which violates the motivation behind 163*91f16700Schasinglulu the Arm Security Extensions. 164*91f16700Schasinglulu 165*91f16700Schasinglulu#. **CSS=1, TEL3=1**. Interrupt is routed to EL3 when execution is in 166*91f16700Schasinglulu non-secure state. This is a valid routing model as secure software in EL3 167*91f16700Schasinglulu can handle the interrupt. 168*91f16700Schasinglulu 169*91f16700SchasingluluMapping of interrupt type to signal 170*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 171*91f16700Schasinglulu 172*91f16700SchasingluluThe framework is meant to work with any interrupt controller implemented by a 173*91f16700Schasingluluplatform. A interrupt controller could generate a type of interrupt as either an 174*91f16700SchasingluluFIQ or IRQ signal to the CPU depending upon the current security state. The 175*91f16700Schasinglulumapping between the type and signal is known only to the platform. The framework 176*91f16700Schasingluluuses this information to determine whether the IRQ or the FIQ bit should be 177*91f16700Schasingluluprogrammed in ``SCR_EL3`` while applying the routing model for a type of 178*91f16700Schasingluluinterrupt. The platform provides this information through the 179*91f16700Schasinglulu``plat_interrupt_type_to_line()`` API (described in the 180*91f16700Schasinglulu:ref:`Porting Guide`). For example, on the FVP port when the platform uses an 181*91f16700SchasingluluArm GICv2 interrupt controller, Secure-EL1 interrupts are signaled through the 182*91f16700SchasingluluFIQ signal while Non-secure interrupts are signaled through the IRQ signal. 183*91f16700SchasingluluThis applies when execution is in either security state. 184*91f16700Schasinglulu 185*91f16700SchasingluluEffect of mapping of several interrupt types to one signal 186*91f16700Schasinglulu^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 187*91f16700Schasinglulu 188*91f16700SchasingluluIt should be noted that if more than one interrupt type maps to a single 189*91f16700Schasingluluinterrupt signal, and if any one of the interrupt type sets **TEL3=1** for a 190*91f16700Schasingluluparticular security state, then interrupt signal will be routed to EL3 when in 191*91f16700Schasingluluthat security state. This means that all the other interrupt types using the 192*91f16700Schasinglulusame interrupt signal will be forced to the same routing model. This should be 193*91f16700Schasingluluborne in mind when choosing the routing model for an interrupt type. 194*91f16700Schasinglulu 195*91f16700SchasingluluFor example, in Arm GICv3, when the execution context is Secure-EL1/ 196*91f16700SchasingluluSecure-EL0, both the EL3 and the non secure interrupt types map to the FIQ 197*91f16700Schasinglulusignal. So if either one of the interrupt type sets the routing model so 198*91f16700Schasingluluthat **TEL3=1** when **CSS=0**, the FIQ bit in ``SCR_EL3`` will be programmed to 199*91f16700Schasingluluroute the FIQ signal to EL3 when executing in Secure-EL1/Secure-EL0, thereby 200*91f16700Schasinglulueffectively routing the other interrupt type also to EL3. 201*91f16700Schasinglulu 202*91f16700SchasingluluAssumptions in Interrupt Management Framework 203*91f16700Schasinglulu--------------------------------------------- 204*91f16700Schasinglulu 205*91f16700SchasingluluThe framework makes the following assumptions to simplify its implementation. 206*91f16700Schasinglulu 207*91f16700Schasinglulu#. Although the framework has support for 2 types of secure interrupts (EL3 208*91f16700Schasinglulu and Secure-EL1 interrupt), only interrupt controller architectures 209*91f16700Schasinglulu like Arm GICv3 has architectural support for EL3 interrupts in the form of 210*91f16700Schasinglulu Group 0 interrupts. In Arm GICv2, all secure interrupts are assumed to be 211*91f16700Schasinglulu handled in Secure-EL1. They can be delivered to Secure-EL1 via EL3 but they 212*91f16700Schasinglulu cannot be handled in EL3. 213*91f16700Schasinglulu 214*91f16700Schasinglulu#. Interrupt exceptions (``PSTATE.I`` and ``F`` bits) are masked during execution 215*91f16700Schasinglulu in EL3. 216*91f16700Schasinglulu 217*91f16700Schasinglulu#. Interrupt management: the following sections describe how interrupts are 218*91f16700Schasinglulu managed by the interrupt handling framework. This entails: 219*91f16700Schasinglulu 220*91f16700Schasinglulu #. Providing an interface to allow registration of a handler and 221*91f16700Schasinglulu specification of the routing model for a type of interrupt. 222*91f16700Schasinglulu 223*91f16700Schasinglulu #. Implementing support to hand control of an interrupt type to its 224*91f16700Schasinglulu registered handler when the interrupt is generated. 225*91f16700Schasinglulu 226*91f16700SchasingluluBoth aspects of interrupt management involve various components in the secure 227*91f16700Schasinglulusoftware stack spanning from EL3 to Secure-EL1. These components are described 228*91f16700Schasingluluin the section `Software components`_. The framework stores information 229*91f16700Schasingluluassociated with each type of interrupt in the following data structure. 230*91f16700Schasinglulu 231*91f16700Schasinglulu.. code:: c 232*91f16700Schasinglulu 233*91f16700Schasinglulu typedef struct intr_type_desc { 234*91f16700Schasinglulu interrupt_type_handler_t handler; 235*91f16700Schasinglulu uint32_t flags; 236*91f16700Schasinglulu uint32_t scr_el3[2]; 237*91f16700Schasinglulu } intr_type_desc_t; 238*91f16700Schasinglulu 239*91f16700SchasingluluThe ``flags`` field stores the routing model for the interrupt type in 240*91f16700Schasinglulubits[1:0]. Bit[0] stores the routing model when execution is in the secure 241*91f16700Schasinglulustate. Bit[1] stores the routing model when execution is in the non-secure 242*91f16700Schasinglulustate. As mentioned in Section `Routing model`_, a value of ``0`` implies that 243*91f16700Schasingluluthe interrupt should be targeted to the FEL. A value of ``1`` implies that it 244*91f16700Schasinglulushould be targeted to EL3. The remaining bits are reserved and SBZ. The helper 245*91f16700Schasinglulumacro ``set_interrupt_rm_flag()`` should be used to set the bits in the 246*91f16700Schasinglulu``flags`` parameter. 247*91f16700Schasinglulu 248*91f16700SchasingluluThe ``scr_el3[2]`` field also stores the routing model but as a mapping of the 249*91f16700Schasinglulumodel in the ``flags`` field to the corresponding bit in the ``SCR_EL3`` for each 250*91f16700Schasinglulusecurity state. 251*91f16700Schasinglulu 252*91f16700SchasingluluThe framework also depends upon the platform port to configure the interrupt 253*91f16700Schasinglulucontroller to distinguish between secure and non-secure interrupts. The platform 254*91f16700Schasingluluis expected to be aware of the secure devices present in the system and their 255*91f16700Schasingluluassociated interrupt numbers. It should configure the interrupt controller to 256*91f16700Schasingluluenable the secure interrupts, ensure that their priority is always higher than 257*91f16700Schasingluluthe non-secure interrupts and target them to the primary CPU. It should also 258*91f16700Schasingluluexport the interface described in the :ref:`Porting Guide` to enable 259*91f16700Schasingluluhandling of interrupts. 260*91f16700Schasinglulu 261*91f16700SchasingluluIn the remainder of this document, for the sake of simplicity a Arm GICv2 system 262*91f16700Schasingluluis considered and it is assumed that the FIQ signal is used to generate Secure-EL1 263*91f16700Schasingluluinterrupts and the IRQ signal is used to generate non-secure interrupts in either 264*91f16700Schasinglulusecurity state. EL3 interrupts are not considered. 265*91f16700Schasinglulu 266*91f16700SchasingluluSoftware components 267*91f16700Schasinglulu------------------- 268*91f16700Schasinglulu 269*91f16700SchasingluluRoles and responsibilities for interrupt management are sub-divided between the 270*91f16700Schasinglulufollowing components of software running in EL3 and Secure-EL1. Each component is 271*91f16700Schasinglulubriefly described below. 272*91f16700Schasinglulu 273*91f16700Schasinglulu#. EL3 Runtime Firmware. This component is common to all ports of TF-A. 274*91f16700Schasinglulu 275*91f16700Schasinglulu#. Secure Payload Dispatcher (SPD) service. This service interfaces with the 276*91f16700Schasinglulu Secure Payload (SP) software which runs in Secure-EL1/Secure-EL0 and is 277*91f16700Schasinglulu responsible for switching execution between secure and non-secure states. 278*91f16700Schasinglulu A switch is triggered by a Secure Monitor Call and it uses the APIs 279*91f16700Schasinglulu exported by the Context management library to implement this functionality. 280*91f16700Schasinglulu Switching execution between the two security states is a requirement for 281*91f16700Schasinglulu interrupt management as well. This results in a significant dependency on 282*91f16700Schasinglulu the SPD service. TF-A implements an example Test Secure Payload Dispatcher 283*91f16700Schasinglulu (TSPD) service. 284*91f16700Schasinglulu 285*91f16700Schasinglulu An SPD service plugs into the EL3 runtime firmware and could be common to 286*91f16700Schasinglulu some ports of TF-A. 287*91f16700Schasinglulu 288*91f16700Schasinglulu#. Secure Payload (SP). On a production system, the Secure Payload corresponds 289*91f16700Schasinglulu to a Secure OS which runs in Secure-EL1/Secure-EL0. It interfaces with the 290*91f16700Schasinglulu SPD service to manage communication with non-secure software. TF-A 291*91f16700Schasinglulu implements an example secure payload called Test Secure Payload (TSP) 292*91f16700Schasinglulu which runs only in Secure-EL1. 293*91f16700Schasinglulu 294*91f16700Schasinglulu A Secure payload implementation could be common to some ports of TF-A, 295*91f16700Schasinglulu just like the SPD service. 296*91f16700Schasinglulu 297*91f16700SchasingluluInterrupt registration 298*91f16700Schasinglulu---------------------- 299*91f16700Schasinglulu 300*91f16700SchasingluluThis section describes in detail the role of each software component (see 301*91f16700Schasinglulu`Software components`_) during the registration of a handler for an interrupt 302*91f16700Schasinglulutype. 303*91f16700Schasinglulu 304*91f16700Schasinglulu.. _el3-runtime-firmware: 305*91f16700Schasinglulu 306*91f16700SchasingluluEL3 runtime firmware 307*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~ 308*91f16700Schasinglulu 309*91f16700SchasingluluThis component declares the following prototype for a handler of an interrupt type. 310*91f16700Schasinglulu 311*91f16700Schasinglulu.. code:: c 312*91f16700Schasinglulu 313*91f16700Schasinglulu typedef uint64_t (*interrupt_type_handler_t)(uint32_t id, 314*91f16700Schasinglulu uint32_t flags, 315*91f16700Schasinglulu void *handle, 316*91f16700Schasinglulu void *cookie); 317*91f16700Schasinglulu 318*91f16700SchasingluluThe ``id`` is parameter is reserved and could be used in the future for passing 319*91f16700Schasingluluthe interrupt id of the highest pending interrupt only if there is a foolproof 320*91f16700Schasingluluway of determining the id. Currently it contains ``INTR_ID_UNAVAILABLE``. 321*91f16700Schasinglulu 322*91f16700SchasingluluThe ``flags`` parameter contains miscellaneous information as follows. 323*91f16700Schasinglulu 324*91f16700Schasinglulu#. Security state, bit[0]. This bit indicates the security state of the lower 325*91f16700Schasinglulu exception level when the interrupt was generated. A value of ``1`` means 326*91f16700Schasinglulu that it was in the non-secure state. A value of ``0`` indicates that it was 327*91f16700Schasinglulu in the secure state. This bit can be used by the handler to ensure that 328*91f16700Schasinglulu interrupt was generated and routed as per the routing model specified 329*91f16700Schasinglulu during registration. 330*91f16700Schasinglulu 331*91f16700Schasinglulu#. Reserved, bits[31:1]. The remaining bits are reserved for future use. 332*91f16700Schasinglulu 333*91f16700SchasingluluThe ``handle`` parameter points to the ``cpu_context`` structure of the current CPU 334*91f16700Schasinglulufor the security state specified in the ``flags`` parameter. 335*91f16700Schasinglulu 336*91f16700SchasingluluOnce the handler routine completes, execution will return to either the secure 337*91f16700Schasingluluor non-secure state. The handler routine must return a pointer to 338*91f16700Schasinglulu``cpu_context`` structure of the current CPU for the target security state. On 339*91f16700SchasingluluAArch64, this return value is currently ignored by the caller as the 340*91f16700Schasingluluappropriate ``cpu_context`` to be used is expected to be set by the handler 341*91f16700Schasingluluvia the context management library APIs. 342*91f16700SchasingluluA portable interrupt handler implementation must set the target context both in 343*91f16700Schasingluluthe structure pointed to by the returned pointer and via the context management 344*91f16700Schasinglululibrary APIs. The handler should treat all error conditions as critical errors 345*91f16700Schasingluluand take appropriate action within its implementation e.g. use assertion 346*91f16700Schasinglulufailures. 347*91f16700Schasinglulu 348*91f16700SchasingluluThe runtime firmware provides the following API for registering a handler for a 349*91f16700Schasingluluparticular type of interrupt. A Secure Payload Dispatcher service should use 350*91f16700Schasingluluthis API to register a handler for Secure-EL1 and optionally for non-secure 351*91f16700Schasingluluinterrupts. This API also requires the caller to specify the routing model for 352*91f16700Schasingluluthe type of interrupt. 353*91f16700Schasinglulu 354*91f16700Schasinglulu.. code:: c 355*91f16700Schasinglulu 356*91f16700Schasinglulu int32_t register_interrupt_type_handler(uint32_t type, 357*91f16700Schasinglulu interrupt_type_handler handler, 358*91f16700Schasinglulu uint64_t flags); 359*91f16700Schasinglulu 360*91f16700SchasingluluThe ``type`` parameter can be one of the three interrupt types listed above i.e. 361*91f16700Schasinglulu``INTR_TYPE_S_EL1``, ``INTR_TYPE_NS`` & ``INTR_TYPE_EL3``. The ``flags`` parameter 362*91f16700Schasingluluis as described in Section 2. 363*91f16700Schasinglulu 364*91f16700SchasingluluThe function will return ``0`` upon a successful registration. It will return 365*91f16700Schasinglulu``-EALREADY`` in case a handler for the interrupt type has already been 366*91f16700Schasingluluregistered. If the ``type`` is unrecognised or the ``flags`` or the ``handler`` are 367*91f16700Schasingluluinvalid it will return ``-EINVAL``. 368*91f16700Schasinglulu 369*91f16700SchasingluluInterrupt routing is governed by the configuration of the ``SCR_EL3.FIQ/IRQ`` bits 370*91f16700Schasingluluprior to entry into a lower exception level in either security state. The 371*91f16700Schasinglulucontext management library maintains a copy of the ``SCR_EL3`` system register for 372*91f16700Schasinglulueach security state in the ``cpu_context`` structure of each CPU. It exports the 373*91f16700Schasinglulufollowing APIs to let EL3 Runtime Firmware program and retrieve the routing 374*91f16700Schasinglulumodel for each security state for the current CPU. The value of ``SCR_EL3`` stored 375*91f16700Schasingluluin the ``cpu_context`` is used by the ``el3_exit()`` function to program the 376*91f16700Schasinglulu``SCR_EL3`` register prior to returning from the EL3 exception level. 377*91f16700Schasinglulu 378*91f16700Schasinglulu.. code:: c 379*91f16700Schasinglulu 380*91f16700Schasinglulu uint32_t cm_get_scr_el3(uint32_t security_state); 381*91f16700Schasinglulu void cm_write_scr_el3_bit(uint32_t security_state, 382*91f16700Schasinglulu uint32_t bit_pos, 383*91f16700Schasinglulu uint32_t value); 384*91f16700Schasinglulu 385*91f16700Schasinglulu``cm_get_scr_el3()`` returns the value of the ``SCR_EL3`` register for the specified 386*91f16700Schasinglulusecurity state of the current CPU. ``cm_write_scr_el3_bit()`` writes a ``0`` or ``1`` 387*91f16700Schasingluluto the bit specified by ``bit_pos``. ``register_interrupt_type_handler()`` invokes 388*91f16700Schasinglulu``set_routing_model()`` API which programs the ``SCR_EL3`` according to the routing 389*91f16700Schasinglulumodel using the ``cm_get_scr_el3()`` and ``cm_write_scr_el3_bit()`` APIs. 390*91f16700Schasinglulu 391*91f16700SchasingluluIt is worth noting that in the current implementation of the framework, the EL3 392*91f16700Schasingluluruntime firmware is responsible for programming the routing model. The SPD is 393*91f16700Schasingluluresponsible for ensuring that the routing model has been adhered to upon 394*91f16700Schasinglulureceiving an interrupt. 395*91f16700Schasinglulu 396*91f16700Schasinglulu.. _spd-int-registration: 397*91f16700Schasinglulu 398*91f16700SchasingluluSecure payload dispatcher 399*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~ 400*91f16700Schasinglulu 401*91f16700SchasingluluA SPD service is responsible for determining and maintaining the interrupt 402*91f16700Schasinglulurouting model supported by itself and the Secure Payload. It is also responsible 403*91f16700Schasinglulufor ferrying interrupts between secure and non-secure software depending upon 404*91f16700Schasingluluthe routing model. It could determine the routing model at build time or at 405*91f16700Schasingluluruntime. It must use this information to register a handler for each interrupt 406*91f16700Schasinglulutype using the ``register_interrupt_type_handler()`` API in EL3 runtime firmware. 407*91f16700Schasinglulu 408*91f16700SchasingluluIf the routing model is not known to the SPD service at build time, then it must 409*91f16700Schasinglulube provided by the SP as the result of its initialisation. The SPD should 410*91f16700Schasingluluprogram the routing model only after SP initialisation has completed e.g. in the 411*91f16700SchasingluluSPD initialisation function pointed to by the ``bl32_init`` variable. 412*91f16700Schasinglulu 413*91f16700SchasingluluThe SPD should determine the mechanism to pass control to the Secure Payload 414*91f16700Schasingluluafter receiving an interrupt from the EL3 runtime firmware. This information 415*91f16700Schasinglulucould either be provided to the SPD service at build time or by the SP at 416*91f16700Schasingluluruntime. 417*91f16700Schasinglulu 418*91f16700SchasingluluTest secure payload dispatcher behavior 419*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 420*91f16700Schasinglulu 421*91f16700Schasinglulu.. note:: 422*91f16700Schasinglulu Where this document discusses ``TSP_NS_INTR_ASYNC_PREEMPT`` as being 423*91f16700Schasinglulu ``1``, the same results also apply when ``EL3_EXCEPTION_HANDLING`` is ``1``. 424*91f16700Schasinglulu 425*91f16700SchasingluluThe TSPD only handles Secure-EL1 interrupts and is provided with the following 426*91f16700Schasinglulurouting model at build time. 427*91f16700Schasinglulu 428*91f16700Schasinglulu- Secure-EL1 interrupts are routed to EL3 when execution is in non-secure 429*91f16700Schasinglulu state and are routed to the FEL when execution is in the secure state 430*91f16700Schasinglulu i.e **CSS=0, TEL3=0** & **CSS=1, TEL3=1** for Secure-EL1 interrupts 431*91f16700Schasinglulu 432*91f16700Schasinglulu- When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is zero, the default routing 433*91f16700Schasinglulu model is used for non-secure interrupts. They are routed to the FEL in 434*91f16700Schasinglulu either security state i.e **CSS=0, TEL3=0** & **CSS=1, TEL3=0** for 435*91f16700Schasinglulu Non-secure interrupts. 436*91f16700Schasinglulu 437*91f16700Schasinglulu- When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is defined to 1, then the 438*91f16700Schasinglulu non secure interrupts are routed to EL3 when execution is in secure state 439*91f16700Schasinglulu i.e **CSS=0, TEL3=1** for non-secure interrupts. This effectively preempts 440*91f16700Schasinglulu Secure-EL1. The default routing model is used for non secure interrupts in 441*91f16700Schasinglulu non-secure state. i.e **CSS=1, TEL3=0**. 442*91f16700Schasinglulu 443*91f16700SchasingluluIt performs the following actions in the ``tspd_init()`` function to fulfill the 444*91f16700Schasinglulurequirements mentioned earlier. 445*91f16700Schasinglulu 446*91f16700Schasinglulu#. It passes control to the Test Secure Payload to perform its 447*91f16700Schasinglulu initialisation. The TSP provides the address of the vector table 448*91f16700Schasinglulu ``tsp_vectors`` in the SP which also includes the handler for Secure-EL1 449*91f16700Schasinglulu interrupts in the ``sel1_intr_entry`` field. The TSPD passes control to the TSP at 450*91f16700Schasinglulu this address when it receives a Secure-EL1 interrupt. 451*91f16700Schasinglulu 452*91f16700Schasinglulu The handover agreement between the TSP and the TSPD requires that the TSPD 453*91f16700Schasinglulu masks all interrupts (``PSTATE.DAIF`` bits) when it calls 454*91f16700Schasinglulu ``tsp_sel1_intr_entry()``. The TSP has to preserve the callee saved general 455*91f16700Schasinglulu purpose, SP_EL1/Secure-EL0, LR, VFP and system registers. It can use 456*91f16700Schasinglulu ``x0-x18`` to enable its C runtime. 457*91f16700Schasinglulu 458*91f16700Schasinglulu#. The TSPD implements a handler function for Secure-EL1 interrupts. This 459*91f16700Schasinglulu function is registered with the EL3 runtime firmware using the 460*91f16700Schasinglulu ``register_interrupt_type_handler()`` API as follows 461*91f16700Schasinglulu 462*91f16700Schasinglulu .. code:: c 463*91f16700Schasinglulu 464*91f16700Schasinglulu /* Forward declaration */ 465*91f16700Schasinglulu interrupt_type_handler tspd_secure_el1_interrupt_handler; 466*91f16700Schasinglulu int32_t rc, flags = 0; 467*91f16700Schasinglulu set_interrupt_rm_flag(flags, NON_SECURE); 468*91f16700Schasinglulu rc = register_interrupt_type_handler(INTR_TYPE_S_EL1, 469*91f16700Schasinglulu tspd_secure_el1_interrupt_handler, 470*91f16700Schasinglulu flags); 471*91f16700Schasinglulu if (rc) 472*91f16700Schasinglulu panic(); 473*91f16700Schasinglulu 474*91f16700Schasinglulu#. When the build flag ``TSP_NS_INTR_ASYNC_PREEMPT`` is defined to 1, the TSPD 475*91f16700Schasinglulu implements a handler function for non-secure interrupts. This function is 476*91f16700Schasinglulu registered with the EL3 runtime firmware using the 477*91f16700Schasinglulu ``register_interrupt_type_handler()`` API as follows 478*91f16700Schasinglulu 479*91f16700Schasinglulu .. code:: c 480*91f16700Schasinglulu 481*91f16700Schasinglulu /* Forward declaration */ 482*91f16700Schasinglulu interrupt_type_handler tspd_ns_interrupt_handler; 483*91f16700Schasinglulu int32_t rc, flags = 0; 484*91f16700Schasinglulu set_interrupt_rm_flag(flags, SECURE); 485*91f16700Schasinglulu rc = register_interrupt_type_handler(INTR_TYPE_NS, 486*91f16700Schasinglulu tspd_ns_interrupt_handler, 487*91f16700Schasinglulu flags); 488*91f16700Schasinglulu if (rc) 489*91f16700Schasinglulu panic(); 490*91f16700Schasinglulu 491*91f16700Schasinglulu.. _sp-int-registration: 492*91f16700Schasinglulu 493*91f16700SchasingluluSecure payload 494*91f16700Schasinglulu~~~~~~~~~~~~~~ 495*91f16700Schasinglulu 496*91f16700SchasingluluA Secure Payload must implement an interrupt handling framework at Secure-EL1 497*91f16700Schasinglulu(Secure-EL1 IHF) to support its chosen interrupt routing model. Secure payload 498*91f16700Schasingluluexecution will alternate between the below cases. 499*91f16700Schasinglulu 500*91f16700Schasinglulu#. In the code where IRQ, FIQ or both interrupts are enabled, if an interrupt 501*91f16700Schasinglulu type is targeted to the FEL, then it will be routed to the Secure-EL1 502*91f16700Schasinglulu exception vector table. This is defined as the **asynchronous mode** of 503*91f16700Schasinglulu handling interrupts. This mode applies to both Secure-EL1 and non-secure 504*91f16700Schasinglulu interrupts. 505*91f16700Schasinglulu 506*91f16700Schasinglulu#. In the code where both interrupts are disabled, if an interrupt type is 507*91f16700Schasinglulu targeted to the FEL, then execution will eventually migrate to the 508*91f16700Schasinglulu non-secure state. Any non-secure interrupts will be handled as described 509*91f16700Schasinglulu in the routing model where **CSS=1 and TEL3=0**. Secure-EL1 interrupts 510*91f16700Schasinglulu will be routed to EL3 (as per the routing model where **CSS=1 and 511*91f16700Schasinglulu TEL3=1**) where the SPD service will hand them to the SP. This is defined 512*91f16700Schasinglulu as the **synchronous mode** of handling interrupts. 513*91f16700Schasinglulu 514*91f16700SchasingluluThe interrupt handling framework implemented by the SP should support one or 515*91f16700Schasingluluboth these interrupt handling models depending upon the chosen routing model. 516*91f16700Schasinglulu 517*91f16700SchasingluluThe following list briefly describes how the choice of a valid routing model 518*91f16700Schasinglulu(see `Valid routing models`_) effects the implementation of the Secure-EL1 519*91f16700SchasingluluIHF. If the choice of the interrupt routing model is not known to the SPD 520*91f16700Schasingluluservice at compile time, then the SP should pass this information to the SPD 521*91f16700Schasingluluservice at runtime during its initialisation phase. 522*91f16700Schasinglulu 523*91f16700SchasingluluAs mentioned earlier, an Arm GICv2 system is considered and it is assumed that 524*91f16700Schasingluluthe FIQ signal is used to generate Secure-EL1 interrupts and the IRQ signal 525*91f16700Schasingluluis used to generate non-secure interrupts in either security state. 526*91f16700Schasinglulu 527*91f16700SchasingluluSecure payload IHF design w.r.t secure-EL1 interrupts 528*91f16700Schasinglulu^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 529*91f16700Schasinglulu 530*91f16700Schasinglulu#. **CSS=0, TEL3=0**. If ``PSTATE.F=0``, Secure-EL1 interrupts will be 531*91f16700Schasinglulu triggered at one of the Secure-EL1 FIQ exception vectors. The Secure-EL1 532*91f16700Schasinglulu IHF should implement support for handling FIQ interrupts asynchronously. 533*91f16700Schasinglulu 534*91f16700Schasinglulu If ``PSTATE.F=1`` then Secure-EL1 interrupts will be handled as per the 535*91f16700Schasinglulu synchronous interrupt handling model. The SP could implement this scenario 536*91f16700Schasinglulu by exporting a separate entrypoint for Secure-EL1 interrupts to the SPD 537*91f16700Schasinglulu service during the registration phase. The SPD service would also need to 538*91f16700Schasinglulu know the state of the system, general purpose and the ``PSTATE`` registers 539*91f16700Schasinglulu in which it should arrange to return execution to the SP. The SP should 540*91f16700Schasinglulu provide this information in an implementation defined way during the 541*91f16700Schasinglulu registration phase if it is not known to the SPD service at build time. 542*91f16700Schasinglulu 543*91f16700Schasinglulu#. **CSS=1, TEL3=1**. Interrupts are routed to EL3 when execution is in 544*91f16700Schasinglulu non-secure state. They should be handled through the synchronous interrupt 545*91f16700Schasinglulu handling model as described in 1. above. 546*91f16700Schasinglulu 547*91f16700Schasinglulu#. **CSS=0, TEL3=1**. Secure-EL1 interrupts are routed to EL3 when execution 548*91f16700Schasinglulu is in secure state. They will not be visible to the SP. The ``PSTATE.F`` bit 549*91f16700Schasinglulu in Secure-EL1/Secure-EL0 will not mask FIQs. The EL3 runtime firmware will 550*91f16700Schasinglulu call the handler registered by the SPD service for Secure-EL1 interrupts. 551*91f16700Schasinglulu Secure-EL1 IHF should then handle all Secure-EL1 interrupt through the 552*91f16700Schasinglulu synchronous interrupt handling model described in 1. above. 553*91f16700Schasinglulu 554*91f16700SchasingluluSecure payload IHF design w.r.t non-secure interrupts 555*91f16700Schasinglulu^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 556*91f16700Schasinglulu 557*91f16700Schasinglulu#. **CSS=0, TEL3=0**. If ``PSTATE.I=0``, non-secure interrupts will be 558*91f16700Schasinglulu triggered at one of the Secure-EL1 IRQ exception vectors . The Secure-EL1 559*91f16700Schasinglulu IHF should co-ordinate with the SPD service to transfer execution to the 560*91f16700Schasinglulu non-secure state where the interrupt should be handled e.g the SP could 561*91f16700Schasinglulu allocate a function identifier to issue a SMC64 or SMC32 to the SPD 562*91f16700Schasinglulu service which indicates that the SP execution has been preempted by a 563*91f16700Schasinglulu non-secure interrupt. If this function identifier is not known to the SPD 564*91f16700Schasinglulu service at compile time then the SP could provide it during the 565*91f16700Schasinglulu registration phase. 566*91f16700Schasinglulu 567*91f16700Schasinglulu If ``PSTATE.I=1`` then the non-secure interrupt will pend until execution 568*91f16700Schasinglulu resumes in the non-secure state. 569*91f16700Schasinglulu 570*91f16700Schasinglulu#. **CSS=0, TEL3=1**. Non-secure interrupts are routed to EL3. They will not 571*91f16700Schasinglulu be visible to the SP. The ``PSTATE.I`` bit in Secure-EL1/Secure-EL0 will 572*91f16700Schasinglulu have not effect. The SPD service should register a non-secure interrupt 573*91f16700Schasinglulu handler which should save the SP state correctly and resume execution in 574*91f16700Schasinglulu the non-secure state where the interrupt will be handled. The Secure-EL1 575*91f16700Schasinglulu IHF does not need to take any action. 576*91f16700Schasinglulu 577*91f16700Schasinglulu#. **CSS=1, TEL3=0**. Non-secure interrupts are handled in the FEL in 578*91f16700Schasinglulu non-secure state (EL1/EL2) and are not visible to the SP. This routing 579*91f16700Schasinglulu model does not affect the SP behavior. 580*91f16700Schasinglulu 581*91f16700SchasingluluA Secure Payload must also ensure that all Secure-EL1 interrupts are correctly 582*91f16700Schasingluluconfigured at the interrupt controller by the platform port of the EL3 runtime 583*91f16700Schasinglulufirmware. It should configure any additional Secure-EL1 interrupts which the EL3 584*91f16700Schasingluluruntime firmware is not aware of through its platform port. 585*91f16700Schasinglulu 586*91f16700SchasingluluTest secure payload behavior 587*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 588*91f16700Schasinglulu 589*91f16700SchasingluluThe routing model for Secure-EL1 and non-secure interrupts chosen by the TSP is 590*91f16700Schasingluludescribed in Section `Secure Payload Dispatcher`__. It is known to the TSPD 591*91f16700Schasingluluservice at build time. 592*91f16700Schasinglulu 593*91f16700Schasinglulu.. __: #spd-int-registration 594*91f16700Schasinglulu 595*91f16700SchasingluluThe TSP implements an entrypoint (``tsp_sel1_intr_entry()``) for handling Secure-EL1 596*91f16700Schasingluluinterrupts taken in non-secure state and routed through the TSPD service 597*91f16700Schasinglulu(synchronous handling model). It passes the reference to this entrypoint via 598*91f16700Schasinglulu``tsp_vectors`` to the TSPD service. 599*91f16700Schasinglulu 600*91f16700SchasingluluThe TSP also replaces the default exception vector table referenced through the 601*91f16700Schasinglulu``early_exceptions`` variable, with a vector table capable of handling FIQ and IRQ 602*91f16700Schasingluluexceptions taken at the same (Secure-EL1) exception level. This table is 603*91f16700Schasinglulureferenced through the ``tsp_exceptions`` variable and programmed into the 604*91f16700SchasingluluVBAR_EL1. It caters for the asynchronous handling model. 605*91f16700Schasinglulu 606*91f16700SchasingluluThe TSP also programs the Secure Physical Timer in the Arm Generic Timer block 607*91f16700Schasingluluto raise a periodic interrupt (every half a second) for the purpose of testing 608*91f16700Schasingluluinterrupt management across all the software components listed in `Software 609*91f16700Schasinglulucomponents`_. 610*91f16700Schasinglulu 611*91f16700SchasingluluInterrupt handling 612*91f16700Schasinglulu------------------ 613*91f16700Schasinglulu 614*91f16700SchasingluluThis section describes in detail the role of each software component (see 615*91f16700SchasingluluSection `Software components`_) in handling an interrupt of a particular type. 616*91f16700Schasinglulu 617*91f16700SchasingluluEL3 runtime firmware 618*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~ 619*91f16700Schasinglulu 620*91f16700SchasingluluThe EL3 runtime firmware populates the IRQ and FIQ exception vectors referenced 621*91f16700Schasingluluby the ``runtime_exceptions`` variable as follows. 622*91f16700Schasinglulu 623*91f16700Schasinglulu#. IRQ and FIQ exceptions taken from the current exception level with 624*91f16700Schasinglulu ``SP_EL0`` or ``SP_EL3`` are reported as irrecoverable error conditions. As 625*91f16700Schasinglulu mentioned earlier, EL3 runtime firmware always executes with the 626*91f16700Schasinglulu ``PSTATE.I`` and ``PSTATE.F`` bits set. 627*91f16700Schasinglulu 628*91f16700Schasinglulu#. The following text describes how the IRQ and FIQ exceptions taken from a 629*91f16700Schasinglulu lower exception level using AArch64 or AArch32 are handled. 630*91f16700Schasinglulu 631*91f16700SchasingluluWhen an interrupt is generated, the vector for each interrupt type is 632*91f16700Schasingluluresponsible for: 633*91f16700Schasinglulu 634*91f16700Schasinglulu#. Saving the entire general purpose register context (x0-x30) immediately 635*91f16700Schasinglulu upon exception entry. The registers are saved in the per-cpu ``cpu_context`` 636*91f16700Schasinglulu data structure referenced by the ``SP_EL3``\ register. 637*91f16700Schasinglulu 638*91f16700Schasinglulu#. Saving the ``ELR_EL3``, ``SP_EL0`` and ``SPSR_EL3`` system registers in the 639*91f16700Schasinglulu per-cpu ``cpu_context`` data structure referenced by the ``SP_EL3`` register. 640*91f16700Schasinglulu 641*91f16700Schasinglulu#. Switching to the C runtime stack by restoring the ``CTX_RUNTIME_SP`` value 642*91f16700Schasinglulu from the per-cpu ``cpu_context`` data structure in ``SP_EL0`` and 643*91f16700Schasinglulu executing the ``msr spsel, #0`` instruction. 644*91f16700Schasinglulu 645*91f16700Schasinglulu#. Determining the type of interrupt. Secure-EL1 interrupts will be signaled 646*91f16700Schasinglulu at the FIQ vector. Non-secure interrupts will be signaled at the IRQ 647*91f16700Schasinglulu vector. The platform should implement the following API to determine the 648*91f16700Schasinglulu type of the pending interrupt. 649*91f16700Schasinglulu 650*91f16700Schasinglulu .. code:: c 651*91f16700Schasinglulu 652*91f16700Schasinglulu uint32_t plat_ic_get_interrupt_type(void); 653*91f16700Schasinglulu 654*91f16700Schasinglulu It should return either ``INTR_TYPE_S_EL1`` or ``INTR_TYPE_NS``. 655*91f16700Schasinglulu 656*91f16700Schasinglulu#. Determining the handler for the type of interrupt that has been generated. 657*91f16700Schasinglulu The following API has been added for this purpose. 658*91f16700Schasinglulu 659*91f16700Schasinglulu .. code:: c 660*91f16700Schasinglulu 661*91f16700Schasinglulu interrupt_type_handler get_interrupt_type_handler(uint32_t interrupt_type); 662*91f16700Schasinglulu 663*91f16700Schasinglulu It returns the reference to the registered handler for this interrupt 664*91f16700Schasinglulu type. The ``handler`` is retrieved from the ``intr_type_desc_t`` structure as 665*91f16700Schasinglulu described in Section 2. ``NULL`` is returned if no handler has been 666*91f16700Schasinglulu registered for this type of interrupt. This scenario is reported as an 667*91f16700Schasinglulu irrecoverable error condition. 668*91f16700Schasinglulu 669*91f16700Schasinglulu#. Calling the registered handler function for the interrupt type generated. 670*91f16700Schasinglulu The ``id`` parameter is set to ``INTR_ID_UNAVAILABLE`` currently. The id along 671*91f16700Schasinglulu with the current security state and a reference to the ``cpu_context_t`` 672*91f16700Schasinglulu structure for the current security state are passed to the handler function 673*91f16700Schasinglulu as its arguments. 674*91f16700Schasinglulu 675*91f16700Schasinglulu The handler function returns a reference to the per-cpu ``cpu_context_t`` 676*91f16700Schasinglulu structure for the target security state. 677*91f16700Schasinglulu 678*91f16700Schasinglulu#. Calling ``el3_exit()`` to return from EL3 into a lower exception level in 679*91f16700Schasinglulu the security state determined by the handler routine. The ``el3_exit()`` 680*91f16700Schasinglulu function is responsible for restoring the register context from the 681*91f16700Schasinglulu ``cpu_context_t`` data structure for the target security state. 682*91f16700Schasinglulu 683*91f16700SchasingluluSecure payload dispatcher 684*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~ 685*91f16700Schasinglulu 686*91f16700SchasingluluInterrupt entry 687*91f16700Schasinglulu^^^^^^^^^^^^^^^ 688*91f16700Schasinglulu 689*91f16700SchasingluluThe SPD service begins handling an interrupt when the EL3 runtime firmware calls 690*91f16700Schasingluluthe handler function for that type of interrupt. The SPD service is responsible 691*91f16700Schasinglulufor the following: 692*91f16700Schasinglulu 693*91f16700Schasinglulu#. Validating the interrupt. This involves ensuring that the interrupt was 694*91f16700Schasinglulu generated according to the interrupt routing model specified by the SPD 695*91f16700Schasinglulu service during registration. It should use the security state of the 696*91f16700Schasinglulu exception level (passed in the ``flags`` parameter of the handler) where 697*91f16700Schasinglulu the interrupt was taken from to determine this. If the interrupt is not 698*91f16700Schasinglulu recognised then the handler should treat it as an irrecoverable error 699*91f16700Schasinglulu condition. 700*91f16700Schasinglulu 701*91f16700Schasinglulu An SPD service can register a handler for Secure-EL1 and/or Non-secure 702*91f16700Schasinglulu interrupts. A non-secure interrupt should never be routed to EL3 from 703*91f16700Schasinglulu from non-secure state. Also if a routing model is chosen where Secure-EL1 704*91f16700Schasinglulu interrupts are routed to S-EL1 when execution is in Secure state, then a 705*91f16700Schasinglulu S-EL1 interrupt should never be routed to EL3 from secure state. The handler 706*91f16700Schasinglulu could use the security state flag to check this. 707*91f16700Schasinglulu 708*91f16700Schasinglulu#. Determining whether a context switch is required. This depends upon the 709*91f16700Schasinglulu routing model and interrupt type. For non secure and S-EL1 interrupt, 710*91f16700Schasinglulu if the security state of the execution context where the interrupt was 711*91f16700Schasinglulu generated is not the same as the security state required for handling 712*91f16700Schasinglulu the interrupt, a context switch is required. The following 2 cases 713*91f16700Schasinglulu require a context switch from secure to non-secure or vice-versa: 714*91f16700Schasinglulu 715*91f16700Schasinglulu #. A Secure-EL1 interrupt taken from the non-secure state should be 716*91f16700Schasinglulu routed to the Secure Payload. 717*91f16700Schasinglulu 718*91f16700Schasinglulu #. A non-secure interrupt taken from the secure state should be routed 719*91f16700Schasinglulu to the last known non-secure exception level. 720*91f16700Schasinglulu 721*91f16700Schasinglulu The SPD service must save the system register context of the current 722*91f16700Schasinglulu security state. It must then restore the system register context of the 723*91f16700Schasinglulu target security state. It should use the ``cm_set_next_eret_context()`` API 724*91f16700Schasinglulu to ensure that the next ``cpu_context`` to be restored is of the target 725*91f16700Schasinglulu security state. 726*91f16700Schasinglulu 727*91f16700Schasinglulu If the target state is secure then execution should be handed to the SP as 728*91f16700Schasinglulu per the synchronous interrupt handling model it implements. A Secure-EL1 729*91f16700Schasinglulu interrupt can be routed to EL3 while execution is in the SP. This implies 730*91f16700Schasinglulu that SP execution can be preempted while handling an interrupt by a 731*91f16700Schasinglulu another higher priority Secure-EL1 interrupt or a EL3 interrupt. The SPD 732*91f16700Schasinglulu service should be able to handle this preemption or manage secure interrupt 733*91f16700Schasinglulu priorities before handing control to the SP. 734*91f16700Schasinglulu 735*91f16700Schasinglulu#. Setting the return value of the handler to the per-cpu ``cpu_context`` if 736*91f16700Schasinglulu the interrupt has been successfully validated and ready to be handled at a 737*91f16700Schasinglulu lower exception level. 738*91f16700Schasinglulu 739*91f16700SchasingluluThe routing model allows non-secure interrupts to interrupt Secure-EL1 when in 740*91f16700Schasinglulusecure state if it has been configured to do so. The SPD service and the SP 741*91f16700Schasinglulushould implement a mechanism for routing these interrupts to the last known 742*91f16700Schasingluluexception level in the non-secure state. The former should save the SP context, 743*91f16700Schasinglulurestore the non-secure context and arrange for entry into the non-secure state 744*91f16700Schasingluluso that the interrupt can be handled. 745*91f16700Schasinglulu 746*91f16700SchasingluluInterrupt exit 747*91f16700Schasinglulu^^^^^^^^^^^^^^ 748*91f16700Schasinglulu 749*91f16700SchasingluluWhen the Secure Payload has finished handling a Secure-EL1 interrupt, it could 750*91f16700Schasinglulureturn control back to the SPD service through a SMC32 or SMC64. The SPD service 751*91f16700Schasinglulushould handle this secure monitor call so that execution resumes in the 752*91f16700Schasingluluexception level and the security state from where the Secure-EL1 interrupt was 753*91f16700Schasingluluoriginally taken. 754*91f16700Schasinglulu 755*91f16700SchasingluluTest secure payload dispatcher Secure-EL1 interrupt handling 756*91f16700Schasinglulu^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 757*91f16700Schasinglulu 758*91f16700SchasingluluThe example TSPD service registers a handler for Secure-EL1 interrupts taken 759*91f16700Schasinglulufrom the non-secure state. During execution in S-EL1, the TSPD expects that the 760*91f16700SchasingluluSecure-EL1 interrupts are handled in S-EL1 by TSP. Its handler 761*91f16700Schasinglulu``tspd_secure_el1_interrupt_handler()`` expects only to be invoked for Secure-EL1 762*91f16700Schasingluluoriginating from the non-secure state. It takes the following actions upon being 763*91f16700Schasingluluinvoked. 764*91f16700Schasinglulu 765*91f16700Schasinglulu#. It uses the security state provided in the ``flags`` parameter to ensure 766*91f16700Schasinglulu that the secure interrupt originated from the non-secure state. It asserts 767*91f16700Schasinglulu if this is not the case. 768*91f16700Schasinglulu 769*91f16700Schasinglulu#. It saves the system register context for the non-secure state by calling 770*91f16700Schasinglulu ``cm_el1_sysregs_context_save(NON_SECURE);``. 771*91f16700Schasinglulu 772*91f16700Schasinglulu#. It sets the ``ELR_EL3`` system register to ``tsp_sel1_intr_entry`` and sets the 773*91f16700Schasinglulu ``SPSR_EL3.DAIF`` bits in the secure CPU context. It sets ``x0`` to 774*91f16700Schasinglulu ``TSP_HANDLE_SEL1_INTR_AND_RETURN``. If the TSP was preempted earlier by a non 775*91f16700Schasinglulu secure interrupt during ``yielding`` SMC processing, save the registers that 776*91f16700Schasinglulu will be trashed, which is the ``ELR_EL3`` and ``SPSR_EL3``, in order to be able 777*91f16700Schasinglulu to re-enter TSP for Secure-EL1 interrupt processing. It does not need to 778*91f16700Schasinglulu save any other secure context since the TSP is expected to preserve it 779*91f16700Schasinglulu (see section `Test secure payload dispatcher behavior`_). 780*91f16700Schasinglulu 781*91f16700Schasinglulu#. It restores the system register context for the secure state by calling 782*91f16700Schasinglulu ``cm_el1_sysregs_context_restore(SECURE);``. 783*91f16700Schasinglulu 784*91f16700Schasinglulu#. It ensures that the secure CPU context is used to program the next 785*91f16700Schasinglulu exception return from EL3 by calling ``cm_set_next_eret_context(SECURE);``. 786*91f16700Schasinglulu 787*91f16700Schasinglulu#. It returns the per-cpu ``cpu_context`` to indicate that the interrupt can 788*91f16700Schasinglulu now be handled by the SP. ``x1`` is written with the value of ``elr_el3`` 789*91f16700Schasinglulu register for the non-secure state. This information is used by the SP for 790*91f16700Schasinglulu debugging purposes. 791*91f16700Schasinglulu 792*91f16700SchasingluluThe figure below describes how the interrupt handling is implemented by the TSPD 793*91f16700Schasingluluwhen a Secure-EL1 interrupt is generated when execution is in the non-secure 794*91f16700Schasinglulustate. 795*91f16700Schasinglulu 796*91f16700Schasinglulu|Image 1| 797*91f16700Schasinglulu 798*91f16700SchasingluluThe TSP issues an SMC with ``TSP_HANDLED_S_EL1_INTR`` as the function identifier to 799*91f16700Schasinglulusignal completion of interrupt handling. 800*91f16700Schasinglulu 801*91f16700SchasingluluThe TSPD service takes the following actions in ``tspd_smc_handler()`` function 802*91f16700Schasingluluupon receiving an SMC with ``TSP_HANDLED_S_EL1_INTR`` as the function identifier: 803*91f16700Schasinglulu 804*91f16700Schasinglulu#. It ensures that the call originated from the secure state otherwise 805*91f16700Schasinglulu execution returns to the non-secure state with ``SMC_UNK`` in ``x0``. 806*91f16700Schasinglulu 807*91f16700Schasinglulu#. It restores the saved ``ELR_EL3`` and ``SPSR_EL3`` system registers back to 808*91f16700Schasinglulu the secure CPU context (see step 3 above) in case the TSP had been preempted 809*91f16700Schasinglulu by a non secure interrupt earlier. 810*91f16700Schasinglulu 811*91f16700Schasinglulu#. It restores the system register context for the non-secure state by 812*91f16700Schasinglulu calling ``cm_el1_sysregs_context_restore(NON_SECURE)``. 813*91f16700Schasinglulu 814*91f16700Schasinglulu#. It ensures that the non-secure CPU context is used to program the next 815*91f16700Schasinglulu exception return from EL3 by calling ``cm_set_next_eret_context(NON_SECURE)``. 816*91f16700Schasinglulu 817*91f16700Schasinglulu#. ``tspd_smc_handler()`` returns a reference to the non-secure ``cpu_context`` 818*91f16700Schasinglulu as the return value. 819*91f16700Schasinglulu 820*91f16700SchasingluluTest secure payload dispatcher non-secure interrupt handling 821*91f16700Schasinglulu^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 822*91f16700Schasinglulu 823*91f16700SchasingluluThe TSP in Secure-EL1 can be preempted by a non-secure interrupt during 824*91f16700Schasinglulu``yielding`` SMC processing or by a higher priority EL3 interrupt during 825*91f16700SchasingluluSecure-EL1 interrupt processing. When ``EL3_EXCEPTION_HANDLING`` is ``0``, only 826*91f16700Schasinglulunon-secure interrupts can cause preemption of TSP since there are no EL3 827*91f16700Schasingluluinterrupts in the system. With ``EL3_EXCEPTION_HANDLING=1`` however, any EL3 828*91f16700Schasingluluinterrupt may preempt Secure execution. 829*91f16700Schasinglulu 830*91f16700SchasingluluIt should be noted that while TSP is preempted, the TSPD only allows entry into 831*91f16700Schasingluluthe TSP either for Secure-EL1 interrupt handling or for resuming the preempted 832*91f16700Schasinglulu``yielding`` SMC in response to the ``TSP_FID_RESUME`` SMC from the normal world. 833*91f16700Schasinglulu(See Section `Implication of preempted SMC on Non-Secure Software`_). 834*91f16700Schasinglulu 835*91f16700SchasingluluThe non-secure interrupt triggered in Secure-EL1 during ``yielding`` SMC 836*91f16700Schasingluluprocessing can be routed to either EL3 or Secure-EL1 and is controlled by build 837*91f16700Schasingluluoption ``TSP_NS_INTR_ASYNC_PREEMPT`` (see Section `Test secure payload 838*91f16700Schasingluludispatcher behavior`_). If the build option is set, the TSPD will set the 839*91f16700Schasinglulurouting model for the non-secure interrupt to be routed to EL3 from secure state 840*91f16700Schasinglului.e. **TEL3=1, CSS=0** and registers ``tspd_ns_interrupt_handler()`` as the 841*91f16700Schasinglulunon-secure interrupt handler. The ``tspd_ns_interrupt_handler()`` on being 842*91f16700Schasingluluinvoked ensures that the interrupt originated from the secure state and disables 843*91f16700Schasinglulurouting of non-secure interrupts from secure state to EL3. This is to prevent 844*91f16700Schasinglulufurther preemption (by a non-secure interrupt) when TSP is reentered for 845*91f16700Schasingluluhandling Secure-EL1 interrupts that triggered while execution was in the normal 846*91f16700Schasingluluworld. The ``tspd_ns_interrupt_handler()`` then invokes 847*91f16700Schasinglulu``tspd_handle_sp_preemption()`` for further handling. 848*91f16700Schasinglulu 849*91f16700SchasingluluIf the ``TSP_NS_INTR_ASYNC_PREEMPT`` build option is zero (default), the default 850*91f16700Schasinglulurouting model for non-secure interrupt in secure state is in effect 851*91f16700Schasinglului.e. **TEL3=0, CSS=0**. During ``yielding`` SMC processing, the IRQ 852*91f16700Schasingluluexceptions are unmasked i.e. ``PSTATE.I=0``, and a non-secure interrupt will 853*91f16700Schasinglulutrigger at Secure-EL1 IRQ exception vector. The TSP saves the general purpose 854*91f16700Schasingluluregister context and issues an SMC with ``TSP_PREEMPTED`` as the function 855*91f16700Schasingluluidentifier to signal preemption of TSP. The TSPD SMC handler, 856*91f16700Schasinglulu``tspd_smc_handler()``, ensures that the SMC call originated from the 857*91f16700Schasinglulusecure state otherwise execution returns to the non-secure state with 858*91f16700Schasinglulu``SMC_UNK`` in ``x0``. It then invokes ``tspd_handle_sp_preemption()`` for 859*91f16700Schasinglulufurther handling. 860*91f16700Schasinglulu 861*91f16700SchasingluluThe ``tspd_handle_sp_preemption()`` takes the following actions upon being 862*91f16700Schasingluluinvoked: 863*91f16700Schasinglulu 864*91f16700Schasinglulu#. It saves the system register context for the secure state by calling 865*91f16700Schasinglulu ``cm_el1_sysregs_context_save(SECURE)``. 866*91f16700Schasinglulu 867*91f16700Schasinglulu#. It restores the system register context for the non-secure state by 868*91f16700Schasinglulu calling ``cm_el1_sysregs_context_restore(NON_SECURE)``. 869*91f16700Schasinglulu 870*91f16700Schasinglulu#. It ensures that the non-secure CPU context is used to program the next 871*91f16700Schasinglulu exception return from EL3 by calling ``cm_set_next_eret_context(NON_SECURE)``. 872*91f16700Schasinglulu 873*91f16700Schasinglulu#. ``SMC_PREEMPTED`` is set in x0 and return to non secure state after 874*91f16700Schasinglulu restoring non secure context. 875*91f16700Schasinglulu 876*91f16700SchasingluluThe Normal World is expected to resume the TSP after the ``yielding`` SMC 877*91f16700Schasinglulupreemption by issuing an SMC with ``TSP_FID_RESUME`` as the function identifier 878*91f16700Schasinglulu(see section `Implication of preempted SMC on Non-Secure Software`_). The TSPD 879*91f16700Schasingluluservice takes the following actions in ``tspd_smc_handler()`` function upon 880*91f16700Schasinglulureceiving this SMC: 881*91f16700Schasinglulu 882*91f16700Schasinglulu#. It ensures that the call originated from the non secure state. An 883*91f16700Schasinglulu assertion is raised otherwise. 884*91f16700Schasinglulu 885*91f16700Schasinglulu#. Checks whether the TSP needs a resume i.e check if it was preempted. It 886*91f16700Schasinglulu then saves the system register context for the non-secure state by calling 887*91f16700Schasinglulu ``cm_el1_sysregs_context_save(NON_SECURE)``. 888*91f16700Schasinglulu 889*91f16700Schasinglulu#. Restores the secure context by calling 890*91f16700Schasinglulu ``cm_el1_sysregs_context_restore(SECURE)`` 891*91f16700Schasinglulu 892*91f16700Schasinglulu#. It ensures that the secure CPU context is used to program the next 893*91f16700Schasinglulu exception return from EL3 by calling ``cm_set_next_eret_context(SECURE)``. 894*91f16700Schasinglulu 895*91f16700Schasinglulu#. ``tspd_smc_handler()`` returns a reference to the secure ``cpu_context`` as the 896*91f16700Schasinglulu return value. 897*91f16700Schasinglulu 898*91f16700SchasingluluThe figure below describes how the TSP/TSPD handle a non-secure interrupt when 899*91f16700Schasingluluit is generated during execution in the TSP with ``PSTATE.I`` = 0 when the 900*91f16700Schasinglulu``TSP_NS_INTR_ASYNC_PREEMPT`` build flag is 0. 901*91f16700Schasinglulu 902*91f16700Schasinglulu|Image 2| 903*91f16700Schasinglulu 904*91f16700Schasinglulu.. _sp-synchronous-int: 905*91f16700Schasinglulu 906*91f16700SchasingluluSecure payload interrupt handling 907*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 908*91f16700Schasinglulu 909*91f16700SchasingluluThe SP should implement one or both of the synchronous and asynchronous 910*91f16700Schasingluluinterrupt handling models depending upon the interrupt routing model it has 911*91f16700Schasingluluchosen (as described in section :ref:`Secure Payload <sp-int-registration>`). 912*91f16700Schasinglulu 913*91f16700SchasingluluIn the synchronous model, it should begin handling a Secure-EL1 interrupt after 914*91f16700Schasinglulureceiving control from the SPD service at an entrypoint agreed upon during build 915*91f16700Schasinglulutime or during the registration phase. Before handling the interrupt, the SP 916*91f16700Schasinglulushould save any Secure-EL1 system register context which is needed for resuming 917*91f16700Schasinglulunormal execution in the SP later e.g. ``SPSR_EL1``, ``ELR_EL1``. After handling 918*91f16700Schasingluluthe interrupt, the SP could return control back to the exception level and 919*91f16700Schasinglulusecurity state where the interrupt was originally taken from. The SP should use 920*91f16700Schasingluluan SMC32 or SMC64 to ask the SPD service to do this. 921*91f16700Schasinglulu 922*91f16700SchasingluluIn the asynchronous model, the Secure Payload is responsible for handling 923*91f16700Schasinglulunon-secure and Secure-EL1 interrupts at the IRQ and FIQ vectors in its exception 924*91f16700Schasingluluvector table when ``PSTATE.I`` and ``PSTATE.F`` bits are 0. As described earlier, 925*91f16700Schasingluluwhen a non-secure interrupt is generated, the SP should coordinate with the SPD 926*91f16700Schasingluluservice to pass control back to the non-secure state in the last known exception 927*91f16700Schasinglululevel. This will allow the non-secure interrupt to be handled in the non-secure 928*91f16700Schasinglulustate. 929*91f16700Schasinglulu 930*91f16700SchasingluluTest secure payload behavior 931*91f16700Schasinglulu^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 932*91f16700Schasinglulu 933*91f16700SchasingluluThe TSPD hands control of a Secure-EL1 interrupt to the TSP at the 934*91f16700Schasinglulu``tsp_sel1_intr_entry()``. The TSP handles the interrupt while ensuring that the 935*91f16700Schasingluluhandover agreement described in Section `Test secure payload dispatcher 936*91f16700Schasinglulubehavior`_ is maintained. It updates some statistics by calling 937*91f16700Schasinglulu``tsp_update_sync_sel1_intr_stats()``. It then calls 938*91f16700Schasinglulu``tsp_common_int_handler()`` which. 939*91f16700Schasinglulu 940*91f16700Schasinglulu#. Checks whether the interrupt is the secure physical timer interrupt. It 941*91f16700Schasinglulu uses the platform API ``plat_ic_get_pending_interrupt_id()`` to get the 942*91f16700Schasinglulu interrupt number. If it is not the secure physical timer interrupt, then 943*91f16700Schasinglulu that means that a higher priority interrupt has preempted it. Invoke 944*91f16700Schasinglulu ``tsp_handle_preemption()`` to handover control back to EL3 by issuing 945*91f16700Schasinglulu an SMC with ``TSP_PREEMPTED`` as the function identifier. 946*91f16700Schasinglulu 947*91f16700Schasinglulu#. Handles the secure timer interrupt interrupt by acknowledging it using the 948*91f16700Schasinglulu ``plat_ic_acknowledge_interrupt()`` platform API, calling 949*91f16700Schasinglulu ``tsp_generic_timer_handler()`` to reprogram the secure physical generic 950*91f16700Schasinglulu timer and calling the ``plat_ic_end_of_interrupt()`` platform API to signal 951*91f16700Schasinglulu end of interrupt processing. 952*91f16700Schasinglulu 953*91f16700SchasingluluThe TSP passes control back to the TSPD by issuing an SMC64 with 954*91f16700Schasinglulu``TSP_HANDLED_S_EL1_INTR`` as the function identifier. 955*91f16700Schasinglulu 956*91f16700SchasingluluThe TSP handles interrupts under the asynchronous model as follows. 957*91f16700Schasinglulu 958*91f16700Schasinglulu#. Secure-EL1 interrupts are handled by calling the ``tsp_common_int_handler()`` 959*91f16700Schasinglulu function. The function has been described above. 960*91f16700Schasinglulu 961*91f16700Schasinglulu#. Non-secure interrupts are handled by calling the ``tsp_common_int_handler()`` 962*91f16700Schasinglulu function which ends up invoking ``tsp_handle_preemption()`` and issuing an 963*91f16700Schasinglulu SMC64 with ``TSP_PREEMPTED`` as the function identifier. Execution resumes at 964*91f16700Schasinglulu the instruction that follows this SMC instruction when the TSPD hands control 965*91f16700Schasinglulu to the TSP in response to an SMC with ``TSP_FID_RESUME`` as the function 966*91f16700Schasinglulu identifier from the non-secure state (see section `Test secure payload 967*91f16700Schasinglulu dispatcher non-secure interrupt handling`_). 968*91f16700Schasinglulu 969*91f16700SchasingluluOther considerations 970*91f16700Schasinglulu-------------------- 971*91f16700Schasinglulu 972*91f16700SchasingluluImplication of preempted SMC on Non-Secure Software 973*91f16700Schasinglulu~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 974*91f16700Schasinglulu 975*91f16700SchasingluluA ``yielding`` SMC call to Secure payload can be preempted by a non-secure 976*91f16700Schasingluluinterrupt and the execution can return to the non-secure world for handling 977*91f16700Schasingluluthe interrupt (For details on ``yielding`` SMC refer `SMC calling convention`_). 978*91f16700SchasingluluIn this case, the SMC call has not completed its execution and the execution 979*91f16700Schasinglulumust return back to the secure payload to resume the preempted SMC call. 980*91f16700SchasingluluThis can be achieved by issuing an SMC call which instructs to resume the 981*91f16700Schasinglulupreempted SMC. 982*91f16700Schasinglulu 983*91f16700SchasingluluA ``fast`` SMC cannot be preempted and hence this case will not happen for 984*91f16700Schasinglulua fast SMC call. 985*91f16700Schasinglulu 986*91f16700SchasingluluIn the Test Secure Payload implementation, ``TSP_FID_RESUME`` is designated 987*91f16700Schasingluluas the resume SMC FID. It is important to note that ``TSP_FID_RESUME`` is a 988*91f16700Schasinglulu``yielding`` SMC which means it too can be be preempted. The typical non 989*91f16700Schasinglulusecure software sequence for issuing a ``yielding`` SMC would look like this, 990*91f16700Schasingluluassuming ``P.STATE.I=0`` in the non secure state : 991*91f16700Schasinglulu 992*91f16700Schasinglulu.. code:: c 993*91f16700Schasinglulu 994*91f16700Schasinglulu int rc; 995*91f16700Schasinglulu rc = smc(TSP_YIELD_SMC_FID, ...); /* Issue a Yielding SMC call */ 996*91f16700Schasinglulu /* The pending non-secure interrupt is handled by the interrupt handler 997*91f16700Schasinglulu and returns back here. */ 998*91f16700Schasinglulu while (rc == SMC_PREEMPTED) { /* Check if the SMC call is preempted */ 999*91f16700Schasinglulu rc = smc(TSP_FID_RESUME); /* Issue resume SMC call */ 1000*91f16700Schasinglulu } 1001*91f16700Schasinglulu 1002*91f16700SchasingluluThe ``TSP_YIELD_SMC_FID`` is any ``yielding`` SMC function identifier and the smc() 1003*91f16700Schasinglulufunction invokes a SMC call with the required arguments. The pending non-secure 1004*91f16700Schasingluluinterrupt causes an IRQ exception and the IRQ handler registered at the 1005*91f16700Schasingluluexception vector handles the non-secure interrupt and returns. The return value 1006*91f16700Schasinglulufrom the SMC call is tested for ``SMC_PREEMPTED`` to check whether it is 1007*91f16700Schasinglulupreempted. If it is, then the resume SMC call ``TSP_FID_RESUME`` is issued. The 1008*91f16700Schasinglulureturn value of the SMC call is tested again to check if it is preempted. 1009*91f16700SchasingluluThis is done in a loop till the SMC call succeeds or fails. If a ``yielding`` 1010*91f16700SchasingluluSMC is preempted, until it is resumed using ``TSP_FID_RESUME`` SMC and 1011*91f16700Schasinglulucompleted, the current TSPD prevents any other SMC call from re-entering 1012*91f16700SchasingluluTSP by returning ``SMC_UNK`` error. 1013*91f16700Schasinglulu 1014*91f16700Schasinglulu-------------- 1015*91f16700Schasinglulu 1016*91f16700Schasinglulu*Copyright (c) 2014-2020, Arm Limited and Contributors. All rights reserved.* 1017*91f16700Schasinglulu 1018*91f16700Schasinglulu.. _SMC calling convention: https://developer.arm.com/docs/den0028/latest 1019*91f16700Schasinglulu 1020*91f16700Schasinglulu.. |Image 1| image:: ../resources/diagrams/sec-int-handling.png 1021*91f16700Schasinglulu.. |Image 2| image:: ../resources/diagrams/non-sec-int-handling.png 1022