blob: 36e2e0fe56b7458f4844913a3f4b8517e8487f2e [file] [log] [blame]
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02001/*
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +01002 * Copyright (c) 2018-2023, Arm Limited. All rights reserved.
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +02003 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#ifndef __TFTF_LIB_H__
8#define __TFTF_LIB_H__
9
10#ifndef __ASSEMBLY__
11
12#include <arch.h>
13#include <arch_helpers.h>
14#include <stdbool.h>
15#include <stdint.h>
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020016
17/*
18 * Possible error codes for signaling the result of a test
19 * TEST_RESULT_MIN and TEST_RESULT_MAX are only used as bounds in the enum.
20 */
21typedef enum {
22 /*
23 * NA = Not applicable.
24 * Initial value for a test result.
25 * Used for CPUs that don't participate in the test.
26 */
27 TEST_RESULT_NA = -1,
28
29 TEST_RESULT_MIN = 0,
30 TEST_RESULT_SKIPPED = TEST_RESULT_MIN,
31 TEST_RESULT_SUCCESS,
32 TEST_RESULT_FAIL,
33 TEST_RESULT_CRASHED,
34
35 TEST_RESULT_MAX
36} test_result_t;
37
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020038#define TEST_RESULT_IS_VALID(result) \
39 ((result >= TEST_RESULT_MIN) && (result < TEST_RESULT_MAX))
40
Jimmy Brisson16de8102023-08-18 08:50:30 -050041#define TEST_ASSERT(must_be_true) \
42 do { \
43 if (!(must_be_true)) { \
44 tftf_testcase_printf("Failed at %s:%d\n", __FILE__, __LINE__); \
45 return TEST_RESULT_FAIL;\
46 } \
47 } while (0)
48
49#define TEST_ASSERT_SKIP(must_be_true) \
50 do { \
51 if (!(must_be_true)) { \
52 tftf_testcase_printf("Failed at %s:%d\n", __FILE__, __LINE__); \
53 return TEST_RESULT_SKIPPED;\
54 } \
55 } while (0)
56
57
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020058/*
59 * PSCI Function Wrappers
60 *
61 * SMC calls to PSCI functions
62 */
63int32_t tftf_psci_cpu_on(u_register_t target_cpu,
64 uintptr_t entry_point_address,
65 u_register_t context_id);
66int32_t tftf_psci_cpu_off(void);
Wing Licb88add2022-10-29 02:32:06 +010067int32_t tftf_psci_set_suspend_mode(uint32_t mode);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +020068int32_t tftf_psci_affinity_info(u_register_t target_affinity,
69 uint32_t lowest_affinity_level);
70int32_t tftf_psci_node_hw_state(u_register_t target_cpu, uint32_t power_level);
71int32_t tftf_get_psci_feature_info(uint32_t psci_func_id);
72u_register_t tftf_psci_stat_count(u_register_t target_cpu,
73 uint32_t power_state);
74u_register_t tftf_psci_stat_residency(u_register_t target_cpu,
75 uint32_t power_state);
76
77/*
78 * PSCI Helper functions
79 */
80
81/*
82 * Gets the context ID used when calling tftf_psci_cpu_on().
83 */
84u_register_t tftf_get_cpu_on_ctx_id(unsigned int core_pos);
85
86/*
87 * Sets the context ID used when calling tftf_psci_cpu_on().
88 */
89void tftf_set_cpu_on_ctx_id(unsigned int core_pos, u_register_t context_id);
90
91/*
92 * Gets the PSCI version of Trusted Firmware-A. The version number returned
93 * is a 32-bit unsigned integer, with the upper 16 bits denoting the major
94 * revision, and the lower 16 bits denoting the minor revision.
95 */
96unsigned int tftf_get_psci_version(void);
97
98/*
99 * Returns 0 if version is not a valid PSCI version supported by TFTF.
100 * Otherwise it returns a value different of 0.
101 */
102int tftf_is_valid_psci_version(unsigned int version);
103
104
105/*
106 * The function constructs a composite state_id up-to the specified
107 * affinity level querying the relevant state property from the platform.
108 * It chooses the first matching state property from the array returned
109 * by platform. In case the requested affinity level is not supported by
110 * the platform, then this function uses DUMMY_STATE_ID as the local state
111 * for that level. This allows the tests to construct composite state-id
112 * for invalid affinity levels as well. It returns the expected return
113 * value from CPU SUSPEND call.
114 */
115int tftf_psci_make_composite_state_id(uint32_t affinity_level,
116 uint32_t state_type, uint32_t *state_id);
117
118/*
119 * This function composes the power state parameter in the right format
120 * needed by PSCI. The detection of the power state format is done during
121 * cold boot by tftf_detect_psci_pstate_format() function.
122 */
123uint32_t tftf_make_psci_pstate(uint32_t affinity_level,
124 uint32_t state_type,
125 uint32_t state_id);
126
127/*
128 * Returns 1, if the EL3 software supports PSCI's original format state ID as
129 * NULL else returns zero
130 */
131unsigned int tftf_is_psci_state_id_null(void);
132
133/*
134 * Returns 1, if the EL3 software supports PSCI's original state format else
135 * returns zero
136 */
137unsigned int tftf_is_psci_pstate_format_original(void);
138
139/* Functions to wait for a specified number of ms or us */
140void waitms(uint64_t ms);
141void waitus(uint64_t us);
142
143/*
Madhukar Pappireddyc783c0b2019-11-14 23:52:37 -0600144 * SMC calls take a function identifier and up to 7 arguments.
145 * Additionally, few SMC calls that originate from EL2 leverage the seventh
146 * argument explicitly. Given that TFTF runs in EL2, we need to be able to
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200147 * specify it.
148 */
149typedef struct {
Sandrine Bailleux13d99f92018-11-16 15:36:08 +0100150 /* Function identifier. Identifies which function is being invoked. */
Sandrine Bailleux17795062018-12-13 16:02:41 +0100151 uint32_t fid;
Sandrine Bailleux13d99f92018-11-16 15:36:08 +0100152
153 u_register_t arg1;
154 u_register_t arg2;
155 u_register_t arg3;
156 u_register_t arg4;
157 u_register_t arg5;
158 u_register_t arg6;
159 u_register_t arg7;
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200160} smc_args;
161
Madhukar Pappireddyc783c0b2019-11-14 23:52:37 -0600162/* SMC calls can return up to 8 register values */
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200163typedef struct {
Sandrine Bailleux13d99f92018-11-16 15:36:08 +0100164 u_register_t ret0;
165 u_register_t ret1;
166 u_register_t ret2;
167 u_register_t ret3;
Madhukar Pappireddyc783c0b2019-11-14 23:52:37 -0600168 u_register_t ret4;
169 u_register_t ret5;
170 u_register_t ret6;
171 u_register_t ret7;
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200172} smc_ret_values;
173
174/*
175 * Trigger an SMC call.
176 */
177smc_ret_values tftf_smc(const smc_args *args);
178
Arunachalam Ganapathy417edca2023-09-05 17:44:24 +0100179/* Assembler routine to trigger a SMC call. */
180smc_ret_values asm_tftf_smc64(uint32_t fid, u_register_t arg1, u_register_t arg2,
181 u_register_t arg3, u_register_t arg4,
182 u_register_t arg5, u_register_t arg6,
183 u_register_t arg7);
184
185/*
186 * Update the SVE hint for the current CPU. Any SMC call made through tftf_smc
187 * will update the SVE hint bit in the SMC Function ID.
188 */
189void tftf_smc_set_sve_hint(bool sve_hint_flag);
190
191/* Return the SVE hint bit value for the current CPU */
192bool tftf_smc_get_sve_hint(void);
193
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200194/*
Olivier Deprez3e1a2952020-03-12 15:44:17 +0100195 * Trigger an HVC call.
196 */
197typedef smc_args hvc_args;
198
199typedef smc_ret_values hvc_ret_values;
200
201hvc_ret_values tftf_hvc(const hvc_args *args);
202
203/*
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200204 * Write a formatted string in the test output buffer.
205 * Just like the standard libc's printf() function, the string produced is under
206 * the control of a format string that specifies how subsequent arguments are
207 * converted.
208 *
209 * The string will appear in the test report.
210 * Use mp_printf() instead for volatile debug messages that are not meant to be
211 * stored into the test report.
212 * Note: The test output buffer referred here is a temporary buffer stored in
213 * RAM. This function doesn't write anything into NVM.
214 *
215 * Upon successful return, return the number of characters printed (not
216 * including the final '\0' character). If an output error is encountered,
217 * a negative value is returned. If the function is not able to print any
218 * character at all, this is considered as an output error. Note that a partial
219 * write (i.e. when the string is truncated) is not considered as an output
220 * error.
221 */
222__attribute__((format(printf, 1, 2)))
223int tftf_testcase_printf(const char *format, ...);
224
225/*
226 * This function is meant to be used by tests.
227 * It tells the framework that the test is going to reset the platform.
228 *
229 * It the test omits to call this function before resetting, the framework will
230 * consider the test has crashed upon resumption.
231 */
232void tftf_notify_reboot(void);
233
234/*
235 * Returns 0 if the test function is executed for the first time,
236 * or 1 if the test rebooted the platform and the test function is being
237 * executed again.
238 * This function is used for tests that reboot the platform, so that they can
239 * execute different code paths on 1st execution and subsequent executions.
240 */
241unsigned int tftf_is_rebooted(void);
242
243static inline unsigned int make_mpid(unsigned int clusterid,
Javier Almansa Sobrino109d5c12020-09-04 12:52:23 +0100244#if PLAT_MAX_PE_PER_CPU > 1
Alexei Fedorov0f305472019-10-29 14:06:54 +0000245 unsigned int coreid,
246 unsigned int threadid)
247#else
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200248 unsigned int coreid)
Alexei Fedorov0f305472019-10-29 14:06:54 +0000249#endif
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200250{
251 /*
252 * If MT bit is set then need to shift the affinities and also set the
253 * MT bit.
254 */
255 if ((read_mpidr_el1() & MPIDR_MT_MASK) != 0)
256 return MPIDR_MT_MASK |
Javier Almansa Sobrino109d5c12020-09-04 12:52:23 +0100257#if PLAT_MAX_PE_PER_CPU > 1
Alexei Fedorov0f305472019-10-29 14:06:54 +0000258 ((threadid & MPIDR_AFFLVL_MASK) << MPIDR_AFF0_SHIFT) |
259#endif
260 ((coreid & MPIDR_AFFLVL_MASK) << MPIDR_AFF1_SHIFT) |
261 ((clusterid & MPIDR_AFFLVL_MASK) << MPIDR_AFF2_SHIFT);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200262 else
Alexei Fedorov0f305472019-10-29 14:06:54 +0000263 return ((coreid & MPIDR_AFFLVL_MASK) << MPIDR_AFF0_SHIFT) |
264 ((clusterid & MPIDR_AFFLVL_MASK) << MPIDR_AFF1_SHIFT);
Sandrine Bailleux3cd87d72018-10-09 11:12:55 +0200265
266}
267
268#endif /* __ASSEMBLY__ */
269#endif /* __TFTF_LIB_H__ */