1################################
2TF-M Inter-Process Communication
3################################
4
5:Authors: Ken Liu, Mingyang Sun
6:Organization: Arm Limited
7
8***********
9Terminology
10***********
11
12IPC - Inter-Process Communication
13
14For more terminology please check Reference_ document.
15
16***************
17Design Overview
18***************
19Components for implementing IPC:
20
21- SPM – for partition information and isolation actions
22- Core – for exception handling
23- Memory pool
24- Message manager
25- Thread
26- Synchronization objects
27- PSA API
28
29**********************
30Implementation Details
31**********************
32Listed modules are all internal modules except PSA API. Prototypes and
33definitions are not listed for internal modules in this document. For PSA
34API definitions, check them in PSA Firmware Framework specification in the
35reference chapter.
36
37SPM and Core
38============
39SPM manages Secure Partition information. Enhancements need to be done in SPM
40data structure for Secure Partition for IPC due to:
41
42- IPC model requires each Secure Partition has its own stack area.
43- Multiple services are holding in same Secure Partition and each service
44  has its own information like message queue, SID and priority.
45- Changed information related manifest items need to be changed, too.
46
47Modifications in Core:
48
49- More SVC calls need to be added into list since PSA API are implemented as
50  SVC calls in TF-M.
51- New PendSV handler for thread scheduling.
52- Arch-related context stacking and switching.
53
54Memory Pool
55===========
56Handles of connection and messages for Secure Partition needs to be allocated
57dynamically. A memory pool is provided in the system to handle dynamic
58allocation. Each memory pool item contains below information:
59
60- A list iterator to chain all of memory pool items.
61- An information member to record information like size and types.
62- The memory item body for caller usage.
63
64A memory area needs to be provided in SPM for the memory pool. It could be an
65array of memory areas defined in the linker script. Two chains are available to
66manage the items: free chain and used chain. And an LRU (Last recent used)
67mechanism is applied for fast seeking while item allocating and destroying.
68
69Message Manager
70===============
71Message Manager handles message creating, pushing, retrieving and destroy. A
72message contains below information:
73
74- Message sender and destination
75- Message status
76- IO vectors for service
77- 'psa_msg_t' for service
78
79A checking needs to be performed in SPM before creating a message to detect if
80a message with the same sender and destination is ongoing. This avoids repeat
81messages are available in the queue.
82
83Thread
84======
85Each Secure Partition has a thread as execution environment. Secure Partition
86is defined statically in TF-M manifest, which indicates that a number of
87threads are statically defined. Threads are chained in SPM and sorted with
88its priority, and there is an extra indicator point to first running thread
89with the highest priority. This helps fast seeking of running threads while
90the scheduler is switching threads.
91
92Thread context contains below information:
93
94- Priority
95- Status
96- Stack pointer
97- Stack pointer limitation
98- Entry
99- Parameter
100- Entry return value
101- Context
102- List iterator
103
104Thread API provides below functions:
105
106- Thread creating and destroying
107- Thread status retrieving and changing
108- Current thread retrieving
109- Thread context switching
110
111PendSV exception in TF-M core is the place thread context APIs been called.
112Before thread switching taking place, isolation status needs to be changed
113based on Secure Partition change and current isolation level – a thread is a
114member of partition which means thread switching caused a partition switching.
115
116Synchronization API
117===================
118A first synchronization object is an event. This could be applied into event
119waiting in the partition, and message response handling in IPC. The event
120object contains below members:
121
122- Owner thread who is waiting for this event
123- Event status (Ready or Not-Ready)
124- List iterator for synchronization objects management
125
126Event API Limitation: could be waited by one thread only.
127
128PSA API
129=======
130This chapter describes the PSA API in an implementation manner.
131
132- API type: could be Client API and Service Partition API
133- Block-able: Block-able API may block caller thread; Non-Block API does not
134  block caller thread.
135- Description: The functionality description and important comments.
136
137.. code-block:: c
138
139    uint32_t psa_framework_version(void);
140    uint32_t psa_version(uint32_t sid);
141
142- Client API
143- Non-Block API
144- These 2 functions are finally handled in SPM and return the framework version
145  or version to the caller.
146
147.. code-block:: c
148
149    psa_handle_t psa_connect(uint32_t sid, uint32_t version);
150    psa_status_t psa_call(psa_handle_t handle, int32_t type,
151                          const psa_invec *in_vec, size_t in_len,
152                          psa_outvec *out_vec, size_t out_len);
153    void psa_close(psa_handle_t handle);
154
155- Client API
156- Block-able API
157- These 3 APIs are implemented in the same manner and just different
158  parameters. SPM converts each call into a corresponding message with a
159  parameter in the message body and pushes the message into service queue to
160  wait for the response. Scheduler switches to a specified thread (partition)
161  and makes Secure Partition to have chance retrieving and process message.
162  After a message response is returned to the caller, the waiting caller gets
163  to go and get the result.
164
165.. code-block:: c
166
167    psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);
168
169- Secure Partition API
170- Block-able API
171- This API blocks caller partition if there is no expected event for it. This
172  function is implemented based on event API.
173
174.. code-block:: c
175
176    void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
177    psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg);
178    size_t psa_read(psa_handle_t msg_handle, uint32_t invec_idx,
179                    void *buffer, size_t num_bytes);
180    size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx,
181                    size_t num_bytes);
182    void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,
183                   const void *buffer, size_t num_bytes);
184    void psa_reply(psa_handle_t msg_handle, psa_status_t status);
185    void psa_clear(void);
186    void psa_eoi(psa_signal_t irq_signal);
187
188- Secure Partition API
189- Non-Block
190- These APIs do not take the initiative to change caller status. They process
191  data and return the processed data back to the caller.
192
193.. code-block:: c
194
195    void psa_notify(int32_t partition_id);
196
197- Secure Partition API
198- Non-Block
199- This API sets DOORBELL bit in destination partition's event. This API does
200  not take the initiative to change caller status.
201
202.. code-block:: c
203
204    void psa_panic(void);
205
206- Secure Partition API
207- Block-able API
208- This function will terminate execution within the calling Secure Partition
209  and will not return.
210
211*********
212Reference
213*********
214
215| `PSA Firmware Framework specification URL`_
216
217.. _PSA Firmware Framework specification URL:
218  https://www.arm.com/architecture/security-features/platform-security
219
220--------------
221
222*Copyright (c) 2019-2022, Arm Limited. All rights reserved.*
223