blob: c68a01413b317883613ec3081007cfdb1a687c2c [file] [log] [blame]
J-Alves7581c382020-05-07 18:34:20 +01001/*
2 * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
3 *
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
J-Alves5aecd982020-06-11 10:25:33 +010017/* Hypervisor ID at physical FFA instance */
18#define HYP_ID (0)
19
20/* By convention, SP IDs (as opposed to VM IDs) have bit 15 set */
21#define SP_ID(x) ((x) | (1 << 15))
22
23typedef unsigned short ffa_vm_id_t;
24typedef unsigned short ffa_vm_count_t;
25typedef unsigned short ffa_vcpu_count_t;
Manish Pandey6b3840a2020-09-15 22:31:58 +010026typedef uint32_t ffa_int_id_t;
J-Alvesf3a393c2020-10-23 16:00:39 +010027typedef uint64_t ffa_memory_handle_t;
28/** Flags to indicate properties of receivers during memory region retrieval. */
29typedef uint8_t ffa_memory_receiver_flags_t;
J-Alves5aecd982020-06-11 10:25:33 +010030
J-Alves7581c382020-05-07 18:34:20 +010031#ifndef __ASSEMBLY__
32
33#include <stdint.h>
34
Max Shvetsovc32f4782020-06-23 09:41:15 +010035struct mailbox_buffers {
36 const void *recv;
37 void *send;
38};
39
40struct ffa_partition_info {
41 /** The ID of the VM the information is about */
42 ffa_vm_id_t id;
43 /** The number of execution contexts implemented by the partition */
44 uint16_t exec_context;
45 /** The Partition's properties, e.g. supported messaging methods */
46 uint32_t properties;
47};
48
J-Alvesf3a393c2020-10-23 16:00:39 +010049enum ffa_data_access {
50 FFA_DATA_ACCESS_NOT_SPECIFIED,
51 FFA_DATA_ACCESS_RO,
52 FFA_DATA_ACCESS_RW,
53 FFA_DATA_ACCESS_RESERVED,
54};
55
56enum ffa_instruction_access {
57 FFA_INSTRUCTION_ACCESS_NOT_SPECIFIED,
58 FFA_INSTRUCTION_ACCESS_NX,
59 FFA_INSTRUCTION_ACCESS_X,
60 FFA_INSTRUCTION_ACCESS_RESERVED,
61};
62
63enum ffa_memory_type {
64 FFA_MEMORY_NOT_SPECIFIED_MEM,
65 FFA_MEMORY_DEVICE_MEM,
66 FFA_MEMORY_NORMAL_MEM,
67};
68
69enum ffa_memory_cacheability {
70 FFA_MEMORY_CACHE_RESERVED = 0x0,
71 FFA_MEMORY_CACHE_NON_CACHEABLE = 0x1,
72 FFA_MEMORY_CACHE_RESERVED_1 = 0x2,
73 FFA_MEMORY_CACHE_WRITE_BACK = 0x3,
74 FFA_MEMORY_DEV_NGNRNE = 0x0,
75 FFA_MEMORY_DEV_NGNRE = 0x1,
76 FFA_MEMORY_DEV_NGRE = 0x2,
77 FFA_MEMORY_DEV_GRE = 0x3,
78};
79
80enum ffa_memory_shareability {
81 FFA_MEMORY_SHARE_NON_SHAREABLE,
82 FFA_MEMORY_SHARE_RESERVED,
83 FFA_MEMORY_OUTER_SHAREABLE,
84 FFA_MEMORY_INNER_SHAREABLE,
85};
86
87typedef uint8_t ffa_memory_access_permissions_t;
88
89/**
90 * This corresponds to table "Memory region attributes descriptor" of the FF-A
91 * 1.0 specification.
92 */
93typedef uint8_t ffa_memory_attributes_t;
94
95#define FFA_DATA_ACCESS_OFFSET (0x0U)
96#define FFA_DATA_ACCESS_MASK ((0x3U) << FFA_DATA_ACCESS_OFFSET)
97
98#define FFA_INSTRUCTION_ACCESS_OFFSET (0x2U)
99#define FFA_INSTRUCTION_ACCESS_MASK ((0x3U) << FFA_INSTRUCTION_ACCESS_OFFSET)
100
101#define FFA_MEMORY_TYPE_OFFSET (0x4U)
102#define FFA_MEMORY_TYPE_MASK ((0x3U) << FFA_MEMORY_TYPE_OFFSET)
103
104#define FFA_MEMORY_CACHEABILITY_OFFSET (0x2U)
105#define FFA_MEMORY_CACHEABILITY_MASK ((0x3U) << FFA_MEMORY_CACHEABILITY_OFFSET)
106
107#define FFA_MEMORY_SHAREABILITY_OFFSET (0x0U)
108#define FFA_MEMORY_SHAREABILITY_MASK ((0x3U) << FFA_MEMORY_SHAREABILITY_OFFSET)
109
110#define ATTR_FUNCTION_SET(name, container_type, offset, mask) \
111 static inline void ffa_set_##name##_attr(container_type *attr, \
112 const enum ffa_##name perm) \
113 { \
114 *attr = (*attr & ~(mask)) | ((perm << offset) & mask); \
115 }
116
117#define ATTR_FUNCTION_GET(name, container_type, offset, mask) \
118 static inline enum ffa_##name ffa_get_##name##_attr( \
119 container_type attr) \
120 { \
121 return (enum ffa_##name)((attr & mask) >> offset); \
122 }
123
124ATTR_FUNCTION_SET(data_access, ffa_memory_access_permissions_t,
125 FFA_DATA_ACCESS_OFFSET, FFA_DATA_ACCESS_MASK)
126ATTR_FUNCTION_GET(data_access, ffa_memory_access_permissions_t,
127 FFA_DATA_ACCESS_OFFSET, FFA_DATA_ACCESS_MASK)
128
129ATTR_FUNCTION_SET(instruction_access, ffa_memory_access_permissions_t,
130 FFA_INSTRUCTION_ACCESS_OFFSET, FFA_INSTRUCTION_ACCESS_MASK)
131ATTR_FUNCTION_GET(instruction_access, ffa_memory_access_permissions_t,
132 FFA_INSTRUCTION_ACCESS_OFFSET, FFA_INSTRUCTION_ACCESS_MASK)
133
134ATTR_FUNCTION_SET(memory_type, ffa_memory_attributes_t, FFA_MEMORY_TYPE_OFFSET,
135 FFA_MEMORY_TYPE_MASK)
136ATTR_FUNCTION_GET(memory_type, ffa_memory_attributes_t, FFA_MEMORY_TYPE_OFFSET,
137 FFA_MEMORY_TYPE_MASK)
138
139ATTR_FUNCTION_SET(memory_cacheability, ffa_memory_attributes_t,
140 FFA_MEMORY_CACHEABILITY_OFFSET, FFA_MEMORY_CACHEABILITY_MASK)
141ATTR_FUNCTION_GET(memory_cacheability, ffa_memory_attributes_t,
142 FFA_MEMORY_CACHEABILITY_OFFSET, FFA_MEMORY_CACHEABILITY_MASK)
143
144ATTR_FUNCTION_SET(memory_shareability, ffa_memory_attributes_t,
145 FFA_MEMORY_SHAREABILITY_OFFSET, FFA_MEMORY_SHAREABILITY_MASK)
146ATTR_FUNCTION_GET(memory_shareability, ffa_memory_attributes_t,
147 FFA_MEMORY_SHAREABILITY_OFFSET, FFA_MEMORY_SHAREABILITY_MASK)
148
149#define FFA_MEMORY_HANDLE_ALLOCATOR_MASK \
150 ((ffa_memory_handle_t)(UINT64_C(1) << 63))
151#define FFA_MEMORY_HANDLE_ALLOCATOR_HYPERVISOR \
152 ((ffa_memory_handle_t)(UINT64_C(1) << 63))
153#define FFA_MEMORY_HANDLE_INVALID (~UINT64_C(0))
154
155/**
156 * A set of contiguous pages which is part of a memory region. This corresponds
157 * to table "Constituent memory region descriptor" of the FFA 1.0 specification.
158 */
159struct ffa_memory_region_constituent {
160 /**
161 * The base IPA of the constituent memory region, aligned to 4 kiB page
162 * size granularity.
163 */
164 void *address;
165 /** The number of 4 kiB pages in the constituent memory region. */
166 uint32_t page_count;
167 /** Reserved field, must be 0. */
168 uint32_t reserved;
169};
170
171/**
172 * A set of pages comprising a memory region. This corresponds to table
173 * "Composite memory region descriptor" of the FFA 1.0 specification.
174 */
175struct ffa_composite_memory_region {
176 /**
177 * The total number of 4 kiB pages included in this memory region. This
178 * must be equal to the sum of page counts specified in each
179 * `ffa_memory_region_constituent`.
180 */
181 uint32_t page_count;
182 /**
183 * The number of constituents (`ffa_memory_region_constituent`)
184 * included in this memory region range.
185 */
186 uint32_t constituent_count;
187 /** Reserved field, must be 0. */
188 uint64_t reserved_0;
189 /** An array of `constituent_count` memory region constituents. */
190 struct ffa_memory_region_constituent constituents[];
191};
192
193/**
194 * This corresponds to table "Memory access permissions descriptor" of the FFA
195 * 1.0 specification.
196 */
197struct ffa_memory_region_attributes {
198 /** The ID of the VM to which the memory is being given or shared. */
199 ffa_vm_id_t receiver;
200 /**
201 * The permissions with which the memory region should be mapped in the
202 * receiver's page table.
203 */
204 ffa_memory_access_permissions_t permissions;
205 /**
206 * Flags used during FFA_MEM_RETRIEVE_REQ and FFA_MEM_RETRIEVE_RESP
207 * for memory regions with multiple borrowers.
208 */
209 ffa_memory_receiver_flags_t flags;
210};
211
212/** Flags to control the behaviour of a memory sharing transaction. */
213typedef uint32_t ffa_memory_region_flags_t;
214
215/**
216 * Clear memory region contents after unmapping it from the sender and before
217 * mapping it for any receiver.
218 */
219#define FFA_MEMORY_REGION_FLAG_CLEAR 0x1U
220
221/**
222 * Whether the hypervisor may time slice the memory sharing or retrieval
223 * operation.
224 */
225#define FFA_MEMORY_REGION_FLAG_TIME_SLICE 0x2U
226
227/**
228 * Whether the hypervisor should clear the memory region after the receiver
229 * relinquishes it or is aborted.
230 */
231#define FFA_MEMORY_REGION_FLAG_CLEAR_RELINQUISH 0x4U
232
233#define FFA_MEMORY_REGION_TRANSACTION_TYPE_MASK ((0x3U) << 3)
234#define FFA_MEMORY_REGION_TRANSACTION_TYPE_UNSPECIFIED ((0x0U) << 3)
235#define FFA_MEMORY_REGION_TRANSACTION_TYPE_SHARE ((0x1U) << 3)
236#define FFA_MEMORY_REGION_TRANSACTION_TYPE_LEND ((0x2U) << 3)
237#define FFA_MEMORY_REGION_TRANSACTION_TYPE_DONATE ((0x3U) << 3)
238
J-Alves0435cae2020-11-06 10:49:56 +0000239/** The maximum number of recipients a memory region may be sent to. */
240#define MAX_MEM_SHARE_RECIPIENTS 1U
241
J-Alvesf3a393c2020-10-23 16:00:39 +0100242/**
243 * This corresponds to table "Endpoint memory access descriptor" of the FFA 1.0
244 * specification.
245 */
246struct ffa_memory_access {
247 struct ffa_memory_region_attributes receiver_permissions;
248 /**
249 * Offset in bytes from the start of the outer `ffa_memory_region` to
250 * an `ffa_composite_memory_region` struct.
251 */
252 uint32_t composite_memory_region_offset;
253 uint64_t reserved_0;
254};
255
256/**
257 * Information about a set of pages which are being shared. This corresponds to
258 * table "Lend, donate or share memory transaction descriptor" of the FFA
259 * 1.0 specification. Note that it is also used for retrieve requests and
260 * responses.
261 */
262struct ffa_memory_region {
263 /**
264 * The ID of the VM which originally sent the memory region, i.e. the
265 * owner.
266 */
267 ffa_vm_id_t sender;
268 ffa_memory_attributes_t attributes;
269 /** Reserved field, must be 0. */
270 uint8_t reserved_0;
271 /** Flags to control behaviour of the transaction. */
272 ffa_memory_region_flags_t flags;
273 ffa_memory_handle_t handle;
274 /**
275 * An implementation defined value associated with the receiver and the
276 * memory region.
277 */
278 uint64_t tag;
279 /** Reserved field, must be 0. */
280 uint32_t reserved_1;
281 /**
282 * The number of `ffa_memory_access` entries included in this
283 * transaction.
284 */
285 uint32_t receiver_count;
286 /**
287 * An array of `attribute_count` endpoint memory access descriptors.
288 * Each one specifies a memory region offset, an endpoint and the
289 * attributes with which this memory region should be mapped in that
290 * endpoint's page table.
291 */
292 struct ffa_memory_access receivers[];
293};
294
295/**
296 * Descriptor used for FFA_MEM_RELINQUISH requests. This corresponds to table
297 * "Descriptor to relinquish a memory region" of the FFA 1.0 specification.
298 */
299struct ffa_mem_relinquish {
300 ffa_memory_handle_t handle;
301 ffa_memory_region_flags_t flags;
302 uint32_t endpoint_count;
303 ffa_vm_id_t endpoints[];
304};
305
306static inline ffa_memory_handle_t ffa_assemble_handle(uint32_t h1, uint32_t h2)
307{
308 return (uint64_t)h1 | (uint64_t)h2 << 32;
309}
310
311static inline ffa_memory_handle_t ffa_mem_success_handle(smc_ret_values r)
312{
313 return ffa_assemble_handle(r.ret2, r.ret3);
314}
315
316/**
317 * Gets the `ffa_composite_memory_region` for the given receiver from an
318 * `ffa_memory_region`, or NULL if it is not valid.
319 */
320static inline struct ffa_composite_memory_region *
321ffa_memory_region_get_composite(struct ffa_memory_region *memory_region,
322 uint32_t receiver_index)
323{
324 uint32_t offset = memory_region->receivers[receiver_index]
325 .composite_memory_region_offset;
326
327 if (offset == 0) {
328 return NULL;
329 }
330
331 return (struct ffa_composite_memory_region *)((uint8_t *)memory_region +
332 offset);
333}
334
335static inline uint32_t ffa_mem_relinquish_init(
336 struct ffa_mem_relinquish *relinquish_request,
337 ffa_memory_handle_t handle, ffa_memory_region_flags_t flags,
338 ffa_vm_id_t sender)
339{
340 relinquish_request->handle = handle;
341 relinquish_request->flags = flags;
342 relinquish_request->endpoint_count = 1;
343 relinquish_request->endpoints[0] = sender;
344 return sizeof(struct ffa_mem_relinquish) + sizeof(ffa_vm_id_t);
345}
346
347uint32_t ffa_memory_retrieve_request_init(
348 struct ffa_memory_region *memory_region, ffa_memory_handle_t handle,
349 ffa_vm_id_t sender, ffa_vm_id_t receiver, uint32_t tag,
350 ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
351 enum ffa_instruction_access instruction_access,
352 enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
353 enum ffa_memory_shareability shareability);
354
355uint32_t ffa_memory_region_init(
356 struct ffa_memory_region *memory_region, size_t memory_region_max_size,
357 ffa_vm_id_t sender, ffa_vm_id_t receiver,
358 const struct ffa_memory_region_constituent constituents[],
359 uint32_t constituent_count, uint32_t tag,
360 ffa_memory_region_flags_t flags, enum ffa_data_access data_access,
361 enum ffa_instruction_access instruction_access,
362 enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
363 enum ffa_memory_shareability shareability, uint32_t *total_length,
364 uint32_t *fragment_length);
365
Max Shvetsovc17c1d32020-06-11 15:03:01 +0100366bool check_spmc_execution_level(void);
J-Alves7581c382020-05-07 18:34:20 +0100367smc_ret_values ffa_msg_send_direct_req(uint32_t source_id, uint32_t dest_id, uint32_t message);
368smc_ret_values ffa_msg_send_direct_req64(uint32_t source_id, uint32_t dest_id, uint64_t message);
J-Alvesd1aae292020-10-08 17:16:58 +0100369smc_ret_values ffa_msg_send_direct_req64_5args(uint32_t source_id, uint32_t dest_id,
370 uint64_t arg0, uint64_t arg1,
371 uint64_t arg2, uint64_t arg3,
372 uint64_t arg4);
373
J-Alves7581c382020-05-07 18:34:20 +0100374smc_ret_values ffa_run(uint32_t dest_id, uint32_t vcpu_id);
J-Alves8f08a052020-05-26 17:14:40 +0100375smc_ret_values ffa_version(uint32_t input_version);
J-Alves5aecd982020-06-11 10:25:33 +0100376smc_ret_values ffa_id_get(void);
377smc_ret_values ffa_msg_wait(void);
378smc_ret_values ffa_msg_send_direct_resp(ffa_vm_id_t source_id,
379 ffa_vm_id_t dest_id, uint32_t message);
380smc_ret_values ffa_error(int32_t error_code);
Max Shvetsovc17c1d32020-06-11 15:03:01 +0100381smc_ret_values ffa_features(uint32_t feature);
Max Shvetsovc32f4782020-06-23 09:41:15 +0100382smc_ret_values ffa_partition_info_get(const uint32_t uuid[4]);
383smc_ret_values ffa_rx_release(void);
Ruari Phippsbd0a7e42020-07-17 16:42:21 +0100384smc_ret_values ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages);
J-Alves7581c382020-05-07 18:34:20 +0100385
J-Alves3ea46d12020-09-09 11:13:05 +0100386smc_ret_values ffa_mem_donate(uint32_t descriptor_length,
387 uint32_t fragment_length);
388smc_ret_values ffa_mem_lend(uint32_t descriptor_length,
389 uint32_t fragment_length);
390smc_ret_values ffa_mem_share(uint32_t descriptor_length,
391 uint32_t fragment_length);
392smc_ret_values ffa_mem_retrieve_req(uint32_t descriptor_length,
393 uint32_t fragment_length);
394smc_ret_values ffa_mem_relinquish(void);
395smc_ret_values ffa_mem_reclaim(uint64_t handle, uint32_t flags);
396
J-Alves7581c382020-05-07 18:34:20 +0100397#endif /* __ASSEMBLY__ */
398
399#endif /* FFA_HELPERS_H */