1 /*
2  * Copyright 2023 The Hafnium Authors.
3  *
4  * Use of this source code is governed by a BSD-style
5  * license that can be found in the LICENSE file or at
6  * https://opensource.org/licenses/BSD-3-Clause.
7  */
8 
9 #pragma once
10 
11 #include "hf/ffa.h"
12 #include "hf/types.h"
13 
14 /**
15  * Bits[31:3] of partition properties must be zero for FF-A v1.0.
16  * This corresponds to table 8.25 "Partition information descriptor"
17  * in DEN0077A FF-A 1.0 REL specification.
18  */
19 #define FFA_PARTITION_v1_0_RES_MASK (~(UINT32_C(0x7)))
20 
21 /**
22  * Create a struct for the "Partition information descriptor" defined for v1.0
23  * which can be returned to v1.0 endpoints.
24  * This corresponds to table 8.25 "Partition information descriptor"
25  * in DEN0077A FF-A 1.0 REL specification.
26  */
27 struct ffa_partition_info_v1_0 {
28 	ffa_id_t vm_id;
29 	ffa_vcpu_count_t vcpu_count;
30 	ffa_partition_properties_t properties;
31 };
32 
33 /**
34  * This corresponds to table 5.16 of the FF-A v1.0 specification,
35  * "Endpoint memory access descriptor".
36  */
37 struct ffa_memory_access_v1_0 {
38 	struct ffa_memory_region_attributes receiver_permissions;
39 	/**
40 	 * Offset in bytes from the start of the outer `ffa_memory_region` to
41 	 * an `ffa_composite_memory_region` struct.
42 	 */
43 	uint32_t composite_memory_region_offset;
44 	uint64_t reserved_0;
45 };
46 
47 typedef struct {
48 	uint8_t shareability : 2;
49 	uint8_t cacheability : 2;
50 	uint8_t type : 2;
51 	uint8_t security : 2;
52 } ffa_memory_attributes_v1_0;
53 
54 ffa_memory_attributes_v1_0 ffa_memory_attributes_truncate(
55 	ffa_memory_attributes_t attrs);
56 
57 ffa_memory_attributes_t ffa_memory_attributes_extend(
58 	ffa_memory_attributes_v1_0 attrs);
59 
60 /**
61  * Information about a set of pages which are being shared. This corresponds to
62  * table 45 of the FF-A 1.0 EAC specification, "Lend, donate or share memory
63  * transaction descriptor". Note that it is also used for retrieve requests and
64  * responses.
65  */
66 struct ffa_memory_region_v1_0 {
67 	/**
68 	 * The ID of the VM which originally sent the memory region, i.e. the
69 	 * owner.
70 	 */
71 	ffa_id_t sender;
72 	ffa_memory_attributes_v1_0 attributes;
73 	/** Reserved field, must be 0. */
74 	uint8_t reserved_0;
75 	/** Flags to control behaviour of the transaction. */
76 	ffa_memory_region_flags_t flags;
77 	ffa_memory_handle_t handle;
78 	/**
79 	 * An implementation defined value associated with the receiver and the
80 	 * memory region.
81 	 */
82 	uint64_t tag;
83 	/** Reserved field, must be 0. */
84 	uint32_t reserved_1;
85 	/**
86 	 * The number of `ffa_memory_access` entries included in this
87 	 * transaction.
88 	 */
89 	uint32_t receiver_count;
90 	/**
91 	 * An array of `receiver_count` endpoint memory access descriptors.
92 	 * Each one specifies a memory region offset, an endpoint and the
93 	 * attributes with which this memory region should be mapped in that
94 	 * endpoint's page table.
95 	 */
96 	struct ffa_memory_access_v1_0 receivers[];
97 };
98 
99 /**
100  * Gets the `ffa_composite_memory_region` for the given receiver from an
101  * `ffa_memory_region`, or NULL if it is not valid.
102  */
103 static inline struct ffa_composite_memory_region *
ffa_memory_region_get_composite_v1_0(struct ffa_memory_region_v1_0 * memory_region,uint32_t receiver_index)104 ffa_memory_region_get_composite_v1_0(
105 	struct ffa_memory_region_v1_0 *memory_region, uint32_t receiver_index)
106 {
107 	uint32_t offset = memory_region->receivers[receiver_index]
108 				  .composite_memory_region_offset;
109 
110 	if (offset == 0) {
111 		return NULL;
112 	}
113 
114 	return (struct ffa_composite_memory_region *)((uint8_t *)memory_region +
115 						      offset);
116 }
117 
118 void ffa_memory_region_init_header_v1_0(
119 	struct ffa_memory_region_v1_0 *memory_region, ffa_id_t sender,
120 	ffa_memory_attributes_t attributes, ffa_memory_region_flags_t flags,
121 	ffa_memory_handle_t handle, uint32_t tag, uint32_t receiver_count);
122 
123 void ffa_memory_access_init_v1_0(struct ffa_memory_access_v1_0 *receiver,
124 				 ffa_id_t receiver_id,
125 				 enum ffa_data_access data_access,
126 				 enum ffa_instruction_access instruction_access,
127 				 ffa_memory_receiver_flags_t flags);
128 
129 uint32_t ffa_memory_region_init_v1_0(
130 	struct ffa_memory_region_v1_0 *memory_region,
131 	size_t memory_region_max_size, ffa_id_t sender,
132 	struct ffa_memory_access_v1_0 receivers[], uint32_t receiver_count,
133 	const struct ffa_memory_region_constituent constituents[],
134 	uint32_t constituent_count, uint32_t tag,
135 	ffa_memory_region_flags_t flags, enum ffa_memory_type type,
136 	enum ffa_memory_cacheability cacheability,
137 	enum ffa_memory_shareability shareability, uint32_t *total_length,
138 	uint32_t *fragment_length);
139 
140 uint32_t ffa_memory_retrieve_request_init_v1_0(
141 	struct ffa_memory_region_v1_0 *memory_region,
142 	ffa_memory_handle_t handle, ffa_id_t sender,
143 	struct ffa_memory_access_v1_0 receivers[], uint32_t receiver_count,
144 	uint32_t tag, ffa_memory_region_flags_t flags,
145 	enum ffa_memory_type type, enum ffa_memory_cacheability cacheability,
146 	enum ffa_memory_shareability shareability);
147