cortex_a57.S 13.7 KB
Newer Older
1
/*
2
 * Copyright (c) 2014-2017, ARM Limited and Contributors. All rights reserved.
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include <arch.h>
31
#include <asm_macros.S>
32
#include <assert_macros.S>
33
#include <bl_common.h>
34
#include <cortex_a57.h>
35
#include <cpu_macros.S>
36
#include <debug.h>
37
#include <plat_macros.S>
38

39
40
41
42
43
44
45
46
47
48
	/* ---------------------------------------------
	 * Disable L1 data cache and unified L2 cache
	 * ---------------------------------------------
	 */
func cortex_a57_disable_dcache
	mrs	x1, sctlr_el3
	bic	x1, x1, #SCTLR_C_BIT
	msr	sctlr_el3, x1
	isb
	ret
49
endfunc cortex_a57_disable_dcache
50
51
52
53
54
55
56
57
58
59
60
61
62

	/* ---------------------------------------------
	 * Disable all types of L2 prefetches.
	 * ---------------------------------------------
	 */
func cortex_a57_disable_l2_prefetch
	mrs	x0, CPUECTLR_EL1
	orr	x0, x0, #CPUECTLR_DIS_TWD_ACC_PFTCH_BIT
	mov	x1, #CPUECTLR_L2_IPFTCH_DIST_MASK
	orr	x1, x1, #CPUECTLR_L2_DPFTCH_DIST_MASK
	bic	x0, x0, x1
	msr	CPUECTLR_EL1, x0
	isb
63
	dsb	ish
64
	ret
65
endfunc cortex_a57_disable_l2_prefetch
66
67
68
69
70
71
72
73
74
75

	/* ---------------------------------------------
	 * Disable intra-cluster coherency
	 * ---------------------------------------------
	 */
func cortex_a57_disable_smp
	mrs	x0, CPUECTLR_EL1
	bic	x0, x0, #CPUECTLR_SMP_BIT
	msr	CPUECTLR_EL1, x0
	ret
76
endfunc cortex_a57_disable_smp
77
78
79
80
81
82
83
84
85
86
87

	/* ---------------------------------------------
	 * Disable debug interfaces
	 * ---------------------------------------------
	 */
func cortex_a57_disable_ext_debug
	mov	x0, #1
	msr	osdlr_el1, x0
	isb
	dsb	sy
	ret
88
endfunc cortex_a57_disable_ext_debug
89

90
91
92
93
94
	/* --------------------------------------------------
	 * Errata Workaround for Cortex A57 Errata #806969.
	 * This applies only to revision r0p0 of Cortex A57.
	 * Inputs:
	 * x0: variant[4:7] and revision[0:3] of current cpu.
95
	 * Shall clobber: x0-x17
96
	 * --------------------------------------------------
97
	 */
98
99
100
101
func errata_a57_806969_wa
	/*
	 * Compare x0 against revision r0p0
	 */
102
103
104
	mov	x17, x30
	bl	check_errata_806969
	cbz	x0, 1f
105
	mrs	x1, CPUACTLR_EL1
106
	orr	x1, x1, #CPUACTLR_NO_ALLOC_WBWA
107
	msr	CPUACTLR_EL1, x1
108
109
1:
	ret	x17
110
endfunc errata_a57_806969_wa
111

112
113
114
115
func check_errata_806969
	mov	x1, #0x00
	b	cpu_rev_var_ls
endfunc check_errata_806969
116
117
118
119
120
121

	/* ---------------------------------------------------
	 * Errata Workaround for Cortex A57 Errata #813420.
	 * This applies only to revision r0p0 of Cortex A57.
	 * Inputs:
	 * x0: variant[4:7] and revision[0:3] of current cpu.
122
	 * Shall clobber: x0-x17
123
124
125
126
127
128
	 * ---------------------------------------------------
	 */
func errata_a57_813420_wa
	/*
	 * Compare x0 against revision r0p0
	 */
129
130
131
	mov	x17, x30
	bl	check_errata_813420
	cbz	x0, 1f
132
	mrs	x1, CPUACTLR_EL1
133
	orr	x1, x1, #CPUACTLR_DCC_AS_DCCI
134
	msr	CPUACTLR_EL1, x1
135
136
1:
	ret	x17
137
endfunc errata_a57_813420_wa
138

139
140
141
142
143
func check_errata_813420
	mov	x1, #0x00
	b	cpu_rev_var_ls
endfunc check_errata_813420

