blob: 2eb53ed8affe198ff65fafef1fc296fc5b23bb06 [file] [log] [blame]
Olivier Deprez61be4c12019-12-06 17:45:07 +01001/*
Max Shvetsov103e0562021-02-04 16:58:31 +00002 * Copyright (c) 2018-2021, Arm Limited. All rights reserved.
Olivier Deprez61be4c12019-12-06 17:45:07 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
Max Shvetsov103e0562021-02-04 16:58:31 +00007#include <debug.h>
8#include <smccc.h>
9
Olivier Deprez61be4c12019-12-06 17:45:07 +010010#include <arch_helpers.h>
J-Alvesb1e81d82020-11-09 15:40:31 +000011#include <cactus_test_cmds.h>
J-Alvesb1e81d82020-11-09 15:40:31 +000012#include <ffa_endpoints.h>
J-Alves7581c382020-05-07 18:34:20 +010013#include <ffa_svc.h>
Max Shvetsovc0e91692020-11-12 17:47:13 +000014#include <lib/events.h>
15#include <lib/power_management.h>
Max Shvetsov103e0562021-02-04 16:58:31 +000016#include <platform.h>
Olivier Deprez61be4c12019-12-06 17:45:07 +010017#include <test_helpers.h>
18
J-Alvesb1e81d82020-11-09 15:40:31 +000019#define ECHO_VAL1 U(0xa0a0a0a0)
20#define ECHO_VAL2 U(0xb0b0b0b0)
21#define ECHO_VAL3 U(0xc0c0c0c0)
22
J-Alvesb1e81d82020-11-09 15:40:31 +000023static const struct ffa_uuid expected_sp_uuids[] = {
24 {PRIMARY_UUID}, {SECONDARY_UUID}, {TERTIARY_UUID}
25 };
26
Max Shvetsovc0e91692020-11-12 17:47:13 +000027static event_t cpu_booted[PLATFORM_CORE_COUNT];
28
Daniel Boulbye79d2072021-03-03 11:34:53 +000029static test_result_t send_cactus_echo_cmd(ffa_id_t sender,
30 ffa_id_t dest,
J-Alves4cb9dee2021-03-03 13:59:52 +000031 uint64_t value)
Olivier Deprez61be4c12019-12-06 17:45:07 +010032{
J-Alves4cb9dee2021-03-03 13:59:52 +000033 smc_ret_values ret;
34 ret = cactus_echo_send_cmd(sender, dest, value);
Olivier Deprez61be4c12019-12-06 17:45:07 +010035
J-Alves43887ec2021-02-22 12:21:44 +000036 /*
37 * Return responses may be FFA_MSG_SEND_DIRECT_RESP or FFA_INTERRUPT,
38 * but only expect the former. Expect SMC32 convention from SP.
39 */
J-Alves4cb9dee2021-03-03 13:59:52 +000040 if (!is_ffa_direct_response(ret)) {
Olivier Deprez61be4c12019-12-06 17:45:07 +010041 return TEST_RESULT_FAIL;
42 }
43
J-Alves4cb9dee2021-03-03 13:59:52 +000044 if (cactus_get_response(ret) != CACTUS_SUCCESS ||
45 cactus_echo_get_val(ret) != value) {
46 ERROR("Echo Failed!\n");
Olivier Deprez61be4c12019-12-06 17:45:07 +010047 return TEST_RESULT_FAIL;
48 }
49
50 return TEST_RESULT_SUCCESS;
51}
52
J-Alves7581c382020-05-07 18:34:20 +010053test_result_t test_ffa_direct_messaging(void)
Olivier Deprez61be4c12019-12-06 17:45:07 +010054{
Olivier Deprez61be4c12019-12-06 17:45:07 +010055 test_result_t result;
56
57 /**********************************************************************
J-Alvesb1e81d82020-11-09 15:40:31 +000058 * Check SPMC has ffa_version and expected FFA endpoints are deployed.
Olivier Deprez61be4c12019-12-06 17:45:07 +010059 **********************************************************************/
J-Alves04469302021-01-21 14:48:13 +000060 CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
Olivier Deprez3f14f5e2020-03-25 23:31:37 +010061
Olivier Deprez61be4c12019-12-06 17:45:07 +010062 /**********************************************************************
63 * Send a message to SP1 through direct messaging
64 **********************************************************************/
J-Alves4cb9dee2021-03-03 13:59:52 +000065 result = send_cactus_echo_cmd(HYP_ID, SP_ID(1), ECHO_VAL1);
Olivier Deprez61be4c12019-12-06 17:45:07 +010066 if (result != TEST_RESULT_SUCCESS) {
67 return result;
68 }
69
70 /**********************************************************************
71 * Send a message to SP2 through direct messaging
72 **********************************************************************/
J-Alves4cb9dee2021-03-03 13:59:52 +000073 result = send_cactus_echo_cmd(HYP_ID, SP_ID(2), ECHO_VAL2);
Olivier Deprez61be4c12019-12-06 17:45:07 +010074 if (result != TEST_RESULT_SUCCESS) {
75 return result;
76 }
77
78 /**********************************************************************
79 * Send a message to SP1 through direct messaging
80 **********************************************************************/
J-Alves4cb9dee2021-03-03 13:59:52 +000081 result = send_cactus_echo_cmd(HYP_ID, SP_ID(1), ECHO_VAL3);
Olivier Deprez61be4c12019-12-06 17:45:07 +010082
Olivier Deprez0be4abe2020-08-04 11:26:13 +020083 return result;
Olivier Deprez61be4c12019-12-06 17:45:07 +010084}
J-Alvesb1e81d82020-11-09 15:40:31 +000085
86/**
87 * The 'send_cactus_req_echo_cmd' sends a CACTUS_REQ_ECHO_CMD to a cactus SP.
88 * Handling this command, cactus should then send CACTUS_ECHO_CMD to
89 * the specified SP according to 'echo_dest'. If the CACTUS_ECHO_CMD is resolved
90 * successfully, cactus will reply to tftf with CACTUS_SUCCESS, or CACTUS_ERROR
91 * otherwise.
92 * For the CACTUS_SUCCESS response, the test returns TEST_RESULT_SUCCESS.
93 */
Daniel Boulbye79d2072021-03-03 11:34:53 +000094static test_result_t send_cactus_req_echo_cmd(ffa_id_t sender,
95 ffa_id_t dest,
96 ffa_id_t echo_dest,
J-Alvesb1e81d82020-11-09 15:40:31 +000097 uint64_t value)
98{
99 smc_ret_values ret;
100
J-Alves53392012020-11-18 14:51:57 +0000101 ret = cactus_req_echo_send_cmd(sender, dest, echo_dest, value);
J-Alvesb1e81d82020-11-09 15:40:31 +0000102
J-Alves06373c52021-02-11 15:17:42 +0000103 if (!is_ffa_direct_response(ret)) {
J-Alvesb1e81d82020-11-09 15:40:31 +0000104 return TEST_RESULT_FAIL;
105 }
106
J-Alves53392012020-11-18 14:51:57 +0000107 if (cactus_get_response(ret) == CACTUS_ERROR) {
J-Alvesb1e81d82020-11-09 15:40:31 +0000108 return TEST_RESULT_FAIL;
109 }
110
111 return TEST_RESULT_SUCCESS;
112}
113
114test_result_t test_ffa_sp_to_sp_direct_messaging(void)
115{
116 test_result_t result;
117
J-Alves04469302021-01-21 14:48:13 +0000118 CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
J-Alvesb1e81d82020-11-09 15:40:31 +0000119
120 result = send_cactus_req_echo_cmd(HYP_ID, SP_ID(1), SP_ID(2),
121 ECHO_VAL1);
122 if (result != TEST_RESULT_SUCCESS) {
123 return result;
124 }
125
126 /*
127 * The following the tests are intended to test the handling of a
128 * direct message request with a VM's ID as a the sender.
129 */
J-Alvesd5d87152021-10-29 11:48:37 +0100130 result = send_cactus_req_echo_cmd(VM_ID(1), SP_ID(2), SP_ID(3),
J-Alvesb1e81d82020-11-09 15:40:31 +0000131 ECHO_VAL2);
132 if (result != TEST_RESULT_SUCCESS) {
133 return result;
134 }
135
J-Alvesd5d87152021-10-29 11:48:37 +0100136 result = send_cactus_req_echo_cmd(VM_ID(2), SP_ID(3), SP_ID(1),
J-Alvesb1e81d82020-11-09 15:40:31 +0000137 ECHO_VAL3);
138
139 return result;
140}
J-Alvesae95ac92020-11-11 13:06:55 +0000141
142test_result_t test_ffa_sp_to_sp_deadlock(void)
143{
144 smc_ret_values ret;
145
146 /**********************************************************************
147 * Check SPMC has ffa_version and expected FFA endpoints are deployed.
148 **********************************************************************/
J-Alves04469302021-01-21 14:48:13 +0000149 CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
J-Alvesae95ac92020-11-11 13:06:55 +0000150
J-Alves53392012020-11-18 14:51:57 +0000151 ret = cactus_req_deadlock_send_cmd(HYP_ID, SP_ID(1), SP_ID(2), SP_ID(3));
J-Alvesae95ac92020-11-11 13:06:55 +0000152
Max Shvetsovc0e91692020-11-12 17:47:13 +0000153 if (is_ffa_direct_response(ret) == false) {
J-Alvesae95ac92020-11-11 13:06:55 +0000154 return TEST_RESULT_FAIL;
155 }
156
J-Alves53392012020-11-18 14:51:57 +0000157 if (cactus_get_response(ret) == CACTUS_ERROR) {
J-Alvesae95ac92020-11-11 13:06:55 +0000158 return TEST_RESULT_FAIL;
159 }
160
161 return TEST_RESULT_SUCCESS;
162}
Max Shvetsovc0e91692020-11-12 17:47:13 +0000163
164/**
165 * Handler that is passed during tftf_cpu_on to individual CPU cores.
166 * Runs a specific core and send a direct message request.
Max Shvetsovc0e91692020-11-12 17:47:13 +0000167 */
168static test_result_t cpu_on_handler(void)
169{
J-Alves79c08f12021-10-27 15:15:16 +0100170 unsigned int core_pos = get_current_core_id();
Max Shvetsovc0e91692020-11-12 17:47:13 +0000171 test_result_t ret = TEST_RESULT_SUCCESS;
172 smc_ret_values ffa_ret;
173
174 /*
Olivier Deprez35e19482021-02-11 09:32:20 +0100175 * Send a direct message request to SP1 (MP SP) from current physical
176 * CPU. Notice SP1 ECs are already woken as a result of the PSCI_CPU_ON
Max Shvetsovc0e91692020-11-12 17:47:13 +0000177 * invocation so they already reached the message loop.
178 * The SPMC uses the MP pinned context corresponding to the physical
179 * CPU emitting the request.
180 */
181 ret = send_cactus_echo_cmd(HYP_ID, SP_ID(1), ECHO_VAL1);
182 if (ret != TEST_RESULT_SUCCESS) {
183 goto out;
184 }
185
186 /*
187 * Secure Partitions beyond the first SP only have their first
188 * EC (or vCPU0) woken up at boot time by the SPMC.
189 * Other ECs need one round of ffa_run to reach the message loop.
190 */
191 ffa_ret = ffa_run(SP_ID(2), core_pos);
192 if (ffa_func_id(ffa_ret) != FFA_MSG_WAIT) {
193 ERROR("Failed to run SP%x on core %u\n", SP_ID(2),
194 core_pos);
195 ret = TEST_RESULT_FAIL;
196 goto out;
197 }
198
199 /*
Olivier Deprez35e19482021-02-11 09:32:20 +0100200 * Send a direct message request to SP2 (MP SP) from current physical
201 * CPU. The SPMC uses the MP pinned context corresponding to the
202 * physical CPU emitting the request.
Max Shvetsovc0e91692020-11-12 17:47:13 +0000203 */
204 ret = send_cactus_echo_cmd(HYP_ID, SP_ID(2), ECHO_VAL2);
205 if (ret != TEST_RESULT_SUCCESS) {
206 goto out;
207 }
208
Olivier Deprez35e19482021-02-11 09:32:20 +0100209 /*
210 * Send a direct message request to SP3 (UP SP) from current physical CPU.
211 * The SPMC uses the single vCPU migrated to the new physical core.
212 * The single SP vCPU may receive requests from multiple physical CPUs.
213 * Thus it is possible one message is being processed on one core while
214 * another (or multiple) cores attempt sending a new direct message
215 * request. In such case the cores attempting the new request receive
216 * a busy response from the SPMC. To handle this case a retry loop is
217 * implemented permitting some fairness.
218 */
219 uint32_t trial_loop = 5U;
220 while (trial_loop--) {
221 ffa_ret = cactus_echo_send_cmd(HYP_ID, SP_ID(3), ECHO_VAL3);
222 if ((ffa_func_id(ffa_ret) == FFA_ERROR) &&
223 (ffa_error_code(ffa_ret) == FFA_ERROR_BUSY)) {
224 VERBOSE("%s(%u) trial %u\n", __func__, core_pos, trial_loop);
225 waitms(1);
226 continue;
227 }
228
229 if (is_ffa_direct_response(ffa_ret) == true) {
230 if (cactus_get_response(ffa_ret) != CACTUS_SUCCESS ||
231 cactus_echo_get_val(ffa_ret) != ECHO_VAL3) {
232 ERROR("Echo Failed!\n");
233 ret = TEST_RESULT_FAIL;
234 }
235
236 goto out;
237 }
238 }
239
240 ret = TEST_RESULT_FAIL;
241
Max Shvetsovc0e91692020-11-12 17:47:13 +0000242out:
243 /* Tell the lead CPU that the calling CPU has completed the test */
244 tftf_send_event(&cpu_booted[core_pos]);
245
246 return ret;
247}
248
249/**
250 * Test direct messaging in multicore setup. Runs SPs on all the cores and sends
251 * direct messages to SPs.
252 */
253test_result_t test_ffa_secondary_core_direct_msg(void)
254{
Max Shvetsovc0e91692020-11-12 17:47:13 +0000255 /**********************************************************************
256 * Check SPMC has ffa_version and expected FFA endpoints are deployed.
257 **********************************************************************/
258 CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
J-Alvesd56c53c2021-07-01 16:32:16 +0100259 return spm_run_multi_core_test((uintptr_t)cpu_on_handler, cpu_booted);
Max Shvetsovc0e91692020-11-12 17:47:13 +0000260}