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