blob: 322afc05aff0fe9417a53014c8d5a123ac101e65 [file] [log] [blame]
Manish Pandey0145ec32024-08-12 17:59:54 +01001/*
2 * Copyright (c) 2024, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
Manish Pandey0145ec32024-08-12 17:59:54 +01006#include <arch.h>
7#include <arch_helpers.h>
8#include <arm_arch_svc.h>
Arvind Ram Prakash81916212024-08-15 15:08:23 -05009#include <events.h>
10#include <plat_topology.h>
11#include <platform.h>
12#include <platform_def.h>
13#include <power_management.h>
14#include <psci.h>
Manish Pandey0145ec32024-08-12 17:59:54 +010015#include <smccc.h>
16#include <sync.h>
Arvind Ram Prakash81916212024-08-15 15:08:23 -050017#include <test_helpers.h>
Manish Pandey0145ec32024-08-12 17:59:54 +010018#include <tftf_lib.h>
Manish Pandey0145ec32024-08-12 17:59:54 +010019
Arvind Ram Prakash81916212024-08-15 15:08:23 -050020static event_t cpu_has_entered_test[PLATFORM_CORE_COUNT];
21
Charlie Bareham70de3ff2024-08-20 11:27:25 +010022static volatile bool exception_triggered;
Arvind Ram Prakash81916212024-08-15 15:08:23 -050023
24static unsigned int test_result;
25
Charlie Bareham70de3ff2024-08-20 11:27:25 +010026static bool exception_handler(void)
Arvind Ram Prakash81916212024-08-15 15:08:23 -050027{
28 uint64_t esr_el2 = read_esr_el2();
29 if (EC_BITS(esr_el2) == EC_UNKNOWN) {
Charlie Bareham70de3ff2024-08-20 11:27:25 +010030 /*
31 * This may be an undef injection, or a trap to EL2 due to a
32 * register not being present. Both cases have the same EC
33 * value.
34 */
35 exception_triggered = true;
Arvind Ram Prakash81916212024-08-15 15:08:23 -050036 return true;
37 }
38
39 return false;
40}
41
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010042static test_result_t test_trbe(void)
43{
44 unsigned int mpid = read_mpidr_el1() & MPID_MASK;
45 unsigned int core_pos = platform_get_core_pos(mpid);
46 bool check_if_affected = is_trbe_errata_affected_core();
47
Charlie Bareham70de3ff2024-08-20 11:27:25 +010048 register_custom_sync_exception_handler(exception_handler);
49 exception_triggered = false;
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010050 read_trblimitr_el1();
Charlie Bareham4397e442024-08-20 10:17:38 +010051 unregister_custom_sync_exception_handler();
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010052
Charlie Bareham70de3ff2024-08-20 11:27:25 +010053 if (exception_triggered == true && check_if_affected == true) {
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010054 test_result = TEST_RESULT_SUCCESS;
Charlie Bareham70de3ff2024-08-20 11:27:25 +010055 tftf_testcase_printf("Exception triggered for core = %d "
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010056 "when accessing TRB_LIMTR\n", core_pos);
Charlie Bareham70de3ff2024-08-20 11:27:25 +010057 } else if (exception_triggered == false && check_if_affected == false) {
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010058 test_result = TEST_RESULT_SUCCESS;
59 tftf_testcase_printf("TRB_LIMITR register accessible for core "
60 "= %d\n", core_pos);
61 } else {
62 test_result = TEST_RESULT_FAIL;
63 }
64
65 return test_result;
66}
67
68static test_result_t test_spe(void)
69{
70 unsigned int mpid = read_mpidr_el1() & MPID_MASK;
71 unsigned int core_pos = platform_get_core_pos(mpid);
72
Charlie Bareham70de3ff2024-08-20 11:27:25 +010073 register_custom_sync_exception_handler(exception_handler);
74 exception_triggered = false;
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010075 read_pmscr_el1();
Charlie Bareham4397e442024-08-20 10:17:38 +010076 unregister_custom_sync_exception_handler();
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010077
Charlie Bareham70de3ff2024-08-20 11:27:25 +010078 if (exception_triggered == true && !is_feat_spe_supported()) {
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010079 test_result = TEST_RESULT_SUCCESS;
Charlie Bareham70de3ff2024-08-20 11:27:25 +010080 tftf_testcase_printf("Exception triggered for core = %d "
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010081 "when accessing PMSCR_EL1\n", core_pos);
Charlie Bareham70de3ff2024-08-20 11:27:25 +010082 } else if (exception_triggered == false &&
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010083 is_feat_spe_supported()) {
84 test_result = TEST_RESULT_SUCCESS;
85 tftf_testcase_printf("PMSCR_EL1 register accessible for core = "
86 "%d\n", core_pos);
87 } else {
88 test_result = TEST_RESULT_FAIL;
89 }
90
91 return test_result;
92}
93
Arvind Ram Prakash81916212024-08-15 15:08:23 -050094/*
95 * Non-lead cpu function that checks if trblimitr_el1 is accessible,
96 * on affected cores this causes a undef injection and passes.In cores that
97 * are not affected test just passes. It fails in other cases.
98 */
99static test_result_t non_lead_cpu_fn(void)
100{
101 unsigned int mpid = read_mpidr_el1() & MPID_MASK;
102 unsigned int core_pos = platform_get_core_pos(mpid);
Charlie Barehame4f2eaa2024-08-12 17:59:54 +0100103 test_result_t result;
Arvind Ram Prakash81916212024-08-15 15:08:23 -0500104
105 test_result = TEST_RESULT_SUCCESS;
106
107 /* Signal to the lead CPU that the calling CPU has entered the test */
108 tftf_send_event(&cpu_has_entered_test[core_pos]);
109
Charlie Barehame4f2eaa2024-08-12 17:59:54 +0100110 result = test_trbe();
111 if (result != TEST_RESULT_SUCCESS) {
112 tftf_testcase_printf("test_trbe_enabled failed with result "
113 "%d\n", result);
114 test_result = result;
115 }
116
117 result = test_spe();
118 if (result != TEST_RESULT_SUCCESS) {
119 tftf_testcase_printf("test_spe_support failed with result %d\n",
120 result);
121 test_result = result;
122 }
Arvind Ram Prakash81916212024-08-15 15:08:23 -0500123
124 /* Ensure that EL3 still functional */
125 smc_args args;
126 smc_ret_values smc_ret;
127 memset(&args, 0, sizeof(args));
128 args.fid = SMCCC_VERSION;
129 smc_ret = tftf_smc(&args);
130
131 tftf_testcase_printf("SMCCC Version = %d.%d\n",
132 (int)((smc_ret.ret0 >> SMCCC_VERSION_MAJOR_SHIFT) & SMCCC_VERSION_MAJOR_MASK),
133 (int)((smc_ret.ret0 >> SMCCC_VERSION_MINOR_SHIFT) & SMCCC_VERSION_MINOR_MASK));
134
Arvind Ram Prakash81916212024-08-15 15:08:23 -0500135 return test_result;
136}
137
138/* This function kicks off non-lead cpus and the non-lead cpu function
139 * checks if errata is applied or not using the test.
140 */
Manish Pandey0145ec32024-08-12 17:59:54 +0100141test_result_t test_asymmetric_features(void)
142{
Arvind Ram Prakash81916212024-08-15 15:08:23 -0500143 unsigned int lead_mpid;
144 unsigned int cpu_mpid, cpu_node;
145 unsigned int core_pos;
146 int psci_ret;
147
Charlie Barehame4f2eaa2024-08-12 17:59:54 +0100148 test_result_t result;
149
150 test_result = TEST_RESULT_SUCCESS;
151
Arvind Ram Prakash81916212024-08-15 15:08:23 -0500152 lead_mpid = read_mpidr_el1() & MPID_MASK;
153
Charlie Barehame4f2eaa2024-08-12 17:59:54 +0100154 /* Testing TRBE and SPE feature in Lead core */
155 result = test_trbe();
156 if (result != TEST_RESULT_SUCCESS) {
157 tftf_testcase_printf("test_trbe_enabled failed with result "
158 "%d\n", result);
159 test_result = result;
160 }
161
162 result = test_spe();
163 if (result != TEST_RESULT_SUCCESS) {
164 tftf_testcase_printf("test_spe_support failed with result %d\n",
165 result);
166 test_result = result;
167 }
168
Arvind Ram Prakash81916212024-08-15 15:08:23 -0500169 SKIP_TEST_IF_LESS_THAN_N_CPUS(2);
170
171 /* Power on all CPUs */
172 for_each_cpu(cpu_node) {
173 cpu_mpid = tftf_get_mpidr_from_node(cpu_node);
174 /* Skip lead CPU as it is already powered on */
175 if (cpu_mpid == lead_mpid)
176 continue;
177
178 psci_ret = tftf_cpu_on(cpu_mpid, (uintptr_t) non_lead_cpu_fn, 0);
179 if (psci_ret != PSCI_E_SUCCESS) {
180 tftf_testcase_printf(
181 "Failed to power on CPU 0x%x (%d)\n",
182 cpu_mpid, psci_ret);
183 return TEST_RESULT_SKIPPED;
184 }
185 }
186
187 /* Wait for non-lead CPUs to enter the test */
188 for_each_cpu(cpu_node) {
189 cpu_mpid = tftf_get_mpidr_from_node(cpu_node);
190 /* Skip lead CPU */
191 if (cpu_mpid == lead_mpid)
192 continue;
193
194 core_pos = platform_get_core_pos(cpu_mpid);
195 tftf_wait_for_event(&cpu_has_entered_test[core_pos]);
196 if (test_result == TEST_RESULT_FAIL)
197 break;
198 }
199
200 unregister_custom_sync_exception_handler();
201
202 return test_result;
Manish Pandey0145ec32024-08-12 17:59:54 +0100203}