1 /*
2 * Copyright (c) 2022, Arm Limited. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24 #pragma once
25
26 #include <arch/ops.h>
27 #include <interface/arm_ffa/arm_ffa.h>
28 #include <lib/smc/smc.h>
29 #include <lib/trusty/uuid.h>
30 #include <stdbool.h>
31
32 /**
33 * enum arm_ffa_init_state - The current state of FF-A initialization.
34 * @ARM_FFA_INIT_UNINIT: FF-A has not been initialized yet.
35 * @ARM_FFA_INIT_SUCCESS: FF-A has been successfully initialized.
36 * @ARM_FFA_INIT_FAILED: Failed to initialize FF-A.
37 */
38 enum arm_ffa_init_state {
39 ARM_FFA_INIT_UNINIT,
40 ARM_FFA_INIT_SUCCESS,
41 ARM_FFA_INIT_FAILED,
42 };
43
44 /**
45 * arm_ffa_init_state() - Return the current state of FF-A initialization.
46 *
47 * Return: one of the &enum arm_ffa_init_state values.
48 */
49 enum arm_ffa_init_state arm_ffa_init_state(void);
50
51 /**
52 * arm_ffa_is_init() - Check whether this module initialized successfully.
53 *
54 * This should only be called once arm_ffa_init() is guaranteed to have
55 * returned.
56 *
57 * Return: %true in case of success, %false otherwise.
58 */
arm_ffa_is_init(void)59 static inline bool arm_ffa_is_init(void) {
60 return arm_ffa_init_state() == ARM_FFA_INIT_SUCCESS;
61 }
62
63 /**
64 * arm_ffa_mem_relinquish() - Relinquish Trusty's access to a memory region.
65 * @handle: Handle of object to relinquish.
66 *
67 * Relinquish shared memory object id with SPM/Hypervisor. Allows the sender to
68 * reclaim the memory (if it has not been retrieved by anyone else).
69 */
70 status_t arm_ffa_mem_relinquish(uint64_t handle);
71
72 struct arm_ffa_cons_mrd;
73
74 /**
75 * struct arm_ffa_mem_frag_info - A fragment of an FF-A shared memory object.
76 * @received_len: Length of the fragment.
77 * @start_index: Index of the address range array where to start reading.
78 * @count: Number of elements in the address range buffer.
79 * @address_ranges: The array of address ranges.
80 */
81 struct arm_ffa_mem_frag_info {
82 uint32_t received_len;
83 size_t start_index;
84 uint32_t count;
85 struct ffa_cons_mrd* address_ranges;
86 };
87
88 /**
89 * arm_ffa_mem_address_range_get() - Gets one address range from the buffer.
90 * @buffer: Buffer that describes a part of an FF-A shared memory object.
91 * @index: The index of the address range to retrieve.
92 * @addr: [out] Start of the retrieved address range.
93 * @size: [out] Size of the retrieved address range.
94 *
95 * Return: 0 on success, LK error code on failure.
96 */
97 status_t arm_ffa_mem_address_range_get(struct arm_ffa_mem_frag_info* buffer,
98 size_t index,
99 paddr_t* addr,
100 size_t* size);
101 /**
102 * arm_ffa_mem_retrieve_start() - Retrieve a memory region from the
103 * SPMC/hypervisor for access from Trusty.
104 * @sender_id: Id of the memory owner.
105 * @handle: The handle identifying the memory region in the transaction.
106 * @tag: The tag identifying the transaction.
107 * @address_range_count: [out] The number of address ranges retrieved.
108 * @arch_mmu_flags: [out] The MMU flags of the received memory.
109 * @frag_info: [out] The shared memory object fragment.
110 *
111 * Only expects one descriptor in the returned memory access descriptor array,
112 * since we don't retrieve memory on behalf of anyone else.
113 *
114 * Grabs RXTX buffer lock. The lock must be subsequently released through
115 * `arm_ffa_rx_release()`.
116 *
117 * Return: 0 on success, LK error code on failure.
118 */
119 status_t arm_ffa_mem_retrieve_start(uint16_t sender_id,
120 uint64_t handle,
121 uint64_t tag,
122 uint32_t* address_range_count,
123 uint* arch_mmu_flags,
124 struct arm_ffa_mem_frag_info* frag_info);
125 /**
126 * arm_ffa_mem_retrieve_next_frag() - Performs an FF-A call to retrieve the
127 * next fragment of a shared memory object.
128 * @handle: The handle of the FF-A memory object to retrieve.
129 * @frag_info: [out] the retrieved fragment of the memory object.
130 *
131 * Return: 0 on success, LK error code on failure.
132 */
133 status_t arm_ffa_mem_retrieve_next_frag(
134 uint64_t handle,
135 struct arm_ffa_mem_frag_info* frag_info);
136
137 /**
138 * arm_ffa_mem_share_kernel_buffer() - Share kernel buffer over FFA.
139 *
140 * @receiver_id: Id of the memory receiver.
141 * @buffer: The start of the buffer. The address must be aligned to
142 * FFA_PAGE_SIZE.
143 * @num_ffa_pages: Number of pages in the buffer. This uses FFA_PAGE_SIZE which
144 * may differ from Trusty's page size.
145 * @arch_mmu_flags: MMU flags used when allocating the buffer. Buffers must have
146 * the NO_EXECUTE bit.
147 * @handle: [out] The handle identifying the memory region in the
148 * transaction.
149 *
150 * Grabs and releases the RXTX buffer lock.
151 *
152 * Return: 0 on success, LK error code on failure.
153 */
154 status_t arm_ffa_mem_share_kernel_buffer(uint16_t receiver_id,
155 paddr_t buffer,
156 size_t num_ffa_pages,
157 uint arch_mmu_flags,
158 uint64_t* handle);
159
160 /**
161 * arm_ffa_mem_reclaim() - Reclaim memory shared over FFA.
162 *
163 * @handle: The handle identifying the previously shared memory region. This
164 * must have been the result of a call to
165 * arm_ffa_mem_share_kernel_buffer().
166 *
167 * Return: 0 on success, LK error code on failure.
168 */
169 status_t arm_ffa_mem_reclaim(uint64_t handle);
170
171 /**
172 * arm_ffa_rx_release() - Relinquish ownership of the RX buffer.
173 *
174 * Return: 0 on success, LK error code on failure.
175 */
176 status_t arm_ffa_rx_release(void);
177
178 /**
179 * arm_ffa_call_error() - Report an error.
180 *
181 * @err: FF-A error code from &enum ffa_error.
182 *
183 * Return: the values of the CPU registers on return to Trusty.
184 */
185 struct smc_ret18 arm_ffa_call_error(enum ffa_error err);
186
187 /**
188 * arm_ffa_call_msg_wait() - Invoke FFA_MSG_WAIT.
189 *
190 * Return: the values of the CPU registers on return to Trusty.
191 */
192 struct smc_ret18 arm_ffa_call_msg_wait(void);
193
194 /**
195 * arm_ffa_msg_send_direct_resp() - Send a direct message response.
196 *
197 * @direct_req_args: The registers passed to the correspoding direct request
198 * message. Must not be %NULL.
199 * @a0: The 1st argument returned as the response.
200 * @a1: The 2nd argument returned as the response.
201 * @a2: The 3rd argument returned as the response.
202 * @a3: The 4th argument returned as the response.
203 * @a4: The 5th argument returned as the response.
204 *
205 * Return: the values of the CPU registers on return to Trusty.
206 */
207 struct smc_ret18 arm_ffa_msg_send_direct_resp(
208 const struct smc_ret18* direct_req_regs,
209 ulong a0,
210 ulong a1,
211 ulong a2,
212 ulong a3,
213 ulong a4);
214
215 /**
216 * arm_ffa_msg_send_direct_req2() - Send a direct message request.
217 *
218 * @uuid: Handler UUID.
219 * @receiver_id: Receiver ID.
220 * @args: Contents of message request - x4-x17. Must not be %NULL.
221 * @resp: The registers passed back in response to the direct message iff
222 * the request was successful. Must not be %NULL.
223 *
224 * Return: 0 on success, LK error code on failure.
225 */
226 status_t arm_ffa_msg_send_direct_req2(
227 uuid_t uuid,
228 uint16_t receiver_id,
229 uint64_t args[static ARM_FFA_MSG_EXTENDED_ARGS_COUNT],
230 struct smc_ret18* resp);
231
232 /**
233 * arm_ffa_msg_send_direct_resp2() - Send a direct message response.
234 *
235 * @direct_req_regs: The registers passed back in response to the direct message
236 * iff the request was successful. Must not be %NULL.
237 * @args: Contents of message response - x4-x17. Must not be %NULL.
238 *
239 * Return: the values of the CPU registers on return to Trusty.
240 */
241 struct smc_ret18 arm_ffa_msg_send_direct_resp2(
242 const struct smc_ret18* direct_req_regs,
243 uint64_t args[static ARM_FFA_MSG_EXTENDED_ARGS_COUNT]);
244
245 /**
246 * arm_ffa_console_log() - Output a buffer using %FFA_CONSOLE_LOG.
247 *
248 * @buf: The buffer to print.
249 * @len: The length of the buffer to print.
250 *
251 * Return: the number of characters successfully printed, or an error code.
252 */
253 ssize_t arm_ffa_console_log(const char* buf, size_t len);
254
255 #if ARCH_ARM64
256 /**
257 * arm_ffa_direct_req2_handler_t - Handler function for DIRECT_REQ2 calls
258 *
259 * @sender_id: Sender's endpoint ID
260 * @regs: Contents of message - x4-x17
261 *
262 * Return: 0 on success, LK error code on failure.
263 */
264 typedef status_t (*arm_ffa_direct_req2_handler_t)(
265 uint16_t sender_id,
266 uint64_t regs[static ARM_FFA_MSG_EXTENDED_ARGS_COUNT]);
267
268 /**
269 * arm_ffa_handle_direct_req2() - Handle DIRECT_REQ2 call
270 *
271 * @regs: CPU registers for FFA call
272 *
273 * Return: 0 on success, LK error code on failure.
274 */
275 status_t arm_ffa_handle_direct_req2(struct smc_ret18* regs);
276
277 /**
278 * arm_ffa_register_direct_req2_handler() - Register DIRECT_REQ2 call handler
279 *
280 * @uuid: UUID of handler to register
281 * @handler: pointer to handler function
282 *
283 * Return: 0 on success, LK error code on failure.
284 */
285 status_t arm_ffa_register_direct_req2_handler(
286 uuid_t uuid,
287 arm_ffa_direct_req2_handler_t handler);
288 #endif
289