blob: d8bba950351697c5883fa59419636d2ce92e0d1b [file] [log] [blame]
J-Alvesd1aae292020-10-08 17:16:58 +01001/*
J-Alves7d28b332021-02-11 16:08:08 +00002 * Copyright (c) 2021, Arm Limited. All rights reserved.
J-Alvesd1aae292020-10-08 17:16:58 +01003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef CACTUS_TEST_CMDS
8#define CACTUS_TEST_CMDS
9
10#include <debug.h>
11#include <ffa_helpers.h>
J-Alves0e1e7ca2021-01-25 14:11:06 +000012#include <spm_common.h>
J-Alvesd1aae292020-10-08 17:16:58 +010013
14/**
15 * Success and error return to be sent over a msg response.
16 */
J-Alves0e1e7ca2021-01-25 14:11:06 +000017#define CACTUS_SUCCESS U(0)
18#define CACTUS_ERROR U(-1)
19
20/**
21 * Error codes.
22 */
23#define CACTUS_ERROR_INVALID U(1)
24#define CACTUS_ERROR_TEST U(2)
25#define CACTUS_ERROR_FFA_CALL U(3)
J-Alvesd1aae292020-10-08 17:16:58 +010026
27/**
28 * Get command from struct smc_ret_values.
29 */
J-Alves53392012020-11-18 14:51:57 +000030static inline uint64_t cactus_get_cmd(smc_ret_values ret)
31{
32 return (uint64_t)ret.ret3;
33}
J-Alvesd1aae292020-10-08 17:16:58 +010034
35/**
36 * Template for commands to be sent to CACTUS partitions over direct
37 * messages interfaces.
38 */
J-Alves53392012020-11-18 14:51:57 +000039static inline smc_ret_values cactus_send_cmd(
40 ffa_vm_id_t source, ffa_vm_id_t dest, uint64_t cmd, uint64_t val0,
41 uint64_t val1, uint64_t val2, uint64_t val3)
42{
43 return ffa_msg_send_direct_req64_5args(source, dest, cmd, val0, val1,
44 val2, val3);
45}
J-Alvesd1aae292020-10-08 17:16:58 +010046
J-Alves7d28b332021-02-11 16:08:08 +000047/**
48 * Template for responses to Cactus commands.
49 * 'cactus_send_response' is the template for custom responses, in case there is
50 * a need to propagate more than one value in the response of a command.
51 */
52static inline smc_ret_values cactus_send_response(
53 ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t resp, uint32_t val0,
54 uint64_t val1, uint64_t val2, uint64_t val3)
55{
56 return ffa_msg_send_direct_resp64_5args(source, dest, resp, val0, val1,
57 val2, val3);
58}
59
60/**
61 * For responses of one value only.
62 */
63static inline smc_ret_values cactus_response(
64 ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t response)
65{
66 return ffa_msg_send_direct_resp(source, dest, response);
67}
68
69static inline uint32_t cactus_get_response(smc_ret_values ret)
70{
71 return (uint32_t)ret.ret3;
72}
73
74/**
75 * In a successful test, in case the SP needs to propagate an extra value
76 * to conclude the test.
77 * If more arguments are needed, a custom response should be defined for the
78 * specific test.
79 */
80static inline smc_ret_values cactus_success_resp(
81 ffa_vm_id_t source, ffa_vm_id_t dest, uint64_t value)
82{
83 return cactus_send_response(source, dest, CACTUS_SUCCESS, value,
84 0, 0, 0);
85}
86
87/**
88 * In case the test fails on the SP side, the 'error_code' should help specify
89 * the reason, which can be specific to the test, or general ones as defined
90 * in the error code list.
91 */
92static inline smc_ret_values cactus_error_resp(
93 ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t error_code)
94{
95 return cactus_send_response(source, dest, CACTUS_ERROR, error_code,
96 0, 0, 0);
97}
98
99static inline uint32_t cactus_error_code(smc_ret_values ret)
100{
101 return (uint32_t) ret.ret4;
102}
103
J-Alvesd1aae292020-10-08 17:16:58 +0100104#define PRINT_CMD(smc_ret) \
105 VERBOSE("cmd %lx; args: %lx, %lx, %lx, %lx\n", \
106 smc_ret.ret3, smc_ret.ret4, smc_ret.ret5, \
107 smc_ret.ret6, smc_ret.ret7)
108
109/**
J-Alves28672f92020-11-09 15:34:31 +0000110 * With this test command the sender transmits a 64-bit value that it then
111 * expects to receive on the respective command response.
112 *
113 * The id is the hex representation of the string 'echo'.
114 */
115#define CACTUS_ECHO_CMD U(0x6563686f)
116
J-Alves53392012020-11-18 14:51:57 +0000117static inline smc_ret_values cactus_echo_send_cmd(
118 ffa_vm_id_t source, ffa_vm_id_t dest, uint64_t echo_val)
119{
120 return cactus_send_cmd(source, dest, CACTUS_ECHO_CMD, echo_val, 0, 0,
121 0);
122}
J-Alves28672f92020-11-09 15:34:31 +0000123
J-Alves53392012020-11-18 14:51:57 +0000124static inline uint64_t cactus_echo_get_val(smc_ret_values ret)
125{
126 return (uint64_t)ret.ret4;
127}
J-Alves28672f92020-11-09 15:34:31 +0000128
129/**
130 * Command to request a cactus secure partition to send an echo command to
131 * another partition.
132 *
133 * The sender of this command expects to receive CACTUS_SUCCESS if the requested
134 * echo interaction happened successfully, or CACTUS_ERROR otherwise.
135 */
136#define CACTUS_REQ_ECHO_CMD (CACTUS_ECHO_CMD + 1)
137
J-Alves53392012020-11-18 14:51:57 +0000138static inline smc_ret_values cactus_req_echo_send_cmd(
139 ffa_vm_id_t source, ffa_vm_id_t dest, ffa_vm_id_t echo_dest,
140 uint64_t echo_val)
141{
142 return cactus_send_cmd(source, dest, CACTUS_REQ_ECHO_CMD, echo_val,
143 echo_dest, 0, 0);
144}
J-Alves28672f92020-11-09 15:34:31 +0000145
J-Alves53392012020-11-18 14:51:57 +0000146static inline ffa_vm_id_t cactus_req_echo_get_echo_dest(smc_ret_values ret)
147{
148 return (ffa_vm_id_t)ret.ret5;
149}
J-Alves28672f92020-11-09 15:34:31 +0000150
151/**
J-Alves1d203f12020-11-11 11:38:49 +0000152 * Command to create a cyclic dependency between SPs, which could result in
153 * a deadlock. This aims at proving such scenario cannot happen.
154 * If the deadlock happens, the system will just hang.
155 * If the deadlock is prevented, the last partition to use the command will
156 * send response CACTUS_SUCCESS.
157 *
158 * The id is the hex representation of the string 'dead'.
159 */
160#define CACTUS_DEADLOCK_CMD U(0x64656164)
161
J-Alves53392012020-11-18 14:51:57 +0000162static inline smc_ret_values cactus_deadlock_send_cmd(
163 ffa_vm_id_t source, ffa_vm_id_t dest, ffa_vm_id_t next_dest)
164{
165 return cactus_send_cmd(source, dest, CACTUS_DEADLOCK_CMD, next_dest, 0,
166 0, 0);
167}
J-Alves1d203f12020-11-11 11:38:49 +0000168
J-Alves53392012020-11-18 14:51:57 +0000169static inline ffa_vm_id_t cactus_deadlock_get_next_dest(smc_ret_values ret)
170{
171 return (ffa_vm_id_t)ret.ret4;
172}
J-Alves1d203f12020-11-11 11:38:49 +0000173
174/**
175 * Command to request a sequence CACTUS_DEADLOCK_CMD between the partitions
176 * of specified IDs.
177 */
178#define CACTUS_REQ_DEADLOCK_CMD (CACTUS_DEADLOCK_CMD + 1)
179
J-Alves53392012020-11-18 14:51:57 +0000180static inline smc_ret_values cactus_req_deadlock_send_cmd(
181 ffa_vm_id_t source, ffa_vm_id_t dest, ffa_vm_id_t next_dest1,
182 ffa_vm_id_t next_dest2)
183{
184 return cactus_send_cmd(source, dest, CACTUS_REQ_DEADLOCK_CMD,
185 next_dest1, next_dest2, 0, 0);
186}
J-Alves1d203f12020-11-11 11:38:49 +0000187
J-Alves53392012020-11-18 14:51:57 +0000188/* To get next_dest1 use CACTUS_DEADLOCK_GET_NEXT_DEST */
189static inline ffa_vm_id_t cactus_deadlock_get_next_dest2(smc_ret_values ret)
190{
191 return (ffa_vm_id_t)ret.ret5;
192}
J-Alves1d203f12020-11-11 11:38:49 +0000193
194/**
J-Alvesd1aae292020-10-08 17:16:58 +0100195 * Command to notify cactus of a memory management operation. The cmd value
196 * should be the memory management smc function id.
J-Alvesb9085f82020-12-07 10:57:28 +0000197 *
198 * The id is the hex representation of the string "mem"
J-Alvesd1aae292020-10-08 17:16:58 +0100199 */
J-Alvesb9085f82020-12-07 10:57:28 +0000200#define CACTUS_MEM_SEND_CMD U(0x6d656d)
J-Alvesd1aae292020-10-08 17:16:58 +0100201
J-Alves53392012020-11-18 14:51:57 +0000202static inline smc_ret_values cactus_mem_send_cmd(
203 ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t mem_func,
204 ffa_memory_handle_t handle)
205{
206 return cactus_send_cmd(source, dest, CACTUS_MEM_SEND_CMD, mem_func,
207 handle, 0, 0);
208}
J-Alvesb9085f82020-12-07 10:57:28 +0000209
J-Alves53392012020-11-18 14:51:57 +0000210static inline ffa_memory_handle_t cactus_mem_send_get_handle(smc_ret_values ret)
211{
212 return (ffa_memory_handle_t)ret.ret5;
213}
J-Alvesd1aae292020-10-08 17:16:58 +0100214
215/**
J-Alves542d8d82020-11-18 10:34:06 +0000216 * Command to request a memory management operation. The 'mem_func' argument
217 * identifies the operation that is to be performend, and 'receiver' is the id
218 * of the partition to receive the memory region.
219 *
220 * The command id is the hex representation of the string "memory".
221 */
222#define CACTUS_REQ_MEM_SEND_CMD U(0x6d656d6f7279)
223
J-Alves53392012020-11-18 14:51:57 +0000224static inline smc_ret_values cactus_req_mem_send_send_cmd(
225 ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t mem_func,
226 ffa_vm_id_t receiver)
227{
228 return cactus_send_cmd(source, dest, CACTUS_REQ_MEM_SEND_CMD, mem_func,
229 receiver, 0, 0);
230}
J-Alves542d8d82020-11-18 10:34:06 +0000231
J-Alves53392012020-11-18 14:51:57 +0000232static inline uint32_t cactus_req_mem_send_get_mem_func(smc_ret_values ret)
233{
234 return (uint32_t)ret.ret4;
235}
236
237static inline ffa_vm_id_t cactus_req_mem_send_get_receiver(smc_ret_values ret)
238{
239 return (ffa_vm_id_t)ret.ret5;
240}
J-Alves542d8d82020-11-18 10:34:06 +0000241
242/**
Olivier Deprez881b1992020-12-01 15:34:34 +0100243 * Request to fill SIMD vectors with dummy values with purpose to check a
244 * save/restore routine during the context switches between secure world and
245 * normal world.
246 *
247 * The command id is the hex representation of the string "SIMD"
248 */
249#define CACTUS_REQ_SIMD_FILL_CMD U(0x53494d44)
250
251static inline smc_ret_values cactus_req_simd_fill_send_cmd(
252 ffa_vm_id_t source, ffa_vm_id_t dest)
253{
J-Alves0e1e7ca2021-01-25 14:11:06 +0000254 return cactus_send_cmd(source, dest, CACTUS_REQ_SIMD_FILL_CMD, 0, 0, 0,
255 0);
Olivier Deprez881b1992020-12-01 15:34:34 +0100256}
257
J-Alves0e1e7ca2021-01-25 14:11:06 +0000258/**
259 * Pairs a command id with a function call, to handle the command ID.
260 */
261struct cactus_cmd_handler {
262 const uint64_t id;
263 smc_ret_values (*fn)(const smc_ret_values *args,
264 struct mailbox_buffers *mb);
265};
266
267/**
268 * Helper to create the name of a handler function.
269 */
270#define CACTUS_HANDLER_FN_NAME(name) cactus_##name##_handler
271
272/**
273 * Define handler's function signature.
274 */
275#define CACTUS_HANDLER_FN(name) \
276 static smc_ret_values CACTUS_HANDLER_FN_NAME(name)( \
277 const smc_ret_values *args, struct mailbox_buffers *mb)
278
279/**
280 * Helper to define Cactus command handler, and pair it with a command ID.
281 * It also creates a table with this information, to be traversed by
282 * 'cactus_handle_cmd' function.
283 */
284#define CACTUS_CMD_HANDLER(name, ID) \
285 CACTUS_HANDLER_FN(name); \
286 struct cactus_cmd_handler name __section(".cactus_handler") = { \
287 .id = ID, .fn = CACTUS_HANDLER_FN_NAME(name), \
288 }; \
289 CACTUS_HANDLER_FN(name)
290
291bool cactus_handle_cmd(smc_ret_values *cmd_args, smc_ret_values *ret,
292 struct mailbox_buffers *mb);
293
J-Alvesd1aae292020-10-08 17:16:58 +0100294#endif