blob: 392006bc45bd517924fb9aaac4166d9058d5b65c [file] [log] [blame]
Imre Kisc674b5b2021-02-09 19:05:27 +01001// SPDX-License-Identifier: BSD-3-Clause
2/*
Imre Kis1bc4a622022-07-19 17:38:00 +02003 * Copyright (c) 2021-2022, Arm Limited and Contributors. All rights reserved.
Imre Kisc674b5b2021-02-09 19:05:27 +01004 */
5
6#include "ffa_api.h"
7#include "sp_api_defines.h"
8#include "sp_messaging.h"
Imre Kisbe97e772021-02-25 17:56:19 +01009#if FFA_DIRECT_MSG_ROUTING_EXTENSION
10#include "ffa_direct_msg_routing_extension.h"
11#endif
Imre Kisc674b5b2021-02-09 19:05:27 +010012
13#include <string.h>
14
15#define SP_MSG_ARG_OFFSET (1)
16
17static void pack_ffa_direct_msg(const struct sp_msg *msg,
18 struct ffa_direct_msg *ffa_msg)
19{
Imre Kisc674b5b2021-02-09 19:05:27 +010020 ffa_msg->source_id = msg->source_id;
21 ffa_msg->destination_id = msg->destination_id;
22
Imre Kis1bc4a622022-07-19 17:38:00 +020023 ffa_msg->args.args64[0] = 0;
24 if (msg->is_64bit_message)
25 memcpy(&ffa_msg->args.args64[SP_MSG_ARG_OFFSET],
26 msg->args.args64, sizeof(msg->args.args64));
27 else
28 memcpy(&ffa_msg->args.args32[SP_MSG_ARG_OFFSET],
29 msg->args.args32, sizeof(msg->args.args32));
Imre Kisc674b5b2021-02-09 19:05:27 +010030}
31
32static void unpack_ffa_direct_msg(const struct ffa_direct_msg *ffa_msg,
33 struct sp_msg *msg)
34{
Imre Kis1bc4a622022-07-19 17:38:00 +020035 if (ffa_msg->function_id == FFA_MSG_SEND_DIRECT_REQ_32 ||
36 ffa_msg->function_id == FFA_MSG_SEND_DIRECT_RESP_32) {
Imre Kisc674b5b2021-02-09 19:05:27 +010037 /*
Imre Kis1bc4a622022-07-19 17:38:00 +020038 * Handling 32 bit request or response
Imre Kisc674b5b2021-02-09 19:05:27 +010039 */
40 msg->source_id = ffa_msg->source_id;
41 msg->destination_id = ffa_msg->destination_id;
Imre Kis1bc4a622022-07-19 17:38:00 +020042 msg->is_64bit_message = FFA_IS_64_BIT_FUNC(ffa_msg->function_id);
Imre Kisc674b5b2021-02-09 19:05:27 +010043
Imre Kis1bc4a622022-07-19 17:38:00 +020044 memcpy(msg->args.args32, &ffa_msg->args.args32[SP_MSG_ARG_OFFSET],
45 sizeof(msg->args.args32));
46 } else if (ffa_msg->function_id == FFA_MSG_SEND_DIRECT_REQ_64 ||
47 ffa_msg->function_id == FFA_MSG_SEND_DIRECT_RESP_64) {
48 /*
49 * Handling 64 bit request or response
50 */
51 msg->source_id = ffa_msg->source_id;
52 msg->destination_id = ffa_msg->destination_id;
53 msg->is_64bit_message = FFA_IS_64_BIT_FUNC(ffa_msg->function_id);
54
55 memcpy(msg->args.args64, &ffa_msg->args.args64[SP_MSG_ARG_OFFSET],
56 sizeof(msg->args.args64));
Imre Kisc674b5b2021-02-09 19:05:27 +010057 } else {
58 /* Success has no message parameters */
59 *msg = (struct sp_msg){ 0 };
60 }
61}
62
63sp_result sp_msg_wait(struct sp_msg *msg)
64{
65 ffa_result ffa_res = FFA_OK;
66 struct ffa_direct_msg ffa_msg = { 0 };
67
68 if (!msg)
69 return SP_RESULT_INVALID_PARAMETERS;
70
71 ffa_res = ffa_msg_wait(&ffa_msg);
72 if (ffa_res != FFA_OK) {
73 *msg = (struct sp_msg){ 0 };
74 return SP_RESULT_FFA(ffa_res);
75 }
76
Imre Kisbe97e772021-02-25 17:56:19 +010077#if FFA_DIRECT_MSG_ROUTING_EXTENSION
78 ffa_res = ffa_direct_msg_routing_ext_wait_post_hook(&ffa_msg);
79 if (ffa_res != FFA_OK) {
80 *msg = (struct sp_msg){ 0 };
81 return SP_RESULT_FFA(ffa_res);
82 }
83#endif
84
Imre Kisc674b5b2021-02-09 19:05:27 +010085 unpack_ffa_direct_msg(&ffa_msg, msg);
86
87 return SP_RESULT_OK;
88}
89
90sp_result sp_msg_send_direct_req(const struct sp_msg *req, struct sp_msg *resp)
91{
92 ffa_result ffa_res = FFA_OK;
93 struct ffa_direct_msg ffa_req = { 0 };
94 struct ffa_direct_msg ffa_resp = { 0 };
95
96 if (!resp)
97 return SP_RESULT_INVALID_PARAMETERS;
98
99 if (!req) {
100 *resp = (struct sp_msg){ 0 };
101 return SP_RESULT_INVALID_PARAMETERS;
102 }
103
104 pack_ffa_direct_msg(req, &ffa_req);
105
Imre Kisbe97e772021-02-25 17:56:19 +0100106#if FFA_DIRECT_MSG_ROUTING_EXTENSION
107 ffa_direct_msg_routing_ext_req_pre_hook(&ffa_req);
108#endif
109
Imre Kis1bc4a622022-07-19 17:38:00 +0200110 if (req->is_64bit_message)
111 ffa_res = ffa_msg_send_direct_req_64(
112 ffa_req.source_id, ffa_req.destination_id,
113 ffa_req.args.args64[0], ffa_req.args.args64[1],
114 ffa_req.args.args64[2], ffa_req.args.args64[3],
115 ffa_req.args.args64[4], &ffa_resp);
116 else
117 ffa_res = ffa_msg_send_direct_req_32(
118 ffa_req.source_id, ffa_req.destination_id,
119 ffa_req.args.args32[0], ffa_req.args.args32[1],
120 ffa_req.args.args32[2], ffa_req.args.args32[3],
121 ffa_req.args.args32[4], &ffa_resp);
Imre Kisc674b5b2021-02-09 19:05:27 +0100122
123 if (ffa_res != FFA_OK) {
Imre Kisbe97e772021-02-25 17:56:19 +0100124#if FFA_DIRECT_MSG_ROUTING_EXTENSION
125 ffa_direct_msg_routing_ext_req_error_hook();
126#endif
Imre Kisc674b5b2021-02-09 19:05:27 +0100127 *resp = (struct sp_msg){ 0 };
128 return SP_RESULT_FFA(ffa_res);
129 }
130
Imre Kisbe97e772021-02-25 17:56:19 +0100131#if FFA_DIRECT_MSG_ROUTING_EXTENSION
132 ffa_res = ffa_direct_msg_routing_ext_req_post_hook(&ffa_resp);
133 if (ffa_res != SP_RESULT_OK) {
134 *resp = (struct sp_msg){ 0 };
135 return SP_RESULT_FFA(ffa_res);
136 }
137#endif
138
Imre Kisc674b5b2021-02-09 19:05:27 +0100139 unpack_ffa_direct_msg(&ffa_resp, resp);
140
141 return SP_RESULT_OK;
142}
143
144sp_result sp_msg_send_direct_resp(const struct sp_msg *resp, struct sp_msg *req)
145{
146 ffa_result ffa_res = FFA_OK;
147 struct ffa_direct_msg ffa_resp = { 0 };
148 struct ffa_direct_msg ffa_req = { 0 };
149
150 if (!req)
151 return SP_RESULT_INVALID_PARAMETERS;
152
153 if (!resp) {
154 *req = (struct sp_msg){ 0 };
155 return SP_RESULT_INVALID_PARAMETERS;
156 }
157
158 pack_ffa_direct_msg(resp, &ffa_resp);
159
Imre Kisbe97e772021-02-25 17:56:19 +0100160#if FFA_DIRECT_MSG_ROUTING_EXTENSION
161 ffa_direct_msg_routing_ext_resp_pre_hook(&ffa_resp);
162#endif
163
Imre Kis1bc4a622022-07-19 17:38:00 +0200164 if (resp->is_64bit_message)
165 ffa_res = ffa_msg_send_direct_resp_64(
166 ffa_resp.source_id, ffa_resp.destination_id,
167 ffa_resp.args.args64[0], ffa_resp.args.args64[1],
168 ffa_resp.args.args64[2], ffa_resp.args.args64[3],
169 ffa_resp.args.args64[4], &ffa_req);
170 else
171 ffa_res = ffa_msg_send_direct_resp_32(
172 ffa_resp.source_id, ffa_resp.destination_id,
173 ffa_resp.args.args32[0], ffa_resp.args.args32[1],
174 ffa_resp.args.args32[2], ffa_resp.args.args32[3],
175 ffa_resp.args.args32[4], &ffa_req);
Imre Kisc674b5b2021-02-09 19:05:27 +0100176
177 if (ffa_res != FFA_OK) {
Imre Kisbe97e772021-02-25 17:56:19 +0100178#if FFA_DIRECT_MSG_ROUTING_EXTENSION
179 ffa_direct_msg_routing_ext_resp_error_hook();
180#endif
Imre Kisc674b5b2021-02-09 19:05:27 +0100181 *req = (struct sp_msg){ 0 };
182 return SP_RESULT_FFA(ffa_res);
183 }
184
Imre Kisbe97e772021-02-25 17:56:19 +0100185#if FFA_DIRECT_MSG_ROUTING_EXTENSION
186 ffa_res = ffa_direct_msg_routing_ext_resp_post_hook(&ffa_req);
187 if (ffa_res != SP_RESULT_OK) {
188 *req = (struct sp_msg){ 0 };
189 return SP_RESULT_FFA(ffa_res);
190 }
191#endif
192
Imre Kisc674b5b2021-02-09 19:05:27 +0100193 unpack_ffa_direct_msg(&ffa_req, req);
194
195 return SP_RESULT_OK;
196}
Imre Kisbe97e772021-02-25 17:56:19 +0100197
198#if FFA_DIRECT_MSG_ROUTING_EXTENSION
199sp_result sp_msg_send_rc_req(const struct sp_msg *req, struct sp_msg *resp)
200{
201 ffa_result ffa_res = FFA_OK;
202 struct ffa_direct_msg ffa_req = { 0 };
203 struct ffa_direct_msg ffa_resp = { 0 };
204
205 if (!resp)
206 return SP_RESULT_INVALID_PARAMETERS;
207
208 if (!req) {
209 *resp = (struct sp_msg){ 0 };
210 return SP_RESULT_INVALID_PARAMETERS;
211 }
212
213 pack_ffa_direct_msg(req, &ffa_req);
214
215 ffa_direct_msg_routing_ext_rc_req_pre_hook(&ffa_req);
216
Imre Kis1bc4a622022-07-19 17:38:00 +0200217 ffa_res = ffa_msg_send_direct_resp_32(ffa_req.source_id,
Imre Kisbe97e772021-02-25 17:56:19 +0100218 ffa_req.destination_id,
Imre Kis1bc4a622022-07-19 17:38:00 +0200219 ffa_req.args.args32[0], ffa_req.args.args32[1],
220 ffa_req.args.args32[2], ffa_req.args.args32[3],
221 ffa_req.args.args32[4], &ffa_resp);
Imre Kisbe97e772021-02-25 17:56:19 +0100222
223 if (ffa_res != FFA_OK) {
224 ffa_direct_msg_routing_ext_rc_req_error_hook();
225 *resp = (struct sp_msg){ 0 };
226 return SP_RESULT_FFA(ffa_res);
227 }
228
229 ffa_res = ffa_direct_msg_routing_ext_rc_req_post_hook(&ffa_resp);
230 if (ffa_res != SP_RESULT_OK) {
231 *resp = (struct sp_msg){ 0 };
232 return SP_RESULT_FFA(ffa_res);
233 }
234
235 unpack_ffa_direct_msg(&ffa_resp, resp);
236
237 return SP_RESULT_OK;
238}
239#endif