**1 - Terminology**
IPC - Inter-Processes Communication
For more terminology please check reference document.
**2 - Design Overview**
IPC re-uses existed components in library mode:
- SPM – for partition information and isolation actions
- Core – for exception handling
Extra components for implementing IPC:
Memory poolExtra components for implementing IPC:
Message manager - Memory pool
Scheduler - Message manager
Synchronization objects - Scheduler
PSA API - Synchronization objects
- PSA API
**3 - Implementation details**
Listed modules are all internal modules except PSA API. Prototypes and definitions are not listed for internal modules in this document. For PSA API definitions, check them in PSA Firmware Framework specification in reference chapter.
**3.1 - SPM and Core**
SPM manages Secure Partition information. Enhancements need to be done in SPM data structure for Secure Partition for IPC due to:
- IPC mode requires each Secure Partition has its own stack area while isolation level 1 of library mode makes all partition shares same stack pointer. This needs to be changed while implementing IPC.
- Multiple services are holding in same Secure Partition and each service has its own information like: message queue, SID and priority.
- Changed information related manifest items need to be changed, too.
Modifications in Core:
- More SVC calls needs to be added into list since PSA API are implemented as SVC calls in TF-M.
- New PendSV handler for thread scheduling.
- PE related context stacking and switching.
**3.2 - Memory pool**
Handles of connection and messages for Secure Partition needs to be allocated dynamically. A memory pool is provided in system to handle dynamic allocation. Each memory pool item contains below information:
- A list iterator to chain all of memory pool items.
- An information member to record information like size and types.
The memory item body for caller usage.
- The memory item body for caller usage.
A memory area needs to be provided in SPM for memory pool. It could be an array or memory areas defined in linker script. Two chains are available to manage the items: free chain and used chain. And an LRU (Last recent used) mechanism is applied for fast seeking while item allocating and destroying.
**3.3 - Message manager**
Message Manager handles message creating, pushing, retrieving and destroy. A message contains below information:
- Message sender and destination
- Message status
- IO vectors for service
- ‘psa_msg_t’ for service
A checking needs to be performed in SPM before creating a message to detect if a message with same sender and destination is ongoing. This avoids repeat messages are available in queue.
**3.4 - Thread**
Each Secure Partition has a thread as execution environment. Secure Partition is defined statically in TF-M manifest, which indicates that number of threads are statically defined. Threads are chained in SPM and sorted with its priority, and there is an extra indicator points to first running thread with highest priority. This helps fast seeking of running threads while scheduler is switching threads.
Thread context contains below information:
- Priority
Status
Stack pointer - Status
- Stack pointer limitation
Entry - Stack pointer limitation
Parameter - Entry
Entry return value - Parameter
Context - Entry return value
List iterator - Context
Thread API provides below functions: - List iterator
Thread creating and destroying
Thread status retrievAPI provides below functions:
- Thread creating and changingdestroying
Current thread - Thread status retrievinging and changing
Thread context switching - Current thread retrieving
- Thread context switching
PendSV exception in TF-M core is the place thread context APIs been called. Before thread switching taking place, isolation status needs to be changed based on Secure Partition change and current isolation level – thread is a member of partition which means thread switching caused a partition switching.
**3.5 - Synchronization API**
The first synchronization object is event. This could be applied into event waiting in partition, and message response handling in IPC. Event object contains below members:
- Owner thread who is waiting on this event
- Event status (Ready or Not-Ready)
- List iterator for synchronization objects management
Event API Limitation: could be waited by one thread only.
**3.6 - PSA API**
This chapter describes the PSA API in implementation manner.
- API type: could be Client API and Service Partition API
- Block-able: Block-able API may block caller thread; Non-Block API does not block caller thread.
`uint32_t psa_framework_version(void);
`
- Client API
- Non-Block API
This function is finally handled in SPM and return the framework version to caller.
`uint32_t psa_version(uint32_t sid);
psa_handle_t psa_connect(uint32_t sid, uint32_t minor_version);`
psa_status_t psa_call(`psa_handle_t handle, const psa_invec *in_vec, size_t in_lenconnect(uint32_t sid, psa_outvec *out_vec, size_t out_len);uint32_t minor_version);`
void`psa_status_t psa_closeall(psa_handle_t handle);le, const psa_invec *in_vec, size_t in_len, psa_outvec *out_vec, size_t out_len);`
`void psa_close(psa_handle_t handle);`
- Client API
- Block-able API
These 4 APIs are implemented in same manner, and just different parameters. SPM convert each call into corresponded message with parameter in message body and push the message into service queue to wait for response. Scheduler switches to specified thread (partition) and make Secure Partition to have chance retrieving and process message. After a message response is returned to caller, the waiting caller get to go and get the result.
psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);
Secure Partition API`psa_signal_t psa_wait(psa_signal_t signal_mask, uint32_t timeout);`
- Secure Partition API
- Block-able API
This API blocks caller partition if there is no expected event for it. This function is implemented based on event API.
void psa_set_rhandle(psa_handle_t msg_handle, void *rhandle);
psa_status_t psa_get(psa_signal_t signal, psa_msg_t *msg);
size_t`void psa_read_set_rhandle(psa_handle_t msg_handle, uint32_t invec_idx,void *buffer, size_t num_bytes);rhandle);`
size`psa_status_t psa_skipget(psa_handle_t msg_handlesignal_t signal, uint32_t invec_idx,size_t num_bytes);psa_msg_t *msg);`
void`size_t psa_writeread(psa_handle_t msg_handle, uint32_t outinvec_idx,const void *buffer, size_t num_bytes);`
void`size_t psa_replyskip(psa_handle_t msg_handle, psa_status_t status);uint32_t invec_idx,size_t num_bytes);`
`void psa_write(psa_clear(handle_t msg_handle, uint32_t outvec_idx,const void); *buffer, size_t num_bytes);`
`void psa_eoi(psa_signal_t irq_signal);reply(psa_handle_t msg_handle, psa_status_t status);`
Secure Partition API`void psa_clear(void);`
`void psa_eoi(psa_signal_t irq_signal);`
- Secure Partition API
- Non-Block
These APIs do not take the initiative to change caller status. They process data and return the processed data back to caller.
void psa_notify(int32_t partition_id);
Secure Partition API
Non-Block
`void psa_notify(int32_t partition_id);`
- Secure Partition API
- Non-Block
This API sets DOORBELL bit in destination partition's event. This API does not take the initiative to change caller status.
**4 - Reference**
PSA Firmware Framework specification[[ https://pages.arm.com/psa-resources-ff.html?_ga=2.156169596.61580709.1542617040-1290528876.1541647333 | PSA Firmware Framework specification ]]