blob: 1f8e81c1e2937bb2a954fc86b05f3d2af87dce67 [file] [log] [blame]
Olivier Deprez61be4c12019-12-06 17:45:07 +01001/*
Daniel Boulbyce386b12022-03-29 18:36:36 +01002 * Copyright (c) 2018-2022, 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>
Daniel Boulby82bf3392023-07-28 18:32:27 +010017#include <spm_test_helpers.h>
Olivier Deprez61be4c12019-12-06 17:45:07 +010018#include <test_helpers.h>
19
J-Alvesb1e81d82020-11-09 15:40:31 +000020#define ECHO_VAL1 U(0xa0a0a0a0)
21#define ECHO_VAL2 U(0xb0b0b0b0)
22#define ECHO_VAL3 U(0xc0c0c0c0)
23
J-Alvesb1e81d82020-11-09 15:40:31 +000024static const struct ffa_uuid expected_sp_uuids[] = {
25 {PRIMARY_UUID}, {SECONDARY_UUID}, {TERTIARY_UUID}
26 };
27
Max Shvetsovc0e91692020-11-12 17:47:13 +000028static event_t cpu_booted[PLATFORM_CORE_COUNT];
29
Daniel Boulbye79d2072021-03-03 11:34:53 +000030static test_result_t send_cactus_echo_cmd(ffa_id_t sender,
31 ffa_id_t dest,
J-Alves4cb9dee2021-03-03 13:59:52 +000032 uint64_t value)
Olivier Deprez61be4c12019-12-06 17:45:07 +010033{
Daniel Boulbyce386b12022-03-29 18:36:36 +010034 struct ffa_value ret;
J-Alves4cb9dee2021-03-03 13:59:52 +000035 ret = cactus_echo_send_cmd(sender, dest, value);
Olivier Deprez61be4c12019-12-06 17:45:07 +010036
J-Alves43887ec2021-02-22 12:21:44 +000037 /*
38 * Return responses may be FFA_MSG_SEND_DIRECT_RESP or FFA_INTERRUPT,
39 * but only expect the former. Expect SMC32 convention from SP.
40 */
J-Alves4cb9dee2021-03-03 13:59:52 +000041 if (!is_ffa_direct_response(ret)) {
Olivier Deprez61be4c12019-12-06 17:45:07 +010042 return TEST_RESULT_FAIL;
43 }
44
J-Alves4cb9dee2021-03-03 13:59:52 +000045 if (cactus_get_response(ret) != CACTUS_SUCCESS ||
46 cactus_echo_get_val(ret) != value) {
47 ERROR("Echo Failed!\n");
Olivier Deprez61be4c12019-12-06 17:45:07 +010048 return TEST_RESULT_FAIL;
49 }
50
51 return TEST_RESULT_SUCCESS;
52}
53
J-Alves7581c382020-05-07 18:34:20 +010054test_result_t test_ffa_direct_messaging(void)
Olivier Deprez61be4c12019-12-06 17:45:07 +010055{
Olivier Deprez61be4c12019-12-06 17:45:07 +010056 test_result_t result;
57
58 /**********************************************************************
J-Alvesb1e81d82020-11-09 15:40:31 +000059 * Check SPMC has ffa_version and expected FFA endpoints are deployed.
Olivier Deprez61be4c12019-12-06 17:45:07 +010060 **********************************************************************/
J-Alves04469302021-01-21 14:48:13 +000061 CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
Olivier Deprez3f14f5e2020-03-25 23:31:37 +010062
Olivier Deprez61be4c12019-12-06 17:45:07 +010063 /**********************************************************************
64 * Send a message to SP1 through direct messaging
65 **********************************************************************/
J-Alves4cb9dee2021-03-03 13:59:52 +000066 result = send_cactus_echo_cmd(HYP_ID, SP_ID(1), ECHO_VAL1);
Olivier Deprez61be4c12019-12-06 17:45:07 +010067 if (result != TEST_RESULT_SUCCESS) {
68 return result;
69 }
70
71 /**********************************************************************
72 * Send a message to SP2 through direct messaging
73 **********************************************************************/
J-Alves4cb9dee2021-03-03 13:59:52 +000074 result = send_cactus_echo_cmd(HYP_ID, SP_ID(2), ECHO_VAL2);
Olivier Deprez61be4c12019-12-06 17:45:07 +010075 if (result != TEST_RESULT_SUCCESS) {
76 return result;
77 }
78
79 /**********************************************************************
80 * Send a message to SP1 through direct messaging
81 **********************************************************************/
J-Alves4cb9dee2021-03-03 13:59:52 +000082 result = send_cactus_echo_cmd(HYP_ID, SP_ID(1), ECHO_VAL3);
Olivier Deprez61be4c12019-12-06 17:45:07 +010083
Olivier Deprez0be4abe2020-08-04 11:26:13 +020084 return result;
Olivier Deprez61be4c12019-12-06 17:45:07 +010085}
J-Alvesb1e81d82020-11-09 15:40:31 +000086
87/**
88 * The 'send_cactus_req_echo_cmd' sends a CACTUS_REQ_ECHO_CMD to a cactus SP.
89 * Handling this command, cactus should then send CACTUS_ECHO_CMD to
90 * the specified SP according to 'echo_dest'. If the CACTUS_ECHO_CMD is resolved
91 * successfully, cactus will reply to tftf with CACTUS_SUCCESS, or CACTUS_ERROR
92 * otherwise.
93 * For the CACTUS_SUCCESS response, the test returns TEST_RESULT_SUCCESS.
94 */
Daniel Boulbye79d2072021-03-03 11:34:53 +000095static test_result_t send_cactus_req_echo_cmd(ffa_id_t sender,
96 ffa_id_t dest,
97 ffa_id_t echo_dest,
J-Alvesb1e81d82020-11-09 15:40:31 +000098 uint64_t value)
99{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100100 struct ffa_value ret;
J-Alvesb1e81d82020-11-09 15:40:31 +0000101
J-Alves53392012020-11-18 14:51:57 +0000102 ret = cactus_req_echo_send_cmd(sender, dest, echo_dest, value);
J-Alvesb1e81d82020-11-09 15:40:31 +0000103
J-Alves06373c52021-02-11 15:17:42 +0000104 if (!is_ffa_direct_response(ret)) {
J-Alvesb1e81d82020-11-09 15:40:31 +0000105 return TEST_RESULT_FAIL;
106 }
107
J-Alves53392012020-11-18 14:51:57 +0000108 if (cactus_get_response(ret) == CACTUS_ERROR) {
J-Alvesb1e81d82020-11-09 15:40:31 +0000109 return TEST_RESULT_FAIL;
110 }
111
112 return TEST_RESULT_SUCCESS;
113}
114
115test_result_t test_ffa_sp_to_sp_direct_messaging(void)
116{
117 test_result_t result;
118
J-Alves04469302021-01-21 14:48:13 +0000119 CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
J-Alvesb1e81d82020-11-09 15:40:31 +0000120
121 result = send_cactus_req_echo_cmd(HYP_ID, SP_ID(1), SP_ID(2),
122 ECHO_VAL1);
123 if (result != TEST_RESULT_SUCCESS) {
124 return result;
125 }
126
127 /*
128 * The following the tests are intended to test the handling of a
129 * direct message request with a VM's ID as a the sender.
130 */
J-Alvesd5d87152021-10-29 11:48:37 +0100131 result = send_cactus_req_echo_cmd(VM_ID(1), SP_ID(2), SP_ID(3),
J-Alvesb1e81d82020-11-09 15:40:31 +0000132 ECHO_VAL2);
133 if (result != TEST_RESULT_SUCCESS) {
134 return result;
135 }
136
J-Alvesd5d87152021-10-29 11:48:37 +0100137 result = send_cactus_req_echo_cmd(VM_ID(2), SP_ID(3), SP_ID(1),
J-Alvesb1e81d82020-11-09 15:40:31 +0000138 ECHO_VAL3);
139
140 return result;
141}
J-Alvesae95ac92020-11-11 13:06:55 +0000142
143test_result_t test_ffa_sp_to_sp_deadlock(void)
144{
Daniel Boulbyce386b12022-03-29 18:36:36 +0100145 struct ffa_value ret;
J-Alvesae95ac92020-11-11 13:06:55 +0000146
147 /**********************************************************************
148 * Check SPMC has ffa_version and expected FFA endpoints are deployed.
149 **********************************************************************/
J-Alves04469302021-01-21 14:48:13 +0000150 CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
J-Alvesae95ac92020-11-11 13:06:55 +0000151
J-Alves53392012020-11-18 14:51:57 +0000152 ret = cactus_req_deadlock_send_cmd(HYP_ID, SP_ID(1), SP_ID(2), SP_ID(3));
J-Alvesae95ac92020-11-11 13:06:55 +0000153
Max Shvetsovc0e91692020-11-12 17:47:13 +0000154 if (is_ffa_direct_response(ret) == false) {
J-Alvesae95ac92020-11-11 13:06:55 +0000155 return TEST_RESULT_FAIL;
156 }
157
J-Alves53392012020-11-18 14:51:57 +0000158 if (cactus_get_response(ret) == CACTUS_ERROR) {
J-Alvesae95ac92020-11-11 13:06:55 +0000159 return TEST_RESULT_FAIL;
160 }
161
162 return TEST_RESULT_SUCCESS;
163}
Max Shvetsovc0e91692020-11-12 17:47:13 +0000164
165/**
166 * Handler that is passed during tftf_cpu_on to individual CPU cores.
167 * Runs a specific core and send a direct message request.
Max Shvetsovc0e91692020-11-12 17:47:13 +0000168 */
169static test_result_t cpu_on_handler(void)
170{
J-Alves79c08f12021-10-27 15:15:16 +0100171 unsigned int core_pos = get_current_core_id();
Max Shvetsovc0e91692020-11-12 17:47:13 +0000172 test_result_t ret = TEST_RESULT_SUCCESS;
Daniel Boulbyce386b12022-03-29 18:36:36 +0100173 struct ffa_value ffa_ret;
Max Shvetsovc0e91692020-11-12 17:47:13 +0000174
175 /*
Olivier Deprez35e19482021-02-11 09:32:20 +0100176 * Send a direct message request to SP1 (MP SP) from current physical
177 * CPU. Notice SP1 ECs are already woken as a result of the PSCI_CPU_ON
Max Shvetsovc0e91692020-11-12 17:47:13 +0000178 * invocation so they already reached the message loop.
179 * The SPMC uses the MP pinned context corresponding to the physical
180 * CPU emitting the request.
181 */
182 ret = send_cactus_echo_cmd(HYP_ID, SP_ID(1), ECHO_VAL1);
183 if (ret != TEST_RESULT_SUCCESS) {
184 goto out;
185 }
186
187 /*
188 * Secure Partitions beyond the first SP only have their first
189 * EC (or vCPU0) woken up at boot time by the SPMC.
190 * Other ECs need one round of ffa_run to reach the message loop.
191 */
192 ffa_ret = ffa_run(SP_ID(2), core_pos);
193 if (ffa_func_id(ffa_ret) != FFA_MSG_WAIT) {
194 ERROR("Failed to run SP%x on core %u\n", SP_ID(2),
195 core_pos);
196 ret = TEST_RESULT_FAIL;
197 goto out;
198 }
199
200 /*
Olivier Deprez35e19482021-02-11 09:32:20 +0100201 * Send a direct message request to SP2 (MP SP) from current physical
202 * CPU. The SPMC uses the MP pinned context corresponding to the
203 * physical CPU emitting the request.
Max Shvetsovc0e91692020-11-12 17:47:13 +0000204 */
205 ret = send_cactus_echo_cmd(HYP_ID, SP_ID(2), ECHO_VAL2);
206 if (ret != TEST_RESULT_SUCCESS) {
207 goto out;
208 }
209
Olivier Deprez35e19482021-02-11 09:32:20 +0100210 /*
211 * Send a direct message request to SP3 (UP SP) from current physical CPU.
212 * The SPMC uses the single vCPU migrated to the new physical core.
213 * The single SP vCPU may receive requests from multiple physical CPUs.
214 * Thus it is possible one message is being processed on one core while
215 * another (or multiple) cores attempt sending a new direct message
216 * request. In such case the cores attempting the new request receive
217 * a busy response from the SPMC. To handle this case a retry loop is
218 * implemented permitting some fairness.
219 */
220 uint32_t trial_loop = 5U;
221 while (trial_loop--) {
222 ffa_ret = cactus_echo_send_cmd(HYP_ID, SP_ID(3), ECHO_VAL3);
223 if ((ffa_func_id(ffa_ret) == FFA_ERROR) &&
224 (ffa_error_code(ffa_ret) == FFA_ERROR_BUSY)) {
225 VERBOSE("%s(%u) trial %u\n", __func__, core_pos, trial_loop);
226 waitms(1);
227 continue;
228 }
229
230 if (is_ffa_direct_response(ffa_ret) == true) {
231 if (cactus_get_response(ffa_ret) != CACTUS_SUCCESS ||
232 cactus_echo_get_val(ffa_ret) != ECHO_VAL3) {
233 ERROR("Echo Failed!\n");
234 ret = TEST_RESULT_FAIL;
235 }
236
237 goto out;
238 }
239 }
240
241 ret = TEST_RESULT_FAIL;
242
Max Shvetsovc0e91692020-11-12 17:47:13 +0000243out:
244 /* Tell the lead CPU that the calling CPU has completed the test */
245 tftf_send_event(&cpu_booted[core_pos]);
246
247 return ret;
248}
249
250/**
251 * Test direct messaging in multicore setup. Runs SPs on all the cores and sends
252 * direct messages to SPs.
253 */
254test_result_t test_ffa_secondary_core_direct_msg(void)
255{
Max Shvetsovc0e91692020-11-12 17:47:13 +0000256 /**********************************************************************
257 * Check SPMC has ffa_version and expected FFA endpoints are deployed.
258 **********************************************************************/
259 CHECK_SPMC_TESTING_SETUP(1, 0, expected_sp_uuids);
J-Alvesd56c53c2021-07-01 16:32:16 +0100260 return spm_run_multi_core_test((uintptr_t)cpu_on_handler, cpu_booted);
Max Shvetsovc0e91692020-11-12 17:47:13 +0000261}