Phriction Trusted Firmware Trusted Firmware M Design Inter-Processes Communication History Version 4 vs 6
Version 4 vs 6
Version 4 vs 6
Content Changes
Content Changes
**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 pool
- Message manager
- Thread
- 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.
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
- Stack pointer limitation
- Entry
- Parameter
- Entry return value
- Context
- List iterator
Thread API provides below functions:
- Thread creating and destroying
- Thread status retrieving and changing
- 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_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
- 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 psa_read(psa_handle_t msg_handle, uint32_t invec_idx,void *buffer, size_t num_bytes);`
`size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx,size_t num_bytes);`
`void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,const void *buffer, size_t num_bytes);`
`void psa_reply(psa_handle_t msg_handle, psa_status_t status);`
`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
This API sets DOORBELL bit in destination partition's event. This API does not take the initiative to change caller status.
**4 - Reference**
[[ https://pages.arm.com/psa-resources-ff.html?_ga=2.156169596.61580709.1542617040-1290528876.1541647333 | PSA Firmware Framework specification ]]
**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 pool
- Message manager
- Thread
- 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 the 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 need to be added into list since PSA API are implemented as SVC calls in TF-M.
- New PendSV handler for thread scheduling.
- arch-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 the 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.
A memory area needs to be provided in SPM for the memory pool. It could be an array of memory areas defined in the 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 the same sender and destination is ongoing. This avoids repeat messages are available in the 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 a number of threads are statically defined. Threads are chained in SPM and sorted with its priority, and there is an extra indicator point to first running thread with the highest priority. This helps fast seeking of running threads while the scheduler is switching threads.
Thread context contains below information:
- Priority
- Status
- Stack pointer
- Stack pointer limitation
- Entry
- Parameter
- Entry return value
- Context
- List iterator
Thread API provides below functions:
- Thread creating and destroying
- Thread status retrieving and changing
- 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 – a thread is a member of partition which means thread switching caused a partition switching.
**3.5 - Synchronization API**
A first synchronization object is an event. This could be applied into event waiting in the partition, and message response handling in IPC. The event object contains below members:
- Owner thread who is waiting for 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 an 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 the 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_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 the same manner and just different parameters. SPM convert each call into a corresponded message with a parameter in the message body and push the message into service queue to wait for the response. Scheduler switches to a specified thread (partition) and makes Secure Partition to have chance retrieving and process message. After a message response is returned to the caller, the waiting caller gets to go and get the result.
`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 psa_read(psa_handle_t msg_handle, uint32_t invec_idx,void *buffer, size_t num_bytes);`
`size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx,size_t num_bytes);`
`void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,const void *buffer, size_t num_bytes);`
`void psa_reply(psa_handle_t msg_handle, psa_status_t status);`
`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 the caller.
`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**
[[ https://pages.arm.com/psa-resources-ff.html?_ga=2.156169596.61580709.1542617040-1290528876.1541647333 | PSA Firmware Framework specification ]]
[[ https://connect.linaro.org/resources/yvr18/sessions/yvr18-108/ | Slides includes IPC basic introduction ]]
[[ https://www.youtube.com/watch?v=6wEFoq49qUw | IPC mode implementation ]]
**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 pool
- Message manager
- Thread
- 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 the 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 - arch-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 the 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.
A memory area needs to be provided in SPM for the memory pool. It could be an array orof memory areas defined in the 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 the same sender and destination is ongoing. This avoids repeat messages are available in the 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 a 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 the highest priority. This helps fast seeking of running threads while the scheduler is switching threads.
Thread context contains below information:
- Priority
- Status
- Stack pointer
- Stack pointer limitation
- Entry
- Parameter
- Entry return value
- Context
- List iterator
Thread API provides below functions:
- Thread creating and destroying
- Thread status retrieving and changing
- 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 – a thread is a member of partition which means thread switching caused a partition switching.
**3.5 - Synchronization API**
TheA first synchronization object is an event. This could be applied into event waiting in the partition, and message response handling in IPC. EThe event object contains below members:
- Owner thread who is waiting onfor 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 an 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 the 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_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 the same manner, and just different parameters. SPM convert each call into a corresponded message with a parameter in the message body and push the message into service queue to wait for the response. Scheduler switches to a specified thread (partition) and makes Secure Partition to have chance retrieving and process message. After a message response is returned to the caller, the waiting caller gets to go and get the result.
`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 psa_read(psa_handle_t msg_handle, uint32_t invec_idx,void *buffer, size_t num_bytes);`
`size_t psa_skip(psa_handle_t msg_handle, uint32_t invec_idx,size_t num_bytes);`
`void psa_write(psa_handle_t msg_handle, uint32_t outvec_idx,const void *buffer, size_t num_bytes);`
`void psa_reply(psa_handle_t msg_handle, psa_status_t status);`
`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 the caller.
`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**
[[ https://pages.arm.com/psa-resources-ff.html?_ga=2.156169596.61580709.1542617040-1290528876.1541647333 | PSA Firmware Framework specification ]]
[[ https://connect.linaro.org/resources/yvr18/sessions/yvr18-108/ | Slides includes IPC basic introduction ]]
[[ https://www.youtube.com/watch?v=6wEFoq49qUw | IPC mode implementation ]]