blob: c65816f5c9b7b6a1fb21ae1071627b136530b725 [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-Alves4cb9dee2021-03-03 13:59:52 +000026#define CACTUS_ERROR_UNHANDLED U(4)
J-Alvesd1aae292020-10-08 17:16:58 +010027
28/**
29 * Get command from struct smc_ret_values.
30 */
J-Alves53392012020-11-18 14:51:57 +000031static inline uint64_t cactus_get_cmd(smc_ret_values ret)
32{
33 return (uint64_t)ret.ret3;
34}
J-Alvesd1aae292020-10-08 17:16:58 +010035
36/**
37 * Template for commands to be sent to CACTUS partitions over direct
38 * messages interfaces.
39 */
J-Alves53392012020-11-18 14:51:57 +000040static inline smc_ret_values cactus_send_cmd(
41 ffa_vm_id_t source, ffa_vm_id_t dest, uint64_t cmd, uint64_t val0,
42 uint64_t val1, uint64_t val2, uint64_t val3)
43{
J-Alvesecd30742021-02-19 18:31:06 +000044 return ffa_msg_send_direct_req64(source, dest, cmd, val0, val1, val2,
45 val3);
J-Alves53392012020-11-18 14:51:57 +000046}
J-Alvesd1aae292020-10-08 17:16:58 +010047
J-Alves7d28b332021-02-11 16:08:08 +000048/**
49 * Template for responses to Cactus commands.
50 * 'cactus_send_response' is the template for custom responses, in case there is
51 * a need to propagate more than one value in the response of a command.
52 */
53static inline smc_ret_values cactus_send_response(
54 ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t resp, uint32_t val0,
55 uint64_t val1, uint64_t val2, uint64_t val3)
56{
J-Alvesecd30742021-02-19 18:31:06 +000057 return ffa_msg_send_direct_resp64(source, dest, resp, val0, val1,
58 val2, val3);
J-Alves7d28b332021-02-11 16:08:08 +000059}
60
61/**
62 * For responses of one value only.
63 */
64static inline smc_ret_values cactus_response(
65 ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t response)
66{
J-Alvesecd30742021-02-19 18:31:06 +000067 return ffa_msg_send_direct_resp64(source, dest, response, 0, 0, 0, 0);
J-Alves7d28b332021-02-11 16:08:08 +000068}
69
70static inline uint32_t cactus_get_response(smc_ret_values ret)
71{
72 return (uint32_t)ret.ret3;
73}
74
75/**
76 * In a successful test, in case the SP needs to propagate an extra value
77 * to conclude the test.
78 * If more arguments are needed, a custom response should be defined for the
79 * specific test.
80 */
81static inline smc_ret_values cactus_success_resp(
82 ffa_vm_id_t source, ffa_vm_id_t dest, uint64_t value)
83{
84 return cactus_send_response(source, dest, CACTUS_SUCCESS, value,
85 0, 0, 0);
86}
87
88/**
89 * In case the test fails on the SP side, the 'error_code' should help specify
90 * the reason, which can be specific to the test, or general ones as defined
91 * in the error code list.
92 */
93static inline smc_ret_values cactus_error_resp(
94 ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t error_code)
95{
96 return cactus_send_response(source, dest, CACTUS_ERROR, error_code,
97 0, 0, 0);
98}
99
100static inline uint32_t cactus_error_code(smc_ret_values ret)
101{
102 return (uint32_t) ret.ret4;
103}
104
J-Alvesd1aae292020-10-08 17:16:58 +0100105#define PRINT_CMD(smc_ret) \
106 VERBOSE("cmd %lx; args: %lx, %lx, %lx, %lx\n", \
107 smc_ret.ret3, smc_ret.ret4, smc_ret.ret5, \
108 smc_ret.ret6, smc_ret.ret7)
109
110/**
J-Alves28672f92020-11-09 15:34:31 +0000111 * With this test command the sender transmits a 64-bit value that it then
112 * expects to receive on the respective command response.
113 *
114 * The id is the hex representation of the string 'echo'.
115 */
116#define CACTUS_ECHO_CMD U(0x6563686f)
117
J-Alves53392012020-11-18 14:51:57 +0000118static inline smc_ret_values cactus_echo_send_cmd(
119 ffa_vm_id_t source, ffa_vm_id_t dest, uint64_t echo_val)
120{
121 return cactus_send_cmd(source, dest, CACTUS_ECHO_CMD, echo_val, 0, 0,
122 0);
123}
J-Alves28672f92020-11-09 15:34:31 +0000124
J-Alves53392012020-11-18 14:51:57 +0000125static inline uint64_t cactus_echo_get_val(smc_ret_values ret)
126{
127 return (uint64_t)ret.ret4;
128}
J-Alves28672f92020-11-09 15:34:31 +0000129
130/**
131 * Command to request a cactus secure partition to send an echo command to
132 * another partition.
133 *
134 * The sender of this command expects to receive CACTUS_SUCCESS if the requested
135 * echo interaction happened successfully, or CACTUS_ERROR otherwise.
136 */
137#define CACTUS_REQ_ECHO_CMD (CACTUS_ECHO_CMD + 1)
138
J-Alves53392012020-11-18 14:51:57 +0000139static inline smc_ret_values cactus_req_echo_send_cmd(
140 ffa_vm_id_t source, ffa_vm_id_t dest, ffa_vm_id_t echo_dest,
141 uint64_t echo_val)
142{
143 return cactus_send_cmd(source, dest, CACTUS_REQ_ECHO_CMD, echo_val,
144 echo_dest, 0, 0);
145}
J-Alves28672f92020-11-09 15:34:31 +0000146
J-Alves53392012020-11-18 14:51:57 +0000147static inline ffa_vm_id_t cactus_req_echo_get_echo_dest(smc_ret_values ret)
148{
149 return (ffa_vm_id_t)ret.ret5;
150}
J-Alves28672f92020-11-09 15:34:31 +0000151
152/**
J-Alves1d203f12020-11-11 11:38:49 +0000153 * Command to create a cyclic dependency between SPs, which could result in
154 * a deadlock. This aims at proving such scenario cannot happen.
155 * If the deadlock happens, the system will just hang.
156 * If the deadlock is prevented, the last partition to use the command will
157 * send response CACTUS_SUCCESS.
158 *
159 * The id is the hex representation of the string 'dead'.
160 */
161#define CACTUS_DEADLOCK_CMD U(0x64656164)
162
J-Alves53392012020-11-18 14:51:57 +0000163static inline smc_ret_values cactus_deadlock_send_cmd(
164 ffa_vm_id_t source, ffa_vm_id_t dest, ffa_vm_id_t next_dest)
165{
166 return cactus_send_cmd(source, dest, CACTUS_DEADLOCK_CMD, next_dest, 0,
167 0, 0);
168}
J-Alves1d203f12020-11-11 11:38:49 +0000169
J-Alves53392012020-11-18 14:51:57 +0000170static inline ffa_vm_id_t cactus_deadlock_get_next_dest(smc_ret_values ret)
171{
172 return (ffa_vm_id_t)ret.ret4;
173}
J-Alves1d203f12020-11-11 11:38:49 +0000174
175/**
176 * Command to request a sequence CACTUS_DEADLOCK_CMD between the partitions
177 * of specified IDs.
178 */
179#define CACTUS_REQ_DEADLOCK_CMD (CACTUS_DEADLOCK_CMD + 1)
180
J-Alves53392012020-11-18 14:51:57 +0000181static inline smc_ret_values cactus_req_deadlock_send_cmd(
182 ffa_vm_id_t source, ffa_vm_id_t dest, ffa_vm_id_t next_dest1,
183 ffa_vm_id_t next_dest2)
184{
185 return cactus_send_cmd(source, dest, CACTUS_REQ_DEADLOCK_CMD,
186 next_dest1, next_dest2, 0, 0);
187}
J-Alves1d203f12020-11-11 11:38:49 +0000188
J-Alves53392012020-11-18 14:51:57 +0000189/* To get next_dest1 use CACTUS_DEADLOCK_GET_NEXT_DEST */
190static inline ffa_vm_id_t cactus_deadlock_get_next_dest2(smc_ret_values ret)
191{
192 return (ffa_vm_id_t)ret.ret5;
193}
J-Alves1d203f12020-11-11 11:38:49 +0000194
195/**
J-Alvesd1aae292020-10-08 17:16:58 +0100196 * Command to notify cactus of a memory management operation. The cmd value
197 * should be the memory management smc function id.
J-Alvesb9085f82020-12-07 10:57:28 +0000198 *
199 * The id is the hex representation of the string "mem"
J-Alvesd1aae292020-10-08 17:16:58 +0100200 */
J-Alvesb9085f82020-12-07 10:57:28 +0000201#define CACTUS_MEM_SEND_CMD U(0x6d656d)
J-Alvesd1aae292020-10-08 17:16:58 +0100202
J-Alves53392012020-11-18 14:51:57 +0000203static inline smc_ret_values cactus_mem_send_cmd(
204 ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t mem_func,
205 ffa_memory_handle_t handle)
206{
207 return cactus_send_cmd(source, dest, CACTUS_MEM_SEND_CMD, mem_func,
208 handle, 0, 0);
209}
J-Alvesb9085f82020-12-07 10:57:28 +0000210
J-Alves53392012020-11-18 14:51:57 +0000211static inline ffa_memory_handle_t cactus_mem_send_get_handle(smc_ret_values ret)
212{
213 return (ffa_memory_handle_t)ret.ret5;
214}
J-Alvesd1aae292020-10-08 17:16:58 +0100215
216/**
J-Alves542d8d82020-11-18 10:34:06 +0000217 * Command to request a memory management operation. The 'mem_func' argument
218 * identifies the operation that is to be performend, and 'receiver' is the id
219 * of the partition to receive the memory region.
220 *
221 * The command id is the hex representation of the string "memory".
222 */
223#define CACTUS_REQ_MEM_SEND_CMD U(0x6d656d6f7279)
224
J-Alves53392012020-11-18 14:51:57 +0000225static inline smc_ret_values cactus_req_mem_send_send_cmd(
226 ffa_vm_id_t source, ffa_vm_id_t dest, uint32_t mem_func,
227 ffa_vm_id_t receiver)
228{
229 return cactus_send_cmd(source, dest, CACTUS_REQ_MEM_SEND_CMD, mem_func,
230 receiver, 0, 0);
231}
J-Alves542d8d82020-11-18 10:34:06 +0000232
J-Alves53392012020-11-18 14:51:57 +0000233static inline uint32_t cactus_req_mem_send_get_mem_func(smc_ret_values ret)
234{
235 return (uint32_t)ret.ret4;
236}
237
238static inline ffa_vm_id_t cactus_req_mem_send_get_receiver(smc_ret_values ret)
239{
240 return (ffa_vm_id_t)ret.ret5;
241}
J-Alves542d8d82020-11-18 10:34:06 +0000242
243/**
Olivier Deprez881b1992020-12-01 15:34:34 +0100244 * Request to fill SIMD vectors with dummy values with purpose to check a
245 * save/restore routine during the context switches between secure world and
246 * normal world.
247 *
248 * The command id is the hex representation of the string "SIMD"
249 */
250#define CACTUS_REQ_SIMD_FILL_CMD U(0x53494d44)
251
252static inline smc_ret_values cactus_req_simd_fill_send_cmd(
253 ffa_vm_id_t source, ffa_vm_id_t dest)
254{
J-Alves0e1e7ca2021-01-25 14:11:06 +0000255 return cactus_send_cmd(source, dest, CACTUS_REQ_SIMD_FILL_CMD, 0, 0, 0,
256 0);
Olivier Deprez881b1992020-12-01 15:34:34 +0100257}
258
J-Alves0e1e7ca2021-01-25 14:11:06 +0000259/**
260 * Pairs a command id with a function call, to handle the command ID.
261 */
262struct cactus_cmd_handler {
263 const uint64_t id;
264 smc_ret_values (*fn)(const smc_ret_values *args,
265 struct mailbox_buffers *mb);
266};
267
268/**
269 * Helper to create the name of a handler function.
270 */
271#define CACTUS_HANDLER_FN_NAME(name) cactus_##name##_handler
272
273/**
274 * Define handler's function signature.
275 */
276#define CACTUS_HANDLER_FN(name) \
277 static smc_ret_values CACTUS_HANDLER_FN_NAME(name)( \
278 const smc_ret_values *args, struct mailbox_buffers *mb)
279
280/**
281 * Helper to define Cactus command handler, and pair it with a command ID.
282 * It also creates a table with this information, to be traversed by
283 * 'cactus_handle_cmd' function.
284 */
285#define CACTUS_CMD_HANDLER(name, ID) \
286 CACTUS_HANDLER_FN(name); \
287 struct cactus_cmd_handler name __section(".cactus_handler") = { \
288 .id = ID, .fn = CACTUS_HANDLER_FN_NAME(name), \
289 }; \
290 CACTUS_HANDLER_FN(name)
291
292bool cactus_handle_cmd(smc_ret_values *cmd_args, smc_ret_values *ret,
293 struct mailbox_buffers *mb);
294
J-Alvesd1aae292020-10-08 17:16:58 +0100295#endif