blob: bde9a258853c1eb56747efaa8ebe1466cff76eb7 [file] [log] [blame]
Mate Toth-Pal4341de02018-10-02 12:55:47 +02001###################
2Secure IRQ handling
3###################
4
5The Armv8-M Architecture makes it possible to configure interrupts to target
6secure state.
7
8TF-M makes it possible for secure partitions to get notified of secure
9interrupts.
10
11By default TF-M sets up interrupts to target NS state. To configure an interrupt
12to target secure state and assign a handler to it, the manifest of the partition
13must be edited.
14
15See the following example:
16
17
18.. code-block:: yaml
19
20 {
21 "name": "...",
22 "type": "...",
23 "priority": "...",
24
25 ...
26
27 "irqs": [
28 {
Jaykumar Pitambarbhai Patelb3799e12019-10-08 17:23:12 +053029 "source": "5",
Mate Toth-Pal4341de02018-10-02 12:55:47 +020030 "signal": "DUAL_TIMER"
31 },
32 {
Jaykumar Pitambarbhai Patelb3799e12019-10-08 17:23:12 +053033 "source": "TFM_IRQ_LINE_TIMER_1",
Mate Toth-Pal4341de02018-10-02 12:55:47 +020034 "signal": "TIMER_1"
35 "tfm_irq_priority": 64,
36 }
37 ],
38
39 ...
40
41 }
42
43To set up a handler in a partition, the ``irqs`` node must be added. A single
44secure partition can have handlers registered for multiple IRQs, in this case
45the list ``irqs`` has multiple elements in it.
46
47An IRQ handler is defined by the following nodes:
48
Jaykumar Pitambarbhai Patelb3799e12019-10-08 17:23:12 +053049- ``source``: The IRQ number or the name IRQ line. With the name of the IRQ
50 line, there must be defined a macro in ``tfm_peripherals_def.h`` which is
51 substituted to the IRQ line num.
Mate Toth-Pal4341de02018-10-02 12:55:47 +020052- ``signal`` The name of the signal for this IRQ
53- ``tfm_irq_priority``: The priority of the IRQ. This number must be in the
54 range [0-255] inclusive. Please note that some of the less significant bits of
55 this value might be dropped based on the number of priority bits implemented
56 in the platform.
57
58.. important::
59
60 The name of the privileged interrupt handler is derived from the node
61 specifying the IRQ line number.
62
Jaykumar Pitambarbhai Patelb3799e12019-10-08 17:23:12 +053063 - In case ``source`` is IRQ number, the name of the handler becomes
64 ``void irq_<number>_Handler(void)``.
65 - In case ``source`` is defined IRQ macro, the name of the handler becomes
66 ``void <macro>_Handler(void)``.
Mate Toth-Pal4341de02018-10-02 12:55:47 +020067
68 This is important, because the derived name have to be present in the vector
69 table as the handler of the IRQ.
70
71.. Note::
72
Jaykumar Pitambarbhai Patelb3799e12019-10-08 17:23:12 +053073 ``signal`` and ``source`` are mandatory.
Mate Toth-Pal4341de02018-10-02 12:55:47 +020074
75 ``tfm_irq_priority`` is optional. If ``tfm_irq_priority`` is not set for an
76 IRQ, the default is value is ``TFM_DEFAULT_SECURE_IRQ_PRIOTITY``.
77
78If an IRQ handler is registered, TF-M will:
79
Jaykumar Pitambarbhai Patelb3799e12019-10-08 17:23:12 +053080- Set the IRQ with number or macro to target secure state
81- Set the priority of IRQ with number or macro to ``tfm_irq_priority`` or to
82 the default.
Mate Toth-Pal4341de02018-10-02 12:55:47 +020083
84TF-M configures the interrupt lines to be disabled by default. Interrupts for a
85service can be enabled by the secure service by calling
86``void tfm_enable_irq(psa_signal_t irq_signal)``. The function can be called in
87the service init function.
88
Mate Toth-Pal4341de02018-10-02 12:55:47 +020089Library model
Galanakis, Minoscc8cde72019-11-11 15:41:23 +000090=============
Mate Toth-Pal4341de02018-10-02 12:55:47 +020091
92In Library model a function with the name derived from the value of the
Jaykumar Pitambarbhai Patelb3799e12019-10-08 17:23:12 +053093``source`` property is generated. This function will be put in the vector table
94by the linker (as the handlers in the startup assembly are defined as weak
95symbols). The code generated for this function will forward the call to the
96function with the name of the value of the ``signal`` property post-fixed with
97``_isr``.
Mate Toth-Pal4341de02018-10-02 12:55:47 +020098
99.. hint::
100
101 for a signal ``"signal": "DUAL_TIMER"`` the name of the handler function is
102 ``DUAL_TIMER_isr``
103
104The signature of the IRQ handler in the partition must be the following:
105
106.. code-block:: c
107
108 void partition_irq_handler(void);
109
110The detailed description on how secure interrupt handling works in the Library
111model see
112`Secure Partition Interrupt Handling design document <https://developer.trustedfirmware.org/w/tf_m/design/secure_partition_interrupt_handling/>`_.
113
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200114IPC model
Galanakis, Minoscc8cde72019-11-11 15:41:23 +0000115=========
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200116
117The detailed description on how secure interrupt handling works in the IPC
118model, see the
119`PSA Firmware Framework and RoT Services specification <https://pages.arm.com/psa-resources-ff.html>`_.
120
Galanakis, Minoscc8cde72019-11-11 15:41:23 +0000121**********************
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200122Implementation details
Galanakis, Minoscc8cde72019-11-11 15:41:23 +0000123**********************
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200124
Galanakis, Minosf56baf62019-11-11 13:57:42 +0000125Library model implementation
Galanakis, Minoscc8cde72019-11-11 15:41:23 +0000126============================
Mate Toth-Pal4341de02018-10-02 12:55:47 +0200127
128As a result of the function call like behaviour of secure services in library
129model, some information that is critical for the SPM to keep track of partition
130states, is stored on the stack of the active partitions. When an interrupt
131happens, and a handler partition is set to running state, it has access to its
132whole stack, and could corrupt the data stacked by the SPM. To prevent this, a
133separate Context stack is introduced for each secure partition, that is used by
134the SPM to save this information before starting to execute secure partition
135code.
136
137A stack frame to this context stack is pushed when the execution in the
138partition is interrupted, and when a handler in the partition interrupts another
139service. So the maximal stack usage can happen in the following situation:
140
141Consider secure partition 'A'. 'A' is running, and then it is interrupted by
142an other partition. Then the lowest priority interrupt of 'A' is triggered.
143Then before the handler returns, the partition is interrupted by another
144partition's handler. Then before the running handler returns, the second
145lowest interrupt of 'A' is triggered. This can go until the highest priority
146interrupt of 'A' is triggered, and then this last handler is interrupted. At
147this point the context stack looks like this:
148
149.. code-block::
150
151 +------------+
152 | [intr_ctx] |
153 | [hndl_ctx] |
154 | . |
155 | . |
156 | . |
157 | [intr_ctx] |
158 | [hndl_ctx] |
159 | [intr_ctx] |
160 +------------+
161
162 Legend:
163 [intr_ctx]: Frame pushed when the partition is interrupted
164 [hndl_ctx]: Frame pushed when the partition is handling an interrupt
165
166So the max stack size can be calculated as a function of the IRQ count of 'A':
167
168.. code-block::
169
170
171 max_stack_size = intr_ctx_size + (IRQ_CNT * (intr_ctx_size + hndl_ctx_size))
172
173--------------
174
175*Copyright (c) 2018-2019, Arm Limited. All rights reserved.*