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