xref: /rk3399_ARM-atf/include/lib/cpus/aarch32/cpu_macros.S (revision 89dba82dfa85fea03e7b2f6ad6a90fcd0aecce55)
1e33b78a6SSoby Mathew/*
20d020822SBoyan Karatotev * Copyright (c) 2016-2025, 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:
510d020822SBoyan Karatotev	 *	Reset function for the CPU
525dd9dbb5SJeenu Viswambharan	 * _power_down_ops:
535dd9dbb5SJeenu Viswambharan	 *	Comma-separated list of functions to perform power-down
545dd9dbb5SJeenu Viswambharan	 *	operatios on the CPU. At least one, and up to
555dd9dbb5SJeenu Viswambharan	 *	CPU_MAX_PWR_DWN_OPS number of functions may be specified.
565dd9dbb5SJeenu Viswambharan	 *	Starting at power level 0, these functions shall handle power
575dd9dbb5SJeenu Viswambharan	 *	down at subsequent power levels. If there aren't exactly
585dd9dbb5SJeenu Viswambharan	 *	CPU_MAX_PWR_DWN_OPS functions, the last specified one will be
595dd9dbb5SJeenu Viswambharan	 *	used to handle power down at subsequent levels
605dd9dbb5SJeenu Viswambharan	 */
615dd9dbb5SJeenu Viswambharan	.macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
625dd9dbb5SJeenu Viswambharan		_power_down_ops:vararg
63da04341eSChris Kay	.section .cpu_ops, "a"
64e33b78a6SSoby Mathew	.align 2
65e33b78a6SSoby Mathew	.type cpu_ops_\_name, %object
66e33b78a6SSoby Mathew	.word \_midr
67b1d27b48SRoberto Vargas#if defined(IMAGE_AT_EL3)
685dd9dbb5SJeenu Viswambharan	.word \_resetfunc
691a0a3f06SYatharth Kochar#endif
703d8256b2SMasahiro Yamada#ifdef IMAGE_BL32
715dd9dbb5SJeenu Viswambharan	/* Insert list of functions */
725dd9dbb5SJeenu Viswambharan	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
731a0a3f06SYatharth Kochar#endif
7410bcd761SJeenu Viswambharan
7534c51f32SBoyan Karatotev	/*
7634c51f32SBoyan Karatotev	 * It is possible (although unlikely) that a cpu may have no errata in
7734c51f32SBoyan Karatotev	 * code. In that case the start label will not be defined. The list is
7834c51f32SBoyan Karatotev	 * inteded to be used in a loop, so define it as zero-length for
7934c51f32SBoyan Karatotev	 * predictable behaviour. Since this macro is always called at the end
8034c51f32SBoyan Karatotev	 * of the cpu file (after all errata have been parsed) we can be sure
8134c51f32SBoyan Karatotev	 * that we are at the end of the list. Some cpus call the macro twice,
8234c51f32SBoyan Karatotev	 * so only do this once.
8334c51f32SBoyan Karatotev	 */
8434c51f32SBoyan Karatotev	.pushsection .rodata.errata_entries
8534c51f32SBoyan Karatotev	.ifndef \_name\()_errata_list_start
8634c51f32SBoyan Karatotev		\_name\()_errata_list_start:
8734c51f32SBoyan Karatotev	.endif
8834c51f32SBoyan Karatotev	/* some call this multiple times, so only do this once */
8934c51f32SBoyan Karatotev	.ifndef \_name\()_errata_list_end
9034c51f32SBoyan Karatotev		\_name\()_errata_list_end:
9134c51f32SBoyan Karatotev	.endif
9234c51f32SBoyan Karatotev	.popsection
9334c51f32SBoyan Karatotev
9434c51f32SBoyan Karatotev	/* and now put them in cpu_ops */
9534c51f32SBoyan Karatotev	.word \_name\()_errata_list_start
9634c51f32SBoyan Karatotev	.word \_name\()_errata_list_end
9734c51f32SBoyan Karatotev
9810bcd761SJeenu Viswambharan#if REPORT_ERRATA
9910bcd761SJeenu Viswambharan	.ifndef \_name\()_cpu_str
10010bcd761SJeenu Viswambharan	  /*
10110bcd761SJeenu Viswambharan	   * Place errata reported flag, and the spinlock to arbitrate access to
10210bcd761SJeenu Viswambharan	   * it in the data section.
10310bcd761SJeenu Viswambharan	   */
10410bcd761SJeenu Viswambharan	  .pushsection .data
10510bcd761SJeenu Viswambharan	  define_asm_spinlock \_name\()_errata_lock
10610bcd761SJeenu Viswambharan	  \_name\()_errata_reported:
10710bcd761SJeenu Viswambharan	  .word	0
10810bcd761SJeenu Viswambharan	  .popsection
10910bcd761SJeenu Viswambharan
11010bcd761SJeenu Viswambharan	  /* Place CPU string in rodata */
11110bcd761SJeenu Viswambharan	  .pushsection .rodata
11210bcd761SJeenu Viswambharan	  \_name\()_cpu_str:
11310bcd761SJeenu Viswambharan	  .asciz "\_name"
11410bcd761SJeenu Viswambharan	  .popsection
11510bcd761SJeenu Viswambharan	.endif
11610bcd761SJeenu Viswambharan
11734c51f32SBoyan Karatotev	.word \_name\()_cpu_str
11810bcd761SJeenu Viswambharan
11910bcd761SJeenu Viswambharan#ifdef IMAGE_BL32
12010bcd761SJeenu Viswambharan	/* Pointers to errata lock and reported flag */
12110bcd761SJeenu Viswambharan	.word \_name\()_errata_lock
12210bcd761SJeenu Viswambharan	.word \_name\()_errata_reported
12310bcd761SJeenu Viswambharan#endif
12410bcd761SJeenu Viswambharan#endif
125e33b78a6SSoby Mathew	.endm
126e33b78a6SSoby Mathew
127da3b038fSDeepak Pandey	/*
128da3b038fSDeepak Pandey	 * Helper macro that reads the part number of the current CPU and jumps
129da3b038fSDeepak Pandey	 * to the given label if it matches the CPU MIDR provided.
130da3b038fSDeepak Pandey	 *
131da3b038fSDeepak Pandey	 * Clobbers: r0-r1
132da3b038fSDeepak Pandey	 */
133da3b038fSDeepak Pandey	.macro  jump_if_cpu_midr _cpu_midr, _label
134da3b038fSDeepak Pandey	ldcopr	r0, MIDR
135da3b038fSDeepak Pandey	ubfx	r0, r0, #MIDR_PN_SHIFT, #12
136da3b038fSDeepak Pandey	ldr	r1, =((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
137da3b038fSDeepak Pandey	cmp	r0, r1
138da3b038fSDeepak Pandey	beq	\_label
139da3b038fSDeepak Pandey	.endm
14010bcd761SJeenu Viswambharan
14134c51f32SBoyan Karatotev/*
14234c51f32SBoyan Karatotev * NOTE an erratum and CVE id could clash. However, both numbers are very large
14334c51f32SBoyan Karatotev * and the probablity is minuscule. Working around this makes code very
14434c51f32SBoyan Karatotev * complicated and extremely difficult to read so it is not considered. In the
14534c51f32SBoyan Karatotev * unlikely event that this does happen, prepending the CVE id with a 0 should
14634c51f32SBoyan Karatotev * resolve the conflict
14734c51f32SBoyan Karatotev */
14834c51f32SBoyan Karatotev
14934c51f32SBoyan Karatotev/*
15034c51f32SBoyan Karatotev * Add an entry for this erratum to the errata framework
15134c51f32SBoyan Karatotev *
15234c51f32SBoyan Karatotev * _cpu:
15334c51f32SBoyan Karatotev *	Name of cpu as given to declare_cpu_ops
15434c51f32SBoyan Karatotev *
15534c51f32SBoyan Karatotev * _cve:
15634c51f32SBoyan Karatotev *	Whether erratum is a CVE. CVE year if yes, 0 otherwise
15734c51f32SBoyan Karatotev *
15834c51f32SBoyan Karatotev * _id:
15934c51f32SBoyan Karatotev *	Erratum or CVE number. Please combine with the previous field with the
16034c51f32SBoyan Karatotev *	ERRATUM or CVE macros
16134c51f32SBoyan Karatotev *
16234c51f32SBoyan Karatotev * _chosen:
16334c51f32SBoyan Karatotev *	Compile time flag on whether the erratum is included
16434c51f32SBoyan Karatotev *
16534c51f32SBoyan Karatotev * _special:
16634c51f32SBoyan Karatotev *	The special non-standard name of an erratum
16734c51f32SBoyan Karatotev */
16834c51f32SBoyan Karatotev.macro add_erratum_entry _cpu:req, _cve:req, _id:req, _chosen:req, _special
16934c51f32SBoyan Karatotev	.pushsection .rodata.errata_entries
17034c51f32SBoyan Karatotev		.align	2
17134c51f32SBoyan Karatotev		.ifndef \_cpu\()_errata_list_start
17234c51f32SBoyan Karatotev		\_cpu\()_errata_list_start:
17334c51f32SBoyan Karatotev		.endif
17434c51f32SBoyan Karatotev
17534c51f32SBoyan Karatotev		.ifnb \_special
17634c51f32SBoyan Karatotev			.word	check_errata_\_special
17734c51f32SBoyan Karatotev		.elseif \_cve
17834c51f32SBoyan Karatotev			.word	check_errata_cve_\_cve\()_\_id
17934c51f32SBoyan Karatotev		.else
18034c51f32SBoyan Karatotev			.word	check_errata_\_id
18134c51f32SBoyan Karatotev		.endif
18234c51f32SBoyan Karatotev		/* Will fit CVEs with up to 10 character in the ID field */
18334c51f32SBoyan Karatotev		.word	\_id
18434c51f32SBoyan Karatotev		.hword	\_cve
18534c51f32SBoyan Karatotev		.byte	\_chosen
186*89dba82dSBoyan Karatotev		.byte	0x0 /* alignment */
18734c51f32SBoyan Karatotev	.popsection
18834c51f32SBoyan Karatotev.endm
18934c51f32SBoyan Karatotev
190c3cf06f1SAntonio Nino Diaz#endif /* CPU_MACROS_S */
191