Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 1 | /* |
Yann Gautier | 36416b1 | 2024-09-23 14:00:01 +0200 | [diff] [blame] | 2 | * Copyright (c) 2022-2025, Arm Limited and Contributors. All rights reserved. |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 3 | * |
| 4 | * SPDX-License-Identifier: BSD-3-Clause |
| 5 | */ |
| 6 | |
| 7 | #include <stdint.h> |
| 8 | #include <string.h> |
| 9 | |
| 10 | #include <common/debug.h> |
Tamas Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 11 | #include <drivers/arm/rse_comms.h> |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 12 | #include <psa/client.h> |
Tamas Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 13 | #include <rse_comms_protocol.h> |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 14 | |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 15 | /* 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 Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 17 | */ |
Tamas Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 18 | union __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 Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 21 | }; |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 22 | |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 23 | static 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 Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 25 | { |
Yann Gautier | 36416b1 | 2024-09-23 14:00:01 +0200 | [diff] [blame] | 26 | size_t comms_mbx_msg_size; |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 27 | 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 Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 31 | size_t i; |
| 32 | |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 33 | for (i = 0U; i < in_len; ++i) { |
| 34 | in_size_total += in_vec[i].len; |
| 35 | } |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 36 | for (i = 0U; i < out_len; ++i) { |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 37 | out_size_total += out_vec[i].len; |
| 38 | } |
| 39 | |
Yann Gautier | 36416b1 | 2024-09-23 14:00:01 +0200 | [diff] [blame] | 40 | comms_mbx_msg_size = rse_mbx_get_max_message_size(); |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 41 | |
Tamas Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 42 | 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 Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 45 | |
Tamas Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 46 | 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 Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 49 | |
| 50 | /* Use embed if we can pack into one message and reply, else use |
Yann Gautier | 36416b1 | 2024-09-23 14:00:01 +0200 | [diff] [blame] | 51 | * pointer_access. The underlying mailbox transport protocol uses a |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 52 | * single uint32_t to track the length, so the amount of data that |
Yann Gautier | 36416b1 | 2024-09-23 14:00:01 +0200 | [diff] [blame] | 53 | * can be in a message is 4 bytes less than rse_mbx_get_max_message_size |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 54 | * 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 Subramaniam | f754bd4 | 2023-12-06 14:27:09 +0530 | [diff] [blame] | 61 | if ((comms_embed_msg_min_size + in_size_total > |
Yann Gautier | 36416b1 | 2024-09-23 14:00:01 +0200 | [diff] [blame] | 62 | comms_mbx_msg_size - sizeof(uint32_t)) || |
Vijayenthiran Subramaniam | f754bd4 | 2023-12-06 14:27:09 +0530 | [diff] [blame] | 63 | (comms_embed_reply_min_size + out_size_total > |
Yann Gautier | 36416b1 | 2024-09-23 14:00:01 +0200 | [diff] [blame] | 64 | comms_mbx_msg_size - sizeof(uint32_t))) { |
Tamas Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 65 | return RSE_COMMS_PROTOCOL_POINTER_ACCESS; |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 66 | } else { |
Tamas Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 67 | return RSE_COMMS_PROTOCOL_EMBED; |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 68 | } |
| 69 | } |
| 70 | |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 71 | psa_status_t psa_call(psa_handle_t handle, int32_t type, const psa_invec *in_vec, size_t in_len, |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 72 | psa_outvec *out_vec, size_t out_len) |
| 73 | { |
Tamas Ban | ab545ef | 2022-10-03 15:34:02 +0200 | [diff] [blame] | 74 | /* Declared statically to avoid using huge amounts of stack space. Maybe revisit if |
| 75 | * functions not being reentrant becomes a problem. |
| 76 | */ |
Tamas Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 77 | static union rse_comms_io_buffer_t io_buf; |
Yann Gautier | 36416b1 | 2024-09-23 14:00:01 +0200 | [diff] [blame] | 78 | int err; |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 79 | 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 Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 85 | |
David Vincze | 002b106 | 2023-09-08 08:00:01 +0200 | [diff] [blame] | 86 | if (type > PSA_CALL_TYPE_MAX || type < PSA_CALL_TYPE_MIN || |
| 87 | in_len > PSA_MAX_IOVEC || out_len > PSA_MAX_IOVEC) { |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 88 | return PSA_ERROR_INVALID_ARGUMENT; |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 89 | } |
| 90 | |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 91 | 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 Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 96 | status = rse_protocol_serialize_msg(handle, type, in_vec, in_len, out_vec, |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 97 | out_len, &io_buf.msg, &msg_size); |
| 98 | if (status != PSA_SUCCESS) { |
| 99 | return status; |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 100 | } |
| 101 | |
Tamas Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 102 | VERBOSE("[RSE-COMMS] Sending message\n"); |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 103 | 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 Gautier | 36416b1 | 2024-09-23 14:00:01 +0200 | [diff] [blame] | 111 | err = rse_mbx_send_data((uint8_t *)&io_buf.msg, msg_size); |
| 112 | if (err != 0) { |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 113 | return PSA_ERROR_COMMUNICATION_FAILURE; |
| 114 | } |
| 115 | |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 116 | #if DEBUG |
| 117 | /* |
| 118 | * Poisoning the message buffer (with a known pattern). |
Tamas Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 119 | * Helps in detecting hypothetical RSE communication bugs. |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 120 | */ |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 121 | memset(&io_buf.msg, 0xA5, msg_size); |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 122 | #endif |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 123 | |
Yann Gautier | 36416b1 | 2024-09-23 14:00:01 +0200 | [diff] [blame] | 124 | err = rse_mbx_receive_data((uint8_t *)&io_buf.reply, &reply_size); |
| 125 | if (err != 0) { |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 126 | return PSA_ERROR_COMMUNICATION_FAILURE; |
| 127 | } |
| 128 | |
Tamas Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 129 | VERBOSE("[RSE-COMMS] Received reply\n"); |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 130 | 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 Ban | e249e56 | 2024-02-21 12:42:00 +0100 | [diff] [blame] | 134 | status = rse_protocol_deserialize_reply(out_vec, out_len, &return_val, |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 135 | &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 Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 145 | |
Yann Gautier | 36416b1 | 2024-09-23 14:00:01 +0200 | [diff] [blame] | 146 | /* Clear the mailbox message buffer to remove assets from memory */ |
Tamas Ban | e3a6fb8 | 2022-09-16 13:42:29 +0200 | [diff] [blame] | 147 | memset(&io_buf, 0x0, sizeof(io_buf)); |
| 148 | |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 149 | seq_num++; |
| 150 | |
Raef Coles | 3125901 | 2022-06-15 14:37:22 +0100 | [diff] [blame] | 151 | return return_val; |
Tamas Ban | ce0c40e | 2022-01-18 16:32:18 +0100 | [diff] [blame] | 152 | } |