blob: cd87859f5cef292fdd1b957a85bca8ab9d4b9732 [file] [log] [blame]
J-Alves7581c382020-05-07 18:34:20 +01001/*
Karl Meakin92aa7702023-10-11 18:48:01 +01002 * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
J-Alves7581c382020-05-07 18:34:20 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef FFA_HELPERS_H
8#define FFA_HELPERS_H
9
J-Alves8f08a052020-05-26 17:14:40 +010010#include <ffa_svc.h>
J-Alves7581c382020-05-07 18:34:20 +010011#include <tftf_lib.h>
12#include <utils_def.h>
13
14/* This error code must be different to the ones used by FFA */
15#define FFA_TFTF_ERROR -42
16
Daniel Boulbye79d2072021-03-03 11:34:53 +000017typedef unsigned short ffa_id_t;
J-Alves5aecd982020-06-11 10:25:33 +010018typedef unsigned short ffa_vm_count_t;
19typedef unsigned short ffa_vcpu_count_t;
J-Alvesf3a393c2020-10-23 16:00:39 +010020typedef uint64_t ffa_memory_handle_t;
21/** Flags to indicate properties of receivers during memory region retrieval. */
22typedef uint8_t ffa_memory_receiver_flags_t;
J-Alves5aecd982020-06-11 10:25:33 +010023
J-Alvesd708c032020-11-19 12:14:21 +000024struct ffa_uuid {
Raghu Krishnamurthyab5321a2023-04-23 16:14:28 -070025 uint32_t uuid[4];
J-Alvesd708c032020-11-19 12:14:21 +000026};
27
J-Alvesda3e6d42022-01-25 10:19:56 +000028/** Length in bytes of the name in boot information descriptor. */
29#define FFA_BOOT_INFO_NAME_LEN 16
30
31/**
32 * The FF-A boot info descriptor, as defined in table 5.8 of section 5.4.1, of
33 * the FF-A v1.1 EAC0 specification.
34 */
35struct ffa_boot_info_desc {
36 char name[FFA_BOOT_INFO_NAME_LEN];
37 uint8_t type;
38 uint8_t reserved;
39 uint16_t flags;
40 uint32_t size;
41 uint64_t content;
42};
43
44/** FF-A boot information type mask. */
45#define FFA_BOOT_INFO_TYPE_SHIFT 7
46#define FFA_BOOT_INFO_TYPE_MASK (0x1U << FFA_BOOT_INFO_TYPE_SHIFT)
47#define FFA_BOOT_INFO_TYPE_STD 0U
48#define FFA_BOOT_INFO_TYPE_IMPDEF 1U
49
50/** Standard boot info type IDs. */
51#define FFA_BOOT_INFO_TYPE_ID_MASK 0x7FU
52#define FFA_BOOT_INFO_TYPE_ID_FDT 0U
53#define FFA_BOOT_INFO_TYPE_ID_HOB 1U
54
55/** FF-A Boot Info descriptors flags. */
56#define FFA_BOOT_INFO_FLAG_MBZ_MASK 0xFFF0U
57
58/** Bits [1:0] encode the format of the name field in ffa_boot_info_desc. */
59#define FFA_BOOT_INFO_FLAG_NAME_FORMAT_SHIFT 0U
60#define FFA_BOOT_INFO_FLAG_NAME_FORMAT_MASK \
61 (0x3U << FFA_BOOT_INFO_FLAG_NAME_FORMAT_SHIFT)
62#define FFA_BOOT_INFO_FLAG_NAME_FORMAT_STRING 0x0U
63#define FFA_BOOT_INFO_FLAG_NAME_FORMAT_UUID 0x1U
64
65/** Bits [3:2] encode the format of the content field in ffa_boot_info_desc. */
66#define FFA_BOOT_INFO_FLAG_CONTENT_FORMAT_SHIFT 2
67#define FFA_BOOT_INFO_FLAG_CONTENT_FORMAT_MASK \
68 (0x3U << FFA_BOOT_INFO_FLAG_CONTENT_FORMAT_SHIFT)
69#define FFA_BOOT_INFO_FLAG_CONTENT_FORMAT_VALUE 0x1U
70#define FFA_BOOT_INFO_FLAG_CONTENT_FORMAT_ADDR 0x0U
71
72static inline uint16_t ffa_boot_info_content_format(
73 struct ffa_boot_info_desc *desc)
74{
75 return (desc->flags & FFA_BOOT_INFO_FLAG_CONTENT_FORMAT_MASK) >>
76 FFA_BOOT_INFO_FLAG_CONTENT_FORMAT_SHIFT;
77}
78
79static inline uint16_t ffa_boot_info_name_format(
80 struct ffa_boot_info_desc *desc)
81{
82 return (desc->flags & FFA_BOOT_INFO_FLAG_NAME_FORMAT_MASK) >>
83 FFA_BOOT_INFO_FLAG_NAME_FORMAT_SHIFT;
84}
85
86static inline uint8_t ffa_boot_info_type_id(struct ffa_boot_info_desc *desc)
87{
88 return desc->type & FFA_BOOT_INFO_TYPE_ID_MASK;
89}
90
91static inline uint8_t ffa_boot_info_type(struct ffa_boot_info_desc *desc)
92{
93 return (desc->type & FFA_BOOT_INFO_TYPE_MASK) >>
94 FFA_BOOT_INFO_TYPE_SHIFT;
95}
96
97/** Length in bytes of the signature in the boot descriptor. */
98#define FFA_BOOT_INFO_HEADER_SIGNATURE_LEN 4
99
100/**
101 * The FF-A boot information header, as defined in table 5.9 of section 5.4.2,
102 * of the FF-A v1.1 EAC0 specification.
103 */
104struct ffa_boot_info_header {
105 uint32_t signature;
106 uint32_t version;
107 uint32_t info_blob_size;
108 uint32_t desc_size;
109 uint32_t desc_count;
110 uint32_t desc_offset;
111 uint64_t reserved;
112 struct ffa_boot_info_desc boot_info[];
113};
114
J-Alves7581c382020-05-07 18:34:20 +0100115#ifndef __ASSEMBLY__
116
J-Alves18c28052021-03-09 09:58:53 +0000117#include <cassert.h>
J-Alves7581c382020-05-07 18:34:20 +0100118#include <stdint.h>
119
J-Alves4439ece2021-11-05 11:52:54 +0000120/**
121 * FF-A Feature ID, to be used with interface FFA_FEATURES.
122 * As defined in the FF-A v1.1 Beta specification, table 13.10, in section
123 * 13.2.
124 */
125
126/** Query interrupt ID of Notification Pending Interrupt. */
127#define FFA_FEATURE_NPI 0x1U
128
129/** Query interrupt ID of Schedule Receiver Interrupt. */
130#define FFA_FEATURE_SRI 0x2U
131
132/** Query interrupt ID of the Managed Exit Interrupt. */
133#define FFA_FEATURE_MEI 0x3U
134
Karl Meakinf2bb5d02024-02-13 17:23:17 +0000135/** Minimum and maximum buffer size reported by FFA_FEATURES(FFA_RXTX_MAP) */
136#define FFA_RXTX_MAP_MIN_BUF_4K 0
137#define FFA_RXTX_MAP_MAX_BUF_PAGE_COUNT 1
138
Max Shvetsov0b7d25f2021-03-05 13:46:42 +0000139/** Partition property: partition supports receipt of direct requests. */
Kathleen Capella7774d6e2022-11-23 19:06:21 -0500140#define FFA_PARTITION_DIRECT_REQ_RECV (UINT32_C(1) << 0)
Max Shvetsov0b7d25f2021-03-05 13:46:42 +0000141
142/** Partition property: partition can send direct requests. */
Kathleen Capella7774d6e2022-11-23 19:06:21 -0500143#define FFA_PARTITION_DIRECT_REQ_SEND (UINT32_C(1) << 1)
Max Shvetsov0b7d25f2021-03-05 13:46:42 +0000144
145/** Partition property: partition can send and receive indirect messages. */
Kathleen Capella7774d6e2022-11-23 19:06:21 -0500146#define FFA_PARTITION_INDIRECT_MSG (UINT32_C(1) << 2)
Max Shvetsov0b7d25f2021-03-05 13:46:42 +0000147
J-Alves4d05dec2021-11-02 11:52:27 +0000148/** Partition property: partition can receive notifications. */
Kathleen Capella7774d6e2022-11-23 19:06:21 -0500149#define FFA_PARTITION_NOTIFICATION (UINT32_C(1) << 3)
J-Alves4d05dec2021-11-02 11:52:27 +0000150
Kathleen Capella7774d6e2022-11-23 19:06:21 -0500151/** Partition property: partition runs in the AArch64 execution state. */
152#define FFA_PARTITION_AARCH64_EXEC (UINT32_C(1) << 8)
153
154/** Partition info descriptor as defined in FF-A v1.1 EAC0 Table 13.37 */
Max Shvetsovc32f4782020-06-23 09:41:15 +0100155struct ffa_partition_info {
156 /** The ID of the VM the information is about */
Daniel Boulbye79d2072021-03-03 11:34:53 +0000157 ffa_id_t id;
Max Shvetsovc32f4782020-06-23 09:41:15 +0100158 /** The number of execution contexts implemented by the partition */
159 uint16_t exec_context;
160 /** The Partition's properties, e.g. supported messaging methods */
161 uint32_t properties;
Daniel Boulby8aa994c2022-01-05 19:44:30 +0000162 /** The uuid of the partition */
163 struct ffa_uuid uuid;
Max Shvetsovc32f4782020-06-23 09:41:15 +0100164};
165
Daniel Boulby2ac55f22022-01-21 12:08:08 +0000166/**
Kathleen Capella7774d6e2022-11-23 19:06:21 -0500167 * Bits[31:3] of partition properties must be zero for FF-A v1.0.
168 * This corresponds to table 8.25 "Partition information descriptor"
169 * in DEN0077A FF-A 1.0 REL specification.
170 */
171#define FFA_PARTITION_v1_0_RES_MASK (~(UINT32_C(0x7)))
172
173/**
Daniel Boulby2ac55f22022-01-21 12:08:08 +0000174 * Partition info descriptor as defined in Table 8.25 of the v1.0
Kathleen Capella7774d6e2022-11-23 19:06:21 -0500175 * FF-A Specification (DEN0077A).
Daniel Boulby2ac55f22022-01-21 12:08:08 +0000176 */
177struct ffa_partition_info_v1_0 {
178 /** The ID of the VM the information is about */
179 ffa_id_t id;
180 /** The number of execution contexts implemented by the partition */
181 uint16_t exec_context;
182 /** The Partition's properties, e.g. supported messaging methods */
183 uint32_t properties;
184};
185
Daniel Boulbyce386b12022-03-29 18:36:36 +0100186struct ffa_value {
187 u_register_t fid;
188 u_register_t arg1;
189 u_register_t arg2;
190 u_register_t arg3;
191 u_register_t arg4;
192 u_register_t arg5;
193 u_register_t arg6;
194 u_register_t arg7;
Raghu Krishnamurthyab5321a2023-04-23 16:14:28 -0700195 u_register_t arg8;
196 u_register_t arg9;
197 u_register_t arg10;
198 u_register_t arg11;
199 u_register_t arg12;
200 u_register_t arg13;
201 u_register_t arg14;
202 u_register_t arg15;
203 u_register_t arg16;
204 u_register_t arg17;
Daniel Boulbyce386b12022-03-29 18:36:36 +0100205};
206
207/* Function to make an SMC or SVC service call depending on the exception
208 * level of the SP.
209 */
210struct ffa_value ffa_service_call(struct ffa_value *args);
211
212/*
213 * Functions to trigger a service call.
214 *
215 * The arguments to pass through the service call must be stored in the
216 * ffa_value structure. The return values of the service call will be stored
217 * in the same structure (overriding the input arguments).
218 *
219 * Return the first return value. It is equivalent to args.fid but is also
220 * provided as the return value for convenience.
221 */
222u_register_t ffa_svc(struct ffa_value *args);
223u_register_t ffa_smc(struct ffa_value *args);
224
225static inline uint32_t ffa_func_id(struct ffa_value val)
J-Alvesf156ae92021-10-08 12:10:05 +0100226{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100227 return (uint32_t)val.fid;
J-Alves6cb21d92021-01-07 15:18:12 +0000228}
229
Daniel Boulbyce386b12022-03-29 18:36:36 +0100230static inline int32_t ffa_error_code(struct ffa_value val)
J-Alvesf156ae92021-10-08 12:10:05 +0100231{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100232 return (int32_t)val.arg2;
J-Alves6cb21d92021-01-07 15:18:12 +0000233}
234
Daniel Boulbyce386b12022-03-29 18:36:36 +0100235static inline ffa_id_t ffa_endpoint_id(struct ffa_value val) {
236 return (ffa_id_t)val.arg2 & 0xffff;
Daniel Boulby198deda2021-03-03 11:35:25 +0000237}
238
Daniel Boulbyce386b12022-03-29 18:36:36 +0100239static inline uint32_t ffa_partition_info_count(struct ffa_value val)
Daniel Boulby2ac55f22022-01-21 12:08:08 +0000240{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100241 return (uint32_t)val.arg2;
Daniel Boulby2ac55f22022-01-21 12:08:08 +0000242}
243
Daniel Boulby07d751e2022-05-30 17:32:00 +0100244static inline uint32_t ffa_partition_info_desc_size(struct ffa_value val)
245{
246 return (uint32_t)val.arg3;
247}
248
Daniel Boulbyce386b12022-03-29 18:36:36 +0100249static inline uint32_t ffa_feature_intid(struct ffa_value val)
J-Alves4439ece2021-11-05 11:52:54 +0000250{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100251 return (uint32_t)val.arg2;
J-Alves4439ece2021-11-05 11:52:54 +0000252}
253
Raghu Krishnamurthyab5321a2023-04-23 16:14:28 -0700254static inline uint16_t ffa_partition_info_regs_get_last_idx(
255 struct ffa_value args)
256{
257 return args.arg2 & 0xFFFF;
258}
259
260static inline uint16_t ffa_partition_info_regs_get_curr_idx(
261 struct ffa_value args)
262{
263 return (args.arg2 >> 16) & 0xFFFF;
264}
265
266static inline uint16_t ffa_partition_info_regs_get_tag(struct ffa_value args)
267{
268 return (args.arg2 >> 32) & 0xFFFF;
269}
270
271static inline uint16_t ffa_partition_info_regs_get_desc_size(
272 struct ffa_value args)
273{
274 return (args.arg2 >> 48);
275}
276
277static inline uint32_t ffa_partition_info_regs_partition_count(
278 struct ffa_value args)
279{
280 return ffa_partition_info_regs_get_last_idx(args) + 1;
281}
282
283static inline uint32_t ffa_partition_info_regs_entry_count(
284 struct ffa_value args, uint16_t start_idx)
285{
286 return (ffa_partition_info_regs_get_curr_idx(args) - start_idx + 1);
287}
288
289static inline uint16_t ffa_partition_info_regs_entry_size(
290 struct ffa_value args)
291{
292 return (args.arg2 >> 48) & 0xFFFFU;
293}
294
J-Alves18c28052021-03-09 09:58:53 +0000295typedef uint64_t ffa_notification_bitmap_t;
296
297#define FFA_NOTIFICATION(ID) (UINT64_C(1) << ID)
298
299#define MAX_FFA_NOTIFICATIONS UINT32_C(64)
300
301#define FFA_NOTIFICATIONS_FLAG_PER_VCPU UINT32_C(0x1 << 0)
302
J-Alvesb0cb5d02021-07-08 11:19:33 +0100303/** Flag to delay Schedule Receiver Interrupt. */
304#define FFA_NOTIFICATIONS_FLAG_DELAY_SRI UINT32_C(0x1 << 1)
305
J-Alves18c28052021-03-09 09:58:53 +0000306#define FFA_NOTIFICATIONS_FLAGS_VCPU_ID(id) UINT32_C((id & 0xFFFF) << 16)
307
J-Alvesf156ae92021-10-08 12:10:05 +0100308#define FFA_NOTIFICATIONS_FLAG_BITMAP_SP UINT32_C(0x1 << 0)
309#define FFA_NOTIFICATIONS_FLAG_BITMAP_VM UINT32_C(0x1 << 1)
310#define FFA_NOTIFICATIONS_FLAG_BITMAP_SPM UINT32_C(0x1 << 2)
311#define FFA_NOTIFICATIONS_FLAG_BITMAP_HYP UINT32_C(0x1 << 3)
312
J-Alves269118a2021-09-22 09:46:11 +0100313/**
314 * The following is an SGI ID, that the SPMC configures as non-secure, as
315 * suggested by the FF-A v1.1 specification, in section 9.4.1.
316 */
317#define FFA_SCHEDULE_RECEIVER_INTERRUPT_ID 8
318
J-Alvesf156ae92021-10-08 12:10:05 +0100319#define FFA_NOTIFICATIONS_BITMAP(lo, hi) \
320 (ffa_notification_bitmap_t)(lo) | \
321 (((ffa_notification_bitmap_t)hi << 32) & 0xFFFFFFFF00000000ULL)
322
323#define FFA_NOTIFICATIONS_FLAGS_VCPU_ID(id) UINT32_C((id & 0xFFFF) << 16)
324
Daniel Boulbyce386b12022-03-29 18:36:36 +0100325static inline ffa_notification_bitmap_t ffa_notifications_get_from_sp(
326 struct ffa_value val)
J-Alvesf156ae92021-10-08 12:10:05 +0100327{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100328 return FFA_NOTIFICATIONS_BITMAP(val.arg2, val.arg3);
J-Alvesf156ae92021-10-08 12:10:05 +0100329}
330
Daniel Boulbyce386b12022-03-29 18:36:36 +0100331static inline ffa_notification_bitmap_t ffa_notifications_get_from_vm(
332 struct ffa_value val)
J-Alvesf156ae92021-10-08 12:10:05 +0100333{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100334 return FFA_NOTIFICATIONS_BITMAP(val.arg4, val.arg5);
J-Alvesf156ae92021-10-08 12:10:05 +0100335}
336
J-Alves5bce2502021-06-14 14:27:45 +0100337/*
338 * FFA_NOTIFICATION_INFO_GET is a SMC64 interface.
339 * The following macros are defined for SMC64 implementation.
340 */
341#define FFA_NOTIFICATIONS_INFO_GET_MAX_IDS 20U
342
343#define FFA_NOTIFICATIONS_INFO_GET_FLAG_MORE_PENDING UINT64_C(0x1)
344
345#define FFA_NOTIFICATIONS_LISTS_COUNT_SHIFT 0x7U
346#define FFA_NOTIFICATIONS_LISTS_COUNT_MASK 0x1FU
347#define FFA_NOTIFICATIONS_LIST_SHIFT(l) (2 * (l - 1) + 12)
348#define FFA_NOTIFICATIONS_LIST_SIZE_MASK 0x3U
349
350static inline uint32_t ffa_notifications_info_get_lists_count(
Daniel Boulbyce386b12022-03-29 18:36:36 +0100351 struct ffa_value ret)
J-Alves5bce2502021-06-14 14:27:45 +0100352{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100353 return (uint32_t)(ret.arg2 >> FFA_NOTIFICATIONS_LISTS_COUNT_SHIFT)
J-Alves5bce2502021-06-14 14:27:45 +0100354 & FFA_NOTIFICATIONS_LISTS_COUNT_MASK;
355}
356
357static inline uint32_t ffa_notifications_info_get_list_size(
Daniel Boulbyce386b12022-03-29 18:36:36 +0100358 struct ffa_value ret, uint32_t list)
J-Alves5bce2502021-06-14 14:27:45 +0100359{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100360 return (uint32_t)(ret.arg2 >> FFA_NOTIFICATIONS_LIST_SHIFT(list)) &
J-Alves5bce2502021-06-14 14:27:45 +0100361 FFA_NOTIFICATIONS_LIST_SIZE_MASK;
362}
363
Daniel Boulbyce386b12022-03-29 18:36:36 +0100364static inline bool ffa_notifications_info_get_more_pending(struct ffa_value ret)
J-Alves5bce2502021-06-14 14:27:45 +0100365{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100366 return (ret.arg2 & FFA_NOTIFICATIONS_INFO_GET_FLAG_MORE_PENDING) != 0U;
J-Alves5bce2502021-06-14 14:27:45 +0100367}
368
J-Alvesf3a393c2020-10-23 16:00:39 +0100369enum ffa_data_access {
370 FFA_DATA_ACCESS_NOT_SPECIFIED,
371 FFA_DATA_ACCESS_RO,
372 FFA_DATA_ACCESS_RW,
373 FFA_DATA_ACCESS_RESERVED,
374};
375
376enum ffa_instruction_access {
377 FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
378 FFA_INSTRUCTION_ACCESS_NX,
379 FFA_INSTRUCTION_ACCESS_X,
380 FFA_INSTRUCTION_ACCESS_RESERVED,
381};
382
383enum ffa_memory_type {
384 FFA_MEMORY_NOT_SPECIFIED_MEM,
385 FFA_MEMORY_DEVICE_MEM,
386 FFA_MEMORY_NORMAL_MEM,
387};
388
389enum ffa_memory_cacheability {
390 FFA_MEMORY_CACHE_RESERVED = 0x0,
391 FFA_MEMORY_CACHE_NON_CACHEABLE = 0x1,
392 FFA_MEMORY_CACHE_RESERVED_1 = 0x2,
393 FFA_MEMORY_CACHE_WRITE_BACK = 0x3,
394 FFA_MEMORY_DEV_NGNRNE = 0x0,
395 FFA_MEMORY_DEV_NGNRE = 0x1,
396 FFA_MEMORY_DEV_NGRE = 0x2,
397 FFA_MEMORY_DEV_GRE = 0x3,
398};
399
400enum ffa_memory_shareability {
401 FFA_MEMORY_SHARE_NON_SHAREABLE,
402 FFA_MEMORY_SHARE_RESERVED,
403 FFA_MEMORY_OUTER_SHAREABLE,
404 FFA_MEMORY_INNER_SHAREABLE,
405};
406
Karl Meakin92aa7702023-10-11 18:48:01 +0100407typedef struct {
408 uint8_t data_access : 2;
409 uint8_t instruction_access : 2;
410} ffa_memory_access_permissions_t;
411
412_Static_assert(sizeof(ffa_memory_access_permissions_t) == sizeof(uint8_t),
413 "ffa_memory_access_permissions_t must be 1 byte wide");
J-Alvesf3a393c2020-10-23 16:00:39 +0100414
415/**
J-Alvesd13d7602023-05-05 14:19:03 +0100416 * FF-A v1.1 REL0 Table 10.18 memory region attributes descriptor NS Bit 6.
417 * Per section 10.10.4.1, NS bit is reserved for FFA_MEM_DONATE/LEND/SHARE
418 * and FFA_MEM_RETRIEVE_REQUEST.
419 */
420enum ffa_memory_security {
421 FFA_MEMORY_SECURITY_UNSPECIFIED = 0,
422 FFA_MEMORY_SECURITY_SECURE = 0,
423 FFA_MEMORY_SECURITY_NON_SECURE,
424};
425
426/**
J-Alvesb42d17f2022-07-04 12:42:13 +0100427 * This corresponds to table 10.18 of the FF-A v1.1 EAC0 specification, "Memory
428 * region attributes descriptor".
J-Alvesf3a393c2020-10-23 16:00:39 +0100429 */
Karl Meakin92aa7702023-10-11 18:48:01 +0100430typedef struct {
431 uint16_t shareability : 2;
432 uint16_t cacheability : 2;
433 uint16_t type : 2;
434 uint16_t security : 1;
435} ffa_memory_attributes_t;
J-Alvesf3a393c2020-10-23 16:00:39 +0100436
Karl Meakin92aa7702023-10-11 18:48:01 +0100437_Static_assert(sizeof(ffa_memory_attributes_t) == sizeof(uint16_t),
438 "ffa_memory_attributes_t must be 2 bytes wide");
J-Alvesf3a393c2020-10-23 16:00:39 +0100439
Karl Meakin0d4f5ff2023-10-13 20:03:16 +0100440#define FFA_MEMORY_HANDLE_ALLOCATOR_MASK UINT64_C(1)
441#define FFA_MEMORY_HANDLE_ALLOCATOR_SHIFT 63U
442#define FFA_MEMORY_HANDLE_ALLOCATOR_HYPERVISOR UINT64_C(1)
443#define FFA_MEMORY_HANDLE_ALLOCATOR_SPMC UINT64_C(0)
J-Alvesf3a393c2020-10-23 16:00:39 +0100444#define FFA_MEMORY_HANDLE_INVALID (~UINT64_C(0))
445
446/**
447 * A set of contiguous pages which is part of a memory region. This corresponds
J-Alvesb42d17f2022-07-04 12:42:13 +0100448 * to table 10.14 of the FF-A v1.1 EAC0 specification, "Constituent memory
449 * region descriptor".
J-Alvesf3a393c2020-10-23 16:00:39 +0100450 */
451struct ffa_memory_region_constituent {
452 /**
453 * The base IPA of the constituent memory region, aligned to 4 kiB page
454 * size granularity.
455 */
456 void *address;
457 /** The number of 4 kiB pages in the constituent memory region. */
458 uint32_t page_count;
459 /** Reserved field, must be 0. */
460 uint32_t reserved;
461};
462
463/**
J-Alvesb42d17f2022-07-04 12:42:13 +0100464 * A set of pages comprising a memory region. This corresponds to table 10.13 of
465 * the FF-A v1.1 EAC0 specification, "Composite memory region descriptor".
J-Alvesf3a393c2020-10-23 16:00:39 +0100466 */
467struct ffa_composite_memory_region {
468 /**
469 * The total number of 4 kiB pages included in this memory region. This
470 * must be equal to the sum of page counts specified in each
471 * `ffa_memory_region_constituent`.
472 */
473 uint32_t page_count;
474 /**
475 * The number of constituents (`ffa_memory_region_constituent`)
476 * included in this memory region range.
477 */
478 uint32_t constituent_count;
479 /** Reserved field, must be 0. */
480 uint64_t reserved_0;
481 /** An array of `constituent_count` memory region constituents. */
482 struct ffa_memory_region_constituent constituents[];
483};
484
485/**
486 * This corresponds to table "Memory access permissions descriptor" of the FFA
487 * 1.0 specification.
488 */
489struct ffa_memory_region_attributes {
490 /** The ID of the VM to which the memory is being given or shared. */
Daniel Boulbye79d2072021-03-03 11:34:53 +0000491 ffa_id_t receiver;
J-Alvesf3a393c2020-10-23 16:00:39 +0100492 /**
493 * The permissions with which the memory region should be mapped in the
494 * receiver's page table.
495 */
496 ffa_memory_access_permissions_t permissions;
497 /**
498 * Flags used during FFA_MEM_RETRIEVE_REQ and FFA_MEM_RETRIEVE_RESP
499 * for memory regions with multiple borrowers.
500 */
501 ffa_memory_receiver_flags_t flags;
502};
503
504/** Flags to control the behaviour of a memory sharing transaction. */
505typedef uint32_t ffa_memory_region_flags_t;
506
507/**
508 * Clear memory region contents after unmapping it from the sender and before
509 * mapping it for any receiver.
510 */
511#define FFA_MEMORY_REGION_FLAG_CLEAR 0x1U
512
513/**
514 * Whether the hypervisor may time slice the memory sharing or retrieval
515 * operation.
516 */
517#define FFA_MEMORY_REGION_FLAG_TIME_SLICE 0x2U
518
519/**
520 * Whether the hypervisor should clear the memory region after the receiver
521 * relinquishes it or is aborted.
522 */
523#define FFA_MEMORY_REGION_FLAG_CLEAR_RELINQUISH 0x4U
524
525#define FFA_MEMORY_REGION_TRANSACTION_TYPE_MASK ((0x3U) << 3)
526#define FFA_MEMORY_REGION_TRANSACTION_TYPE_UNSPECIFIED ((0x0U) << 3)
527#define FFA_MEMORY_REGION_TRANSACTION_TYPE_SHARE ((0x1U) << 3)
528#define FFA_MEMORY_REGION_TRANSACTION_TYPE_LEND ((0x2U) << 3)
529#define FFA_MEMORY_REGION_TRANSACTION_TYPE_DONATE ((0x3U) << 3)
530
J-Alves0435cae2020-11-06 10:49:56 +0000531/** The maximum number of recipients a memory region may be sent to. */
J-Alvesf3253312024-01-18 17:05:26 +0000532#define MAX_MEM_SHARE_RECIPIENTS 2U
J-Alves0435cae2020-11-06 10:49:56 +0000533
Daniel Boulbya24f23a2023-11-15 18:23:40 +0000534struct ffa_memory_access_impdef {
535 uint64_t val[2];
536};
537
J-Alvesf3a393c2020-10-23 16:00:39 +0100538/**
539 * This corresponds to table "Endpoint memory access descriptor" of the FFA 1.0
540 * specification.
541 */
542struct ffa_memory_access {
543 struct ffa_memory_region_attributes receiver_permissions;
544 /**
545 * Offset in bytes from the start of the outer `ffa_memory_region` to
546 * an `ffa_composite_memory_region` struct.
547 */
548 uint32_t composite_memory_region_offset;
Daniel Boulbya24f23a2023-11-15 18:23:40 +0000549 /* Space for implementation defined information */
550 struct ffa_memory_access_impdef impdef;
J-Alvesf3a393c2020-10-23 16:00:39 +0100551 uint64_t reserved_0;
552};
553
554/**
555 * Information about a set of pages which are being shared. This corresponds to
J-Alvesb42d17f2022-07-04 12:42:13 +0100556 * table 10.20 of the FF-A v1.1 EAC0 specification, "Lend, donate or share
557 * memory transaction descriptor". Note that it is also used for retrieve
558 * requests and responses.
J-Alvesf3a393c2020-10-23 16:00:39 +0100559 */
560struct ffa_memory_region {
561 /**
562 * The ID of the VM which originally sent the memory region, i.e. the
563 * owner.
564 */
Daniel Boulbye79d2072021-03-03 11:34:53 +0000565 ffa_id_t sender;
J-Alvesf3a393c2020-10-23 16:00:39 +0100566 ffa_memory_attributes_t attributes;
J-Alvesf3a393c2020-10-23 16:00:39 +0100567 /** Flags to control behaviour of the transaction. */
568 ffa_memory_region_flags_t flags;
569 ffa_memory_handle_t handle;
570 /**
571 * An implementation defined value associated with the receiver and the
572 * memory region.
573 */
574 uint64_t tag;
J-Alvesb42d17f2022-07-04 12:42:13 +0100575 /** Size of the memory access descriptor. */
576 uint32_t memory_access_desc_size;
J-Alvesf3a393c2020-10-23 16:00:39 +0100577 /**
578 * The number of `ffa_memory_access` entries included in this
579 * transaction.
580 */
581 uint32_t receiver_count;
582 /**
J-Alvesb42d17f2022-07-04 12:42:13 +0100583 * Offset of the 'receivers' field, which relates to the memory access
584 * descriptors.
585 */
586 uint32_t receivers_offset;
587 /** Reserved field (12 bytes) must be 0. */
588 uint32_t reserved[3];
589 /**
590 * An array of `receiver_count` endpoint memory access descriptors.
J-Alvesf3a393c2020-10-23 16:00:39 +0100591 * Each one specifies a memory region offset, an endpoint and the
592 * attributes with which this memory region should be mapped in that
593 * endpoint's page table.
594 */
595 struct ffa_memory_access receivers[];
596};
597
598/**
599 * Descriptor used for FFA_MEM_RELINQUISH requests. This corresponds to table
J-Alvesb42d17f2022-07-04 12:42:13 +0100600 * 16.25 of the FF-A v1.1 EAC0 specification, "Descriptor to relinquish a memory
601 * region".
J-Alvesf3a393c2020-10-23 16:00:39 +0100602 */
603struct ffa_mem_relinquish {
604 ffa_memory_handle_t handle;
605 ffa_memory_region_flags_t flags;
606 uint32_t endpoint_count;
Daniel Boulbye79d2072021-03-03 11:34:53 +0000607 ffa_id_t endpoints[];
J-Alvesf3a393c2020-10-23 16:00:39 +0100608};
609
610static inline ffa_memory_handle_t ffa_assemble_handle(uint32_t h1, uint32_t h2)
611{
J-Alves18c28052021-03-09 09:58:53 +0000612 return (ffa_notification_bitmap_t)h1 |
613 (ffa_notification_bitmap_t)h2 << 32;
J-Alvesf3a393c2020-10-23 16:00:39 +0100614}
615
Daniel Boulbyce386b12022-03-29 18:36:36 +0100616static inline ffa_memory_handle_t ffa_mem_success_handle(struct ffa_value r)
J-Alvesf3a393c2020-10-23 16:00:39 +0100617{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100618 return ffa_assemble_handle(r.arg2, r.arg3);
J-Alvesf3a393c2020-10-23 16:00:39 +0100619}
620
Karl Meakin0d4f5ff2023-10-13 20:03:16 +0100621static inline ffa_memory_handle_t ffa_frag_handle(struct ffa_value r)
622{
623 return ffa_assemble_handle(r.arg1, r.arg2);
624}
625
626static inline ffa_id_t ffa_frag_sender(struct ffa_value args)
627{
628 return (args.arg4 >> 16) & 0xffff;
629}
630
J-Alvesf3a393c2020-10-23 16:00:39 +0100631/**
J-Alvesf0b3bd62024-01-18 17:01:37 +0000632 * To maintain forwards compatability we can't make assumptions about the size
633 * of the endpoint memory access descriptor so provide a helper function
634 * to get a receiver from the receiver array using the memory access descriptor
635 * size field from the memory region descriptor struct.
636 * Returns NULL if we cannot return the receiver.
637 */
638static inline struct ffa_memory_access *ffa_memory_region_get_receiver(
639 struct ffa_memory_region *memory_region, uint32_t receiver_index)
640{
641 uint32_t memory_access_desc_size =
642 memory_region->memory_access_desc_size;
643
644 if (receiver_index >= memory_region->receiver_count) {
645 return NULL;
646 }
647
648 /*
649 * Memory access descriptor size cannot be greater than the size of
650 * the memory access descriptor defined by the current FF-A version.
651 */
652 if (memory_access_desc_size > sizeof(struct ffa_memory_access)) {
653 return NULL;
654 }
655
656 /* Check we cannot use receivers offset to cause overflow. */
657 if (memory_region->receivers_offset !=
658 sizeof(struct ffa_memory_region)) {
659 return NULL;
660 }
661
662 return (struct ffa_memory_access *)((uint8_t *)memory_region +
663 memory_region->receivers_offset +
664 (receiver_index *
665 memory_access_desc_size));
666}
667
668/**
J-Alvesf3a393c2020-10-23 16:00:39 +0100669 * Gets the `ffa_composite_memory_region` for the given receiver from an
670 * `ffa_memory_region`, or NULL if it is not valid.
671 */
672static inline struct ffa_composite_memory_region *
673ffa_memory_region_get_composite(struct ffa_memory_region *memory_region,
674 uint32_t receiver_index)
675{
676 uint32_t offset = memory_region->receivers[receiver_index]
677 .composite_memory_region_offset;
678
679 if (offset == 0) {
680 return NULL;
681 }
682
683 return (struct ffa_composite_memory_region *)((uint8_t *)memory_region +
684 offset);
685}
686
687static inline uint32_t ffa_mem_relinquish_init(
688 struct ffa_mem_relinquish *relinquish_request,
689 ffa_memory_handle_t handle, ffa_memory_region_flags_t flags,
Daniel Boulbye79d2072021-03-03 11:34:53 +0000690 ffa_id_t sender)
J-Alvesf3a393c2020-10-23 16:00:39 +0100691{
692 relinquish_request->handle = handle;
693 relinquish_request->flags = flags;
694 relinquish_request->endpoint_count = 1;
695 relinquish_request->endpoints[0] = sender;
Daniel Boulbye79d2072021-03-03 11:34:53 +0000696 return sizeof(struct ffa_mem_relinquish) + sizeof(ffa_id_t);
J-Alvesf3a393c2020-10-23 16:00:39 +0100697}
698
699uint32_t ffa_memory_retrieve_request_init(
700 struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
Karl Meakin1331a8c2023-09-14 16:25:15 +0100701 ffa_id_t sender, struct ffa_memory_access receivers[],
702 uint32_t receiver_count, uint32_t tag, ffa_memory_region_flags_t flags,
J-Alvesf3a393c2020-10-23 16:00:39 +0100703 enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
704 enum ffa_memory_shareability shareability);
705
Karl Meakin3d879b82023-06-16 10:32:08 +0100706void ffa_hypervisor_retrieve_request_init(struct ffa_memory_region *region,
707 ffa_memory_handle_t handle);
708
J-Alvesf3a393c2020-10-23 16:00:39 +0100709uint32_t ffa_memory_region_init(
710 struct ffa_memory_region *memory_region, size_t memory_region_max_size,
Karl Meakin1331a8c2023-09-14 16:25:15 +0100711 ffa_id_t sender, struct ffa_memory_access receivers[],
712 uint32_t receiver_count,
J-Alvesf3a393c2020-10-23 16:00:39 +0100713 const struct ffa_memory_region_constituent constituents[],
714 uint32_t constituent_count, uint32_t tag,
Karl Meakin1331a8c2023-09-14 16:25:15 +0100715 ffa_memory_region_flags_t flags, enum ffa_memory_type type,
716 enum ffa_memory_cacheability cacheability,
J-Alvesf3a393c2020-10-23 16:00:39 +0100717 enum ffa_memory_shareability shareability, uint32_t *total_length,
718 uint32_t *fragment_length);
719
Karl Meakin0d4f5ff2023-10-13 20:03:16 +0100720uint32_t ffa_memory_fragment_init(
721 struct ffa_memory_region_constituent *fragment,
722 size_t fragment_max_size,
723 const struct ffa_memory_region_constituent constituents[],
724 uint32_t constituent_count, uint32_t *fragment_length);
725
Daniel Boulbyce386b12022-03-29 18:36:36 +0100726static inline ffa_id_t ffa_dir_msg_dest(struct ffa_value val) {
727 return (ffa_id_t)val.arg1 & U(0xFFFF);
J-Alves6cb21d92021-01-07 15:18:12 +0000728}
729
Daniel Boulbyce386b12022-03-29 18:36:36 +0100730static inline ffa_id_t ffa_dir_msg_source(struct ffa_value val) {
731 return (ffa_id_t)(val.arg1 >> 16U);
J-Alves6cb21d92021-01-07 15:18:12 +0000732}
733
Daniel Boulbyce386b12022-03-29 18:36:36 +0100734struct ffa_value ffa_msg_send_direct_req64(ffa_id_t source_id,
735 ffa_id_t dest_id, uint64_t arg0,
736 uint64_t arg1, uint64_t arg2,
737 uint64_t arg3, uint64_t arg4);
J-Alvesd1aae292020-10-08 17:16:58 +0100738
Daniel Boulbyce386b12022-03-29 18:36:36 +0100739struct ffa_value ffa_msg_send_direct_req32(ffa_id_t source_id,
740 ffa_id_t dest_id, uint32_t arg0,
741 uint32_t arg1, uint32_t arg2,
742 uint32_t arg3, uint32_t arg4);
J-Alvesecd30742021-02-19 18:31:06 +0000743
Daniel Boulbyce386b12022-03-29 18:36:36 +0100744struct ffa_value ffa_msg_send_direct_resp64(ffa_id_t source_id,
745 ffa_id_t dest_id, uint64_t arg0,
746 uint64_t arg1, uint64_t arg2,
747 uint64_t arg3, uint64_t arg4);
J-Alvesecd30742021-02-19 18:31:06 +0000748
Daniel Boulbyce386b12022-03-29 18:36:36 +0100749struct ffa_value ffa_msg_send_direct_resp32(ffa_id_t source_id,
750 ffa_id_t dest_id, uint32_t arg0,
751 uint32_t arg1, uint32_t arg2,
752 uint32_t arg3, uint32_t arg4);
J-Alves035b7d02021-02-11 10:40:35 +0000753
Daniel Boulbyce386b12022-03-29 18:36:36 +0100754struct ffa_value ffa_run(uint32_t dest_id, uint32_t vcpu_id);
755struct ffa_value ffa_version(uint32_t input_version);
756struct ffa_value ffa_id_get(void);
757struct ffa_value ffa_spm_id_get(void);
758struct ffa_value ffa_msg_wait(void);
759struct ffa_value ffa_error(int32_t error_code);
760struct ffa_value ffa_features(uint32_t feature);
Karl Meakin31b81772023-03-14 15:38:17 +0000761struct ffa_value ffa_features_with_input_property(uint32_t feature,
762 uint32_t param);
Daniel Boulbyce386b12022-03-29 18:36:36 +0100763struct ffa_value ffa_partition_info_get(const struct ffa_uuid uuid);
764struct ffa_value ffa_rx_release(void);
765struct ffa_value ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages);
766struct ffa_value ffa_rxtx_unmap(void);
767struct ffa_value ffa_mem_donate(uint32_t descriptor_length,
768 uint32_t fragment_length);
769struct ffa_value ffa_mem_lend(uint32_t descriptor_length,
J-Alves3ea46d12020-09-09 11:13:05 +0100770 uint32_t fragment_length);
Daniel Boulbyce386b12022-03-29 18:36:36 +0100771struct ffa_value ffa_mem_share(uint32_t descriptor_length,
772 uint32_t fragment_length);
773struct ffa_value ffa_mem_retrieve_req(uint32_t descriptor_length,
774 uint32_t fragment_length);
775struct ffa_value ffa_mem_relinquish(void);
776struct ffa_value ffa_mem_reclaim(uint64_t handle, uint32_t flags);
Karl Meakin0d4f5ff2023-10-13 20:03:16 +0100777struct ffa_value ffa_mem_frag_rx(ffa_memory_handle_t handle,
778 uint32_t fragment_length);
779struct ffa_value ffa_mem_frag_tx(ffa_memory_handle_t handle,
780 uint32_t fragment_length);
Daniel Boulbyce386b12022-03-29 18:36:36 +0100781struct ffa_value ffa_notification_bitmap_create(ffa_id_t vm_id,
782 ffa_vcpu_count_t vcpu_count);
783struct ffa_value ffa_notification_bitmap_destroy(ffa_id_t vm_id);
784struct ffa_value ffa_notification_bind(ffa_id_t sender, ffa_id_t receiver,
785 uint32_t flags,
J-Alves18c28052021-03-09 09:58:53 +0000786 ffa_notification_bitmap_t notifications);
Daniel Boulbyce386b12022-03-29 18:36:36 +0100787struct ffa_value ffa_notification_unbind(ffa_id_t sender, ffa_id_t receiver,
788 ffa_notification_bitmap_t notifications);
789struct ffa_value ffa_notification_set(ffa_id_t sender, ffa_id_t receiver,
790 uint32_t flags,
791 ffa_notification_bitmap_t bitmap);
792struct ffa_value ffa_notification_get(ffa_id_t receiver, uint32_t vcpu_id,
793 uint32_t flags);
794struct ffa_value ffa_notification_info_get(void);
Maksims Svecovs0b452232022-05-24 11:30:34 +0100795
796struct ffa_value ffa_console_log(const char* message, size_t char_count);
Raghu Krishnamurthyab5321a2023-04-23 16:14:28 -0700797struct ffa_value ffa_partition_info_get_regs(const struct ffa_uuid uuid,
798 const uint16_t start_index,
799 const uint16_t tag);
Karl Meakin367ff542023-11-01 15:05:37 +0000800
Daniel Boulbya24f23a2023-11-15 18:23:40 +0000801struct ffa_memory_access ffa_memory_access_init(
Karl Meakin367ff542023-11-01 15:05:37 +0000802 ffa_id_t receiver_id, enum ffa_data_access data_access,
803 enum ffa_instruction_access instruction_access,
Daniel Boulbya24f23a2023-11-15 18:23:40 +0000804 ffa_memory_receiver_flags_t flags,
805 struct ffa_memory_access_impdef *impdef);
Karl Meakin367ff542023-11-01 15:05:37 +0000806
J-Alves7581c382020-05-07 18:34:20 +0100807#endif /* __ASSEMBLY__ */
808
809#endif /* FFA_HELPERS_H */