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