blob: 7ccf89003a4e95a71ca3e93754949692818ea213 [file] [log] [blame]
Antonio Nino Diaz652d20a2018-12-10 17:17:33 +00001/*
Olivier Deprez61be4c12019-12-06 17:45:07 +01002 * Copyright (c) 2018-2020, Arm Limited. All rights reserved.
Antonio Nino Diaz652d20a2018-12-10 17:17:33 +00003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <debug.h>
8#include <smccc.h>
J-Alves7581c382020-05-07 18:34:20 +01009#include <ffa_helpers.h>
10#include <ffa_svc.h>
Antonio Nino Diaz652d20a2018-12-10 17:17:33 +000011
Max Shvetsovc17c1d32020-06-11 15:03:01 +010012#define OPTEE_FFA_GET_API_VERSION (0)
13#define OPTEE_FFA_GET_OS_VERSION (1)
14#define OPTEE_FFA_GET_OS_VERSION_MAJOR (3)
15#define OPTEE_FFA_GET_OS_VERSION_MINOR (8)
16
Olivier Deprez61be4c12019-12-06 17:45:07 +010017/*-----------------------------------------------------------------------------
J-Alves7581c382020-05-07 18:34:20 +010018 * FFA_RUN
Olivier Deprez61be4c12019-12-06 17:45:07 +010019 *
20 * Parameters
21 * uint32 Function ID (w0): 0x8400006D
22 * uint32 Target information (w1): Information to identify target SP/VM
23 * -Bits[31:16]: ID of SP/VM.
24 * -Bits[15:0]: ID of vCPU of SP/VM to run.
25 * Other Parameter registers w2-w7/x2-x7: Reserved (MBZ)
26 *
J-Alves7581c382020-05-07 18:34:20 +010027 * On failure, returns FFA_ERROR in w0 and error code in w2:
Olivier Deprez61be4c12019-12-06 17:45:07 +010028 * -INVALID_PARAMETERS: Unrecognized endpoint or vCPU ID
J-Alves7581c382020-05-07 18:34:20 +010029 * -NOT_SUPPORTED: This function is not implemented at this FFA instance
Olivier Deprez61be4c12019-12-06 17:45:07 +010030 * -DENIED: Callee is not in a state to handle this request
31 * -BUSY: vCPU is busy and caller must retry later
32 * -ABORTED: vCPU or VM ran into an unexpected error and has aborted
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +000033 */
J-Alves7581c382020-05-07 18:34:20 +010034smc_ret_values ffa_run(uint32_t dest_id, uint32_t vcpu_id)
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +000035{
Olivier Deprez61be4c12019-12-06 17:45:07 +010036 smc_args args = {
J-Alves7581c382020-05-07 18:34:20 +010037 FFA_MSG_RUN,
Olivier Deprez61be4c12019-12-06 17:45:07 +010038 (dest_id << 16) | vcpu_id,
39 0, 0, 0, 0, 0, 0
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +000040 };
41
Olivier Deprez61be4c12019-12-06 17:45:07 +010042 return tftf_smc(&args);
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +000043}
44
Olivier Deprez61be4c12019-12-06 17:45:07 +010045/*-----------------------------------------------------------------------------
J-Alves7581c382020-05-07 18:34:20 +010046 * FFA_MSG_SEND_DIRECT_REQ
Olivier Deprez61be4c12019-12-06 17:45:07 +010047 *
48 * Parameters
49 * uint32 Function ID (w0): 0x8400006F / 0xC400006F
50 * uint32 Source/Destination IDs (w1): Source and destination endpoint IDs
51 * -Bit[31:16]: Source endpoint ID
52 * -Bit[15:0]: Destination endpoint ID
53 * uint32/uint64 (w2/x2) - RFU MBZ
54 * w3-w7 - Implementation defined
55 *
J-Alves7581c382020-05-07 18:34:20 +010056 * On failure, returns FFA_ERROR in w0 and error code in w2:
Olivier Deprez61be4c12019-12-06 17:45:07 +010057 * -INVALID_PARAMETERS: Invalid endpoint ID or non-zero reserved register
58 * -DENIED: Callee is not in a state to handle this request
J-Alves7581c382020-05-07 18:34:20 +010059 * -NOT_SUPPORTED: This function is not implemented at this FFA instance
Olivier Deprez61be4c12019-12-06 17:45:07 +010060 * -BUSY: Message target is busy
61 * -ABORTED: Message target ran into an unexpected error and has aborted
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +000062 */
J-Alves7581c382020-05-07 18:34:20 +010063static smc_ret_values __ffa_msg_send_direct_req32_5(uint32_t source_id,
Olivier Deprez61be4c12019-12-06 17:45:07 +010064 uint32_t dest_id,
65 uint32_t arg0,
66 uint32_t arg1,
67 uint32_t arg2,
68 uint32_t arg3,
69 uint32_t arg4)
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +000070{
Olivier Deprez61be4c12019-12-06 17:45:07 +010071 smc_args args = {
J-Alves7581c382020-05-07 18:34:20 +010072 FFA_MSG_SEND_DIRECT_REQ_SMC32,
Olivier Deprez61be4c12019-12-06 17:45:07 +010073 (source_id << 16) | dest_id,
74 0,
75 arg0, arg1, arg2, arg3, arg4
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +000076 };
77
Olivier Deprez61be4c12019-12-06 17:45:07 +010078 return tftf_smc(&args);
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +000079}
80
Olivier Deprez61be4c12019-12-06 17:45:07 +010081/* Direct message send helper accepting a single 32b message argument */
J-Alves7581c382020-05-07 18:34:20 +010082smc_ret_values ffa_msg_send_direct_req(uint32_t source_id, uint32_t dest_id,
Olivier Deprez61be4c12019-12-06 17:45:07 +010083 uint32_t message)
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +000084{
J-Alves7581c382020-05-07 18:34:20 +010085 return __ffa_msg_send_direct_req32_5(source_id, dest_id,
Olivier Deprez61be4c12019-12-06 17:45:07 +010086 message, 0, 0, 0, 0);
87}
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +000088
J-Alves7581c382020-05-07 18:34:20 +010089static smc_ret_values __ffa_msg_send_direct_req64_5(uint32_t source_id,
Olivier Deprez61be4c12019-12-06 17:45:07 +010090 uint32_t dest_id,
91 uint64_t arg0,
92 uint64_t arg1,
93 uint64_t arg2,
94 uint64_t arg3,
95 uint64_t arg4)
96{
97 smc_args args = {
J-Alves7581c382020-05-07 18:34:20 +010098 FFA_MSG_SEND_DIRECT_REQ_SMC64,
Olivier Deprez61be4c12019-12-06 17:45:07 +010099 (source_id << 16) | dest_id,
100 0,
101 arg0, arg1, arg2, arg3, arg4
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +0000102 };
103
Olivier Deprez61be4c12019-12-06 17:45:07 +0100104 return tftf_smc(&args);
105}
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +0000106
Olivier Deprez61be4c12019-12-06 17:45:07 +0100107/* Direct message send helper accepting a single 64b message argument */
J-Alves7581c382020-05-07 18:34:20 +0100108smc_ret_values ffa_msg_send_direct_req64(uint32_t source_id, uint32_t dest_id,
Olivier Deprez61be4c12019-12-06 17:45:07 +0100109 uint64_t message)
110{
J-Alves7581c382020-05-07 18:34:20 +0100111 return __ffa_msg_send_direct_req64_5(source_id, dest_id,
Olivier Deprez61be4c12019-12-06 17:45:07 +0100112 message, 0, 0, 0, 0);
Antonio Nino Diazad8fcee2018-12-18 10:51:36 +0000113}
J-Alves8f08a052020-05-26 17:14:40 +0100114
J-Alves5aecd982020-06-11 10:25:33 +0100115/*
Max Shvetsovc17c1d32020-06-11 15:03:01 +0100116 * check_spmc_execution_level
117 *
118 * Attempt sending impdef protocol messages to OP-TEE through direct messaging.
119 * Criteria for detecting OP-TEE presence is that responses match defined
120 * version values. In the case of SPMC running at S-EL2 (and Cactus instances
121 * running at S-EL1) the response will not match the pre-defined version IDs.
122 *
123 * Returns true if SPMC is probed as being OP-TEE at S-EL1.
124 *
125 */
126bool check_spmc_execution_level(void)
127{
128 unsigned int is_optee_spmc_criteria = 0U;
129 smc_ret_values ret_values;
130
131 /*
132 * Send a first OP-TEE-defined protocol message through
133 * FFA direct message.
134 *
135 */
136 ret_values = ffa_msg_send_direct_req(HYP_ID, SP_ID(1),
137 OPTEE_FFA_GET_API_VERSION);
138 if ((ret_values.ret3 == FFA_VERSION_MAJOR) &&
139 (ret_values.ret4 == FFA_VERSION_MINOR)) {
140 is_optee_spmc_criteria++;
141 }
142
143 /*
144 * Send a second OP-TEE-defined protocol message through
145 * FFA direct message.
146 *
147 */
148 ret_values = ffa_msg_send_direct_req(HYP_ID, SP_ID(1),
149 OPTEE_FFA_GET_OS_VERSION);
150 if ((ret_values.ret3 == OPTEE_FFA_GET_OS_VERSION_MAJOR) &&
151 (ret_values.ret4 == OPTEE_FFA_GET_OS_VERSION_MINOR)) {
152 is_optee_spmc_criteria++;
153 }
154
155 return (is_optee_spmc_criteria == 2U);
156}
157
158/*
J-Alves5aecd982020-06-11 10:25:33 +0100159 * FFA Version ABI helper.
160 * Version fields:
161 * -Bits[30:16]: Major version.
162 * -Bits[15:0]: Minor version.
163 */
J-Alves8f08a052020-05-26 17:14:40 +0100164smc_ret_values ffa_version(uint32_t input_version)
165{
166 smc_args args = {
167 .fid = FFA_VERSION,
168 .arg1 = input_version
169 };
170
171 return tftf_smc(&args);
172}
J-Alves5aecd982020-06-11 10:25:33 +0100173
174smc_ret_values ffa_id_get(void)
175{
176 smc_args args = {
177 .fid = FFA_ID_GET
178 };
179
180 return tftf_smc(&args);
181}
182
183smc_ret_values ffa_msg_wait(void)
184{
185 smc_args args = {
186 .fid = FFA_MSG_WAIT
187 };
188
189 return tftf_smc(&args);
190}
191
192smc_ret_values ffa_msg_send_direct_resp(ffa_vm_id_t source_id,
193 ffa_vm_id_t dest_id,
194 uint32_t message)
195{
196 smc_args args = {
197 .fid = FFA_MSG_SEND_DIRECT_RESP_SMC32,
198 .arg1 = ((uint32_t)source_id << 16) | dest_id,
199 .arg3 = message
200 };
201
202 return tftf_smc(&args);
203}
204
205smc_ret_values ffa_error(int32_t error_code)
206{
207 smc_args args = {
208 .fid = FFA_ERROR,
209 .arg1 = 0,
210 .arg2 = error_code
211 };
212
213 return tftf_smc(&args);
214}
Max Shvetsovc17c1d32020-06-11 15:03:01 +0100215
216/* Query the higher EL if the requested FF-A feature is implemented. */
217smc_ret_values ffa_features(uint32_t feature)
218{
219 smc_args args = {
220 .fid = FFA_FEATURES,
221 .arg1 = feature
222 };
223
224 return tftf_smc(&args);
225}
Max Shvetsovc32f4782020-06-23 09:41:15 +0100226
227/* Get information about VMs or SPs based on UUID */
228smc_ret_values ffa_partition_info_get(const uint32_t uuid[4])
229{
230 smc_args args = {
231 .fid = FFA_PARTITION_INFO_GET,
232 .arg1 = uuid[0],
233 .arg2 = uuid[1],
234 .arg3 = uuid[2],
235 .arg4 = uuid[3]
236 };
237
238 return tftf_smc(&args);
239}
240
241/* Query SPMD that the rx buffer of the partition can be released */
242smc_ret_values ffa_rx_release(void)
243{
244 smc_args args = {
245 .fid = FFA_RX_RELEASE
246 };
247
248 return tftf_smc(&args);
249}
Ruari Phippsbd0a7e42020-07-17 16:42:21 +0100250
251/* Map the RXTX buffer */
252smc_ret_values ffa_rxtx_map(uintptr_t send, uintptr_t recv, uint32_t pages)
253{
254 smc_args args = {
255 .fid = FFA_RXTX_MAP_SMC64,
256 .arg1 = send,
257 .arg2 = recv,
258 .arg3 = pages
259 };
260
261 return tftf_smc(&args);
262}