xref: /rk3399_ARM-atf/include/lib/cpus/aarch64/cpu_macros.S (revision ff2743e544f0f82381ebb9dff8f14eacb837d2e0)
1/*
2 * Copyright (c) 2014-2018, 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 <arch.h>
10#include <errata_report.h>
11
12#define CPU_IMPL_PN_MASK	(MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \
13				(MIDR_PN_MASK << MIDR_PN_SHIFT)
14
15/* The number of CPU operations allowed */
16#define CPU_MAX_PWR_DWN_OPS		2
17
18/* Special constant to specify that CPU has no reset function */
19#define CPU_NO_RESET_FUNC		0
20
21#define CPU_NO_EXTRA1_FUNC		0
22#define CPU_NO_EXTRA2_FUNC		0
23
24/* Word size for 64-bit CPUs */
25#define CPU_WORD_SIZE			8
26
27#if defined(IMAGE_BL1) || defined(IMAGE_BL31) ||(defined(IMAGE_BL2) && BL2_AT_EL3)
28#define IMAGE_AT_EL3
29#endif
30
31/*
32 * Whether errata status needs reporting. Errata status is printed in debug
33 * builds for both BL1 and BL31 images.
34 */
35#if (defined(IMAGE_BL1) || defined(IMAGE_BL31)) && DEBUG
36# define REPORT_ERRATA	1
37#else
38# define REPORT_ERRATA	0
39#endif
40
41	/*
42	 * Define the offsets to the fields in cpu_ops structure.
43	 */
44	.struct 0
45CPU_MIDR: /* cpu_ops midr */
46	.space  8
47/* Reset fn is needed in BL at reset vector */
48#if defined(IMAGE_AT_EL3)
49CPU_RESET_FUNC: /* cpu_ops reset_func */
50	.space  8
51#endif
52CPU_EXTRA1_FUNC:
53	.space	8
54CPU_EXTRA2_FUNC:
55	.space	8
56#ifdef IMAGE_BL31 /* The power down core and cluster is needed only in BL31 */
57CPU_PWR_DWN_OPS: /* cpu_ops power down functions */
58	.space  (8 * CPU_MAX_PWR_DWN_OPS)
59#endif
60
61/*
62 * Fields required to print errata status. Only in BL31 that the printing
63 * require mutual exclusion and printed flag.
64 */
65#if REPORT_ERRATA
66CPU_ERRATA_FUNC:
67	.space	8
68#if defined(IMAGE_BL31)
69CPU_ERRATA_LOCK:
70	.space	8
71CPU_ERRATA_PRINTED:
72	.space	8
73#endif
74#endif
75
76#if defined(IMAGE_BL31) && CRASH_REPORTING
77CPU_REG_DUMP: /* cpu specific register dump for crash reporting */
78	.space  8
79#endif
80CPU_OPS_SIZE = .
81
82	/*
83	 * Write given expressions as quad words
84	 *
85	 * _count:
86	 *	Write at least _count quad words. If the given number of
87	 *	expressions is less than _count, repeat the last expression to
88	 *	fill _count quad words in total
89	 * _rest:
90	 *	Optional list of expressions. _this is for parameter extraction
91	 *	only, and has no significance to the caller
92	 *
93	 * Invoked as:
94	 *	fill_constants 2, foo, bar, blah, ...
95	 */
96	.macro fill_constants _count:req, _this, _rest:vararg
97	  .ifgt \_count
98	    /* Write the current expression */
99	    .ifb \_this
100	      .error "Nothing to fill"
101	    .endif
102	    .quad \_this
103
104	    /* Invoke recursively for remaining expressions */
105	    .ifnb \_rest
106	      fill_constants \_count-1, \_rest
107	    .else
108	      fill_constants \_count-1, \_this
109	    .endif
110	  .endif
111	.endm
112
113	/*
114	 * Declare CPU operations
115	 *
116	 * _name:
117	 *	Name of the CPU for which operations are being specified
118	 * _midr:
119	 *	Numeric value expected to read from CPU's MIDR
120	 * _resetfunc:
121	 *	Reset function for the CPU. If there's no CPU reset function,
122	 *	specify CPU_NO_RESET_FUNC
123	 * _extra1:
124	 *	This is a placeholder for future per CPU operations.  Currently,
125	 *	some CPUs use this entry to set a test function to determine if
126	 *	the workaround for CVE-2017-5715 needs to be applied or not.
127	 * _extra2:
128	 *	This is a placeholder for future per CPU operations.  Currently
129	 *	some CPUs use this entry to set a function to disable the
130	 *	workaround for CVE-2018-3639.
131	 * _power_down_ops:
132	 *	Comma-separated list of functions to perform power-down
133	 *	operatios on the CPU. At least one, and up to
134	 *	CPU_MAX_PWR_DWN_OPS number of functions may be specified.
135	 *	Starting at power level 0, these functions shall handle power
136	 *	down at subsequent power levels. If there aren't exactly
137	 *	CPU_MAX_PWR_DWN_OPS functions, the last specified one will be
138	 *	used to handle power down at subsequent levels
139	 */
140	.macro declare_cpu_ops_base _name:req, _midr:req, _resetfunc:req, \
141		_extra1:req, _extra2:req, _power_down_ops:vararg
142	.section cpu_ops, "a"
143	.align 3
144	.type cpu_ops_\_name, %object
145	.quad \_midr
146#if defined(IMAGE_AT_EL3)
147	.quad \_resetfunc
148#endif
149	.quad \_extra1
150	.quad \_extra2
151#ifdef IMAGE_BL31
1521:
153	/* Insert list of functions */
154	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
1552:
156	/*
157	 * Error if no or more than CPU_MAX_PWR_DWN_OPS were specified in the
158	 * list
159	 */
160	.ifeq 2b - 1b
161	  .error "At least one power down function must be specified"
162	.else
163	  .iflt 2b - 1b - (CPU_MAX_PWR_DWN_OPS * CPU_WORD_SIZE)
164	    .error "More than CPU_MAX_PWR_DWN_OPS functions specified"
165	  .endif
166	.endif
167#endif
168
169#if REPORT_ERRATA
170	.ifndef \_name\()_cpu_str
171	  /*
172	   * Place errata reported flag, and the spinlock to arbitrate access to
173	   * it in the data section.
174	   */
175	  .pushsection .data
176	  define_asm_spinlock \_name\()_errata_lock
177	  \_name\()_errata_reported:
178	  .word	0
179	  .popsection
180
181	  /* Place CPU string in rodata */
182	  .pushsection .rodata
183	  \_name\()_cpu_str:
184	  .asciz "\_name"
185	  .popsection
186	.endif
187
188	/*
189	 * Weakly-bound, optional errata status printing function for CPUs of
190	 * this class.
191	 */
192	.weak \_name\()_errata_report
193	.quad \_name\()_errata_report
194
195#ifdef IMAGE_BL31
196	/* Pointers to errata lock and reported flag */
197	.quad \_name\()_errata_lock
198	.quad \_name\()_errata_reported
199#endif
200#endif
201
202#if defined(IMAGE_BL31) && CRASH_REPORTING
203	.quad \_name\()_cpu_reg_dump
204#endif
205	.endm
206
207	.macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
208		_power_down_ops:vararg
209		declare_cpu_ops_base \_name, \_midr, \_resetfunc, 0, 0, \
210			\_power_down_ops
211	.endm
212
213	.macro declare_cpu_ops_wa _name:req, _midr:req, \
214		_resetfunc:req, _extra1:req, _extra2:req, \
215		_power_down_ops:vararg
216		declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
217			\_extra1, \_extra2, \_power_down_ops
218	.endm
219
220#if REPORT_ERRATA
221	/*
222	 * Print status of a CPU errata
223	 *
224	 * _chosen:
225	 *	Identifier indicating whether or not a CPU errata has been
226	 *	compiled in.
227	 * _cpu:
228	 *	Name of the CPU
229	 * _id:
230	 *	Errata identifier
231	 * _rev_var:
232	 *	Register containing the combined value CPU revision and variant
233	 *	- typically the return value of cpu_get_rev_var
234	 */
235	.macro report_errata _chosen, _cpu, _id, _rev_var=x8
236	/* Stash a string with errata ID */
237	.pushsection .rodata
238	\_cpu\()_errata_\_id\()_str:
239	.asciz	"\_id"
240	.popsection
241
242	/* Check whether errata applies */
243	mov	x0, \_rev_var
244	/* Shall clobber: x0-x7 */
245	bl	check_errata_\_id
246
247	.ifeq \_chosen
248	/*
249	 * Errata workaround has not been compiled in. If the errata would have
250	 * applied had it been compiled in, print its status as missing.
251	 */
252	cbz	x0, 900f
253	mov	x0, #ERRATA_MISSING
254	.endif
255900:
256	adr	x1, \_cpu\()_cpu_str
257	adr	x2, \_cpu\()_errata_\_id\()_str
258	bl	errata_print_msg
259	.endm
260#endif
261
262#endif /* __CPU_MACROS_S__ */
263
264	/*
265	 * This macro is used on some CPUs to detect if they are vulnerable
266	 * to CVE-2017-5715.
267	 */
268	.macro	cpu_check_csv2 _reg _label
269	mrs	\_reg, id_aa64pfr0_el1
270	ubfx	\_reg, \_reg, #ID_AA64PFR0_CSV2_SHIFT, #ID_AA64PFR0_CSV2_LENGTH
271	/*
272	 * If the field equals to 1 then branch targets trained in one
273	 * context cannot affect speculative execution in a different context.
274	 */
275	cmp	\_reg, #1
276	beq	\_label
277	.endm
278