blob: a2020341d27d470c574d0c707d6725fe08829f4f [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
22static volatile bool undef_injection_triggered;
23
24static unsigned int test_result;
25
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010026static bool undef_injection_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) {
30 undef_injection_triggered = true;
31 return true;
32 }
33
34 return false;
35}
36
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010037static test_result_t test_trbe(void)
38{
39 unsigned int mpid = read_mpidr_el1() & MPID_MASK;
40 unsigned int core_pos = platform_get_core_pos(mpid);
41 bool check_if_affected = is_trbe_errata_affected_core();
42
Charlie Bareham4397e442024-08-20 10:17:38 +010043 register_custom_sync_exception_handler(undef_injection_handler);
44 undef_injection_triggered = false;
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010045 read_trblimitr_el1();
Charlie Bareham4397e442024-08-20 10:17:38 +010046 unregister_custom_sync_exception_handler();
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010047
48 if (undef_injection_triggered == true && check_if_affected == true) {
49 test_result = TEST_RESULT_SUCCESS;
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010050 tftf_testcase_printf("Undef injection triggered for core = %d "
51 "when accessing TRB_LIMTR\n", core_pos);
52 } else if (undef_injection_triggered == false && check_if_affected == false) {
53 test_result = TEST_RESULT_SUCCESS;
54 tftf_testcase_printf("TRB_LIMITR register accessible for core "
55 "= %d\n", core_pos);
56 } else {
57 test_result = TEST_RESULT_FAIL;
58 }
59
60 return test_result;
61}
62
63static test_result_t test_spe(void)
64{
65 unsigned int mpid = read_mpidr_el1() & MPID_MASK;
66 unsigned int core_pos = platform_get_core_pos(mpid);
67
Charlie Bareham4397e442024-08-20 10:17:38 +010068 register_custom_sync_exception_handler(undef_injection_handler);
69 undef_injection_triggered = false;
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010070 read_pmscr_el1();
Charlie Bareham4397e442024-08-20 10:17:38 +010071 unregister_custom_sync_exception_handler();
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010072
73 if (undef_injection_triggered == true && !is_feat_spe_supported()) {
74 test_result = TEST_RESULT_SUCCESS;
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010075 tftf_testcase_printf("Undef injection triggered for core = %d "
76 "when accessing PMSCR_EL1\n", core_pos);
77 } else if (undef_injection_triggered == false &&
78 is_feat_spe_supported()) {
79 test_result = TEST_RESULT_SUCCESS;
80 tftf_testcase_printf("PMSCR_EL1 register accessible for core = "
81 "%d\n", core_pos);
82 } else {
83 test_result = TEST_RESULT_FAIL;
84 }
85
86 return test_result;
87}
88
Arvind Ram Prakash81916212024-08-15 15:08:23 -050089/*
90 * Non-lead cpu function that checks if trblimitr_el1 is accessible,
91 * on affected cores this causes a undef injection and passes.In cores that
92 * are not affected test just passes. It fails in other cases.
93 */
94static test_result_t non_lead_cpu_fn(void)
95{
96 unsigned int mpid = read_mpidr_el1() & MPID_MASK;
97 unsigned int core_pos = platform_get_core_pos(mpid);
Charlie Barehame4f2eaa2024-08-12 17:59:54 +010098 test_result_t result;
Arvind Ram Prakash81916212024-08-15 15:08:23 -050099
100 test_result = TEST_RESULT_SUCCESS;
101
102 /* Signal to the lead CPU that the calling CPU has entered the test */
103 tftf_send_event(&cpu_has_entered_test[core_pos]);
104
Charlie Barehame4f2eaa2024-08-12 17:59:54 +0100105 result = test_trbe();
106 if (result != TEST_RESULT_SUCCESS) {
107 tftf_testcase_printf("test_trbe_enabled failed with result "
108 "%d\n", result);
109 test_result = result;
110 }
111
112 result = test_spe();
113 if (result != TEST_RESULT_SUCCESS) {
114 tftf_testcase_printf("test_spe_support failed with result %d\n",
115 result);
116 test_result = result;
117 }
Arvind Ram Prakash81916212024-08-15 15:08:23 -0500118
119 /* Ensure that EL3 still functional */
120 smc_args args;
121 smc_ret_values smc_ret;
122 memset(&args, 0, sizeof(args));
123 args.fid = SMCCC_VERSION;
124 smc_ret = tftf_smc(&args);
125
126 tftf_testcase_printf("SMCCC Version = %d.%d\n",
127 (int)((smc_ret.ret0 >> SMCCC_VERSION_MAJOR_SHIFT) & SMCCC_VERSION_MAJOR_MASK),
128 (int)((smc_ret.ret0 >> SMCCC_VERSION_MINOR_SHIFT) & SMCCC_VERSION_MINOR_MASK));
129
Arvind Ram Prakash81916212024-08-15 15:08:23 -0500130 return test_result;
131}
132
133/* This function kicks off non-lead cpus and the non-lead cpu function
134 * checks if errata is applied or not using the test.
135 */
Manish Pandey0145ec32024-08-12 17:59:54 +0100136test_result_t test_asymmetric_features(void)
137{
Arvind Ram Prakash81916212024-08-15 15:08:23 -0500138 unsigned int lead_mpid;
139 unsigned int cpu_mpid, cpu_node;
140 unsigned int core_pos;
141 int psci_ret;
142
Charlie Barehame4f2eaa2024-08-12 17:59:54 +0100143 test_result_t result;
144
145 test_result = TEST_RESULT_SUCCESS;
146
Arvind Ram Prakash81916212024-08-15 15:08:23 -0500147 lead_mpid = read_mpidr_el1() & MPID_MASK;
148
Charlie Barehame4f2eaa2024-08-12 17:59:54 +0100149 /* Testing TRBE and SPE feature in Lead core */
150 result = test_trbe();
151 if (result != TEST_RESULT_SUCCESS) {
152 tftf_testcase_printf("test_trbe_enabled failed with result "
153 "%d\n", result);
154 test_result = result;
155 }
156
157 result = test_spe();
158 if (result != TEST_RESULT_SUCCESS) {
159 tftf_testcase_printf("test_spe_support failed with result %d\n",
160 result);
161 test_result = result;
162 }
163
Arvind Ram Prakash81916212024-08-15 15:08:23 -0500164 SKIP_TEST_IF_LESS_THAN_N_CPUS(2);
165
166 /* Power on all CPUs */
167 for_each_cpu(cpu_node) {
168 cpu_mpid = tftf_get_mpidr_from_node(cpu_node);
169 /* Skip lead CPU as it is already powered on */
170 if (cpu_mpid == lead_mpid)
171 continue;
172
173 psci_ret = tftf_cpu_on(cpu_mpid, (uintptr_t) non_lead_cpu_fn, 0);
174 if (psci_ret != PSCI_E_SUCCESS) {
175 tftf_testcase_printf(
176 "Failed to power on CPU 0x%x (%d)\n",
177 cpu_mpid, psci_ret);
178 return TEST_RESULT_SKIPPED;
179 }
180 }
181
182 /* Wait for non-lead CPUs to enter the test */
183 for_each_cpu(cpu_node) {
184 cpu_mpid = tftf_get_mpidr_from_node(cpu_node);
185 /* Skip lead CPU */
186 if (cpu_mpid == lead_mpid)
187 continue;
188
189 core_pos = platform_get_core_pos(cpu_mpid);
190 tftf_wait_for_event(&cpu_has_entered_test[core_pos]);
191 if (test_result == TEST_RESULT_FAIL)
192 break;
193 }
194
195 unregister_custom_sync_exception_handler();
196
197 return test_result;
Manish Pandey0145ec32024-08-12 17:59:54 +0100198}