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