144
145
146
147
148
149
150
151
	/* --------------------------------------------------------------------
	 * Disable the over-read from the LDNP instruction.
	 *
	 * This applies to all revisions <= r1p2. The performance degradation
	 * observed with LDNP/STNP has been fixed on r1p3 and onwards.
	 *
	 * Inputs:
	 * x0: variant[4:7] and revision[0:3] of current cpu.
152
	 * Shall clobber: x0-x17
153
154
155
156
157
158
	 * ---------------------------------------------------------------------
	 */
func a57_disable_ldnp_overread
	/*
	 * Compare x0 against revision r1p2
	 */
159
160
161
	mov	x17, x30
	bl	check_errata_disable_ldnp_overread
	cbz	x0, 1f
162
163
164
	mrs	x1, CPUACTLR_EL1
	orr	x1, x1, #CPUACTLR_DIS_OVERREAD
	msr	CPUACTLR_EL1, x1
165
166
1:
	ret	x17
167
168
endfunc a57_disable_ldnp_overread

169
170
171
172
173
func check_errata_disable_ldnp_overread
	mov	x1, #0x12
	b	cpu_rev_var_ls
endfunc check_errata_disable_ldnp_overread

174
175
176
177
178
	/* ---------------------------------------------------
	 * Errata Workaround for Cortex A57 Errata #826974.
	 * This applies only to revision <= r1p1 of Cortex A57.
	 * Inputs:
	 * x0: variant[4:7] and revision[0:3] of current cpu.
179
	 * Shall clobber: x0-x17
180
181
182
183
184
185
	 * ---------------------------------------------------
	 */
func errata_a57_826974_wa
	/*
	 * Compare x0 against revision r1p1
	 */
186
187
188
	mov	x17, x30
	bl	check_errata_826974
	cbz	x0, 1f
189
190
191
	mrs	x1, CPUACTLR_EL1
	orr	x1, x1, #CPUACTLR_DIS_LOAD_PASS_DMB
	msr	CPUACTLR_EL1, x1
192
193
1:
	ret	x17
194
195
endfunc errata_a57_826974_wa

196
197
198
199
200
func check_errata_826974
	mov	x1, #0x11
	b	cpu_rev_var_ls
endfunc check_errata_826974

201
202
203
204
205
	/* ---------------------------------------------------
	 * Errata Workaround for Cortex A57 Errata #826977.
	 * This applies only to revision <= r1p1 of Cortex A57.
	 * Inputs:
	 * x0: variant[4:7] and revision[0:3] of current cpu.
206
	 * Shall clobber: x0-x17
207
208
209
210
211
212
	 * ---------------------------------------------------
	 */
func errata_a57_826977_wa
	/*
	 * Compare x0 against revision r1p1
	 */
213
214
215
	mov	x17, x30
	bl	check_errata_826977
	cbz	x0, 1f
216
217
218
	mrs	x1, CPUACTLR_EL1
	orr	x1, x1, #CPUACTLR_GRE_NGRE_AS_NGNRE
	msr	CPUACTLR_EL1, x1
219
220
1:
	ret	x17
221
222
endfunc errata_a57_826977_wa

223
224
225
226
227
func check_errata_826977
	mov	x1, #0x11
	b	cpu_rev_var_ls
endfunc check_errata_826977

228
229
230
231
232
	/* ---------------------------------------------------
	 * Errata Workaround for Cortex A57 Errata #828024.
	 * This applies only to revision <= r1p1 of Cortex A57.
	 * Inputs:
	 * x0: variant[4:7] and revision[0:3] of current cpu.
233
	 * Shall clobber: x0-x17
234
235
236
237
238
239
	 * ---------------------------------------------------
	 */
func errata_a57_828024_wa
	/*
	 * Compare x0 against revision r1p1
	 */
240
241
242
	mov	x17, x30
	bl	check_errata_828024
	cbz	x0, 1f
243
244
245
246
247
248
249
250
251
	mrs	x1, CPUACTLR_EL1
	/*
	 * Setting the relevant bits in CPUACTLR_EL1 has to be done in 2
	 * instructions here because the resulting bitmask doesn't fit in a
	 * 16-bit value so it cannot be encoded in a single instruction.
	 */
	orr	x1, x1, #CPUACTLR_NO_ALLOC_WBWA
	orr	x1, x1, #(CPUACTLR_DIS_L1_STREAMING | CPUACTLR_DIS_STREAMING)
	msr	CPUACTLR_EL1, x1
252
253
1:
	ret	x17
254
endfunc errata_a57_828024_wa
255

256
257
258
259
260
func check_errata_828024
	mov	x1, #0x11
	b	cpu_rev_var_ls
endfunc check_errata_828024

