blob: 89fd8fead3fbe12be5f50f669b42c02f8e4f558c [file] [log] [blame]
Imre Kis9fcf8412020-11-23 03:15:45 +01001// SPDX-License-Identifier: BSD-3-Clause
2/*
Balint Dobszay40410ab2022-01-19 16:31:02 +01003 * Copyright (c) 2020-2022, Arm Limited and Contributors. All rights reserved.
Imre Kis9fcf8412020-11-23 03:15:45 +01004 */
5
6#include <assert.h> // for assert
7#include <stddef.h> // for size_t
8#include <stdint.h> // for uint32_t, uint16_t, uintptr_t, U
Imre Kise56c7b12023-06-01 13:33:40 +02009#include <string.h> // for memcpy
Imre Kis9fcf8412020-11-23 03:15:45 +010010#include "ffa_api.h" // for FFA_OK, ffa_interrupt_handler, ffa_fea...
11#include "ffa_api_defines.h" // for FFA_PARAM_MBZ, FFA_OK, FFA_ERROR, FFA_...
12#include "ffa_api_types.h" // for ffa_result, ffa_direct_msg, ffa_uuid
13#include "ffa_internal_api.h" // for ffa_params, ffa_svc
14#include "util.h" // for GENMASK_32, SHIFT_U32, BIT
15
16/*
17 * Unpacks the error code from the FFA_ERROR message. It is a signed 32 bit
18 * value in an unsigned 64 bit field so proper casting must be used to avoid
19 * compiler dependent behavior.
20 */
21static inline ffa_result ffa_get_errorcode(struct ffa_params *result)
22{
23 uint32_t raw_value = result->a2;
24
25 return *(ffa_result *)(&raw_value);
26}
27
28/*
29 * Unpacks the content of the SVC result into an ffa_direct_msg structure.
30 */
31static inline void ffa_unpack_direct_msg(struct ffa_params *svc_result,
32 struct ffa_direct_msg *msg)
33{
34 msg->function_id = svc_result->a0;
35 msg->source_id = (svc_result->a1 >> 16);
36 msg->destination_id = svc_result->a1;
Imre Kis1bc4a622022-07-19 17:38:00 +020037
38 if (FFA_IS_32_BIT_FUNC(msg->function_id)) {
39 msg->args.args32[0] = svc_result->a3;
40 msg->args.args32[1] = svc_result->a4;
41 msg->args.args32[2] = svc_result->a5;
42 msg->args.args32[3] = svc_result->a6;
43 msg->args.args32[4] = svc_result->a7;
44 } else {
45 msg->args.args64[0] = svc_result->a3;
46 msg->args.args64[1] = svc_result->a4;
47 msg->args.args64[2] = svc_result->a5;
48 msg->args.args64[3] = svc_result->a6;
49 msg->args.args64[4] = svc_result->a7;
50 }
Imre Kis9fcf8412020-11-23 03:15:45 +010051}
52
53/*
54 * The end of the interrupt handler is indicated by an FFA_MSG_WAIT call.
55 */
56static inline void ffa_return_from_interrupt(struct ffa_params *result)
57{
58 ffa_svc(FFA_MSG_WAIT, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
59 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
60 result);
61}
62
63static inline void ffa_uuid_to_abi_format(const struct ffa_uuid *uuid,
64 uint32_t *result)
65{
66 size_t i = 0;
67
68 for (i = 0; i < 4; i++) {
69 result[i] = uuid->uuid[4 * i];
70 result[i] |= SHIFT_U32(uuid->uuid[4 * i + 1], 8);
71 result[i] |= SHIFT_U32(uuid->uuid[4 * i + 2], 16);
72 result[i] |= SHIFT_U32(uuid->uuid[4 * i + 3], 24);
73 }
74}
75
76ffa_result ffa_version(uint32_t *version)
77{
78 struct ffa_params result = {0};
79 uint32_t self_version = 0;
80
81 self_version = (FFA_VERSION_MAJOR << FFA_VERSION_MAJOR_SHIFT) |
Imre Kis1f5b1c62024-01-15 12:51:03 +010082 (FFA_VERSION_MINOR << FFA_VERSION_MINOR_SHIFT);
Imre Kis9fcf8412020-11-23 03:15:45 +010083
84 ffa_svc(FFA_VERSION, self_version, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
85 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
86 &result);
87
88 if (result.a0 & BIT(31)) {
89 uint32_t raw_error = result.a0;
90
91 *version = 0;
92
93 return *(ffa_result *)(&raw_error);
94 }
95
96 *version = result.a0;
97 return FFA_OK;
98}
99
100ffa_result ffa_features(uint32_t ffa_function_id,
101 struct ffa_interface_properties *interface_properties)
102{
103 struct ffa_params result = {0};
104
105 ffa_svc(FFA_FEATURES, ffa_function_id, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
106 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
107 &result);
108
109 if (result.a0 == FFA_ERROR) {
110 interface_properties->interface_properties[0] = 0;
111 interface_properties->interface_properties[1] = 0;
112 return ffa_get_errorcode(&result);
113 }
114
115 assert(result.a0 == FFA_SUCCESS_32);
116 interface_properties->interface_properties[0] = result.a2;
117 interface_properties->interface_properties[1] = result.a3;
118 return FFA_OK;
119}
120
121ffa_result ffa_rx_release(void)
122{
123 struct ffa_params result = {0};
124
125 ffa_svc(FFA_RX_RELEASE, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
126 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
127 &result);
128
129 if (result.a0 == FFA_ERROR)
130 return ffa_get_errorcode(&result);
131
132 assert(result.a0 == FFA_SUCCESS_32);
133 return FFA_OK;
134}
135
136ffa_result ffa_rxtx_map(const void *tx_buffer, const void *rx_buffer,
137 uint32_t page_count)
138{
139 struct ffa_params result = {0};
140
141 assert(page_count <= FFA_RXTX_MAP_PAGE_COUNT_MAX);
142
143 page_count = SHIFT_U32(page_count & FFA_RXTX_MAP_PAGE_COUNT_MASK,
144 FFA_RXTX_MAP_PAGE_COUNT_SHIFT);
145
Balint Dobszay40410ab2022-01-19 16:31:02 +0100146 ffa_svc(FFA_RXTX_MAP_64, (uintptr_t)tx_buffer, (uintptr_t)rx_buffer,
Imre Kis9fcf8412020-11-23 03:15:45 +0100147 page_count, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
148 FFA_PARAM_MBZ, &result);
149
150 if (result.a0 == FFA_ERROR)
151 return ffa_get_errorcode(&result);
152
Balint Dobszay40410ab2022-01-19 16:31:02 +0100153 /*
154 * There are no 64-bit parameters returned with FFA_SUCCESS, the SPMC
155 * will use the default 32-bit version.
156 */
Imre Kis9fcf8412020-11-23 03:15:45 +0100157 assert(result.a0 == FFA_SUCCESS_32);
158 return FFA_OK;
159}
160
161ffa_result ffa_rxtx_unmap(uint16_t id)
162{
163 struct ffa_params result = {0};
164
165 ffa_svc(FFA_RXTX_UNMAP, SHIFT_U32(id, FFA_RXTX_UNMAP_ID_SHIFT),
166 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
167 FFA_PARAM_MBZ, FFA_PARAM_MBZ, &result);
168
169 if (result.a0 == FFA_ERROR)
170 return ffa_get_errorcode(&result);
171
172 assert(result.a0 == FFA_SUCCESS_32);
173 return FFA_OK;
174}
175
Imre Kis595c5d02024-01-15 15:28:19 +0100176#if CFG_FFA_VERSION == FFA_VERSION_1_0
Imre Kis9fcf8412020-11-23 03:15:45 +0100177ffa_result ffa_partition_info_get(const struct ffa_uuid *uuid, uint32_t *count)
178{
179 struct ffa_params result = {0};
180 uint32_t abi_uuid[4] = {0};
181
182 ffa_uuid_to_abi_format(uuid, abi_uuid);
183
184 ffa_svc(FFA_PARTITION_INFO_GET, abi_uuid[0], abi_uuid[1], abi_uuid[2],
185 abi_uuid[3], FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
186 &result);
187
188 if (result.a0 == FFA_ERROR) {
189 *count = UINT32_C(0);
190 return ffa_get_errorcode(&result);
191 }
192
193 assert(result.a0 == FFA_SUCCESS_32);
194 *count = result.a2;
195 return FFA_OK;
196}
Imre Kis595c5d02024-01-15 15:28:19 +0100197#elif CFG_FFA_VERSION >= FFA_VERSION_1_1
198ffa_result ffa_partition_info_get(const struct ffa_uuid *uuid, uint32_t flags, uint32_t *count,
199 uint32_t *size)
200{
201 struct ffa_params result = {0};
202 uint32_t abi_uuid[4] = {0};
203
204 ffa_uuid_to_abi_format(uuid, abi_uuid);
205
206 ffa_svc(FFA_PARTITION_INFO_GET, abi_uuid[0], abi_uuid[1], abi_uuid[2],
207 abi_uuid[3], flags, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
208 &result);
209
210 if (result.a0 == FFA_ERROR) {
211 *count = UINT32_C(0);
212 *size = UINT32_C(0);
213 return ffa_get_errorcode(&result);
214 }
215
216 assert(result.a0 == FFA_SUCCESS_32);
217 *count = result.a2;
218 *size = result.a3;
219 return FFA_OK;
220}
221#endif /* CFG_FFA_VERSION */
Imre Kis9fcf8412020-11-23 03:15:45 +0100222
223ffa_result ffa_id_get(uint16_t *id)
224{
225 struct ffa_params result = {0};
226
227 ffa_svc(FFA_ID_GET, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
228 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
229 &result);
230
231 if (result.a0 == FFA_ERROR) {
232 *id = FFA_ID_GET_ID_MASK;
233 return ffa_get_errorcode(&result);
234 }
235
236 assert(result.a0 == FFA_SUCCESS_32);
237 *id = (result.a2 >> FFA_ID_GET_ID_SHIFT) & FFA_ID_GET_ID_MASK;
238 return FFA_OK;
239}
240
241ffa_result ffa_msg_wait(struct ffa_direct_msg *msg)
242{
243 struct ffa_params result = {0};
244
245 ffa_svc(FFA_MSG_WAIT, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
246 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
247 &result);
248
249 while (result.a0 == FFA_INTERRUPT) {
250 ffa_interrupt_handler(result.a2);
251 ffa_return_from_interrupt(&result);
252 }
253
254 if (result.a0 == FFA_ERROR) {
255 return ffa_get_errorcode(&result);
Imre Kis1bc4a622022-07-19 17:38:00 +0200256 } else if (FFA_TO_32_BIT_FUNC(result.a0) == FFA_MSG_SEND_DIRECT_REQ_32) {
Imre Kis9fcf8412020-11-23 03:15:45 +0100257 ffa_unpack_direct_msg(&result, msg);
258 } else {
259 assert(result.a0 == FFA_SUCCESS_32);
260 *msg = (struct ffa_direct_msg){.function_id = result.a0};
261 }
262
263 return FFA_OK;
264}
265
Imre Kis1bc4a622022-07-19 17:38:00 +0200266static ffa_result ffa_msg_send_direct_req(uint32_t function_id, uint32_t resp_id,
267 uint16_t source, uint16_t dest,
268 uint64_t a0, uint64_t a1, uint64_t a2,
269 uint64_t a3, uint64_t a4,
270 struct ffa_direct_msg *msg)
Imre Kis9fcf8412020-11-23 03:15:45 +0100271{
272 struct ffa_params result = {0};
273
Imre Kis1bc4a622022-07-19 17:38:00 +0200274 ffa_svc(function_id,
Imre Kis9fcf8412020-11-23 03:15:45 +0100275 SHIFT_U32(source, FFA_MSG_SEND_DIRECT_REQ_SOURCE_ID_SHIFT) |
276 dest, FFA_PARAM_MBZ, a0, a1, a2, a3, a4, &result);
277
278 while (result.a0 == FFA_INTERRUPT) {
279 ffa_interrupt_handler(result.a2);
280 ffa_return_from_interrupt(&result);
281 }
282
283 if (result.a0 == FFA_ERROR) {
284 return ffa_get_errorcode(&result);
Imre Kis1bc4a622022-07-19 17:38:00 +0200285 } else if (result.a0 == resp_id) {
Imre Kis9fcf8412020-11-23 03:15:45 +0100286 ffa_unpack_direct_msg(&result, msg);
287 } else {
288 assert(result.a0 == FFA_SUCCESS_32);
289 *msg = (struct ffa_direct_msg){.function_id = result.a0};
290 }
291
292 return FFA_OK;
293}
294
Imre Kis1bc4a622022-07-19 17:38:00 +0200295ffa_result ffa_msg_send_direct_req_32(uint16_t source, uint16_t dest,
296 uint32_t a0, uint32_t a1, uint32_t a2,
297 uint32_t a3, uint32_t a4,
298 struct ffa_direct_msg *msg)
299{
300 return ffa_msg_send_direct_req(FFA_MSG_SEND_DIRECT_REQ_32,
301 FFA_MSG_SEND_DIRECT_RESP_32,
302 source, dest, a0, a1, a2, a3, a4, msg);
303}
304
305ffa_result ffa_msg_send_direct_req_64(uint16_t source, uint16_t dest,
306 uint64_t a0, uint64_t a1, uint64_t a2,
307 uint64_t a3, uint64_t a4,
308 struct ffa_direct_msg *msg)
309{
310 return ffa_msg_send_direct_req(FFA_MSG_SEND_DIRECT_REQ_64,
311 FFA_MSG_SEND_DIRECT_RESP_64,
312 source, dest, a0, a1, a2, a3, a4, msg);
313}
314
315static ffa_result ffa_msg_send_direct_resp(uint32_t function_id,
316 uint16_t source, uint16_t dest,
317 uint64_t a0, uint64_t a1,
318 uint64_t a2, uint64_t a3,
319 uint64_t a4,
320 struct ffa_direct_msg *msg)
Imre Kis9fcf8412020-11-23 03:15:45 +0100321{
322 struct ffa_params result = {0};
323
Imre Kis1bc4a622022-07-19 17:38:00 +0200324 ffa_svc(function_id,
Imre Kis9fcf8412020-11-23 03:15:45 +0100325 SHIFT_U32(source, FFA_MSG_SEND_DIRECT_RESP_SOURCE_ID_SHIFT) |
326 dest, FFA_PARAM_MBZ, a0, a1, a2, a3, a4, &result);
327
328 while (result.a0 == FFA_INTERRUPT) {
329 ffa_interrupt_handler(result.a2);
330 ffa_return_from_interrupt(&result);
331 }
332
333 if (result.a0 == FFA_ERROR) {
334 return ffa_get_errorcode(&result);
Imre Kis1bc4a622022-07-19 17:38:00 +0200335 } else if (FFA_TO_32_BIT_FUNC(result.a0) == FFA_MSG_SEND_DIRECT_REQ_32) {
Imre Kis9fcf8412020-11-23 03:15:45 +0100336 ffa_unpack_direct_msg(&result, msg);
337 } else {
338 assert(result.a0 == FFA_SUCCESS_32);
339 *msg = (struct ffa_direct_msg){.function_id = result.a0};
340 }
341
342 return FFA_OK;
343}
Imre Kise3112e02020-11-23 03:15:46 +0100344
Imre Kis1bc4a622022-07-19 17:38:00 +0200345ffa_result ffa_msg_send_direct_resp_32(uint16_t source, uint16_t dest,
346 uint32_t a0, uint32_t a1, uint32_t a2,
347 uint32_t a3, uint32_t a4,
348 struct ffa_direct_msg *msg)
349{
350 return ffa_msg_send_direct_resp(FFA_MSG_SEND_DIRECT_RESP_32, source,
351 dest, a0, a1, a2, a3, a4, msg);
352}
353
354ffa_result ffa_msg_send_direct_resp_64(uint16_t source, uint16_t dest,
355 uint64_t a0, uint64_t a1, uint64_t a2,
356 uint64_t a3, uint64_t a4,
357 struct ffa_direct_msg *msg)
358{
359 return ffa_msg_send_direct_resp(FFA_MSG_SEND_DIRECT_RESP_64, source,
360 dest, a0, a1, a2, a3, a4, msg);
361}
362
Imre Kise3112e02020-11-23 03:15:46 +0100363ffa_result ffa_mem_donate(uint32_t total_length, uint32_t fragment_length,
364 void *buffer_address, uint32_t page_count,
365 uint64_t *handle)
366{
367 struct ffa_params result = {0};
368
Balint Dobszay40410ab2022-01-19 16:31:02 +0100369 ffa_svc((buffer_address) ? FFA_MEM_DONATE_64 : FFA_MEM_DONATE_32,
370 total_length, fragment_length, (uintptr_t)buffer_address,
371 page_count, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
372 &result);
Imre Kise3112e02020-11-23 03:15:46 +0100373
374 if (result.a0 == FFA_ERROR) {
375 *handle = 0U;
376 return ffa_get_errorcode(&result);
377 }
378
Balint Dobszay40410ab2022-01-19 16:31:02 +0100379 /*
380 * There are no 64-bit parameters returned with FFA_SUCCESS, the SPMC
381 * will use the default 32-bit version.
382 */
Imre Kise3112e02020-11-23 03:15:46 +0100383 assert(result.a0 == FFA_SUCCESS_32);
384 *handle = reg_pair_to_64(result.a3, result.a2);
385 return FFA_OK;
386}
387
388ffa_result ffa_mem_donate_rxtx(uint32_t total_length, uint32_t fragment_length,
389 uint64_t *handle)
390{
391 return ffa_mem_donate(total_length, fragment_length, NULL, 0, handle);
392}
393
394ffa_result ffa_mem_lend(uint32_t total_length, uint32_t fragment_length,
395 void *buffer_address, uint32_t page_count,
396 uint64_t *handle)
397{
398 struct ffa_params result = {0};
399
Balint Dobszay40410ab2022-01-19 16:31:02 +0100400 ffa_svc((buffer_address) ? FFA_MEM_LEND_64 : FFA_MEM_LEND_32,
401 total_length, fragment_length, (uintptr_t)buffer_address,
402 page_count, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
403 &result);
Imre Kise3112e02020-11-23 03:15:46 +0100404
405 if (result.a0 == FFA_ERROR) {
406 *handle = 0U;
407 return ffa_get_errorcode(&result);
408 }
409
Balint Dobszay40410ab2022-01-19 16:31:02 +0100410 /*
411 * There are no 64-bit parameters returned with FFA_SUCCESS, the SPMC
412 * will use the default 32-bit version.
413 */
Imre Kise3112e02020-11-23 03:15:46 +0100414 assert(result.a0 == FFA_SUCCESS_32);
415 *handle = reg_pair_to_64(result.a3, result.a2);
416 return FFA_OK;
417}
418
419ffa_result ffa_mem_lend_rxtx(uint32_t total_length, uint32_t fragment_length,
420 uint64_t *handle)
421{
422 return ffa_mem_lend(total_length, fragment_length, NULL, 0, handle);
423}
424
425ffa_result ffa_mem_share(uint32_t total_length, uint32_t fragment_length,
426 void *buffer_address, uint32_t page_count,
427 uint64_t *handle)
428{
429 struct ffa_params result = {0};
430
Balint Dobszay40410ab2022-01-19 16:31:02 +0100431 ffa_svc((buffer_address) ? FFA_MEM_SHARE_64 : FFA_MEM_SHARE_32,
432 total_length, fragment_length, (uintptr_t)buffer_address,
433 page_count, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
434 &result);
Imre Kise3112e02020-11-23 03:15:46 +0100435
436 if (result.a0 == FFA_ERROR) {
437 *handle = 0U;
438 return ffa_get_errorcode(&result);
439 }
440
Balint Dobszay40410ab2022-01-19 16:31:02 +0100441 /*
442 * There are no 64-bit parameters returned with FFA_SUCCESS, the SPMC
443 * will use the default 32-bit version.
444 */
Imre Kise3112e02020-11-23 03:15:46 +0100445 assert(result.a0 == FFA_SUCCESS_32);
446 *handle = reg_pair_to_64(result.a3, result.a2);
447 return FFA_OK;
448}
449
450ffa_result ffa_mem_share_rxtx(uint32_t total_length, uint32_t fragment_length,
451 uint64_t *handle)
452{
453 return ffa_mem_share(total_length, fragment_length, NULL, 0, handle);
454}
455
456ffa_result ffa_mem_retrieve_req(uint32_t total_length, uint32_t fragment_length,
457 void *buffer_address, uint32_t page_count,
458 uint32_t *resp_total_length,
459 uint32_t *resp_fragment_length)
460{
461 struct ffa_params result = {0};
462
Balint Dobszay40410ab2022-01-19 16:31:02 +0100463 ffa_svc((buffer_address) ? FFA_MEM_RETRIEVE_REQ_64 : FFA_MEM_RETRIEVE_REQ_32,
464 total_length, fragment_length, (uintptr_t)buffer_address,
465 page_count, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
466 &result);
Imre Kise3112e02020-11-23 03:15:46 +0100467
468 if (result.a0 == FFA_ERROR) {
469 *resp_total_length = 0U;
470 *resp_fragment_length = 0U;
471 return ffa_get_errorcode(&result);
472 }
473
474 assert(result.a0 == FFA_MEM_RETRIEVE_RESP);
475 *resp_total_length = result.a1;
476 *resp_fragment_length = result.a2;
477 return FFA_OK;
478}
479
480ffa_result ffa_mem_retrieve_req_rxtx(uint32_t total_length,
481 uint32_t fragment_length,
482 uint32_t *resp_total_length,
483 uint32_t *resp_fragment_length)
484{
485 return ffa_mem_retrieve_req(total_length, fragment_length, NULL, 0,
486 resp_total_length, resp_fragment_length);
487}
488
489ffa_result ffa_mem_relinquish(void)
490{
491 struct ffa_params result = {0};
492
493 ffa_svc(FFA_MEM_RELINQUISH, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
494 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
495 &result);
496
497 if (result.a0 == FFA_ERROR)
498 return ffa_get_errorcode(&result);
499
500 assert(result.a0 == FFA_SUCCESS_32);
501 return FFA_OK;
502}
503
504ffa_result ffa_mem_reclaim(uint64_t handle, uint32_t flags)
505{
506 struct ffa_params result = {0};
507 uint32_t handle_hi = 0;
508 uint32_t handle_lo = 0;
509
510 reg_pair_from_64(handle, &handle_hi, &handle_lo);
511
512 ffa_svc(FFA_MEM_RECLAIM, handle_lo, handle_hi, flags, FFA_PARAM_MBZ,
513 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, &result);
514
515 if (result.a0 == FFA_ERROR)
516 return ffa_get_errorcode(&result);
517
518 assert(result.a0 == FFA_SUCCESS_32);
519 return FFA_OK;
520}
Imre Kisa5201e42022-02-22 15:25:21 +0100521
522ffa_result ffa_mem_perm_get(const void *base_address, uint32_t *mem_perm)
523{
524 struct ffa_params result = {0};
525
526 ffa_svc(FFA_MEM_PERM_GET, (uintptr_t)base_address, FFA_PARAM_MBZ,
527 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
528 FFA_PARAM_MBZ, &result);
529
530 if (result.a0 == FFA_ERROR)
531 return ffa_get_errorcode(&result);
532
533 assert(result.a0 == FFA_SUCCESS_32);
534 *mem_perm = result.a2;
535 return FFA_OK;
536}
537
538ffa_result ffa_mem_perm_set(const void *base_address, uint32_t page_count,
539 uint32_t mem_perm)
540{
541 struct ffa_params result = {0};
542
543 assert((mem_perm & FFA_MEM_PERM_RESERVED_MASK) == 0);
544
545 ffa_svc(FFA_MEM_PERM_SET, (uintptr_t)base_address, page_count, mem_perm,
546 FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ, FFA_PARAM_MBZ,
547 &result);
548
549 if (result.a0 == FFA_ERROR)
550 return ffa_get_errorcode(&result);
551
552 assert(result.a0 == FFA_SUCCESS_32);
553 return FFA_OK;
554}
Imre Kise56c7b12023-06-01 13:33:40 +0200555
556ffa_result ffa_console_log_32(const char *message, size_t length)
557{
558 struct ffa_params result = {0};
559 uint32_t char_lists[6] = {0};
560
561 assert(length > 0 && length <= sizeof(char_lists));
562
563 memcpy(char_lists, message, MIN(length, sizeof(char_lists)));
564
565 ffa_svc(FFA_CONSOLE_LOG_32, length, char_lists[0], char_lists[1],
566 char_lists[2], char_lists[3], char_lists[4], char_lists[5],
567 &result);
568
569 if (result.a0 == FFA_ERROR)
570 return ffa_get_errorcode(&result);
571
572 assert(result.a0 == FFA_SUCCESS_32);
573 return FFA_OK;
574}
575
576ffa_result ffa_console_log_64(const char *message, size_t length)
577{
578 struct ffa_params result = {0};
579 uint64_t char_lists[6] = {0};
580
581 assert(length > 0 && length <= sizeof(char_lists));
582
583 memcpy(char_lists, message, MIN(length, sizeof(char_lists)));
584
585 ffa_svc(FFA_CONSOLE_LOG_64, length, char_lists[0], char_lists[1],
586 char_lists[2], char_lists[3], char_lists[4], char_lists[5],
587 &result);
588
589 if (result.a0 == FFA_ERROR)
590 return ffa_get_errorcode(&result);
591
592 assert(result.a0 == FFA_SUCCESS_32);
593 return FFA_OK;
594}