blob: 48023bcb01e5c11b68f000a9a12aa79ed044ad0f [file] [log] [blame]
Tamas Bance0c40e2022-01-18 16:32:18 +01001/*
Yann Gautier36416b12024-09-23 14:00:01 +02002 * Copyright (c) 2022-2025, Arm Limited and Contributors. All rights reserved.
Tamas Bance0c40e2022-01-18 16:32:18 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <stdint.h>
8#include <string.h>
9
10#include <common/debug.h>
Tamas Bane249e562024-02-21 12:42:00 +010011#include <drivers/arm/rse_comms.h>
Tamas Bance0c40e2022-01-18 16:32:18 +010012#include <psa/client.h>
Tamas Bane249e562024-02-21 12:42:00 +010013#include <rse_comms_protocol.h>
Tamas Bance0c40e2022-01-18 16:32:18 +010014
Raef Coles31259012022-06-15 14:37:22 +010015/* Union as message space and reply space are never used at the same time, and this saves space as
16 * we can overlap them.
Tamas Bance0c40e2022-01-18 16:32:18 +010017 */
Tamas Bane249e562024-02-21 12:42:00 +010018union __packed __attribute__((aligned(4))) rse_comms_io_buffer_t {
19 struct serialized_rse_comms_msg_t msg;
20 struct serialized_rse_comms_reply_t reply;
Raef Coles31259012022-06-15 14:37:22 +010021};
Tamas Bance0c40e2022-01-18 16:32:18 +010022
Raef Coles31259012022-06-15 14:37:22 +010023static uint8_t select_protocol_version(const psa_invec *in_vec, size_t in_len,
24 const psa_outvec *out_vec, size_t out_len)
Tamas Bance0c40e2022-01-18 16:32:18 +010025{
Yann Gautier36416b12024-09-23 14:00:01 +020026 size_t comms_mbx_msg_size;
Raef Coles31259012022-06-15 14:37:22 +010027 size_t comms_embed_msg_min_size;
28 size_t comms_embed_reply_min_size;
29 size_t in_size_total = 0;
30 size_t out_size_total = 0;
Tamas Bance0c40e2022-01-18 16:32:18 +010031 size_t i;
32
Raef Coles31259012022-06-15 14:37:22 +010033 for (i = 0U; i < in_len; ++i) {
34 in_size_total += in_vec[i].len;
35 }
Tamas Bance0c40e2022-01-18 16:32:18 +010036 for (i = 0U; i < out_len; ++i) {
Raef Coles31259012022-06-15 14:37:22 +010037 out_size_total += out_vec[i].len;
38 }
39
Yann Gautier36416b12024-09-23 14:00:01 +020040 comms_mbx_msg_size = rse_mbx_get_max_message_size();
Raef Coles31259012022-06-15 14:37:22 +010041
Tamas Bane249e562024-02-21 12:42:00 +010042 comms_embed_msg_min_size = sizeof(struct serialized_rse_comms_header_t) +
43 sizeof(struct rse_embed_msg_t) -
44 PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE;
Raef Coles31259012022-06-15 14:37:22 +010045
Tamas Bane249e562024-02-21 12:42:00 +010046 comms_embed_reply_min_size = sizeof(struct serialized_rse_comms_header_t) +
47 sizeof(struct rse_embed_reply_t) -
48 PLAT_RSE_COMMS_PAYLOAD_MAX_SIZE;
Raef Coles31259012022-06-15 14:37:22 +010049
50 /* Use embed if we can pack into one message and reply, else use
Yann Gautier36416b12024-09-23 14:00:01 +020051 * pointer_access. The underlying mailbox transport protocol uses a
Raef Coles31259012022-06-15 14:37:22 +010052 * single uint32_t to track the length, so the amount of data that
Yann Gautier36416b12024-09-23 14:00:01 +020053 * can be in a message is 4 bytes less than rse_mbx_get_max_message_size
Raef Coles31259012022-06-15 14:37:22 +010054 * reports.
55 *
56 * TODO tune this with real performance numbers, it's possible a
57 * pointer_access message is less performant than multiple embed
58 * messages due to ATU configuration costs to allow access to the
59 * pointers.
60 */
Vijayenthiran Subramaniamf754bd42023-12-06 14:27:09 +053061 if ((comms_embed_msg_min_size + in_size_total >
Yann Gautier36416b12024-09-23 14:00:01 +020062 comms_mbx_msg_size - sizeof(uint32_t)) ||
Vijayenthiran Subramaniamf754bd42023-12-06 14:27:09 +053063 (comms_embed_reply_min_size + out_size_total >
Yann Gautier36416b12024-09-23 14:00:01 +020064 comms_mbx_msg_size - sizeof(uint32_t))) {
Tamas Bane249e562024-02-21 12:42:00 +010065 return RSE_COMMS_PROTOCOL_POINTER_ACCESS;
Raef Coles31259012022-06-15 14:37:22 +010066 } else {
Tamas Bane249e562024-02-21 12:42:00 +010067 return RSE_COMMS_PROTOCOL_EMBED;
Tamas Bance0c40e2022-01-18 16:32:18 +010068 }
69}
70
Raef Coles31259012022-06-15 14:37:22 +010071psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec, size_t in_len,
Tamas Bance0c40e2022-01-18 16:32:18 +010072 psa_outvec *out_vec, size_t out_len)
73{
Tamas Banab545ef2022-10-03 15:34:02 +020074 /* Declared statically to avoid using huge amounts of stack space. Maybe revisit if
75 * functions not being reentrant becomes a problem.
76 */
Tamas Bane249e562024-02-21 12:42:00 +010077 static union rse_comms_io_buffer_t io_buf;
Yann Gautier36416b12024-09-23 14:00:01 +020078 int err;
Raef Coles31259012022-06-15 14:37:22 +010079 psa_status_t status;
80 static uint8_t seq_num = 1U;
81 size_t msg_size;
82 size_t reply_size = sizeof(io_buf.reply);
83 psa_status_t return_val;
84 size_t idx;
Tamas Bance0c40e2022-01-18 16:32:18 +010085
David Vincze002b1062023-09-08 08:00:01 +020086 if (type > PSA_CALL_TYPE_MAX || type < PSA_CALL_TYPE_MIN ||
87 in_len > PSA_MAX_IOVEC || out_len > PSA_MAX_IOVEC) {
Raef Coles31259012022-06-15 14:37:22 +010088 return PSA_ERROR_INVALID_ARGUMENT;
Tamas Bance0c40e2022-01-18 16:32:18 +010089 }
90
Raef Coles31259012022-06-15 14:37:22 +010091 io_buf.msg.header.seq_num = seq_num,
92 /* No need to distinguish callers (currently concurrent calls are not supported). */
93 io_buf.msg.header.client_id = 1U,
94 io_buf.msg.header.protocol_ver = select_protocol_version(in_vec, in_len, out_vec, out_len);
95
Tamas Bane249e562024-02-21 12:42:00 +010096 status = rse_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec,
Raef Coles31259012022-06-15 14:37:22 +010097 out_len, &io_buf.msg, &msg_size);
98 if (status != PSA_SUCCESS) {
99 return status;
Tamas Bance0c40e2022-01-18 16:32:18 +0100100 }
101
Tamas Bane249e562024-02-21 12:42:00 +0100102 VERBOSE("[RSE-COMMS] Sending message\n");
Raef Coles31259012022-06-15 14:37:22 +0100103 VERBOSE("protocol_ver=%u\n", io_buf.msg.header.protocol_ver);
104 VERBOSE("seq_num=%u\n", io_buf.msg.header.seq_num);
105 VERBOSE("client_id=%u\n", io_buf.msg.header.client_id);
106 for (idx = 0; idx < in_len; idx++) {
107 VERBOSE("in_vec[%lu].len=%lu\n", idx, in_vec[idx].len);
108 VERBOSE("in_vec[%lu].buf=%p\n", idx, (void *)in_vec[idx].base);
109 }
110
Yann Gautier36416b12024-09-23 14:00:01 +0200111 err = rse_mbx_send_data((uint8_t *)&io_buf.msg, msg_size);
112 if (err != 0) {
Tamas Bance0c40e2022-01-18 16:32:18 +0100113 return PSA_ERROR_COMMUNICATION_FAILURE;
114 }
115
Tamas Bance0c40e2022-01-18 16:32:18 +0100116#if DEBUG
117 /*
118 * Poisoning the message buffer (with a known pattern).
Tamas Bane249e562024-02-21 12:42:00 +0100119 * Helps in detecting hypothetical RSE communication bugs.
Tamas Bance0c40e2022-01-18 16:32:18 +0100120 */
Raef Coles31259012022-06-15 14:37:22 +0100121 memset(&io_buf.msg, 0xA5, msg_size);
Tamas Bance0c40e2022-01-18 16:32:18 +0100122#endif
Raef Coles31259012022-06-15 14:37:22 +0100123
Yann Gautier36416b12024-09-23 14:00:01 +0200124 err = rse_mbx_receive_data((uint8_t *)&io_buf.reply, &reply_size);
125 if (err != 0) {
Tamas Bance0c40e2022-01-18 16:32:18 +0100126 return PSA_ERROR_COMMUNICATION_FAILURE;
127 }
128
Tamas Bane249e562024-02-21 12:42:00 +0100129 VERBOSE("[RSE-COMMS] Received reply\n");
Raef Coles31259012022-06-15 14:37:22 +0100130 VERBOSE("protocol_ver=%u\n", io_buf.reply.header.protocol_ver);
131 VERBOSE("seq_num=%u\n", io_buf.reply.header.seq_num);
132 VERBOSE("client_id=%u\n", io_buf.reply.header.client_id);
133
Tamas Bane249e562024-02-21 12:42:00 +0100134 status = rse_protocol_deserialize_reply(out_vec, out_len, &return_val,
Raef Coles31259012022-06-15 14:37:22 +0100135 &io_buf.reply, reply_size);
136 if (status != PSA_SUCCESS) {
137 return status;
138 }
139
140 VERBOSE("return_val=%d\n", return_val);
141 for (idx = 0U; idx < out_len; idx++) {
142 VERBOSE("out_vec[%lu].len=%lu\n", idx, out_vec[idx].len);
143 VERBOSE("out_vec[%lu].buf=%p\n", idx, (void *)out_vec[idx].base);
144 }
Tamas Bance0c40e2022-01-18 16:32:18 +0100145
Yann Gautier36416b12024-09-23 14:00:01 +0200146 /* Clear the mailbox message buffer to remove assets from memory */
Tamas Bane3a6fb82022-09-16 13:42:29 +0200147 memset(&io_buf, 0x0, sizeof(io_buf));
148
Tamas Bance0c40e2022-01-18 16:32:18 +0100149 seq_num++;
150
Raef Coles31259012022-06-15 14:37:22 +0100151 return return_val;
Tamas Bance0c40e2022-01-18 16:32:18 +0100152}