261
262
263
264
265
	/* ---------------------------------------------------
	 * Errata Workaround for Cortex A57 Errata #829520.
	 * This applies only to revision <= r1p2 of Cortex A57.
	 * Inputs:
	 * x0: variant[4:7] and revision[0:3] of current cpu.
266
	 * Shall clobber: x0-x17
267
268
269
270
271
272
	 * ---------------------------------------------------
	 */
func errata_a57_829520_wa
	/*
	 * Compare x0 against revision r1p2
	 */
273
274
275
	mov	x17, x30
	bl	check_errata_829520
	cbz	x0, 1f
276
277
278
	mrs	x1, CPUACTLR_EL1
	orr	x1, x1, #CPUACTLR_DIS_INDIRECT_PREDICTOR
	msr	CPUACTLR_EL1, x1
279
280
1:
	ret	x17
281
282
endfunc errata_a57_829520_wa

283
284
285
286
287
func check_errata_829520
	mov	x1, #0x12
	b	cpu_rev_var_ls
endfunc check_errata_829520

288
289
290
291
292
	/* ---------------------------------------------------
	 * Errata Workaround for Cortex A57 Errata #833471.
	 * This applies only to revision <= r1p2 of Cortex A57.
	 * Inputs:
	 * x0: variant[4:7] and revision[0:3] of current cpu.
293
	 * Shall clobber: x0-x17
294
295
296
297
298
299
	 * ---------------------------------------------------
	 */
func errata_a57_833471_wa
	/*
	 * Compare x0 against revision r1p2
	 */
300
301
302
	mov	x17, x30
	bl	check_errata_833471
	cbz	x0, 1f
303
304
305
	mrs	x1, CPUACTLR_EL1
	orr	x1, x1, #CPUACTLR_FORCE_FPSCR_FLUSH
	msr	CPUACTLR_EL1, x1
306
307
1:
	ret	x17
308
309
endfunc errata_a57_833471_wa

310
311
312
313
314
func check_errata_833471
	mov	x1, #0x12
	b	cpu_rev_var_ls
endfunc check_errata_833471

315
316
	/* -------------------------------------------------
	 * The CPU Ops reset function for Cortex-A57.
317
	 * Shall clobber: x0-x19
318
319
320
321
	 * -------------------------------------------------
	 */
func cortex_a57_reset_func
	mov	x19, x30
322
323
	bl	cpu_get_rev_var
	mov	x18, x0
324
325

#if ERRATA_A57_806969
326
	mov	x0, x18
327
	bl	errata_a57_806969_wa
328
329
#endif

330
#if ERRATA_A57_813420
331
	mov	x0, x18
332
333
	bl	errata_a57_813420_wa
#endif
334

335
#if A57_DISABLE_NON_TEMPORAL_HINT
336
	mov	x0, x18
337
338
339
	bl	a57_disable_ldnp_overread
#endif

340
#if ERRATA_A57_826974
341
	mov	x0, x18
342
343
344
	bl	errata_a57_826974_wa
#endif

345
#if ERRATA_A57_826977
346
	mov	x0, x18
347
348
349
	bl	errata_a57_826977_wa
#endif

350
#if ERRATA_A57_828024
351
	mov	x0, x18
352
353
	bl	errata_a57_828024_wa
#endif
354
355

#if ERRATA_A57_829520
356
	mov	x0, x18
357
358
359
	bl	errata_a57_829520_wa
#endif

360
#if ERRATA_A57_833471
361
	mov	x0, x18
362
363
364
	bl	errata_a57_833471_wa
#endif

365
	/* ---------------------------------------------
366
	 * Enable the SMP bit.
367
368
	 * ---------------------------------------------
	 */
369
	mrs	x0, CPUECTLR_EL1
370
	orr	x0, x0, #CPUECTLR_SMP_BIT
371
	msr	CPUECTLR_EL1, x0
372
	isb
373
	ret	x19
374
endfunc cortex_a57_reset_func
375

376
377
378
379
	/* ----------------------------------------------------
	 * The CPU Ops core power down function for Cortex-A57.
	 * ----------------------------------------------------
	 */
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
func cortex_a57_core_pwr_dwn
	mov	x18, x30

	/* ---------------------------------------------
	 * Turn off caches.
	 * ---------------------------------------------
	 */
	bl	cortex_a57_disable_dcache

	/* ---------------------------------------------
	 * Disable the L2 prefetches.
	 * ---------------------------------------------
	 */
	bl	cortex_a57_disable_l2_prefetch

	/* ---------------------------------------------
396
	 * Flush L1 caches.
397
398
399
	 * ---------------------------------------------
	 */
	mov	x0, #DCCISW
