xref: /rk3399_ARM-atf/lib/cpus/errata_common.c (revision 352719479122597c0df3a52a57eaa6c76b376b2b)
1 /*
2  * Copyright (c) 2024-2025, Arm Limited and Contributors. All rights reserved.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause
5  */
6 
7 /* Runtime C routines for errata workarounds and common routines */
8 
9 #include <assert.h>
10 
11 #include <arch.h>
12 #include <arch_helpers.h>
13 #include <cortex_a75.h>
14 #include <cortex_a510.h>
15 #include <cortex_a520.h>
16 #include <cortex_a710.h>
17 #include <cortex_a715.h>
18 #include <cortex_a720.h>
19 #include <cortex_a720_ae.h>
20 #include <cortex_a725.h>
21 #include <cortex_x2.h>
22 #include <cortex_x3.h>
23 #include <cortex_x4.h>
24 #include <cortex_x925.h>
25 #include <c1_ultra.h>
26 #include <lib/cpus/cpu_ops.h>
27 #include <lib/cpus/errata.h>
28 #include <neoverse_n2.h>
29 #include <neoverse_n3.h>
30 #include <neoverse_v2.h>
31 #include <neoverse_v3.h>
32 
33 struct erratum_entry *find_erratum_entry(uint32_t errata_id)
34 {
35 	struct cpu_ops *cpu_ops;
36 	struct erratum_entry *entry, *end;
37 
38 	cpu_ops = get_cpu_ops_ptr();
39 	assert(cpu_ops != NULL);
40 
41 	entry = cpu_ops->errata_list_start;
42 	assert(entry != NULL);
43 
44 	end = cpu_ops->errata_list_end;
45 	assert(end != NULL);
46 
47 	end--; /* point to the last erratum entry of the queried cpu */
48 
49 	while ((entry <= end)) {
50 		if (entry->id == errata_id) {
51 			return entry;
52 		}
53 		entry += 1;
54 	}
55 	return NULL;
56 }
57 
58 bool check_if_trbe_disable_affected_core(void)
59 {
60 	switch (EXTRACT_PARTNUM(read_midr())) {
61 #if ERRATA_A520_2938996
62 	case EXTRACT_PARTNUM(CORTEX_A520_MIDR):
63 		return check_erratum_cortex_a520_2938996(cpu_get_rev_var()) == ERRATA_APPLIES;
64 #endif
65 #if ERRATA_X4_2726228
66 	case EXTRACT_PARTNUM(CORTEX_X4_MIDR):
67 		return check_erratum_cortex_x4_2726228(cpu_get_rev_var()) == ERRATA_APPLIES;
68 #endif
69 #if ERRATA_A510_2971420
70 	case EXTRACT_PARTNUM(CORTEX_A510_MIDR):
71 		return check_erratum_cortex_a510_2971420(cpu_get_rev_var()) == ERRATA_APPLIES;
72 #endif
73 	default:
74 		break;
75 	}
76 	return false;
77 }
78 
79 #if ERRATA_A75_764081
80 bool errata_a75_764081_applies(void)
81 {
82 	long rev_var = cpu_get_rev_var();
83 	if (check_erratum_cortex_a75_764081(rev_var) == ERRATA_APPLIES) {
84 		return true;
85 	}
86 	return false;
87 }
88 #endif /* ERRATA_A75_764081 */
89 
90 bool errata_ich_vmcr_el2_applies(void)
91 {
92 	switch (EXTRACT_PARTNUM(read_midr())) {
93 #if ERRATA_A710_3701772
94 	case EXTRACT_PARTNUM(CORTEX_A710_MIDR):
95 		if (check_erratum_cortex_a710_3701772(cpu_get_rev_var()) == ERRATA_APPLIES)
96 			return true;
97 		break;
98 #endif /* ERRATA_A710_3701772 */
99 
100 #if ERRATA_A715_3699560
101 	case EXTRACT_PARTNUM(CORTEX_A715_MIDR):
102 		if (check_erratum_cortex_a715_3699560(cpu_get_rev_var()) == ERRATA_APPLIES)
103 			return true;
104 		break;
105 #endif /* ERRATA_A715_3699560 */
106 
107 #if ERRATA_A720_3699561
108 	case EXTRACT_PARTNUM(CORTEX_A720_MIDR):
109 		if (check_erratum_cortex_a720_3699561(cpu_get_rev_var()) == ERRATA_APPLIES)
110 			return true;;
111 		break;
112 #endif /* ERRATA_A720_3699561 */
113 
114 #if ERRATA_A720_AE_3699562
115 	case EXTRACT_PARTNUM(CORTEX_A720_AE_MIDR):
116 		if (check_erratum_cortex_a720_ae_3699562(cpu_get_rev_var()) == ERRATA_APPLIES)
117 			return true;
118 		break;
119 #endif /* ERRATA_A720_AE_3699562 */
120 
121 #if ERRATA_A725_3699564
122 	case EXTRACT_PARTNUM(CORTEX_A725_MIDR):
123 		if (check_erratum_cortex_a725_3699564(cpu_get_rev_var()) == ERRATA_APPLIES)
124 			return true;
125 		break;
126 #endif /* ERRATA_A725_3699564 */
127 
128 #if ERRATA_X2_3701772
129 	case EXTRACT_PARTNUM(CORTEX_X2_MIDR):
130 		if (check_erratum_cortex_x2_3701772(cpu_get_rev_var()) == ERRATA_APPLIES)
131 			return true;
132 		break;
133 #endif /* ERRATA_X2_3701772 */
134 
135 #if ERRATA_X3_3701769
136 	case EXTRACT_PARTNUM(CORTEX_X3_MIDR):
137 		if (check_erratum_cortex_x3_3701769(cpu_get_rev_var()) == ERRATA_APPLIES)
138 			return true;
139 		break;
140 #endif /* ERRATA_X3_3701769 */
141 
142 #if ERRATA_X4_3701758
143 	case EXTRACT_PARTNUM(CORTEX_X4_MIDR):
144 		if (check_erratum_cortex_x4_3701758(cpu_get_rev_var()) == ERRATA_APPLIES)
145 			return true;
146 		break;
147 #endif /* ERRATA_X4_3701758 */
148 
149 #if ERRATA_X925_3701747
150 	case EXTRACT_PARTNUM(CORTEX_X925_MIDR):
151 		if (check_erratum_cortex_x925_3701747(cpu_get_rev_var()) == ERRATA_APPLIES)
152 			return true;
153 		break;
154 #endif /* ERRATA_X925_3701747 */
155 
156 #if ERRATA_N2_3701773
157 	case EXTRACT_PARTNUM(NEOVERSE_N2_MIDR):
158 		if (check_erratum_neoverse_n2_3701773(cpu_get_rev_var()) == ERRATA_APPLIES)
159 			return true;
160 		break;
161 #endif /* ERRATA_N2_3701773 */
162 
163 #if ERRATA_N3_3699563
164 	case EXTRACT_PARTNUM(NEOVERSE_N3_MIDR):
165 		if (check_erratum_neoverse_n3_3699563(cpu_get_rev_var()) == ERRATA_APPLIES)
166 			return true;
167 		break;
168 #endif /* ERRATA_N3_3699563 */
169 
170 #if ERRATA_V2_3701771
171 	case EXTRACT_PARTNUM(NEOVERSE_V2_MIDR):
172 		if (check_erratum_neoverse_v2_3701771(cpu_get_rev_var()) == ERRATA_APPLIES)
173 			return true;
174 		break;
175 #endif /* ERRATA_V2_3701771 */
176 
177 #if ERRATA_V3_3701767
178 	case EXTRACT_PARTNUM(NEOVERSE_V3_MIDR):
179 		if (check_erratum_neoverse_v3_3701767(cpu_get_rev_var()) == ERRATA_APPLIES)
180 			return true;
181 		break;
182 #endif /* ERRATA_V3_3701767 */
183 
184 #if ERRATA_C1ULTRA_3658374
185 	case EXTRACT_PARTNUM(C1_ULTRA_MIDR):
186 		if (check_erratum_c1_ultra_3658374(cpu_get_rev_var()) == ERRATA_APPLIES)
187 			return true;
188 		break;
189 #endif /* ERRATA_C1ULTRA_3658374 */
190 
191 	default:
192 		break;
193 	}
194 
195 	return false;
196 }
197 
198 int check_erratum_applies(uint32_t cve, int errata_id)
199 {
200 	struct erratum_entry *entry;
201 	long rev_var;
202 
203 	rev_var = cpu_get_rev_var();
204 
205 	entry = find_erratum_entry(errata_id);
206 
207 	if (entry == NULL) {
208 		return ERRATA_NOT_APPLIES;
209 	}
210 
211 	assert(entry->cve == cve);
212 
213 	return entry->check_func(rev_var);
214 }
215