xref: /arm-trusted-firmware/drivers/arm/rss/rss_comms_protocol_embed.c (revision 91f16700b400a8c0651d24a598fc48ee2997a0d7)
1*91f16700Schasinglulu /*
2*91f16700Schasinglulu  * Copyright (c) 2022-2023, Arm Limited. All rights reserved.
3*91f16700Schasinglulu  *
4*91f16700Schasinglulu  * SPDX-License-Identifier: BSD-3-Clause
5*91f16700Schasinglulu  *
6*91f16700Schasinglulu  */
7*91f16700Schasinglulu 
8*91f16700Schasinglulu #include <assert.h>
9*91f16700Schasinglulu #include <string.h>
10*91f16700Schasinglulu 
11*91f16700Schasinglulu #include <common/debug.h>
12*91f16700Schasinglulu #include "rss_comms_protocol_embed.h"
13*91f16700Schasinglulu 
14*91f16700Schasinglulu #define TYPE_OFFSET	(16U)
15*91f16700Schasinglulu #define TYPE_MASK	(0xFFFFUL << TYPE_OFFSET)
16*91f16700Schasinglulu #define IN_LEN_OFFSET	(8U)
17*91f16700Schasinglulu #define IN_LEN_MASK	(0xFFUL << IN_LEN_OFFSET)
18*91f16700Schasinglulu #define OUT_LEN_OFFSET	(0U)
19*91f16700Schasinglulu #define OUT_LEN_MASK	(0xFFUL << OUT_LEN_OFFSET)
20*91f16700Schasinglulu 
21*91f16700Schasinglulu #define PARAM_PACK(type, in_len, out_len)			  \
22*91f16700Schasinglulu 	(((((uint32_t)type) << TYPE_OFFSET) & TYPE_MASK)	| \
23*91f16700Schasinglulu 	 ((((uint32_t)in_len) << IN_LEN_OFFSET) & IN_LEN_MASK)	| \
24*91f16700Schasinglulu 	 ((((uint32_t)out_len) << OUT_LEN_OFFSET) & OUT_LEN_MASK))
25*91f16700Schasinglulu 
26*91f16700Schasinglulu psa_status_t rss_protocol_embed_serialize_msg(psa_handle_t handle,
27*91f16700Schasinglulu 					      int16_t type,
28*91f16700Schasinglulu 					      const psa_invec *in_vec,
29*91f16700Schasinglulu 					      uint8_t in_len,
30*91f16700Schasinglulu 					      const psa_outvec *out_vec,
31*91f16700Schasinglulu 					      uint8_t out_len,
32*91f16700Schasinglulu 					      struct rss_embed_msg_t *msg,
33*91f16700Schasinglulu 					      size_t *msg_len)
34*91f16700Schasinglulu {
35*91f16700Schasinglulu 	uint32_t payload_size = 0;
36*91f16700Schasinglulu 	uint32_t i;
37*91f16700Schasinglulu 
38*91f16700Schasinglulu 	assert(msg != NULL);
39*91f16700Schasinglulu 	assert(msg_len != NULL);
40*91f16700Schasinglulu 	assert(in_vec != NULL);
41*91f16700Schasinglulu 
42*91f16700Schasinglulu 	msg->ctrl_param = PARAM_PACK(type, in_len, out_len);
43*91f16700Schasinglulu 	msg->handle = handle;
44*91f16700Schasinglulu 
45*91f16700Schasinglulu 	/* Fill msg iovec lengths */
46*91f16700Schasinglulu 	for (i = 0U; i < in_len; ++i) {
47*91f16700Schasinglulu 		msg->io_size[i] = in_vec[i].len;
48*91f16700Schasinglulu 	}
49*91f16700Schasinglulu 	for (i = 0U; i < out_len; ++i) {
50*91f16700Schasinglulu 		msg->io_size[in_len + i] = out_vec[i].len;
51*91f16700Schasinglulu 	}
52*91f16700Schasinglulu 
53*91f16700Schasinglulu 	for (i = 0U; i < in_len; ++i) {
54*91f16700Schasinglulu 		if (in_vec[i].len > sizeof(msg->trailer) - payload_size) {
55*91f16700Schasinglulu 			return PSA_ERROR_INVALID_ARGUMENT;
56*91f16700Schasinglulu 		}
57*91f16700Schasinglulu 		memcpy(msg->trailer + payload_size,
58*91f16700Schasinglulu 		       in_vec[i].base,
59*91f16700Schasinglulu 		       in_vec[i].len);
60*91f16700Schasinglulu 		payload_size += in_vec[i].len;
61*91f16700Schasinglulu 	}
62*91f16700Schasinglulu 
63*91f16700Schasinglulu 	/* Output the actual size of the message, to optimize sending */
64*91f16700Schasinglulu 	*msg_len = sizeof(*msg) - sizeof(msg->trailer) + payload_size;
65*91f16700Schasinglulu 
66*91f16700Schasinglulu 	return PSA_SUCCESS;
67*91f16700Schasinglulu }
68*91f16700Schasinglulu 
69*91f16700Schasinglulu psa_status_t rss_protocol_embed_deserialize_reply(psa_outvec *out_vec,
70*91f16700Schasinglulu 						  uint8_t out_len,
71*91f16700Schasinglulu 						  psa_status_t *return_val,
72*91f16700Schasinglulu 						  const struct rss_embed_reply_t *reply,
73*91f16700Schasinglulu 						  size_t reply_size)
74*91f16700Schasinglulu {
75*91f16700Schasinglulu 	uint32_t payload_offset = 0;
76*91f16700Schasinglulu 	uint32_t i;
77*91f16700Schasinglulu 
78*91f16700Schasinglulu 	assert(reply != NULL);
79*91f16700Schasinglulu 	assert(return_val != NULL);
80*91f16700Schasinglulu 
81*91f16700Schasinglulu 	for (i = 0U; i < out_len; ++i) {
82*91f16700Schasinglulu 		if ((sizeof(*reply) - sizeof(reply->trailer) + payload_offset)
83*91f16700Schasinglulu 		    > reply_size) {
84*91f16700Schasinglulu 			return PSA_ERROR_INVALID_ARGUMENT;
85*91f16700Schasinglulu 		}
86*91f16700Schasinglulu 
87*91f16700Schasinglulu 		memcpy(out_vec[i].base,
88*91f16700Schasinglulu 		       reply->trailer + payload_offset,
89*91f16700Schasinglulu 		       reply->out_size[i]);
90*91f16700Schasinglulu 		out_vec[i].len = reply->out_size[i];
91*91f16700Schasinglulu 		payload_offset += reply->out_size[i];
92*91f16700Schasinglulu 	}
93*91f16700Schasinglulu 
94*91f16700Schasinglulu 	*return_val = reply->return_val;
95*91f16700Schasinglulu 
96*91f16700Schasinglulu 	return PSA_SUCCESS;
97*91f16700Schasinglulu }
98