400
	bl	dcsw_op_level1
401
402
403
404
405
406
407
408
409
410
411
412
413

	/* ---------------------------------------------
	 * Come out of intra cluster coherency
	 * ---------------------------------------------
	 */
	bl	cortex_a57_disable_smp

	/* ---------------------------------------------
	 * Force the debug interfaces to be quiescent
	 * ---------------------------------------------
	 */
	mov	x30, x18
	b	cortex_a57_disable_ext_debug
414
endfunc cortex_a57_core_pwr_dwn
415

416
417
418
419
	/* -------------------------------------------------------
	 * The CPU Ops cluster power down function for Cortex-A57.
	 * -------------------------------------------------------
	 */
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
func cortex_a57_cluster_pwr_dwn
	mov	x18, x30

	/* ---------------------------------------------
	 * Turn off caches.
	 * ---------------------------------------------
	 */
	bl	cortex_a57_disable_dcache

	/* ---------------------------------------------
	 * Disable the L2 prefetches.
	 * ---------------------------------------------
	 */
	bl	cortex_a57_disable_l2_prefetch

435
#if !SKIP_A57_L1_FLUSH_PWR_DWN
436
437
438
439
440
441
	/* -------------------------------------------------
	 * Flush the L1 caches.
	 * -------------------------------------------------
	 */
	mov	x0, #DCCISW
	bl	dcsw_op_level1
442
#endif
443
444
445
446
447
448
	/* ---------------------------------------------
	 * Disable the optional ACP.
	 * ---------------------------------------------
	 */
	bl	plat_disable_acp

449
450
451
	/* -------------------------------------------------
	 * Flush the L2 caches.
	 * -------------------------------------------------
452
453
	 */
	mov	x0, #DCCISW
454
	bl	dcsw_op_level2
455
456
457
458
459
460
461
462
463
464
465
466
467

	/* ---------------------------------------------
	 * Come out of intra cluster coherency
	 * ---------------------------------------------
	 */
	bl	cortex_a57_disable_smp

	/* ---------------------------------------------
	 * Force the debug interfaces to be quiescent
	 * ---------------------------------------------
	 */
	mov	x30, x18
	b	cortex_a57_disable_ext_debug
468
endfunc cortex_a57_cluster_pwr_dwn
469

470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
#if REPORT_ERRATA
/*
 * Errata printing function for Cortex A57. Must follow AAPCS.
 */
func cortex_a57_errata_report
	stp	x8, x30, [sp, #-16]!

	bl	cpu_get_rev_var
	mov	x8, x0

	/*
	 * Report all errata. The revision-variant information is passed to
	 * checking functions of each errata.
	 */
	report_errata ERRATA_A57_806969, cortex_a57, 806969
	report_errata ERRATA_A57_813420, cortex_a57, 813420
	report_errata A57_DISABLE_NON_TEMPORAL_HINT, cortex_a57, \
		disable_ldnp_overread
	report_errata ERRATA_A57_826974, cortex_a57, 826974
	report_errata ERRATA_A57_826977, cortex_a57, 826977
	report_errata ERRATA_A57_828024, cortex_a57, 828024
	report_errata ERRATA_A57_829520, cortex_a57, 829520
	report_errata ERRATA_A57_833471, cortex_a57, 833471

	ldp	x8, x30, [sp], #16
	ret
endfunc cortex_a57_errata_report
#endif

499
500
501
502
503
504
505
506
507
508
509
	/* ---------------------------------------------
	 * This function provides cortex_a57 specific
	 * register information for crash reporting.
	 * It needs to return with x6 pointing to
	 * a list of register names in ascii and
	 * x8 - x15 having values of registers to be
	 * reported.
	 * ---------------------------------------------
	 */
.section .rodata.cortex_a57_regs, "aS"
cortex_a57_regs:  /* The ascii list of register names to be reported */
510
	.asciz	"cpuectlr_el1", "cpumerrsr_el1", "l2merrsr_el1", ""
511
512
513
514

func cortex_a57_cpu_reg_dump
	adr	x6, cortex_a57_regs
	mrs	x8, CPUECTLR_EL1
515
516
	mrs	x9, CPUMERRSR_EL1
	mrs	x10, L2MERRSR_EL1
517
	ret
518
endfunc cortex_a57_cpu_reg_dump
519
520


521
522
523
524
declare_cpu_ops cortex_a57, CORTEX_A57_MIDR, \
	cortex_a57_reset_func, \
	cortex_a57_core_pwr_dwn, \
	cortex_a57_cluster_pwr_dwn