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