1######################## 2RSE communication design 3######################## 4 5The RSE communication protocol is designed to be a lightweight serialization of 6the psa_call() API through a combination of in-band MHU (Message Handling Unit) 7transport and parameter-passing through shared memory. 8 9************** 10Message format 11************** 12 13To call an RSE service, the client must send a message in-band over the MHU 14sender link to RSE and wait for a reply message on the MHU receiver (either by 15polling the MHU or waiting for interrupt). The messages are defined as packed C 16structs, which are serialized in byte-order over the MHU links. 17 18Messages encoding a psa_call() to RSE take the form:: 19 20 __PACKED_STRUCT serialized_psa_msg_t { 21 struct serialized_rse_comms_header_t header; 22 __PACKED_UNION { 23 struct rse_embed_msg_t embed; 24 struct rse_pointer_access_msg_t pointer_access; 25 } msg; 26 }; 27 28Replies from RSE take the form:: 29 30 __PACKED_STRUCT serialized_psa_reply_t { 31 struct serialized_rse_comms_header_t header; 32 __PACKED_UNION { 33 struct rse_embed_reply_t embed; 34 struct rse_pointer_access_reply_t pointer_access; 35 } reply; 36 }; 37 38All messages (calls and replies), in all protocols carry the following header:: 39 40 __PACKED_STRUCT serialized_rse_comms_header_t { 41 uint8_t protocol_ver; 42 uint8_t seq_num; 43 uint16_t client_id; 44 }; 45 46The ``client_id`` can be used by the caller to identify different clients at the 47endpoint for access control purposes. It is combined with an RSE-internal 48identifier for the endpoint to create the PSA Client ID for the call. 49 50The sequence number, ``seq_num``, is returned in the reply message to allow the 51client to identify which message is being responded to, since replies may be 52out-of-order. The sender is free to assign sequence numbers using a scheme of 53its choice, and it is the sender's responsibility to ensure that two messages 54with the same sequence number are not in simultaneous flight. 55 56The ``protocol_ver`` identifies which message protocol is being used. There are 57two protocols currently supported, "embed" (``protocol_ver=0``) and "pointer 58access" (``protocol_ver=1``). 59 60Embed protocol 61============== 62 63The embed protocol embeds the psa_call iovecs into the message sent over the 64MHU. It has the following format:: 65 66 __PACKED_STRUCT rse_embed_msg_t { 67 psa_handle_t handle; 68 uint32_t ctrl_param; 69 uint16_t io_size[PSA_MAX_IOVEC]; 70 uint8_t payload[RSE_COMMS_PAYLOAD_MAX_SIZE]; 71 }; 72 73The ``handle`` is the psa_call handle parameter and the ``ctrl_param`` packs the 74type, in_len and out_len parameters of psa_call into one parameter. 75 76The ``io_size`` array contains the sizes of the up to ``PSA_MAX_IOVEC`` (4) 77iovecs, in order, with the invec sizes before the outvec sizes. 78 79The ``payload`` array then contains the invec data packed contiguously in order. 80The length of this parameter is variable, equal to the sum of the invec lengths 81in io_size. The caller does not need to pad the payload to the maximum size. The 82maximum payload size for this protocol, ``RSE_COMMS_PAYLOAD_MAX_SIZE``, is a 83build-time option. 84 85Replies in the embed protocol take the form:: 86 87 __PACKED_STRUCT rse_embed_reply_t { 88 int32_t return_val; 89 uint16_t out_size[PSA_MAX_IOVEC]; 90 uint8_t payload[RSE_COMMS_PAYLOAD_MAX_SIZE]; 91 }; 92 93The ``return_val`` is the return value of the psa_call() invocation, the 94``out_size`` is the (potentially updated) sizes of the outvecs and the 95``payload`` buffer contains the outvec data serialized contiguously in outvec 96order. 97 98Pointer access protocol 99======================= 100 101The pointer access protocol passes the psa_call iovecs as pointers to shared 102memory using the following MHU message format:: 103 104 __PACKED_STRUCT rse_pointer_access_msg_t { 105 psa_handle_t handle; 106 uint32_t ctrl_param; 107 uint32_t io_sizes[PSA_MAX_IOVEC]; 108 uint64_t host_ptrs[PSA_MAX_IOVEC]; 109 }; 110 111The ``handle``, ``ctrl_param`` and ``io_sizes`` have the same definition as in 112the embed protocol. 113 114The ``host_ptrs`` point to each of the up to ``PSA_MAX_IOVEC`` iovec buffers in 115host system memory. It is the caller's responsibility to write the invec data to 116the invec pointers before sending the message, and ensure that the memory 117pointed-to remains valid for the duration of the call. 118 119The reply message has the form:: 120 121 __PACKED_STRUCT rse_pointer_access_reply_t { 122 int32_t return_val; 123 uint32_t out_size[PSA_MAX_IOVEC]; 124 }; 125 126The ``return_val`` and ``out_size`` have the same meaning as in the embed 127protocol. 128 129RSE writes the outvec data to the pointers supplied in the call message prior to 130sending the MHU reply message, so no further payload is sent in the reply 131message. 132 133************************ 134Implementation structure 135************************ 136 137The RSE side of the communication implementation is located in 138``platform/ext/target/arm/rse/common/rse_comms``. The implementation is 139structured as follows: 140 141- ``rse_comms.c``: Implements the TF-M RPC layer using RSE comms implementation. 142- ``rse_comms_hal.c``: Abstracts MHU message sending and receiving. 143 144- ``rse_comms_protocol.c``: The common part of the RSE comms protocol. 145- ``rse_comms_protocol_embed.c``: The embed RSE comms protocol. 146- ``rse_comms_protocol_protocol_access.c``: The pointer access RSE comms protocol. 147 148- ``rse_comms_atu.c``: Allocates and frees ATU regions for host pointer access. 149- ``rse_comms_permissions_hal.c``: Checks service access permissions and pointer validity. 150 151A reference implementation of the client side of the RSE comms is available in 152the Trusted Firmware-A repository. 153 154-------------- 155 156*Copyright (c) 2022-2023, Arm Limited. All rights reserved.* 157