• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2014-2019, 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 <assert_macros.S>
11#include <lib/cpus/errata_report.h>
12
13#define CPU_IMPL_PN_MASK	(MIDR_IMPL_MASK << MIDR_IMPL_SHIFT) | \
14				(MIDR_PN_MASK << MIDR_PN_SHIFT)
15
16/* The number of CPU operations allowed */
17#define CPU_MAX_PWR_DWN_OPS		2
18
19/* Special constant to specify that CPU has no reset function */
20#define CPU_NO_RESET_FUNC		0
21
22#define CPU_NO_EXTRA1_FUNC		0
23#define CPU_NO_EXTRA2_FUNC		0
24
25/* Word size for 64-bit CPUs */
26#define CPU_WORD_SIZE			8
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	.equ	CPU_MIDR_SIZE, CPU_WORD_SIZE
40	.equ	CPU_EXTRA1_FUNC_SIZE, CPU_WORD_SIZE
41	.equ	CPU_EXTRA2_FUNC_SIZE, CPU_WORD_SIZE
42	.equ	CPU_E_HANDLER_FUNC_SIZE, CPU_WORD_SIZE
43	.equ	CPU_RESET_FUNC_SIZE, CPU_WORD_SIZE
44	.equ	CPU_PWR_DWN_OPS_SIZE, CPU_WORD_SIZE * CPU_MAX_PWR_DWN_OPS
45	.equ	CPU_ERRATA_FUNC_SIZE, CPU_WORD_SIZE
46	.equ	CPU_ERRATA_LOCK_SIZE, CPU_WORD_SIZE
47	.equ	CPU_ERRATA_PRINTED_SIZE, CPU_WORD_SIZE
48	.equ	CPU_REG_DUMP_SIZE, CPU_WORD_SIZE
49
50#ifndef IMAGE_AT_EL3
51	.equ	CPU_RESET_FUNC_SIZE, 0
52#endif
53
54/* The power down core and cluster is needed only in BL31 */
55#ifndef IMAGE_BL31
56	.equ	CPU_PWR_DWN_OPS_SIZE, 0
57#endif
58
59/* Fields required to print errata status. */
60#if !REPORT_ERRATA
61	.equ	CPU_ERRATA_FUNC_SIZE, 0
62#endif
63
64/* Only BL31 requieres mutual exclusion and printed flag.  */
65#if !(REPORT_ERRATA && defined(IMAGE_BL31))
66	.equ	CPU_ERRATA_LOCK_SIZE, 0
67	.equ	CPU_ERRATA_PRINTED_SIZE, 0
68#endif
69
70#if !defined(IMAGE_BL31) || !CRASH_REPORTING
71	.equ	CPU_REG_DUMP_SIZE, 0
72#endif
73
74/*
75 * Define the offsets to the fields in cpu_ops structure.
76 * Every offset is defined based in the offset and size of the previous
77 * field.
78 */
79	.equ	CPU_MIDR, 0
80	.equ	CPU_RESET_FUNC, CPU_MIDR + CPU_MIDR_SIZE
81	.equ	CPU_EXTRA1_FUNC, CPU_RESET_FUNC + CPU_RESET_FUNC_SIZE
82	.equ	CPU_EXTRA2_FUNC, CPU_EXTRA1_FUNC + CPU_EXTRA1_FUNC_SIZE
83	.equ	CPU_E_HANDLER_FUNC, CPU_EXTRA2_FUNC + CPU_EXTRA2_FUNC_SIZE
84	.equ	CPU_PWR_DWN_OPS, CPU_E_HANDLER_FUNC + CPU_E_HANDLER_FUNC_SIZE
85	.equ	CPU_ERRATA_FUNC, CPU_PWR_DWN_OPS + CPU_PWR_DWN_OPS_SIZE
86	.equ	CPU_ERRATA_LOCK, CPU_ERRATA_FUNC + CPU_ERRATA_FUNC_SIZE
87	.equ	CPU_ERRATA_PRINTED, CPU_ERRATA_LOCK + CPU_ERRATA_LOCK_SIZE
88	.equ	CPU_REG_DUMP, CPU_ERRATA_PRINTED + CPU_ERRATA_PRINTED_SIZE
89	.equ	CPU_OPS_SIZE, CPU_REG_DUMP + CPU_REG_DUMP_SIZE
90
91	/*
92	 * Write given expressions as quad words
93	 *
94	 * _count:
95	 *	Write at least _count quad words. If the given number of
96	 *	expressions is less than _count, repeat the last expression to
97	 *	fill _count quad words in total
98	 * _rest:
99	 *	Optional list of expressions. _this is for parameter extraction
100	 *	only, and has no significance to the caller
101	 *
102	 * Invoked as:
103	 *	fill_constants 2, foo, bar, blah, ...
104	 */
105	.macro fill_constants _count:req, _this, _rest:vararg
106	  .ifgt \_count
107	    /* Write the current expression */
108	    .ifb \_this
109	      .error "Nothing to fill"
110	    .endif
111	    .quad \_this
112
113	    /* Invoke recursively for remaining expressions */
114	    .ifnb \_rest
115	      fill_constants \_count-1, \_rest
116	    .else
117	      fill_constants \_count-1, \_this
118	    .endif
119	  .endif
120	.endm
121
122	/*
123	 * Declare CPU operations
124	 *
125	 * _name:
126	 *	Name of the CPU for which operations are being specified
127	 * _midr:
128	 *	Numeric value expected to read from CPU's MIDR
129	 * _resetfunc:
130	 *	Reset function for the CPU. If there's no CPU reset function,
131	 *	specify CPU_NO_RESET_FUNC
132	 * _extra1:
133	 *	This is a placeholder for future per CPU operations.  Currently,
134	 *	some CPUs use this entry to set a test function to determine if
135	 *	the workaround for CVE-2017-5715 needs to be applied or not.
136	 * _extra2:
137	 *	This is a placeholder for future per CPU operations.  Currently
138	 *	some CPUs use this entry to set a function to disable the
139	 *	workaround for CVE-2018-3639.
140	 * _e_handler:
141	 *	This is a placeholder for future per CPU exception handlers.
142	 * _power_down_ops:
143	 *	Comma-separated list of functions to perform power-down
144	 *	operatios on the CPU. At least one, and up to
145	 *	CPU_MAX_PWR_DWN_OPS number of functions may be specified.
146	 *	Starting at power level 0, these functions shall handle power
147	 *	down at subsequent power levels. If there aren't exactly
148	 *	CPU_MAX_PWR_DWN_OPS functions, the last specified one will be
149	 *	used to handle power down at subsequent levels
150	 */
151	.macro declare_cpu_ops_base _name:req, _midr:req, _resetfunc:req, \
152		_extra1:req, _extra2:req, _e_handler:req, _power_down_ops:vararg
153	.section cpu_ops, "a"
154	.align 3
155	.type cpu_ops_\_name, %object
156	.quad \_midr
157#if defined(IMAGE_AT_EL3)
158	.quad \_resetfunc
159#endif
160	.quad \_extra1
161	.quad \_extra2
162	.quad \_e_handler
163#ifdef IMAGE_BL31
164	/* Insert list of functions */
165	fill_constants CPU_MAX_PWR_DWN_OPS, \_power_down_ops
166#endif
167
168#if REPORT_ERRATA
169	.ifndef \_name\()_cpu_str
170	  /*
171	   * Place errata reported flag, and the spinlock to arbitrate access to
172	   * it in the data section.
173	   */
174	  .pushsection .data
175	  define_asm_spinlock \_name\()_errata_lock
176	  \_name\()_errata_reported:
177	  .word	0
178	  .popsection
179
180	  /* Place CPU string in rodata */
181	  .pushsection .rodata
182	  \_name\()_cpu_str:
183	  .asciz "\_name"
184	  .popsection
185	.endif
186
187	/*
188	 * Mandatory errata status printing function for CPUs of
189	 * this class.
190	 */
191	.quad \_name\()_errata_report
192
193#ifdef IMAGE_BL31
194	/* Pointers to errata lock and reported flag */
195	.quad \_name\()_errata_lock
196	.quad \_name\()_errata_reported
197#endif
198#endif
199
200#if defined(IMAGE_BL31) && CRASH_REPORTING
201	.quad \_name\()_cpu_reg_dump
202#endif
203	.endm
204
205	.macro declare_cpu_ops _name:req, _midr:req, _resetfunc:req, \
206		_power_down_ops:vararg
207		declare_cpu_ops_base \_name, \_midr, \_resetfunc, 0, 0, 0, \
208			\_power_down_ops
209	.endm
210
211	.macro declare_cpu_ops_eh _name:req, _midr:req, _resetfunc:req, \
212		_e_handler:req, _power_down_ops:vararg
213		declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
214			0, 0, \_e_handler, \_power_down_ops
215	.endm
216
217	.macro declare_cpu_ops_wa _name:req, _midr:req, \
218		_resetfunc:req, _extra1:req, _extra2:req, \
219		_power_down_ops:vararg
220		declare_cpu_ops_base \_name, \_midr, \_resetfunc, \
221			\_extra1, \_extra2, 0, \_power_down_ops
222	.endm
223
224#if REPORT_ERRATA
225	/*
226	 * Print status of a CPU errata
227	 *
228	 * _chosen:
229	 *	Identifier indicating whether or not a CPU errata has been
230	 *	compiled in.
231	 * _cpu:
232	 *	Name of the CPU
233	 * _id:
234	 *	Errata identifier
235	 * _rev_var:
236	 *	Register containing the combined value CPU revision and variant
237	 *	- typically the return value of cpu_get_rev_var
238	 */
239	.macro report_errata _chosen, _cpu, _id, _rev_var=x8
240	/* Stash a string with errata ID */
241	.pushsection .rodata
242	\_cpu\()_errata_\_id\()_str:
243	.asciz	"\_id"
244	.popsection
245
246	/* Check whether errata applies */
247	mov	x0, \_rev_var
248	/* Shall clobber: x0-x7 */
249	bl	check_errata_\_id
250
251	.ifeq \_chosen
252	/*
253	 * Errata workaround has not been compiled in. If the errata would have
254	 * applied had it been compiled in, print its status as missing.
255	 */
256	cbz	x0, 900f
257	mov	x0, #ERRATA_MISSING
258	.endif
259900:
260	adr	x1, \_cpu\()_cpu_str
261	adr	x2, \_cpu\()_errata_\_id\()_str
262	bl	errata_print_msg
263	.endm
264#endif
265
266	/*
267	 * This macro is used on some CPUs to detect if they are vulnerable
268	 * to CVE-2017-5715.
269	 */
270	.macro	cpu_check_csv2 _reg _label
271	mrs	\_reg, id_aa64pfr0_el1
272	ubfx	\_reg, \_reg, #ID_AA64PFR0_CSV2_SHIFT, #ID_AA64PFR0_CSV2_LENGTH
273	/*
274	 * If the field equals 1, branch targets trained in one context cannot
275	 * affect speculative execution in a different context.
276	 *
277	 * If the field equals 2, it means that the system is also aware of
278	 * SCXTNUM_ELx register contexts. We aren't using them in the TF, so we
279	 * expect users of the registers to do the right thing.
280	 *
281	 * Only apply mitigations if the value of this field is 0.
282	 */
283#if ENABLE_ASSERTIONS
284	cmp	\_reg, #3 /* Only values 0 to 2 are expected */
285	ASM_ASSERT(lo)
286#endif
287
288	cmp	\_reg, #0
289	bne	\_label
290	.endm
291
292	/*
293	 * Helper macro that reads the part number of the current
294	 * CPU and jumps to the given label if it matches the CPU
295	 * MIDR provided.
296	 *
297	 * Clobbers x0.
298	 */
299	.macro  jump_if_cpu_midr _cpu_midr, _label
300	mrs	x0, midr_el1
301	ubfx	x0, x0, MIDR_PN_SHIFT, #12
302	cmp	w0, #((\_cpu_midr >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
303	b.eq	\_label
304	.endm
305
306#endif /* CPU_MACROS_S */
307