xref: /rk3399_ARM-atf/include/lib/cpus/aarch64/cpu_macros.S (revision dd9fae1ce0e7b985c9fe8f8f8ae358b8c166c6a9)
1/*
2 * Copyright (c) 2014-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 <assert_macros.S>
10#include <lib/cpus/cpu_ops.h>
11#include <lib/cpus/errata.h>
12
13	/*
14	 * Write given expressions as quad words
15	 *
16	 * _count:
17	 *	Write at least _count quad words. If the given number of
18	 *	expressions is less than _count, repeat the last expression to
19	 *	fill _count quad words in total
20	 * _rest:
21	 *	Optional list of expressions. _this is for parameter extraction
22	 *	only, and has no significance to the caller
23	 *
24	 * Invoked as:
25	 *	fill_constants 2, foo, bar, blah, ...
26	 */
27	.macro fill_constants _count:req, _this, _rest:vararg
28	  .ifgt \_count
29	    /* Write the current expression */
30	    .ifb \_this
31	      .error "Nothing to fill"
32	    .endif
33	    .quad \_this
34
35	    /* Invoke recursively for remaining expressions */
36	    .ifnb \_rest
37	      fill_constants \_count-1, \_rest
38	    .else
39	      fill_constants \_count-1, \_this
40	    .endif
41	  .endif
42	.endm
43
44	/*
45	 * Declare CPU operations
46	 *
47	 * _name:
48	 *	Name of the CPU for which operations are being specified
49	 * _midr:
50	 *	Numeric value expected to read from CPU's MIDR
51	 * _resetfunc:
52	 *	Reset function for the CPU. If there's no CPU reset function,
53	 *	specify CPU_NO_RESET_FUNC
54	 * _extra1:
55	 *	This is a placeholder for future per CPU operations.  Currently,
56	 *	some CPUs use this entry to set a test function to determine if
57	 *	the workaround for CVE-2017-5715 needs to be applied or not.
58	 * _extra2:
59	 *	This is a placeholder for future per CPU operations. Currently
60	 *	some CPUs use this entry to set a function to disable the
61	 *	workaround for CVE-2018-3639.
62	 * _extra3:
63	 *	This is a placeholder for future per CPU operations. Currently,
64	 *	some CPUs use this entry to set a test function to determine if
65	 *	the workaround for CVE-2022-23960 needs to be applied or not.
66	 * _e_handler:
67	 *	This is a placeholder for future per CPU exception handlers.
68	 * _power_down_ops:
69	 *	Comma-separated list of functions to perform power-down
70	 *	operatios on the CPU. At least one, and up to
71	 *	CPU_MAX_PWR_DWN_OPS number of functions may be specified.
72	 *	Starting at power level 0, these functions shall handle power
73	 *	down at subsequent power levels. If there aren't exactly
74	 *	CPU_MAX_PWR_DWN_OPS functions, the last specified one will be
75	 *	used to handle power down at subsequent levels
76	 */
77	.macro declare_cpu_ops_base _name:req, _midr:req, _resetfunc:req, \
78		_extra1:req, _extra2:req, _extra3:req, _e_handler:req, _power_down_ops:vararg
79	.section .cpu_ops, "a"
80	.align 3
81	.type cpu_ops_\_name, %object
82	.quad \_midr
83#if defined(IMAGE_AT_EL3)
84	.quad \_resetfunc
85#endif
86	.quad \_extra1
87	.quad \_extra2
88	.quad \_extra3
89	.quad \_e_handler
90#ifdef IMAGE_BL31
91	/* Insert list of functions */
92	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
93#endif
94
95#if REPORT_ERRATA
96	.ifndef \_name\()_cpu_str
97	  /*
98	   * Place errata reported flag, and the spinlock to arbitrate access to
99	   * it in the data section.
100	   */
101	  .pushsection .data
102	  define_asm_spinlock \_name\()_errata_lock
103	  \_name\()_errata_reported:
104	  .word	0
105	  .popsection
106
107	  /* Place CPU string in rodata */
108	  .pushsection .rodata
109	  \_name\()_cpu_str:
110	  .asciz "\_name"
111	  .popsection
112	.endif
113
114	/*
115	 * Mandatory errata status printing function for CPUs of
116	 * this class.
117	 */
118	.quad \_name\()_errata_report
119
120#ifdef IMAGE_BL31
121	/* Pointers to errata lock and reported flag */
122	.quad \_name\()_errata_lock
123	.quad \_name\()_errata_reported
124#endif
125#endif
126
127#if defined(IMAGE_BL31) && CRASH_REPORTING
128	.quad \_name\()_cpu_reg_dump
129#endif
130	.endm
131
132	.macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
133		_power_down_ops:vararg
134		declare_cpu_ops_base \_name, \_midr, \_resetfunc, 0, 0, 0, 0, \
135			\_power_down_ops
136	.endm
137
138	.macro declare_cpu_ops_eh _name:req, _midr:req, _resetfunc:req, \
139		_e_handler:req, _power_down_ops:vararg
140		declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
141			0, 0, 0, \_e_handler, \_power_down_ops
142	.endm
143
144	.macro declare_cpu_ops_wa _name:req, _midr:req, \
145		_resetfunc:req, _extra1:req, _extra2:req, \
146		_extra3:req, _power_down_ops:vararg
147		declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
148			\_extra1, \_extra2, \_extra3, 0, \_power_down_ops
149	.endm
150
151#if REPORT_ERRATA
152	/*
153	 * Print status of a CPU errata
154	 *
155	 * _chosen:
156	 *	Identifier indicating whether or not a CPU errata has been
157	 *	compiled in.
158	 * _cpu:
159	 *	Name of the CPU
160	 * _id:
161	 *	Errata identifier
162	 * _rev_var:
163	 *	Register containing the combined value CPU revision and variant
164	 *	- typically the return value of cpu_get_rev_var
165	 */
166	.macro report_errata _chosen, _cpu, _id, _rev_var=x8
167	/* Stash a string with errata ID */
168	.pushsection .rodata
169	\_cpu\()_errata_\_id\()_str:
170	.asciz	"\_id"
171	.popsection
172
173	/* Check whether errata applies */
174	mov	x0, \_rev_var
175	/* Shall clobber: x0-x7 */
176	bl	check_errata_\_id
177
178	.ifeq \_chosen
179	/*
180	 * Errata workaround has not been compiled in. If the errata would have
181	 * applied had it been compiled in, print its status as missing.
182	 */
183	cbz	x0, 900f
184	mov	x0, #ERRATA_MISSING
185	.endif
186900:
187	adr	x1, \_cpu\()_cpu_str
188	adr	x2, \_cpu\()_errata_\_id\()_str
189	bl	errata_print_msg
190	.endm
191#endif
192
193	/*
194	 * This macro is used on some CPUs to detect if they are vulnerable
195	 * to CVE-2017-5715.
196	 */
197	.macro	cpu_check_csv2 _reg _label
198	mrs	\_reg, id_aa64pfr0_el1
199	ubfx	\_reg, \_reg, #ID_AA64PFR0_CSV2_SHIFT, #ID_AA64PFR0_CSV2_LENGTH
200	/*
201	 * If the field equals 1, branch targets trained in one context cannot
202	 * affect speculative execution in a different context.
203	 *
204	 * If the field equals 2, it means that the system is also aware of
205	 * SCXTNUM_ELx register contexts. We aren't using them in the TF, so we
206	 * expect users of the registers to do the right thing.
207	 *
208	 * Only apply mitigations if the value of this field is 0.
209	 */
210#if ENABLE_ASSERTIONS
211	cmp	\_reg, #3 /* Only values 0 to 2 are expected */
212	ASM_ASSERT(lo)
213#endif
214
215	cmp	\_reg, #0
216	bne	\_label
217	.endm
218
219	/*
220	 * Helper macro that reads the part number of the current
221	 * CPU and jumps to the given label if it matches the CPU
222	 * MIDR provided.
223	 *
224	 * Clobbers x0.
225	 */
226	.macro  jump_if_cpu_midr _cpu_midr, _label
227	mrs	x0, midr_el1
228	ubfx	x0, x0, MIDR_PN_SHIFT, #12
229	cmp	w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
230	b.eq	\_label
231	.endm
232
233#endif /* CPU_MACROS_S */
234