xref: /rk3399_ARM-atf/lib/cpus/aarch64/denver.S (revision 89dba82dfa85fea03e7b2f6ad6a90fcd0aecce55)
13a8c55f6SVarun Wadekar/*
2*89dba82dSBoyan Karatotev * Copyright (c) 2015-2025, Arm Limited and Contributors. All rights reserved.
3b2ed9989SVarun Wadekar * Copyright (c) 2020-2022, NVIDIA Corporation. All rights reserved.
43a8c55f6SVarun Wadekar *
582cb2c1aSdp-arm * SPDX-License-Identifier: BSD-3-Clause
63a8c55f6SVarun Wadekar */
73a8c55f6SVarun Wadekar
83a8c55f6SVarun Wadekar#include <arch.h>
93a8c55f6SVarun Wadekar#include <asm_macros.S>
103a8c55f6SVarun Wadekar#include <assert_macros.S>
11b0301467SVarun Wadekar#include <context.h>
123a8c55f6SVarun Wadekar#include <denver.h>
133a8c55f6SVarun Wadekar#include <cpu_macros.S>
143a8c55f6SVarun Wadekar#include <plat_macros.S>
153a8c55f6SVarun Wadekar
16*89dba82dSBoyan Karatotevcpu_reset_prologue denver
17*89dba82dSBoyan Karatotev
18b0301467SVarun Wadekar	/* -------------------------------------------------
19b0301467SVarun Wadekar	 * CVE-2017-5715 mitigation
20b0301467SVarun Wadekar	 *
21b0301467SVarun Wadekar	 * Flush the indirect branch predictor and RSB on
22b0301467SVarun Wadekar	 * entry to EL3 by issuing a newly added instruction
23b0301467SVarun Wadekar	 * for Denver CPUs.
24b0301467SVarun Wadekar	 *
25b0301467SVarun Wadekar	 * To achieve this without performing any branch
26b0301467SVarun Wadekar	 * instruction, a per-cpu vbar is installed which
27b0301467SVarun Wadekar	 * executes the workaround and then branches off to
28b0301467SVarun Wadekar	 * the corresponding vector entry in the main vector
29b0301467SVarun Wadekar	 * table.
30b0301467SVarun Wadekar	 * -------------------------------------------------
31b0301467SVarun Wadekar	 */
32b0301467SVarun Wadekarvector_base workaround_bpflush_runtime_exceptions
33b0301467SVarun Wadekar
34b0301467SVarun Wadekar	.macro	apply_workaround
35b0301467SVarun Wadekar	stp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
36b0301467SVarun Wadekar
37c5c1af0dSVarun Wadekar	/* Disable cycle counter when event counting is prohibited */
38c5c1af0dSVarun Wadekar	mrs	x1, pmcr_el0
39c5c1af0dSVarun Wadekar	orr	x0, x1, #PMCR_EL0_DP_BIT
40c5c1af0dSVarun Wadekar	msr	pmcr_el0, x0
41c5c1af0dSVarun Wadekar	isb
42c5c1af0dSVarun Wadekar
43b0301467SVarun Wadekar	/* -------------------------------------------------
44b0301467SVarun Wadekar	 * A new write-only system register where a write of
45b0301467SVarun Wadekar	 * 1 to bit 0 will cause the indirect branch predictor
46b0301467SVarun Wadekar	 * and RSB to be flushed.
47b0301467SVarun Wadekar	 *
48b0301467SVarun Wadekar	 * A write of 0 to bit 0 will be ignored. A write of
49b0301467SVarun Wadekar	 * 1 to any other bit will cause an MCA.
50b0301467SVarun Wadekar	 * -------------------------------------------------
51b0301467SVarun Wadekar	 */
52b0301467SVarun Wadekar	mov	x0, #1
53b0301467SVarun Wadekar	msr	s3_0_c15_c0_6, x0
54b0301467SVarun Wadekar	isb
55b0301467SVarun Wadekar
56b0301467SVarun Wadekar	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
57b0301467SVarun Wadekar	.endm
58b0301467SVarun Wadekar
59b0301467SVarun Wadekar	/* ---------------------------------------------------------------------
60b0301467SVarun Wadekar	 * Current EL with SP_EL0 : 0x0 - 0x200
61b0301467SVarun Wadekar	 * ---------------------------------------------------------------------
62b0301467SVarun Wadekar	 */
63b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_sp_el0
64b0301467SVarun Wadekar	b	sync_exception_sp_el0
65a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_sync_exception_sp_el0
66b0301467SVarun Wadekar
67b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_sp_el0
68b0301467SVarun Wadekar	b	irq_sp_el0
69a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_irq_sp_el0
70b0301467SVarun Wadekar
71b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_sp_el0
72b0301467SVarun Wadekar	b	fiq_sp_el0
73a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_fiq_sp_el0
74b0301467SVarun Wadekar
75b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_sp_el0
76b0301467SVarun Wadekar	b	serror_sp_el0
77a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_serror_sp_el0
78b0301467SVarun Wadekar
79b0301467SVarun Wadekar	/* ---------------------------------------------------------------------
80b0301467SVarun Wadekar	 * Current EL with SP_ELx: 0x200 - 0x400
81b0301467SVarun Wadekar	 * ---------------------------------------------------------------------
82b0301467SVarun Wadekar	 */
83b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_sp_elx
84b0301467SVarun Wadekar	b	sync_exception_sp_elx
85a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_sync_exception_sp_elx
86b0301467SVarun Wadekar
87b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_sp_elx
88b0301467SVarun Wadekar	b	irq_sp_elx
89a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_irq_sp_elx
90b0301467SVarun Wadekar
91b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_sp_elx
92b0301467SVarun Wadekar	b	fiq_sp_elx
93a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_fiq_sp_elx
94b0301467SVarun Wadekar
95b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_sp_elx
96b0301467SVarun Wadekar	b	serror_sp_elx
97a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_serror_sp_elx
98b0301467SVarun Wadekar
99b0301467SVarun Wadekar	/* ---------------------------------------------------------------------
100b0301467SVarun Wadekar	 * Lower EL using AArch64 : 0x400 - 0x600
101b0301467SVarun Wadekar	 * ---------------------------------------------------------------------
102b0301467SVarun Wadekar	 */
103b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_aarch64
104b0301467SVarun Wadekar	apply_workaround
105b0301467SVarun Wadekar	b	sync_exception_aarch64
106a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_sync_exception_aarch64
107b0301467SVarun Wadekar
108b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_aarch64
109b0301467SVarun Wadekar	apply_workaround
110b0301467SVarun Wadekar	b	irq_aarch64
111a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_irq_aarch64
112b0301467SVarun Wadekar
113b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_aarch64
114b0301467SVarun Wadekar	apply_workaround
115b0301467SVarun Wadekar	b	fiq_aarch64
116a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_fiq_aarch64
117b0301467SVarun Wadekar
118b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_aarch64
119b0301467SVarun Wadekar	apply_workaround
120b0301467SVarun Wadekar	b	serror_aarch64
121a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_serror_aarch64
122b0301467SVarun Wadekar
123b0301467SVarun Wadekar	/* ---------------------------------------------------------------------
124b0301467SVarun Wadekar	 * Lower EL using AArch32 : 0x600 - 0x800
125b0301467SVarun Wadekar	 * ---------------------------------------------------------------------
126b0301467SVarun Wadekar	 */
127b0301467SVarun Wadekarvector_entry workaround_bpflush_sync_exception_aarch32
128b0301467SVarun Wadekar	apply_workaround
129b0301467SVarun Wadekar	b	sync_exception_aarch32
130a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_sync_exception_aarch32
131b0301467SVarun Wadekar
132b0301467SVarun Wadekarvector_entry workaround_bpflush_irq_aarch32
133b0301467SVarun Wadekar	apply_workaround
134b0301467SVarun Wadekar	b	irq_aarch32
135a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_irq_aarch32
136b0301467SVarun Wadekar
137b0301467SVarun Wadekarvector_entry workaround_bpflush_fiq_aarch32
138b0301467SVarun Wadekar	apply_workaround
139b0301467SVarun Wadekar	b	fiq_aarch32
140a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_fiq_aarch32
141b0301467SVarun Wadekar
142b0301467SVarun Wadekarvector_entry workaround_bpflush_serror_aarch32
143b0301467SVarun Wadekar	apply_workaround
144b0301467SVarun Wadekar	b	serror_aarch32
145a9203edaSRoberto Vargasend_vector_entry workaround_bpflush_serror_aarch32
146b0301467SVarun Wadekar
1479f1c5dd1SVarun Wadekar	.global	denver_disable_dco
1489f1c5dd1SVarun Wadekar
1493a8c55f6SVarun Wadekar	/* ---------------------------------------------
1503a8c55f6SVarun Wadekar	 * Disable debug interfaces
1513a8c55f6SVarun Wadekar	 * ---------------------------------------------
1523a8c55f6SVarun Wadekar	 */
1533a8c55f6SVarun Wadekarfunc denver_disable_ext_debug
1543a8c55f6SVarun Wadekar	mov	x0, #1
1553a8c55f6SVarun Wadekar	msr	osdlr_el1, x0
1563a8c55f6SVarun Wadekar	isb
1573a8c55f6SVarun Wadekar	dsb	sy
1583a8c55f6SVarun Wadekar	ret
1593a8c55f6SVarun Wadekarendfunc denver_disable_ext_debug
1603a8c55f6SVarun Wadekar
1613a8c55f6SVarun Wadekar	/* ----------------------------------------------------
1623a8c55f6SVarun Wadekar	 * Enable dynamic code optimizer (DCO)
1633a8c55f6SVarun Wadekar	 * ----------------------------------------------------
1643a8c55f6SVarun Wadekar	 */
1653a8c55f6SVarun Wadekarfunc denver_enable_dco
1665f902752SVarun Wadekar	/* DCO is not supported on PN5 and later */
1675f902752SVarun Wadekar	mrs	x1, midr_el1
1685f902752SVarun Wadekar	mov_imm	x2, DENVER_MIDR_PN4
1695f902752SVarun Wadekar	cmp	x1, x2
1705f902752SVarun Wadekar	b.hi	1f
1715f902752SVarun Wadekar
172e6c0da15SKalyani Chidambaram	mov	x18, x30
1731593cae4SVarun Wadekar	bl	plat_my_core_pos
1743a8c55f6SVarun Wadekar	mov	x1, #1
1753a8c55f6SVarun Wadekar	lsl	x1, x1, x0
1763a8c55f6SVarun Wadekar	msr	s3_0_c15_c0_2, x1
177e6c0da15SKalyani Chidambaram	mov	x30, x18
1785f902752SVarun Wadekar1:	ret
1793a8c55f6SVarun Wadekarendfunc denver_enable_dco
1803a8c55f6SVarun Wadekar
1813a8c55f6SVarun Wadekar	/* ----------------------------------------------------
1823a8c55f6SVarun Wadekar	 * Disable dynamic code optimizer (DCO)
1833a8c55f6SVarun Wadekar	 * ----------------------------------------------------
1843a8c55f6SVarun Wadekar	 */
1853a8c55f6SVarun Wadekarfunc denver_disable_dco
1865f902752SVarun Wadekar	/* DCO is not supported on PN5 and later */
1875f902752SVarun Wadekar	mrs	x1, midr_el1
1885f902752SVarun Wadekar	mov_imm	x2, DENVER_MIDR_PN4
1895f902752SVarun Wadekar	cmp	x1, x2
1905f902752SVarun Wadekar	b.hi	2f
1911593cae4SVarun Wadekar
1923a8c55f6SVarun Wadekar	/* turn off background work */
1935f902752SVarun Wadekar	mov	x18, x30
1941593cae4SVarun Wadekar	bl	plat_my_core_pos
1953a8c55f6SVarun Wadekar	mov	x1, #1
1963a8c55f6SVarun Wadekar	lsl	x1, x1, x0
1973a8c55f6SVarun Wadekar	lsl	x2, x1, #16
1983a8c55f6SVarun Wadekar	msr	s3_0_c15_c0_2, x2
1993a8c55f6SVarun Wadekar	isb
2003a8c55f6SVarun Wadekar
2013a8c55f6SVarun Wadekar	/* wait till the background work turns off */
2023a8c55f6SVarun Wadekar1:	mrs	x2, s3_0_c15_c0_2
2033a8c55f6SVarun Wadekar	lsr	x2, x2, #32
2043a8c55f6SVarun Wadekar	and	w2, w2, 0xFFFF
2053a8c55f6SVarun Wadekar	and	x2, x2, x1
2063a8c55f6SVarun Wadekar	cbnz	x2, 1b
2073a8c55f6SVarun Wadekar
208e6c0da15SKalyani Chidambaram	mov	x30, x18
2095f902752SVarun Wadekar2:	ret
2103a8c55f6SVarun Wadekarendfunc denver_disable_dco
2113a8c55f6SVarun Wadekar
21215702f28SBoyan Karatotevworkaround_reset_start denver, CVE(2017, 5715), WORKAROUND_CVE_2017_5715
21315702f28SBoyan Karatotev#if IMAGE_BL31
21415702f28SBoyan Karatotev	adr	x1, workaround_bpflush_runtime_exceptions
21515702f28SBoyan Karatotev	msr	vbar_el3, x1
21615702f28SBoyan Karatotev#endif
21715702f28SBoyan Karatotevworkaround_reset_end denver, CVE(2017, 5715)
21815702f28SBoyan Karatotev
21915702f28SBoyan Karatotevcheck_erratum_custom_start denver, CVE(2017, 5715)
22083353962SVarun Wadekar	mov	x0, #ERRATA_MISSING
22183353962SVarun Wadekar#if WORKAROUND_CVE_2017_5715
22283353962SVarun Wadekar	/*
22383353962SVarun Wadekar	 * Check if the CPU supports the special instruction
22483353962SVarun Wadekar	 * required to flush the indirect branch predictor and
22583353962SVarun Wadekar	 * RSB. Support for this operation can be determined by
22683353962SVarun Wadekar	 * comparing bits 19:16 of ID_AFR0_EL1 with 0b0001.
22783353962SVarun Wadekar	 */
22883353962SVarun Wadekar	mrs	x1, id_afr0_el1
22983353962SVarun Wadekar	mov	x2, #0x10000
23083353962SVarun Wadekar	and	x1, x1, x2
23183353962SVarun Wadekar	cbz	x1, 1f
23283353962SVarun Wadekar	mov	x0, #ERRATA_APPLIES
23383353962SVarun Wadekar1:
23483353962SVarun Wadekar#endif
23583353962SVarun Wadekar	ret
23615702f28SBoyan Karatotevcheck_erratum_custom_end denver, CVE(2017, 5715)
23783353962SVarun Wadekar
23815702f28SBoyan Karatotevworkaround_reset_start denver, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
2396cf8d65fSVarun Wadekar	/*
2406cf8d65fSVarun Wadekar	 * Denver CPUs with DENVER_MIDR_PN3 or earlier, use different
2416cf8d65fSVarun Wadekar	 * bits in the ACTLR_EL3 register to disable speculative
2426cf8d65fSVarun Wadekar	 * store buffer and memory disambiguation.
2436cf8d65fSVarun Wadekar	 */
2446cf8d65fSVarun Wadekar	mrs	x0, midr_el1
2456cf8d65fSVarun Wadekar	mov_imm	x1, DENVER_MIDR_PN4
2466cf8d65fSVarun Wadekar	cmp	x0, x1
2476cf8d65fSVarun Wadekar	mrs	x0, actlr_el3
2486cf8d65fSVarun Wadekar	mov	x1, #(DENVER_CPU_DIS_MD_EL3 | DENVER_CPU_DIS_SSB_EL3)
2496cf8d65fSVarun Wadekar	mov	x2, #(DENVER_PN4_CPU_DIS_MD_EL3 | DENVER_PN4_CPU_DIS_SSB_EL3)
2506cf8d65fSVarun Wadekar	csel	x3, x1, x2, ne
2516cf8d65fSVarun Wadekar	orr	x0, x0, x3
2526cf8d65fSVarun Wadekar	msr	actlr_el3, x0
2536cf8d65fSVarun Wadekar	isb
2546cf8d65fSVarun Wadekar	dsb	sy
25515702f28SBoyan Karatotevworkaround_reset_end denver, CVE(2018, 3639)
2566cf8d65fSVarun Wadekar
25715702f28SBoyan Karatotevcheck_erratum_chosen denver, CVE(2018, 3639), WORKAROUND_CVE_2018_3639
25815702f28SBoyan Karatotev
25915702f28SBoyan Karatotevcpu_reset_func_start denver
2603a8c55f6SVarun Wadekar	/* ----------------------------------------------------
261cf3ed0dcSVarun Wadekar	 * Reset ACTLR.PMSTATE to C1 state
262cf3ed0dcSVarun Wadekar	 * ----------------------------------------------------
263cf3ed0dcSVarun Wadekar	 */
264cf3ed0dcSVarun Wadekar	mrs	x0, actlr_el1
265cf3ed0dcSVarun Wadekar	bic	x0, x0, #DENVER_CPU_PMSTATE_MASK
266cf3ed0dcSVarun Wadekar	orr	x0, x0, #DENVER_CPU_PMSTATE_C1
267cf3ed0dcSVarun Wadekar	msr	actlr_el1, x0
268cf3ed0dcSVarun Wadekar
269cf3ed0dcSVarun Wadekar	/* ----------------------------------------------------
2703a8c55f6SVarun Wadekar	 * Enable dynamic code optimizer (DCO)
2713a8c55f6SVarun Wadekar	 * ----------------------------------------------------
2723a8c55f6SVarun Wadekar	 */
2733a8c55f6SVarun Wadekar	bl	denver_enable_dco
27415702f28SBoyan Karatotevcpu_reset_func_end denver
2753a8c55f6SVarun Wadekar
2763a8c55f6SVarun Wadekar	/* ----------------------------------------------------
2773a8c55f6SVarun Wadekar	 * The CPU Ops core power down function for Denver.
2783a8c55f6SVarun Wadekar	 * ----------------------------------------------------
2793a8c55f6SVarun Wadekar	 */
2803a8c55f6SVarun Wadekarfunc denver_core_pwr_dwn
2813a8c55f6SVarun Wadekar
2823a8c55f6SVarun Wadekar	mov	x19, x30
2833a8c55f6SVarun Wadekar
2843a8c55f6SVarun Wadekar	/* ---------------------------------------------
2853a8c55f6SVarun Wadekar	 * Force the debug interfaces to be quiescent
2863a8c55f6SVarun Wadekar	 * ---------------------------------------------
2873a8c55f6SVarun Wadekar	 */
2883a8c55f6SVarun Wadekar	bl	denver_disable_ext_debug
2893a8c55f6SVarun Wadekar
2903a8c55f6SVarun Wadekar	ret	x19
2913a8c55f6SVarun Wadekarendfunc denver_core_pwr_dwn
2923a8c55f6SVarun Wadekar
2933a8c55f6SVarun Wadekar	/* -------------------------------------------------------
2943a8c55f6SVarun Wadekar	 * The CPU Ops cluster power down function for Denver.
2953a8c55f6SVarun Wadekar	 * -------------------------------------------------------
2963a8c55f6SVarun Wadekar	 */
2973a8c55f6SVarun Wadekarfunc denver_cluster_pwr_dwn
2983a8c55f6SVarun Wadekar	ret
2993a8c55f6SVarun Wadekarendfunc denver_cluster_pwr_dwn
3003a8c55f6SVarun Wadekar
3013a8c55f6SVarun Wadekar	/* ---------------------------------------------
3023a8c55f6SVarun Wadekar	 * This function provides Denver specific
3033a8c55f6SVarun Wadekar	 * register information for crash reporting.
3043a8c55f6SVarun Wadekar	 * It needs to return with x6 pointing to
3053a8c55f6SVarun Wadekar	 * a list of register names in ascii and
3063a8c55f6SVarun Wadekar	 * x8 - x15 having values of registers to be
3073a8c55f6SVarun Wadekar	 * reported.
3083a8c55f6SVarun Wadekar	 * ---------------------------------------------
3093a8c55f6SVarun Wadekar	 */
3103a8c55f6SVarun Wadekar.section .rodata.denver_regs, "aS"
3113a8c55f6SVarun Wadekardenver_regs:  /* The ascii list of register names to be reported */
3123a8c55f6SVarun Wadekar	.asciz	"actlr_el1", ""
3133a8c55f6SVarun Wadekar
3143a8c55f6SVarun Wadekarfunc denver_cpu_reg_dump
3153a8c55f6SVarun Wadekar	adr	x6, denver_regs
3163a8c55f6SVarun Wadekar	mrs	x8, ACTLR_EL1
3173a8c55f6SVarun Wadekar	ret
3183a8c55f6SVarun Wadekarendfunc denver_cpu_reg_dump
3193a8c55f6SVarun Wadekar
3209b624a7dSVarun Wadekar/* macro to declare cpu_ops for Denver SKUs */
3219b624a7dSVarun Wadekar.macro	denver_cpu_ops_wa midr
3229b624a7dSVarun Wadekar	declare_cpu_ops_wa denver, \midr, \
323e956e228SVarun Wadekar		denver_reset_func, \
32415702f28SBoyan Karatotev		check_erratum_denver_5715, \
32583353962SVarun Wadekar		CPU_NO_EXTRA2_FUNC, \
326b2ed9989SVarun Wadekar		CPU_NO_EXTRA3_FUNC, \
327e956e228SVarun Wadekar		denver_core_pwr_dwn, \
328e956e228SVarun Wadekar		denver_cluster_pwr_dwn
3299b624a7dSVarun Wadekar.endm
330e956e228SVarun Wadekar
3319b624a7dSVarun Wadekardenver_cpu_ops_wa DENVER_MIDR_PN0
3329b624a7dSVarun Wadekardenver_cpu_ops_wa DENVER_MIDR_PN1
3339b624a7dSVarun Wadekardenver_cpu_ops_wa DENVER_MIDR_PN2
3349b624a7dSVarun Wadekardenver_cpu_ops_wa DENVER_MIDR_PN3
3359b624a7dSVarun Wadekardenver_cpu_ops_wa DENVER_MIDR_PN4
3369b624a7dSVarun Wadekardenver_cpu_ops_wa DENVER_MIDR_PN5
3379b624a7dSVarun Wadekardenver_cpu_ops_wa DENVER_MIDR_PN6
3389b624a7dSVarun Wadekardenver_cpu_ops_wa DENVER_MIDR_PN7
3399b624a7dSVarun Wadekardenver_cpu_ops_wa DENVER_MIDR_PN8
340c6d25c00SHemant Nigamdenver_cpu_ops_wa DENVER_MIDR_PN9
341