xref: /rk3399_ARM-atf/docs/design/interrupt-framework-design.rst (revision 40d553cfde38d4f68449c62967cd1ce0d6478750)
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