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