xref: /rk3399_ARM-atf/include/lib/cpus/aarch32/cpu_macros.S (revision 34c51f327d47653637cf3604b4cd20819e795f25)
1e33b78a6SSoby Mathew/*
2*34c51f32SBoyan Karatotev * Copyright (c) 2016-2023, Arm Limited and Contributors. All rights reserved.
3e33b78a6SSoby Mathew *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
5e33b78a6SSoby Mathew */
6c3cf06f1SAntonio Nino Diaz#ifndef CPU_MACROS_S
7c3cf06f1SAntonio Nino Diaz#define CPU_MACROS_S
8e33b78a6SSoby Mathew
9007433d8SBoyan Karatotev#include <lib/cpus/cpu_ops.h>
106bb96fa6SBoyan Karatotev#include <lib/cpus/errata.h>
11e33b78a6SSoby Mathew
12e33b78a6SSoby Mathew	/*
135dd9dbb5SJeenu Viswambharan	 * Write given expressions as words
145dd9dbb5SJeenu Viswambharan	 *
155dd9dbb5SJeenu Viswambharan	 * _count:
165dd9dbb5SJeenu Viswambharan	 *	Write at least _count words. If the given number of expressions
175dd9dbb5SJeenu Viswambharan	 *	is less than _count, repeat the last expression to fill _count
185dd9dbb5SJeenu Viswambharan	 *	words in total
195dd9dbb5SJeenu Viswambharan	 * _rest:
205dd9dbb5SJeenu Viswambharan	 *	Optional list of expressions. _this is for parameter extraction
215dd9dbb5SJeenu Viswambharan	 *	only, and has no significance to the caller
225dd9dbb5SJeenu Viswambharan	 *
235dd9dbb5SJeenu Viswambharan	 * Invoked as:
245dd9dbb5SJeenu Viswambharan	 *	fill_constants 2, foo, bar, blah, ...
25e33b78a6SSoby Mathew	 */
265dd9dbb5SJeenu Viswambharan	.macro fill_constants _count:req, _this, _rest:vararg
275dd9dbb5SJeenu Viswambharan	  .ifgt \_count
285dd9dbb5SJeenu Viswambharan	    /* Write the current expression */
295dd9dbb5SJeenu Viswambharan	    .ifb \_this
305dd9dbb5SJeenu Viswambharan	      .error "Nothing to fill"
315dd9dbb5SJeenu Viswambharan	    .endif
325dd9dbb5SJeenu Viswambharan	    .word \_this
335dd9dbb5SJeenu Viswambharan
345dd9dbb5SJeenu Viswambharan	    /* Invoke recursively for remaining expressions */
355dd9dbb5SJeenu Viswambharan	    .ifnb \_rest
365dd9dbb5SJeenu Viswambharan	      fill_constants \_count-1, \_rest
375dd9dbb5SJeenu Viswambharan	    .else
385dd9dbb5SJeenu Viswambharan	      fill_constants \_count-1, \_this
395dd9dbb5SJeenu Viswambharan	    .endif
405dd9dbb5SJeenu Viswambharan	  .endif
415dd9dbb5SJeenu Viswambharan	.endm
425dd9dbb5SJeenu Viswambharan
435dd9dbb5SJeenu Viswambharan	/*
445dd9dbb5SJeenu Viswambharan	 * Declare CPU operations
455dd9dbb5SJeenu Viswambharan	 *
465dd9dbb5SJeenu Viswambharan	 * _name:
475dd9dbb5SJeenu Viswambharan	 *	Name of the CPU for which operations are being specified
485dd9dbb5SJeenu Viswambharan	 * _midr:
495dd9dbb5SJeenu Viswambharan	 *	Numeric value expected to read from CPU's MIDR
505dd9dbb5SJeenu Viswambharan	 * _resetfunc:
515dd9dbb5SJeenu Viswambharan	 *	Reset function for the CPU. If there's no CPU reset function,
525dd9dbb5SJeenu Viswambharan	 *	specify CPU_NO_RESET_FUNC
535dd9dbb5SJeenu Viswambharan	 * _power_down_ops:
545dd9dbb5SJeenu Viswambharan	 *	Comma-separated list of functions to perform power-down
555dd9dbb5SJeenu Viswambharan	 *	operatios on the CPU. At least one, and up to
565dd9dbb5SJeenu Viswambharan	 *	CPU_MAX_PWR_DWN_OPS number of functions may be specified.
575dd9dbb5SJeenu Viswambharan	 *	Starting at power level 0, these functions shall handle power
585dd9dbb5SJeenu Viswambharan	 *	down at subsequent power levels. If there aren't exactly
595dd9dbb5SJeenu Viswambharan	 *	CPU_MAX_PWR_DWN_OPS functions, the last specified one will be
605dd9dbb5SJeenu Viswambharan	 *	used to handle power down at subsequent levels
615dd9dbb5SJeenu Viswambharan	 */
625dd9dbb5SJeenu Viswambharan	.macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
635dd9dbb5SJeenu Viswambharan		_power_down_ops:vararg
64da04341eSChris Kay	.section .cpu_ops, "a"
65e33b78a6SSoby Mathew	.align 2
66e33b78a6SSoby Mathew	.type cpu_ops_\_name, %object
67e33b78a6SSoby Mathew	.word \_midr
68b1d27b48SRoberto Vargas#if defined(IMAGE_AT_EL3)
695dd9dbb5SJeenu Viswambharan	.word \_resetfunc
701a0a3f06SYatharth Kochar#endif
713d8256b2SMasahiro Yamada#ifdef IMAGE_BL32
725dd9dbb5SJeenu Viswambharan	/* Insert list of functions */
735dd9dbb5SJeenu Viswambharan	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
741a0a3f06SYatharth Kochar#endif
7510bcd761SJeenu Viswambharan
76*34c51f32SBoyan Karatotev	/*
77*34c51f32SBoyan Karatotev	 * It is possible (although unlikely) that a cpu may have no errata in
78*34c51f32SBoyan Karatotev	 * code. In that case the start label will not be defined. The list is
79*34c51f32SBoyan Karatotev	 * inteded to be used in a loop, so define it as zero-length for
80*34c51f32SBoyan Karatotev	 * predictable behaviour. Since this macro is always called at the end
81*34c51f32SBoyan Karatotev	 * of the cpu file (after all errata have been parsed) we can be sure
82*34c51f32SBoyan Karatotev	 * that we are at the end of the list. Some cpus call the macro twice,
83*34c51f32SBoyan Karatotev	 * so only do this once.
84*34c51f32SBoyan Karatotev	 */
85*34c51f32SBoyan Karatotev	.pushsection .rodata.errata_entries
86*34c51f32SBoyan Karatotev	.ifndef \_name\()_errata_list_start
87*34c51f32SBoyan Karatotev		\_name\()_errata_list_start:
88*34c51f32SBoyan Karatotev	.endif
89*34c51f32SBoyan Karatotev	/* some call this multiple times, so only do this once */
90*34c51f32SBoyan Karatotev	.ifndef \_name\()_errata_list_end
91*34c51f32SBoyan Karatotev		\_name\()_errata_list_end:
92*34c51f32SBoyan Karatotev	.endif
93*34c51f32SBoyan Karatotev	.popsection
94*34c51f32SBoyan Karatotev
95*34c51f32SBoyan Karatotev	/* and now put them in cpu_ops */
96*34c51f32SBoyan Karatotev	.word \_name\()_errata_list_start
97*34c51f32SBoyan Karatotev	.word \_name\()_errata_list_end
98*34c51f32SBoyan Karatotev
9910bcd761SJeenu Viswambharan#if REPORT_ERRATA
10010bcd761SJeenu Viswambharan	.ifndef \_name\()_cpu_str
10110bcd761SJeenu Viswambharan	  /*
10210bcd761SJeenu Viswambharan	   * Place errata reported flag, and the spinlock to arbitrate access to
10310bcd761SJeenu Viswambharan	   * it in the data section.
10410bcd761SJeenu Viswambharan	   */
10510bcd761SJeenu Viswambharan	  .pushsection .data
10610bcd761SJeenu Viswambharan	  define_asm_spinlock \_name\()_errata_lock
10710bcd761SJeenu Viswambharan	  \_name\()_errata_reported:
10810bcd761SJeenu Viswambharan	  .word	0
10910bcd761SJeenu Viswambharan	  .popsection
11010bcd761SJeenu Viswambharan
11110bcd761SJeenu Viswambharan	  /* Place CPU string in rodata */
11210bcd761SJeenu Viswambharan	  .pushsection .rodata
11310bcd761SJeenu Viswambharan	  \_name\()_cpu_str:
11410bcd761SJeenu Viswambharan	  .asciz "\_name"
11510bcd761SJeenu Viswambharan	  .popsection
11610bcd761SJeenu Viswambharan	.endif
11710bcd761SJeenu Viswambharan
11810bcd761SJeenu Viswambharan	/*
11912af5ed4SSoby Mathew	 * Mandatory errata status printing function for CPUs of
12010bcd761SJeenu Viswambharan	 * this class.
12110bcd761SJeenu Viswambharan	 */
12210bcd761SJeenu Viswambharan	.word \_name\()_errata_report
123*34c51f32SBoyan Karatotev	.word \_name\()_cpu_str
12410bcd761SJeenu Viswambharan
12510bcd761SJeenu Viswambharan#ifdef IMAGE_BL32
12610bcd761SJeenu Viswambharan	/* Pointers to errata lock and reported flag */
12710bcd761SJeenu Viswambharan	.word \_name\()_errata_lock
12810bcd761SJeenu Viswambharan	.word \_name\()_errata_reported
12910bcd761SJeenu Viswambharan#endif
13010bcd761SJeenu Viswambharan#endif
131e33b78a6SSoby Mathew	.endm
132e33b78a6SSoby Mathew
13310bcd761SJeenu Viswambharan#if REPORT_ERRATA
13410bcd761SJeenu Viswambharan	/*
13510bcd761SJeenu Viswambharan	 * Print status of a CPU errata
13610bcd761SJeenu Viswambharan	 *
13710bcd761SJeenu Viswambharan	 * _chosen:
13810bcd761SJeenu Viswambharan	 *	Identifier indicating whether or not a CPU errata has been
13910bcd761SJeenu Viswambharan	 *	compiled in.
14010bcd761SJeenu Viswambharan	 * _cpu:
14110bcd761SJeenu Viswambharan	 *	Name of the CPU
14210bcd761SJeenu Viswambharan	 * _id:
14310bcd761SJeenu Viswambharan	 *	Errata identifier
14410bcd761SJeenu Viswambharan	 * _rev_var:
14510bcd761SJeenu Viswambharan	 *	Register containing the combined value CPU revision and variant
14610bcd761SJeenu Viswambharan	 *	- typically the return value of cpu_get_rev_var
14710bcd761SJeenu Viswambharan	 */
14810bcd761SJeenu Viswambharan	.macro report_errata _chosen, _cpu, _id, _rev_var=r4
14910bcd761SJeenu Viswambharan	/* Stash a string with errata ID */
15010bcd761SJeenu Viswambharan	.pushsection .rodata
15110bcd761SJeenu Viswambharan	\_cpu\()_errata_\_id\()_str:
15210bcd761SJeenu Viswambharan	.asciz	"\_id"
15310bcd761SJeenu Viswambharan	.popsection
15410bcd761SJeenu Viswambharan
15510bcd761SJeenu Viswambharan	/* Check whether errata applies */
15610bcd761SJeenu Viswambharan	mov	r0, \_rev_var
15710bcd761SJeenu Viswambharan	bl	check_errata_\_id
15810bcd761SJeenu Viswambharan
15910bcd761SJeenu Viswambharan	.ifeq \_chosen
16010bcd761SJeenu Viswambharan	/*
16110bcd761SJeenu Viswambharan	 * Errata workaround has not been compiled in. If the errata would have
16210bcd761SJeenu Viswambharan	 * applied had it been compiled in, print its status as missing.
16310bcd761SJeenu Viswambharan	 */
16410bcd761SJeenu Viswambharan	cmp	r0, #0
16510bcd761SJeenu Viswambharan	movne	r0, #ERRATA_MISSING
16610bcd761SJeenu Viswambharan	.endif
16710bcd761SJeenu Viswambharan	ldr	r1, =\_cpu\()_cpu_str
16810bcd761SJeenu Viswambharan	ldr	r2, =\_cpu\()_errata_\_id\()_str
16910bcd761SJeenu Viswambharan	bl	errata_print_msg
17010bcd761SJeenu Viswambharan	.endm
17110bcd761SJeenu Viswambharan#endif
172da3b038fSDeepak Pandey	/*
173da3b038fSDeepak Pandey	 * Helper macro that reads the part number of the current CPU and jumps
174da3b038fSDeepak Pandey	 * to the given label if it matches the CPU MIDR provided.
175da3b038fSDeepak Pandey	 *
176da3b038fSDeepak Pandey	 * Clobbers: r0-r1
177da3b038fSDeepak Pandey	 */
178da3b038fSDeepak Pandey	.macro  jump_if_cpu_midr _cpu_midr, _label
179da3b038fSDeepak Pandey	ldcopr	r0, MIDR
180da3b038fSDeepak Pandey	ubfx	r0, r0, #MIDR_PN_SHIFT, #12
181da3b038fSDeepak Pandey	ldr	r1, =((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
182da3b038fSDeepak Pandey	cmp	r0, r1
183da3b038fSDeepak Pandey	beq	\_label
184da3b038fSDeepak Pandey	.endm
18510bcd761SJeenu Viswambharan
186*34c51f32SBoyan Karatotev/*
187*34c51f32SBoyan Karatotev * NOTE an erratum and CVE id could clash. However, both numbers are very large
188*34c51f32SBoyan Karatotev * and the probablity is minuscule. Working around this makes code very
189*34c51f32SBoyan Karatotev * complicated and extremely difficult to read so it is not considered. In the
190*34c51f32SBoyan Karatotev * unlikely event that this does happen, prepending the CVE id with a 0 should
191*34c51f32SBoyan Karatotev * resolve the conflict
192*34c51f32SBoyan Karatotev */
193*34c51f32SBoyan Karatotev
194*34c51f32SBoyan Karatotev/*
195*34c51f32SBoyan Karatotev * Add an entry for this erratum to the errata framework
196*34c51f32SBoyan Karatotev *
197*34c51f32SBoyan Karatotev * _cpu:
198*34c51f32SBoyan Karatotev *	Name of cpu as given to declare_cpu_ops
199*34c51f32SBoyan Karatotev *
200*34c51f32SBoyan Karatotev * _cve:
201*34c51f32SBoyan Karatotev *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
202*34c51f32SBoyan Karatotev *
203*34c51f32SBoyan Karatotev * _id:
204*34c51f32SBoyan Karatotev *	Erratum or CVE number. Please combine with the previous field with the
205*34c51f32SBoyan Karatotev *	ERRATUM or CVE macros
206*34c51f32SBoyan Karatotev *
207*34c51f32SBoyan Karatotev * _chosen:
208*34c51f32SBoyan Karatotev *	Compile time flag on whether the erratum is included
209*34c51f32SBoyan Karatotev *
210*34c51f32SBoyan Karatotev * _special:
211*34c51f32SBoyan Karatotev *	The special non-standard name of an erratum
212*34c51f32SBoyan Karatotev */
213*34c51f32SBoyan Karatotev.macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req, _special
214*34c51f32SBoyan Karatotev	.pushsection .rodata.errata_entries
215*34c51f32SBoyan Karatotev		.align	2
216*34c51f32SBoyan Karatotev		.ifndef \_cpu\()_errata_list_start
217*34c51f32SBoyan Karatotev		\_cpu\()_errata_list_start:
218*34c51f32SBoyan Karatotev		.endif
219*34c51f32SBoyan Karatotev
220*34c51f32SBoyan Karatotev		/* unused on AArch32, maintain for portability */
221*34c51f32SBoyan Karatotev		.word	0
222*34c51f32SBoyan Karatotev		/* TODO(errata ABI): this prevents all checker functions from
223*34c51f32SBoyan Karatotev		 * being optimised away. Can be done away with unless the ABI
224*34c51f32SBoyan Karatotev		 * needs them */
225*34c51f32SBoyan Karatotev		.ifnb \_special
226*34c51f32SBoyan Karatotev			.word	check_errata_\_special
227*34c51f32SBoyan Karatotev		.elseif \_cve
228*34c51f32SBoyan Karatotev			.word	check_errata_cve_\_cve\()_\_id
229*34c51f32SBoyan Karatotev		.else
230*34c51f32SBoyan Karatotev			.word	check_errata_\_id
231*34c51f32SBoyan Karatotev		.endif
232*34c51f32SBoyan Karatotev		/* Will fit CVEs with up to 10 character in the ID field */
233*34c51f32SBoyan Karatotev		.word	\_id
234*34c51f32SBoyan Karatotev		.hword	\_cve
235*34c51f32SBoyan Karatotev		.byte	\_chosen
236*34c51f32SBoyan Karatotev		/* TODO(errata ABI): mitigated field for known but unmitigated
237*34c51f32SBoyan Karatotev		 * errata*/
238*34c51f32SBoyan Karatotev		.byte	0x1
239*34c51f32SBoyan Karatotev	.popsection
240*34c51f32SBoyan Karatotev.endm
241*34c51f32SBoyan Karatotev
242*34c51f32SBoyan Karatotev/*
243*34c51f32SBoyan Karatotev * Maintain compatibility with the old scheme of "each cpu has its own reporter".
244*34c51f32SBoyan Karatotev * TODO remove entirely once all cpus have been converted. This includes the
245*34c51f32SBoyan Karatotev * cpu_ops entry, as print_errata_status can call this directly for all cpus
246*34c51f32SBoyan Karatotev */
247*34c51f32SBoyan Karatotev.macro errata_report_shim _cpu:req
248*34c51f32SBoyan Karatotev	#if REPORT_ERRATA
249*34c51f32SBoyan Karatotev	func \_cpu\()_errata_report
250*34c51f32SBoyan Karatotev		push	{r12, lr}
251*34c51f32SBoyan Karatotev
252*34c51f32SBoyan Karatotev		bl generic_errata_report
253*34c51f32SBoyan Karatotev
254*34c51f32SBoyan Karatotev		pop	{r12, lr}
255*34c51f32SBoyan Karatotev		bx	lr
256*34c51f32SBoyan Karatotev	endfunc \_cpu\()_errata_report
257*34c51f32SBoyan Karatotev	#endif
258*34c51f32SBoyan Karatotev.endm
259c3cf06f1SAntonio Nino Diaz#endif /* CPU_MACROS_S */
260