1/*
2 * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#ifndef CPU_MACROS_S
7#define CPU_MACROS_S
8
9#include <lib/cpus/cpu_ops.h>
10#include <lib/cpus/errata.h>
11
12	/*
13	 * Write given expressions as words
14	 *
15	 * _count:
16	 *	Write at least _count words. If the given number of expressions
17	 *	is less than _count, repeat the last expression to fill _count
18	 *	words in total
19	 * _rest:
20	 *	Optional list of expressions. _this is for parameter extraction
21	 *	only, and has no significance to the caller
22	 *
23	 * Invoked as:
24	 *	fill_constants 2, foo, bar, blah, ...
25	 */
26	.macro fill_constants _count:req, _this, _rest:vararg
27	  .ifgt \_count
28	    /* Write the current expression */
29	    .ifb \_this
30	      .error "Nothing to fill"
31	    .endif
32	    .word \_this
33
34	    /* Invoke recursively for remaining expressions */
35	    .ifnb \_rest
36	      fill_constants \_count-1, \_rest
37	    .else
38	      fill_constants \_count-1, \_this
39	    .endif
40	  .endif
41	.endm
42
43	/*
44	 * Declare CPU operations
45	 *
46	 * _name:
47	 *	Name of the CPU for which operations are being specified
48	 * _midr:
49	 *	Numeric value expected to read from CPU's MIDR
50	 * _resetfunc:
51	 *	Reset function for the CPU. If there's no CPU reset function,
52	 *	specify CPU_NO_RESET_FUNC
53	 * _power_down_ops:
54	 *	Comma-separated list of functions to perform power-down
55	 *	operatios on the CPU. At least one, and up to
56	 *	CPU_MAX_PWR_DWN_OPS number of functions may be specified.
57	 *	Starting at power level 0, these functions shall handle power
58	 *	down at subsequent power levels. If there aren't exactly
59	 *	CPU_MAX_PWR_DWN_OPS functions, the last specified one will be
60	 *	used to handle power down at subsequent levels
61	 */
62	.macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
63		_power_down_ops:vararg
64	.section .cpu_ops, "a"
65	.align 2
66	.type cpu_ops_\_name, %object
67	.word \_midr
68#if defined(IMAGE_AT_EL3)
69	.word \_resetfunc
70#endif
71#ifdef IMAGE_BL32
72	/* Insert list of functions */
73	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
74#endif
75
76	/*
77	 * It is possible (although unlikely) that a cpu may have no errata in
78	 * code. In that case the start label will not be defined. The list is
79	 * inteded to be used in a loop, so define it as zero-length for
80	 * predictable behaviour. Since this macro is always called at the end
81	 * of the cpu file (after all errata have been parsed) we can be sure
82	 * that we are at the end of the list. Some cpus call the macro twice,
83	 * so only do this once.
84	 */
85	.pushsection .rodata.errata_entries
86	.ifndef \_name\()_errata_list_start
87		\_name\()_errata_list_start:
88	.endif
89	/* some call this multiple times, so only do this once */
90	.ifndef \_name\()_errata_list_end
91		\_name\()_errata_list_end:
92	.endif
93	.popsection
94
95	/* and now put them in cpu_ops */
96	.word \_name\()_errata_list_start
97	.word \_name\()_errata_list_end
98
99#if REPORT_ERRATA
100	.ifndef \_name\()_cpu_str
101	  /*
102	   * Place errata reported flag, and the spinlock to arbitrate access to
103	   * it in the data section.
104	   */
105	  .pushsection .data
106	  define_asm_spinlock \_name\()_errata_lock
107	  \_name\()_errata_reported:
108	  .word	0
109	  .popsection
110
111	  /* Place CPU string in rodata */
112	  .pushsection .rodata
113	  \_name\()_cpu_str:
114	  .asciz "\_name"
115	  .popsection
116	.endif
117
118	/*
119	 * Mandatory errata status printing function for CPUs of
120	 * this class.
121	 */
122	.word \_name\()_errata_report
123	.word \_name\()_cpu_str
124
125#ifdef IMAGE_BL32
126	/* Pointers to errata lock and reported flag */
127	.word \_name\()_errata_lock
128	.word \_name\()_errata_reported
129#endif
130#endif
131	.endm
132
133#if REPORT_ERRATA
134	/*
135	 * Print status of a CPU errata
136	 *
137	 * _chosen:
138	 *	Identifier indicating whether or not a CPU errata has been
139	 *	compiled in.
140	 * _cpu:
141	 *	Name of the CPU
142	 * _id:
143	 *	Errata identifier
144	 * _rev_var:
145	 *	Register containing the combined value CPU revision and variant
146	 *	- typically the return value of cpu_get_rev_var
147	 */
148	.macro report_errata _chosen, _cpu, _id, _rev_var=r4
149	/* Stash a string with errata ID */
150	.pushsection .rodata
151	\_cpu\()_errata_\_id\()_str:
152	.asciz	"\_id"
153	.popsection
154
155	/* Check whether errata applies */
156	mov	r0, \_rev_var
157	bl	check_errata_\_id
158
159	.ifeq \_chosen
160	/*
161	 * Errata workaround has not been compiled in. If the errata would have
162	 * applied had it been compiled in, print its status as missing.
163	 */
164	cmp	r0, #0
165	movne	r0, #ERRATA_MISSING
166	.endif
167	ldr	r1, =\_cpu\()_cpu_str
168	ldr	r2, =\_cpu\()_errata_\_id\()_str
169	bl	errata_print_msg
170	.endm
171#endif
172	/*
173	 * Helper macro that reads the part number of the current CPU and jumps
174	 * to the given label if it matches the CPU MIDR provided.
175	 *
176	 * Clobbers: r0-r1
177	 */
178	.macro  jump_if_cpu_midr _cpu_midr, _label
179	ldcopr	r0, MIDR
180	ubfx	r0, r0, #MIDR_PN_SHIFT, #12
181	ldr	r1, =((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
182	cmp	r0, r1
183	beq	\_label
184	.endm
185
186/*
187 * NOTE an erratum and CVE id could clash. However, both numbers are very large
188 * and the probablity is minuscule. Working around this makes code very
189 * complicated and extremely difficult to read so it is not considered. In the
190 * unlikely event that this does happen, prepending the CVE id with a 0 should
191 * resolve the conflict
192 */
193
194/*
195 * Add an entry for this erratum to the errata framework
196 *
197 * _cpu:
198 *	Name of cpu as given to declare_cpu_ops
199 *
200 * _cve:
201 *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
202 *
203 * _id:
204 *	Erratum or CVE number. Please combine with the previous field with the
205 *	ERRATUM or CVE macros
206 *
207 * _chosen:
208 *	Compile time flag on whether the erratum is included
209 *
210 * _special:
211 *	The special non-standard name of an erratum
212 */
213.macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req, _special
214	.pushsection .rodata.errata_entries
215		.align	2
216		.ifndef \_cpu\()_errata_list_start
217		\_cpu\()_errata_list_start:
218		.endif
219
220		/* unused on AArch32, maintain for portability */
221		.word	0
222		/* TODO(errata ABI): this prevents all checker functions from
223		 * being optimised away. Can be done away with unless the ABI
224		 * needs them */
225		.ifnb \_special
226			.word	check_errata_\_special
227		.elseif \_cve
228			.word	check_errata_cve_\_cve\()_\_id
229		.else
230			.word	check_errata_\_id
231		.endif
232		/* Will fit CVEs with up to 10 character in the ID field */
233		.word	\_id
234		.hword	\_cve
235		.byte	\_chosen
236		/* TODO(errata ABI): mitigated field for known but unmitigated
237		 * errata*/
238		.byte	0x1
239	.popsection
240.endm
241
242/*
243 * Maintain compatibility with the old scheme of "each cpu has its own reporter".
244 * TODO remove entirely once all cpus have been converted. This includes the
245 * cpu_ops entry, as print_errata_status can call this directly for all cpus
246 */
247.macro errata_report_shim _cpu:req
248	#if REPORT_ERRATA
249	func \_cpu\()_errata_report
250		push	{r12, lr}
251
252		bl generic_errata_report
253
254		pop	{r12, lr}
255		bx	lr
256	endfunc \_cpu\()_errata_report
257	#endif
258.endm
259#endif /* CPU_MACROS_S */
260