1 // SPDX-License-Identifier: BSD-3-Clause
2 /*
3 * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
4 */
5
6 #include "ffa_api.h"
7 #include "sp_api_defines.h"
8 #include "sp_messaging.h"
9 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
10 #include "ffa_direct_msg_routing_extension.h"
11 #endif
12
13 #include <string.h>
14
pack_ffa_direct_msg(const struct sp_msg * msg,struct ffa_direct_msg * ffa_msg)15 static void pack_ffa_direct_msg(const struct sp_msg *msg,
16 struct ffa_direct_msg *ffa_msg)
17 {
18 ffa_msg->source_id = msg->source_id;
19 ffa_msg->destination_id = msg->destination_id;
20
21 if (msg->is_64bit_message) {
22 ffa_msg->function_id = FFA_TO_64_BIT_FUNC(0);
23 memcpy(ffa_msg->args.args64, msg->args.args64, sizeof(msg->args.args64));
24 } else {
25 memcpy(ffa_msg->args.args32, msg->args.args32, sizeof(msg->args.args32));
26 }
27 }
28
unpack_ffa_direct_msg(const struct ffa_direct_msg * ffa_msg,struct sp_msg * msg)29 static void unpack_ffa_direct_msg(const struct ffa_direct_msg *ffa_msg,
30 struct sp_msg *msg)
31 {
32 if (ffa_msg->function_id == FFA_MSG_SEND_DIRECT_REQ_32 ||
33 ffa_msg->function_id == FFA_MSG_SEND_DIRECT_RESP_32) {
34 /*
35 * Handling 32 bit request or response
36 */
37 msg->source_id = ffa_msg->source_id;
38 msg->destination_id = ffa_msg->destination_id;
39 msg->is_64bit_message = false;
40
41 memcpy(msg->args.args32, ffa_msg->args.args32, sizeof(msg->args.args32));
42 } else if (ffa_msg->function_id == FFA_MSG_SEND_DIRECT_REQ_64 ||
43 ffa_msg->function_id == FFA_MSG_SEND_DIRECT_RESP_64) {
44 /*
45 * Handling 64 bit request or response
46 */
47 msg->source_id = ffa_msg->source_id;
48 msg->destination_id = ffa_msg->destination_id;
49 msg->is_64bit_message = true;
50
51 memcpy(msg->args.args64, ffa_msg->args.args64, sizeof(msg->args.args64));
52 } else {
53 /* Success has no message parameters */
54 *msg = (struct sp_msg){ 0 };
55 }
56 }
57
sp_msg_wait(struct sp_msg * msg)58 sp_result sp_msg_wait(struct sp_msg *msg)
59 {
60 ffa_result ffa_res = FFA_OK;
61 struct ffa_direct_msg ffa_msg = { 0 };
62
63 if (!msg)
64 return SP_RESULT_INVALID_PARAMETERS;
65
66 ffa_res = ffa_msg_wait(&ffa_msg);
67 if (ffa_res != FFA_OK) {
68 *msg = (struct sp_msg){ 0 };
69 return SP_RESULT_FFA(ffa_res);
70 }
71
72 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
73 ffa_res = ffa_direct_msg_routing_ext_wait_post_hook(&ffa_msg);
74 if (ffa_res != FFA_OK) {
75 *msg = (struct sp_msg){ 0 };
76 return SP_RESULT_FFA(ffa_res);
77 }
78 #endif
79
80 unpack_ffa_direct_msg(&ffa_msg, msg);
81
82 return SP_RESULT_OK;
83 }
84
sp_msg_send_direct_req(const struct sp_msg * req,struct sp_msg * resp)85 sp_result sp_msg_send_direct_req(const struct sp_msg *req, struct sp_msg *resp)
86 {
87 ffa_result ffa_res = FFA_OK;
88 struct ffa_direct_msg ffa_req = { 0 };
89 struct ffa_direct_msg ffa_resp = { 0 };
90
91 if (!resp)
92 return SP_RESULT_INVALID_PARAMETERS;
93
94 if (!req) {
95 *resp = (struct sp_msg){ 0 };
96 return SP_RESULT_INVALID_PARAMETERS;
97 }
98
99 pack_ffa_direct_msg(req, &ffa_req);
100
101 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
102 ffa_res = ffa_direct_msg_routing_ext_req_pre_hook(&ffa_req);
103 if (ffa_res != FFA_OK) {
104 *resp = (struct sp_msg){ 0 };
105 return SP_RESULT_INVALID_PARAMETERS;
106 }
107 #endif
108
109 if (req->is_64bit_message)
110 ffa_res = ffa_msg_send_direct_req_64(
111 ffa_req.source_id, ffa_req.destination_id,
112 ffa_req.args.args64[0], ffa_req.args.args64[1],
113 ffa_req.args.args64[2], ffa_req.args.args64[3],
114 ffa_req.args.args64[4], &ffa_resp);
115 else
116 ffa_res = ffa_msg_send_direct_req_32(
117 ffa_req.source_id, ffa_req.destination_id,
118 ffa_req.args.args32[0], ffa_req.args.args32[1],
119 ffa_req.args.args32[2], ffa_req.args.args32[3],
120 ffa_req.args.args32[4], &ffa_resp);
121
122 if (ffa_res != FFA_OK) {
123 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
124 ffa_direct_msg_routing_ext_req_error_hook();
125 #endif
126 *resp = (struct sp_msg){ 0 };
127 return SP_RESULT_FFA(ffa_res);
128 }
129
130 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
131 ffa_res = ffa_direct_msg_routing_ext_req_post_hook(&ffa_resp);
132 if (ffa_res != SP_RESULT_OK) {
133 *resp = (struct sp_msg){ 0 };
134 return SP_RESULT_FFA(ffa_res);
135 }
136 #endif
137
138 unpack_ffa_direct_msg(&ffa_resp, resp);
139
140 return SP_RESULT_OK;
141 }
142
sp_msg_send_direct_resp(const struct sp_msg * resp,struct sp_msg * req)143 sp_result sp_msg_send_direct_resp(const struct sp_msg *resp, struct sp_msg *req)
144 {
145 ffa_result ffa_res = FFA_OK;
146 struct ffa_direct_msg ffa_resp = { 0 };
147 struct ffa_direct_msg ffa_req = { 0 };
148
149 if (!req)
150 return SP_RESULT_INVALID_PARAMETERS;
151
152 if (!resp) {
153 *req = (struct sp_msg){ 0 };
154 return SP_RESULT_INVALID_PARAMETERS;
155 }
156
157 pack_ffa_direct_msg(resp, &ffa_resp);
158
159 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
160 ffa_res = ffa_direct_msg_routing_ext_resp_pre_hook(&ffa_resp);
161 if (ffa_res != FFA_OK) {
162 *req = (struct sp_msg){ 0 };
163 return SP_RESULT_INVALID_PARAMETERS;
164 }
165 #endif
166
167 if (resp->is_64bit_message)
168 ffa_res = ffa_msg_send_direct_resp_64(
169 ffa_resp.source_id, ffa_resp.destination_id,
170 ffa_resp.args.args64[0], ffa_resp.args.args64[1],
171 ffa_resp.args.args64[2], ffa_resp.args.args64[3],
172 ffa_resp.args.args64[4], &ffa_req);
173 else
174 ffa_res = ffa_msg_send_direct_resp_32(
175 ffa_resp.source_id, ffa_resp.destination_id,
176 ffa_resp.args.args32[0], ffa_resp.args.args32[1],
177 ffa_resp.args.args32[2], ffa_resp.args.args32[3],
178 ffa_resp.args.args32[4], &ffa_req);
179
180 if (ffa_res != FFA_OK) {
181 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
182 ffa_direct_msg_routing_ext_resp_error_hook();
183 #endif
184 *req = (struct sp_msg){ 0 };
185 return SP_RESULT_FFA(ffa_res);
186 }
187
188 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
189 ffa_res = ffa_direct_msg_routing_ext_resp_post_hook(&ffa_req);
190 if (ffa_res != SP_RESULT_OK) {
191 *req = (struct sp_msg){ 0 };
192 return SP_RESULT_FFA(ffa_res);
193 }
194 #endif
195
196 unpack_ffa_direct_msg(&ffa_req, req);
197
198 return SP_RESULT_OK;
199 }
200
201 #if FFA_DIRECT_MSG_ROUTING_EXTENSION
sp_msg_send_rc_req(const struct sp_msg * req,struct sp_msg * resp)202 sp_result sp_msg_send_rc_req(const struct sp_msg *req, struct sp_msg *resp)
203 {
204 ffa_result ffa_res = FFA_OK;
205 struct ffa_direct_msg ffa_req = { 0 };
206 struct ffa_direct_msg ffa_resp = { 0 };
207
208 if (!resp)
209 return SP_RESULT_INVALID_PARAMETERS;
210
211 if (!req) {
212 *resp = (struct sp_msg){ 0 };
213 return SP_RESULT_INVALID_PARAMETERS;
214 }
215
216 pack_ffa_direct_msg(req, &ffa_req);
217
218 ffa_res = ffa_direct_msg_routing_ext_rc_req_pre_hook(&ffa_req);
219 if (ffa_res != FFA_OK) {
220 *resp = (struct sp_msg){ 0 };
221 return SP_RESULT_INVALID_PARAMETERS;
222 }
223
224 ffa_res = ffa_msg_send_direct_resp_32(ffa_req.source_id,
225 ffa_req.destination_id,
226 ffa_req.args.args32[0], ffa_req.args.args32[1],
227 ffa_req.args.args32[2], ffa_req.args.args32[3],
228 ffa_req.args.args32[4], &ffa_resp);
229
230 if (ffa_res != FFA_OK) {
231 ffa_direct_msg_routing_ext_rc_req_error_hook();
232 *resp = (struct sp_msg){ 0 };
233 return SP_RESULT_FFA(ffa_res);
234 }
235
236 ffa_res = ffa_direct_msg_routing_ext_rc_req_post_hook(&ffa_resp);
237 if (ffa_res != SP_RESULT_OK) {
238 *resp = (struct sp_msg){ 0 };
239 return SP_RESULT_FFA(ffa_res);
240 }
241
242 unpack_ffa_direct_msg(&ffa_resp, resp);
243
244 return SP_RESULT_OK;
245 }
246 #endif
247