xref: /rk3399_ARM-atf/lib/cpus/aarch64/denver.S (revision b0301467bc25151e4c2180b1e1e5dee3bdad963e)
13a8c55f6SVarun Wadekar/*
2*b0301467SVarun Wadekar * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
33a8c55f6SVarun Wadekar *
482cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
53a8c55f6SVarun Wadekar */
63a8c55f6SVarun Wadekar
73a8c55f6SVarun Wadekar#include <arch.h>
83a8c55f6SVarun Wadekar#include <asm_macros.S>
93a8c55f6SVarun Wadekar#include <assert_macros.S>
10*b0301467SVarun Wadekar#include <context.h>
113a8c55f6SVarun Wadekar#include <denver.h>
123a8c55f6SVarun Wadekar#include <cpu_macros.S>
133a8c55f6SVarun Wadekar#include <plat_macros.S>
143a8c55f6SVarun Wadekar
15*b0301467SVarun Wadekar	/* -------------------------------------------------
16*b0301467SVarun Wadekar	 * CVE-2017-5715 mitigation
17*b0301467SVarun Wadekar	 *
18*b0301467SVarun Wadekar	 * Flush the indirect branch predictor and RSB on
19*b0301467SVarun Wadekar	 * entry to EL3 by issuing a newly added instruction
20*b0301467SVarun Wadekar	 * for Denver CPUs.
21*b0301467SVarun Wadekar	 *
22*b0301467SVarun Wadekar	 * To achieve this without performing any branch
23*b0301467SVarun Wadekar	 * instruction, a per-cpu vbar is installed which
24*b0301467SVarun Wadekar	 * executes the workaround and then branches off to
25*b0301467SVarun Wadekar	 * the corresponding vector entry in the main vector
26*b0301467SVarun Wadekar	 * table.
27*b0301467SVarun Wadekar	 * -------------------------------------------------
28*b0301467SVarun Wadekar	 */
29*b0301467SVarun Wadekar	.globl	workaround_bpflush_runtime_exceptions
30*b0301467SVarun Wadekar
31*b0301467SVarun Wadekarvector_base workaround_bpflush_runtime_exceptions
32*b0301467SVarun Wadekar
33*b0301467SVarun Wadekar	.macro	apply_workaround
34*b0301467SVarun Wadekar	stp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
35*b0301467SVarun Wadekar
36*b0301467SVarun Wadekar	/* -------------------------------------------------
37*b0301467SVarun Wadekar	 * A new write-only system register where a write of
38*b0301467SVarun Wadekar	 * 1 to bit 0 will cause the indirect branch predictor
39*b0301467SVarun Wadekar	 * and RSB to be flushed.
40*b0301467SVarun Wadekar	 *
41*b0301467SVarun Wadekar	 * A write of 0 to bit 0 will be ignored. A write of
42*b0301467SVarun Wadekar	 * 1 to any other bit will cause an MCA.
43*b0301467SVarun Wadekar	 * -------------------------------------------------
44*b0301467SVarun Wadekar	 */
45*b0301467SVarun Wadekar	mov	x0, #1
46*b0301467SVarun Wadekar	msr	s3_0_c15_c0_6, x0
47*b0301467SVarun Wadekar	isb
48*b0301467SVarun Wadekar
49*b0301467SVarun Wadekar	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
50*b0301467SVarun Wadekar	.endm
51*b0301467SVarun Wadekar
52*b0301467SVarun Wadekar	/* ---------------------------------------------------------------------
53*b0301467SVarun Wadekar	 * Current EL with SP_EL0 : 0x0 - 0x200
54*b0301467SVarun Wadekar	 * ---------------------------------------------------------------------
55*b0301467SVarun Wadekar	 */
56*b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_sp_el0
57*b0301467SVarun Wadekar	b	sync_exception_sp_el0
58*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_sync_exception_sp_el0
59*b0301467SVarun Wadekar
60*b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_sp_el0
61*b0301467SVarun Wadekar	b	irq_sp_el0
62*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_irq_sp_el0
63*b0301467SVarun Wadekar
64*b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_sp_el0
65*b0301467SVarun Wadekar	b	fiq_sp_el0
66*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_fiq_sp_el0
67*b0301467SVarun Wadekar
68*b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_sp_el0
69*b0301467SVarun Wadekar	b	serror_sp_el0
70*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_serror_sp_el0
71*b0301467SVarun Wadekar
72*b0301467SVarun Wadekar	/* ---------------------------------------------------------------------
73*b0301467SVarun Wadekar	 * Current EL with SP_ELx: 0x200 - 0x400
74*b0301467SVarun Wadekar	 * ---------------------------------------------------------------------
75*b0301467SVarun Wadekar	 */
76*b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_sp_elx
77*b0301467SVarun Wadekar	b	sync_exception_sp_elx
78*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_sync_exception_sp_elx
79*b0301467SVarun Wadekar
80*b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_sp_elx
81*b0301467SVarun Wadekar	b	irq_sp_elx
82*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_irq_sp_elx
83*b0301467SVarun Wadekar
84*b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_sp_elx
85*b0301467SVarun Wadekar	b	fiq_sp_elx
86*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_fiq_sp_elx
87*b0301467SVarun Wadekar
88*b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_sp_elx
89*b0301467SVarun Wadekar	b	serror_sp_elx
90*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_serror_sp_elx
91*b0301467SVarun Wadekar
92*b0301467SVarun Wadekar	/* ---------------------------------------------------------------------
93*b0301467SVarun Wadekar	 * Lower EL using AArch64 : 0x400 - 0x600
94*b0301467SVarun Wadekar	 * ---------------------------------------------------------------------
95*b0301467SVarun Wadekar	 */
96*b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_aarch64
97*b0301467SVarun Wadekar	apply_workaround
98*b0301467SVarun Wadekar	b	sync_exception_aarch64
99*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_sync_exception_aarch64
100*b0301467SVarun Wadekar
101*b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_aarch64
102*b0301467SVarun Wadekar	apply_workaround
103*b0301467SVarun Wadekar	b	irq_aarch64
104*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_irq_aarch64
105*b0301467SVarun Wadekar
106*b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_aarch64
107*b0301467SVarun Wadekar	apply_workaround
108*b0301467SVarun Wadekar	b	fiq_aarch64
109*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_fiq_aarch64
110*b0301467SVarun Wadekar
111*b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_aarch64
112*b0301467SVarun Wadekar	apply_workaround
113*b0301467SVarun Wadekar	b	serror_aarch64
114*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_serror_aarch64
115*b0301467SVarun Wadekar
116*b0301467SVarun Wadekar	/* ---------------------------------------------------------------------
117*b0301467SVarun Wadekar	 * Lower EL using AArch32 : 0x600 - 0x800
118*b0301467SVarun Wadekar	 * ---------------------------------------------------------------------
119*b0301467SVarun Wadekar	 */
120*b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_aarch32
121*b0301467SVarun Wadekar	apply_workaround
122*b0301467SVarun Wadekar	b	sync_exception_aarch32
123*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_sync_exception_aarch32
124*b0301467SVarun Wadekar
125*b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_aarch32
126*b0301467SVarun Wadekar	apply_workaround
127*b0301467SVarun Wadekar	b	irq_aarch32
128*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_irq_aarch32
129*b0301467SVarun Wadekar
130*b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_aarch32
131*b0301467SVarun Wadekar	apply_workaround
132*b0301467SVarun Wadekar	b	fiq_aarch32
133*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_fiq_aarch32
134*b0301467SVarun Wadekar
135*b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_aarch32
136*b0301467SVarun Wadekar	apply_workaround
137*b0301467SVarun Wadekar	b	serror_aarch32
138*b0301467SVarun Wadekar	check_vector_size workaround_bpflush_serror_aarch32
139*b0301467SVarun Wadekar
1409f1c5dd1SVarun Wadekar	.global	denver_disable_dco
1419f1c5dd1SVarun Wadekar
1423a8c55f6SVarun Wadekar	/* ---------------------------------------------
1433a8c55f6SVarun Wadekar	 * Disable debug interfaces
1443a8c55f6SVarun Wadekar	 * ---------------------------------------------
1453a8c55f6SVarun Wadekar	 */
1463a8c55f6SVarun Wadekarfunc denver_disable_ext_debug
1473a8c55f6SVarun Wadekar	mov	x0, #1
1483a8c55f6SVarun Wadekar	msr	osdlr_el1, x0
1493a8c55f6SVarun Wadekar	isb
1503a8c55f6SVarun Wadekar	dsb	sy
1513a8c55f6SVarun Wadekar	ret
1523a8c55f6SVarun Wadekarendfunc denver_disable_ext_debug
1533a8c55f6SVarun Wadekar
1543a8c55f6SVarun Wadekar	/* ----------------------------------------------------
1553a8c55f6SVarun Wadekar	 * Enable dynamic code optimizer (DCO)
1563a8c55f6SVarun Wadekar	 * ----------------------------------------------------
1573a8c55f6SVarun Wadekar	 */
1583a8c55f6SVarun Wadekarfunc denver_enable_dco
1593a8c55f6SVarun Wadekar	mrs	x0, mpidr_el1
1603a8c55f6SVarun Wadekar	and	x0, x0, #0xF
1613a8c55f6SVarun Wadekar	mov	x1, #1
1623a8c55f6SVarun Wadekar	lsl	x1, x1, x0
1633a8c55f6SVarun Wadekar	msr	s3_0_c15_c0_2, x1
1643a8c55f6SVarun Wadekar	ret
1653a8c55f6SVarun Wadekarendfunc denver_enable_dco
1663a8c55f6SVarun Wadekar
1673a8c55f6SVarun Wadekar	/* ----------------------------------------------------
1683a8c55f6SVarun Wadekar	 * Disable dynamic code optimizer (DCO)
1693a8c55f6SVarun Wadekar	 * ----------------------------------------------------
1703a8c55f6SVarun Wadekar	 */
1713a8c55f6SVarun Wadekarfunc denver_disable_dco
1723a8c55f6SVarun Wadekar
1733a8c55f6SVarun Wadekar	/* turn off background work */
1743a8c55f6SVarun Wadekar	mrs	x0, mpidr_el1
1753a8c55f6SVarun Wadekar	and	x0, x0, #0xF
1763a8c55f6SVarun Wadekar	mov	x1, #1
1773a8c55f6SVarun Wadekar	lsl	x1, x1, x0
1783a8c55f6SVarun Wadekar	lsl	x2, x1, #16
1793a8c55f6SVarun Wadekar	msr	s3_0_c15_c0_2, x2
1803a8c55f6SVarun Wadekar	isb
1813a8c55f6SVarun Wadekar
1823a8c55f6SVarun Wadekar	/* wait till the background work turns off */
1833a8c55f6SVarun Wadekar1:	mrs	x2, s3_0_c15_c0_2
1843a8c55f6SVarun Wadekar	lsr	x2, x2, #32
1853a8c55f6SVarun Wadekar	and	w2, w2, 0xFFFF
1863a8c55f6SVarun Wadekar	and	x2, x2, x1
1873a8c55f6SVarun Wadekar	cbnz	x2, 1b
1883a8c55f6SVarun Wadekar
1893a8c55f6SVarun Wadekar	ret
1903a8c55f6SVarun Wadekarendfunc denver_disable_dco
1913a8c55f6SVarun Wadekar
1923a8c55f6SVarun Wadekar	/* -------------------------------------------------
1933a8c55f6SVarun Wadekar	 * The CPU Ops reset function for Denver.
1943a8c55f6SVarun Wadekar	 * -------------------------------------------------
1953a8c55f6SVarun Wadekar	 */
1963a8c55f6SVarun Wadekarfunc denver_reset_func
1973a8c55f6SVarun Wadekar
1983a8c55f6SVarun Wadekar	mov	x19, x30
1993a8c55f6SVarun Wadekar
200*b0301467SVarun Wadekar#if IMAGE_BL31 && WORKAROUND_CVE_2017_5715
201*b0301467SVarun Wadekar	/*
202*b0301467SVarun Wadekar	 * Check if the CPU supports the special instruction
203*b0301467SVarun Wadekar	 * required to flush the indirect branch predictor and
204*b0301467SVarun Wadekar	 * RSB. Support for this operation can be determined by
205*b0301467SVarun Wadekar	 * comparing bits 19:16 of ID_AFR0_EL1 with 0b0001.
206*b0301467SVarun Wadekar	 */
207*b0301467SVarun Wadekar	mrs	x0, id_afr0_el1
208*b0301467SVarun Wadekar	mov	x1, #0x10000
209*b0301467SVarun Wadekar	and	x0, x0, x1
210*b0301467SVarun Wadekar	cmp	x0, #0
211*b0301467SVarun Wadekar	adr	x1, workaround_bpflush_runtime_exceptions
212*b0301467SVarun Wadekar	mrs	x2, vbar_el3
213*b0301467SVarun Wadekar	csel	x0, x1, x2, ne
214*b0301467SVarun Wadekar	msr	vbar_el3, x0
215*b0301467SVarun Wadekar#endif
216*b0301467SVarun Wadekar
2173a8c55f6SVarun Wadekar	/* ----------------------------------------------------
2183a8c55f6SVarun Wadekar	 * Enable dynamic code optimizer (DCO)
2193a8c55f6SVarun Wadekar	 * ----------------------------------------------------
2203a8c55f6SVarun Wadekar	 */
2213a8c55f6SVarun Wadekar	bl	denver_enable_dco
2223a8c55f6SVarun Wadekar
2233a8c55f6SVarun Wadekar	ret	x19
2243a8c55f6SVarun Wadekarendfunc denver_reset_func
2253a8c55f6SVarun Wadekar
2263a8c55f6SVarun Wadekar	/* ----------------------------------------------------
2273a8c55f6SVarun Wadekar	 * The CPU Ops core power down function for Denver.
2283a8c55f6SVarun Wadekar	 * ----------------------------------------------------
2293a8c55f6SVarun Wadekar	 */
2303a8c55f6SVarun Wadekarfunc denver_core_pwr_dwn
2313a8c55f6SVarun Wadekar
2323a8c55f6SVarun Wadekar	mov	x19, x30
2333a8c55f6SVarun Wadekar
2343a8c55f6SVarun Wadekar	/* ---------------------------------------------
2353a8c55f6SVarun Wadekar	 * Force the debug interfaces to be quiescent
2363a8c55f6SVarun Wadekar	 * ---------------------------------------------
2373a8c55f6SVarun Wadekar	 */
2383a8c55f6SVarun Wadekar	bl	denver_disable_ext_debug
2393a8c55f6SVarun Wadekar
2403a8c55f6SVarun Wadekar	ret	x19
2413a8c55f6SVarun Wadekarendfunc denver_core_pwr_dwn
2423a8c55f6SVarun Wadekar
2433a8c55f6SVarun Wadekar	/* -------------------------------------------------------
2443a8c55f6SVarun Wadekar	 * The CPU Ops cluster power down function for Denver.
2453a8c55f6SVarun Wadekar	 * -------------------------------------------------------
2463a8c55f6SVarun Wadekar	 */
2473a8c55f6SVarun Wadekarfunc denver_cluster_pwr_dwn
2483a8c55f6SVarun Wadekar	ret
2493a8c55f6SVarun Wadekarendfunc denver_cluster_pwr_dwn
2503a8c55f6SVarun Wadekar
2513a8c55f6SVarun Wadekar	/* ---------------------------------------------
2523a8c55f6SVarun Wadekar	 * This function provides Denver specific
2533a8c55f6SVarun Wadekar	 * register information for crash reporting.
2543a8c55f6SVarun Wadekar	 * It needs to return with x6 pointing to
2553a8c55f6SVarun Wadekar	 * a list of register names in ascii and
2563a8c55f6SVarun Wadekar	 * x8 - x15 having values of registers to be
2573a8c55f6SVarun Wadekar	 * reported.
2583a8c55f6SVarun Wadekar	 * ---------------------------------------------
2593a8c55f6SVarun Wadekar	 */
2603a8c55f6SVarun Wadekar.section .rodata.denver_regs, "aS"
2613a8c55f6SVarun Wadekardenver_regs:  /* The ascii list of register names to be reported */
2623a8c55f6SVarun Wadekar	.asciz	"actlr_el1", ""
2633a8c55f6SVarun Wadekar
2643a8c55f6SVarun Wadekarfunc denver_cpu_reg_dump
2653a8c55f6SVarun Wadekar	adr	x6, denver_regs
2663a8c55f6SVarun Wadekar	mrs	x8, ACTLR_EL1
2673a8c55f6SVarun Wadekar	ret
2683a8c55f6SVarun Wadekarendfunc denver_cpu_reg_dump
2693a8c55f6SVarun Wadekar
270e956e228SVarun Wadekardeclare_cpu_ops denver, DENVER_MIDR_PN0, \
271e956e228SVarun Wadekar	denver_reset_func, \
272e956e228SVarun Wadekar	denver_core_pwr_dwn, \
273e956e228SVarun Wadekar	denver_cluster_pwr_dwn
274e956e228SVarun Wadekar
275e956e228SVarun Wadekardeclare_cpu_ops denver, DENVER_MIDR_PN1, \
276e956e228SVarun Wadekar	denver_reset_func, \
277e956e228SVarun Wadekar	denver_core_pwr_dwn, \
278e956e228SVarun Wadekar	denver_cluster_pwr_dwn
279e956e228SVarun Wadekar
280e956e228SVarun Wadekardeclare_cpu_ops denver, DENVER_MIDR_PN2, \
281e956e228SVarun Wadekar	denver_reset_func, \
282e956e228SVarun Wadekar	denver_core_pwr_dwn, \
283e956e228SVarun Wadekar	denver_cluster_pwr_dwn
284e956e228SVarun Wadekar
285e956e228SVarun Wadekardeclare_cpu_ops denver, DENVER_MIDR_PN3, \
286e956e228SVarun Wadekar	denver_reset_func, \
287e956e228SVarun Wadekar	denver_core_pwr_dwn, \
288e956e228SVarun Wadekar	denver_cluster_pwr_dwn
289e956e228SVarun Wadekar
290e956e228SVarun Wadekardeclare_cpu_ops denver, DENVER_MIDR_PN4, \
2915dd9dbb5SJeenu Viswambharan	denver_reset_func, \
2925dd9dbb5SJeenu Viswambharan	denver_core_pwr_dwn, \
2935dd9dbb5SJeenu Viswambharan	denver_cluster_pwr_dwn
294