xref: /arm-trusted-firmware/docs/design/interrupt-framework-design.rst (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
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