• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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