blob: ac474f87a997e90fa2efc652be43add005724ec7 [file] [log] [blame]
Bence Balogh0c582be2024-01-11 22:21:31 +01001/*
Bence Balogh7527ddf2025-02-25 08:18:14 +01002 * Copyright (c) 2022-2025, Arm Limited. All rights reserved.
Bence Balogh0c582be2024-01-11 22:21:31 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdint.h>
8#include <string.h>
9
Bence Baloghdb872262024-02-22 16:59:35 +010010#include "protocols/rpc/common/packed-c/status.h"
11#include "psa/client.h"
Gyorgy Szinge6b38462024-10-24 17:36:45 +020012#include "rse_comms_caller.h"
13#include "rse_comms_protocol.h"
Bence Baloghdb872262024-02-22 16:59:35 +010014#include "trace.h"
Bence Balogh0c582be2024-01-11 22:21:31 +010015
Bence Baloghdb872262024-02-22 16:59:35 +010016/* This value should be set according to the implemented channels
17 * in the MHU. As only the Embed protocol is supported at the moment,
18 * it is set big enough to fit even the largest messages.
Bence Balogh0c582be2024-01-11 22:21:31 +010019 */
Bence Baloghdb872262024-02-22 16:59:35 +010020#ifndef COMMS_MHU_MSG_SIZE
21#define COMMS_MHU_MSG_SIZE 0x2200
22#endif
Bence Balogh0c582be2024-01-11 22:21:31 +010023
Bence Balogh7527ddf2025-02-25 08:18:14 +010024/*
25 * This must be set beforehand, during the SP's initialization. This is
26 * the FF-A ID of the SP.
27 */
28extern uint16_t own_id;
29
Bence Baloghdb872262024-02-22 16:59:35 +010030static uint8_t select_protocol_version(const struct psa_invec *in_vec, size_t in_len,
31 const struct psa_outvec *out_vec, size_t out_len)
Bence Balogh0c582be2024-01-11 22:21:31 +010032{
Bence Balogh0c582be2024-01-11 22:21:31 +010033 size_t comms_embed_msg_min_size;
34 size_t comms_embed_reply_min_size;
35 size_t in_size_total = 0;
36 size_t out_size_total = 0;
37 size_t i;
38
39 for (i = 0U; i < in_len; ++i) {
40 in_size_total += in_vec[i].len;
41 }
42 for (i = 0U; i < out_len; ++i) {
43 out_size_total += out_vec[i].len;
44 }
45
Gyorgy Szinge6b38462024-10-24 17:36:45 +020046 comms_embed_msg_min_size = sizeof(struct serialized_rse_comms_header_t) +
47 sizeof(struct rse_embed_msg_t) - PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE;
Bence Balogh0c582be2024-01-11 22:21:31 +010048
Gyorgy Szinge6b38462024-10-24 17:36:45 +020049 comms_embed_reply_min_size = sizeof(struct serialized_rse_comms_header_t) +
50 sizeof(struct rse_embed_reply_t) -
51 PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE;
Bence Balogh0c582be2024-01-11 22:21:31 +010052
53 /* Use embed if we can pack into one message and reply, else use
54 * pointer_access. The underlying MHU transport protocol uses a
55 * single uint32_t to track the length, so the amount of data that
56 * can be in a message is 4 bytes less than mhu_get_max_message_size
57 * reports.
58 *
59 * TODO tune this with real performance numbers, it's possible a
60 * pointer_access message is less performant than multiple embed
61 * messages due to ATU configuration costs to allow access to the
62 * pointers.
63 */
64 if ((comms_embed_msg_min_size + in_size_total >
Bence Baloghdb872262024-02-22 16:59:35 +010065 COMMS_MHU_MSG_SIZE - sizeof(uint32_t)) ||
Bence Balogh0c582be2024-01-11 22:21:31 +010066 (comms_embed_reply_min_size + out_size_total >
Bence Baloghdb872262024-02-22 16:59:35 +010067 COMMS_MHU_MSG_SIZE - sizeof(uint32_t))) {
Gyorgy Szinge6b38462024-10-24 17:36:45 +020068 return RSE_COMMS_PROTOCOL_POINTER_ACCESS;
Bence Balogh0c582be2024-01-11 22:21:31 +010069 } else {
Gyorgy Szinge6b38462024-10-24 17:36:45 +020070 return RSE_COMMS_PROTOCOL_EMBED;
Bence Balogh0c582be2024-01-11 22:21:31 +010071 }
72}
73
Bence Baloghdb872262024-02-22 16:59:35 +010074psa_status_t __psa_call(struct rpc_caller_interface *caller, psa_handle_t handle, int32_t client_id,
75 int32_t type, const struct psa_invec *in_vec, size_t in_len,
76 struct psa_outvec *out_vec, size_t out_len)
Bence Balogh0c582be2024-01-11 22:21:31 +010077{
Bence Balogh0c582be2024-01-11 22:21:31 +010078 static uint8_t seq_num = 1U;
Bence Baloghdb872262024-02-22 16:59:35 +010079 rpc_status_t rpc_status = RPC_ERROR_INTERNAL;
80 psa_status_t psa_status = PSA_ERROR_INVALID_ARGUMENT;
81 psa_status_t return_val = PSA_ERROR_INVALID_ARGUMENT;
Gyorgy Szinge6b38462024-10-24 17:36:45 +020082 rse_comms_call_handle rpc_handle = (rse_comms_call_handle)caller;
Bence Baloghdb872262024-02-22 16:59:35 +010083 size_t req_len = 0;
84 size_t resp_len = 0;
Gyorgy Szinge6b38462024-10-24 17:36:45 +020085 struct serialized_rse_comms_msg_t *req = NULL;
86 struct serialized_rse_comms_reply_t *reply = NULL;
Bence Baloghdb872262024-02-22 16:59:35 +010087 uint8_t protocol_ver = 0;
Bence Balogh0c582be2024-01-11 22:21:31 +010088
Bence Baloghdb872262024-02-22 16:59:35 +010089 protocol_ver = select_protocol_version(in_vec, in_len, out_vec, out_len);
90
Gyorgy Szinge6b38462024-10-24 17:36:45 +020091 psa_status = rse_protocol_calculate_msg_len(handle, protocol_ver, in_vec, in_len, &req_len);
Bence Baloghdb872262024-02-22 16:59:35 +010092 if (psa_status != PSA_SUCCESS) {
93 EMSG("Message size calculation failed: %d", psa_status);
94 return psa_status;
Bence Balogh0c582be2024-01-11 22:21:31 +010095 }
96
Gyorgy Szinge6b38462024-10-24 17:36:45 +020097 rpc_handle = rse_comms_caller_begin(caller, (uint8_t **)&req, req_len);
Bence Baloghdb872262024-02-22 16:59:35 +010098 if (!rpc_handle) {
99 EMSG("Could not get handle");
100 return PSA_ERROR_GENERIC_ERROR;
101 }
102
103 req->header.seq_num = seq_num;
Bence Balogh7527ddf2025-02-25 08:18:14 +0100104
105 /*
106 * This is needed because the "0" is not accepted in TF-M so it has to be remapped
107 * to a different value.
108 * The SE-Proxy's own FFA ID is used as the new value. This is a viable option
109 * because the SE-Proxy SP never originates requests itself, it just
110 * forwards the requests of the other endpoints.
111 */
112
113 if (client_id == 0)
114 req->header.client_id = own_id;
115 else
116 req->header.client_id = client_id;
117
Bence Baloghdb872262024-02-22 16:59:35 +0100118 req->header.protocol_ver = protocol_ver;
Bence Balogh0c582be2024-01-11 22:21:31 +0100119
Gyorgy Szinge6b38462024-10-24 17:36:45 +0200120 psa_status = rse_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec, out_len, req,
Bence Baloghdb872262024-02-22 16:59:35 +0100121 &req_len);
122 if (psa_status != PSA_SUCCESS) {
123 EMSG("Serialize msg failed: %d", psa_status);
124 return psa_status;
Bence Balogh0c582be2024-01-11 22:21:31 +0100125 }
126
Gyorgy Szinge6b38462024-10-24 17:36:45 +0200127 DMSG("Sending rse_comms message");
Bence Baloghdb872262024-02-22 16:59:35 +0100128 DMSG("protocol_ver=%u", req->header.protocol_ver);
129 DMSG("seq_num=%u", req->header.seq_num);
130 DMSG("client_id=%u", req->header.client_id);
131
132 resp_len = sizeof(*reply);
133
Gyorgy Szinge6b38462024-10-24 17:36:45 +0200134 rpc_status = rse_comms_caller_invoke(rpc_handle, 0, (uint8_t **)&reply, &resp_len);
Bence Baloghdb872262024-02-22 16:59:35 +0100135 if (rpc_status != RPC_SUCCESS) {
136 EMSG("Invoke failed: %d", rpc_status);
137 return PSA_ERROR_GENERIC_ERROR;
Bence Balogh0c582be2024-01-11 22:21:31 +0100138 }
139
Gyorgy Szinge6b38462024-10-24 17:36:45 +0200140 DMSG("Received rse_comms reply");
Bence Baloghdb872262024-02-22 16:59:35 +0100141 DMSG("protocol_ver=%u", reply->header.protocol_ver);
142 DMSG("seq_num=%u", reply->header.seq_num);
143 DMSG("client_id=%u", reply->header.client_id);
144 DMSG("resp_len=%lu", resp_len);
145
Gyorgy Szinge6b38462024-10-24 17:36:45 +0200146 psa_status = rse_protocol_deserialize_reply(out_vec, out_len, &return_val, reply, resp_len);
Bence Baloghdb872262024-02-22 16:59:35 +0100147 if (psa_status != PSA_SUCCESS) {
148 EMSG("Protocol deserialize reply failed: %d", psa_status);
149 return psa_status;
Bence Balogh0c582be2024-01-11 22:21:31 +0100150 }
151
Bence Baloghdb872262024-02-22 16:59:35 +0100152 DMSG("Return_val=%d", return_val);
Bence Balogh0c582be2024-01-11 22:21:31 +0100153
Gyorgy Szinge6b38462024-10-24 17:36:45 +0200154 rse_comms_caller_end(rpc_handle);
Bence Balogh0c582be2024-01-11 22:21:31 +0100155
156 seq_num++;
157
158 return return_val;
159}
160
Bence Baloghdb872262024-02-22 16:59:35 +0100161psa_status_t psa_call_client_id(struct rpc_caller_interface *caller, psa_handle_t psa_handle,
162 int32_t client_id, int32_t type, const struct psa_invec *in_vec,
163 size_t in_len, struct psa_outvec *out_vec, size_t out_len)
Bence Balogh0c582be2024-01-11 22:21:31 +0100164{
Bence Baloghdb872262024-02-22 16:59:35 +0100165 return __psa_call(caller, psa_handle, client_id, type, in_vec, in_len, out_vec, out_len);
166}
Bence Balogh0c582be2024-01-11 22:21:31 +0100167
Bence Baloghdb872262024-02-22 16:59:35 +0100168psa_status_t psa_call(struct rpc_caller_interface *caller, psa_handle_t psa_handle, int32_t type,
169 const struct psa_invec *in_vec, size_t in_len, struct psa_outvec *out_vec,
170 size_t out_len)
171{
172 return __psa_call(caller, psa_handle, 0, type, in_vec, in_len, out_vec, out_len);
Bence Balogh0c582be2024-01-11 22:21:31 +0100173}