xref: /rk3399_ARM-atf/lib/cpus/aarch64/rainier.S (revision 015240d9d35c88d4f5c2845e8b8bfceb6d25dd9d)
1/*
2 * Copyright (c) 2020, Arm Limited. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6
7#include <arch.h>
8#include <asm_macros.S>
9#include <context.h>
10#include <cpu_macros.S>
11#include <cpuamu.h>
12#include <rainier.h>
13
14/* Hardware handled coherency */
15#if HW_ASSISTED_COHERENCY == 0
16#error "Rainier CPU must be compiled with HW_ASSISTED_COHERENCY enabled"
17#endif
18
19/* 64-bit only core */
20#if CTX_INCLUDE_AARCH32_REGS == 1
21#error "Rainier CPU supports only AArch64. Compile with CTX_INCLUDE_AARCH32_REGS=0"
22#endif
23
24#if ERRATA_RAINIER_IC_TRAP
25	.global rainier_errata_ic_trap_handler
26#endif
27
28/* --------------------------------------------------
29 * Disable speculative loads if Rainier supports
30 * SSBS.
31 *
32 * Shall clobber: x0.
33 * --------------------------------------------------
34 */
35func rainier_disable_speculative_loads
36	/* Check if the PE implements SSBS */
37	mrs	x0, id_aa64pfr1_el1
38	tst	x0, #(ID_AA64PFR1_EL1_SSBS_MASK << ID_AA64PFR1_EL1_SSBS_SHIFT)
39	b.eq	1f
40
41	/* Disable speculative loads */
42	msr	SSBS, xzr
43
441:
45	ret
46endfunc rainier_disable_speculative_loads
47
48/* --------------------------------------------------
49 * Errata Workaround for Neoverse N1 Erratum 1542419.
50 * This applies to revisions r3p0 - r4p0 of Neoverse N1
51 * Since Rainier core is based on Neoverse N1 r4p0, this
52 * errata applies to Rainier core r0p0
53 * Inputs:
54 * x0: variant[4:7] and revision[0:3] of current cpu.
55 * Shall clobber: x0-x17
56 * --------------------------------------------------
57 */
58func errata_n1_1542419_wa
59	/* Compare x0 against revision r3p0 and r4p0 */
60	mov	x17, x30
61	bl	check_errata_1542419
62	cbz	x0, 1f
63
64        /* Apply instruction patching sequence */
65	mov	x0, xzr
66	msr	CPUPSELR_EL3, x0
67	ldr	x0, =0xEE670D35
68	msr	CPUPOR_EL3, x0
69	ldr	x0, =0xFFFF0FFF
70	msr	CPUPMR_EL3, x0
71	ldr	x0, =0x08000020007D
72	msr	CPUPCR_EL3, x0
73	isb
741:
75	ret	x17
76endfunc errata_n1_1542419_wa
77
78func check_errata_1542419
79	/* Applies to Rainier core r0p0. */
80	mov	x1, #0x00
81	b	cpu_rev_var_ls
82endfunc check_errata_1542419
83
84func rainier_reset_func
85	mov	x19, x30
86
87	bl	rainier_disable_speculative_loads
88
89	/* Forces all cacheable atomic instructions to be near */
90	mrs	x0, RAINIER_CPUACTLR2_EL1
91	orr	x0, x0, #RAINIER_CPUACTLR2_EL1_BIT_2
92	msr	RAINIER_CPUACTLR2_EL1, x0
93	isb
94
95	bl	cpu_get_rev_var
96	mov	x18, x0
97
98#if ERRATA_N1_1542419
99	mov	x0, x18
100	bl	errata_n1_1542419_wa
101#endif
102
103#if ENABLE_AMU
104	/* Make sure accesses from EL0/EL1 and EL2 are not trapped to EL3 */
105	mrs	x0, actlr_el3
106	orr	x0, x0, #RAINIER_ACTLR_AMEN_BIT
107	msr	actlr_el3, x0
108
109	/* Make sure accesses from EL0/EL1 are not trapped to EL2 */
110	mrs	x0, actlr_el2
111	orr	x0, x0, #RAINIER_ACTLR_AMEN_BIT
112	msr	actlr_el2, x0
113
114	/* Enable group0 counters */
115	mov	x0, #RAINIER_AMU_GROUP0_MASK
116	msr	CPUAMCNTENSET_EL0, x0
117#endif
118
119	isb
120	ret	x19
121endfunc rainier_reset_func
122
123	/* ---------------------------------------------
124	 * HW will do the cache maintenance while powering down
125	 * ---------------------------------------------
126	 */
127func rainier_core_pwr_dwn
128	/* ---------------------------------------------
129	 * Enable CPU power down bit in power control register
130	 * ---------------------------------------------
131	 */
132	mrs	x0, RAINIER_CPUPWRCTLR_EL1
133	orr	x0, x0, #RAINIER_CORE_PWRDN_EN_MASK
134	msr	RAINIER_CPUPWRCTLR_EL1, x0
135	isb
136	ret
137endfunc rainier_core_pwr_dwn
138
139#if REPORT_ERRATA
140/*
141 * Errata printing function for Rainier. Must follow AAPCS.
142 */
143func rainier_errata_report
144	stp	x8, x30, [sp, #-16]!
145
146	bl	cpu_get_rev_var
147	mov	x8, x0
148
149	/*
150	 * Report all errata. The revision-variant information is passed to
151	 * checking functions of each errata.
152	 */
153	report_errata ERRATA_N1_1542419, rainier, 1542419
154
155	ldp	x8, x30, [sp], #16
156	ret
157endfunc rainier_errata_report
158#endif
159
160/*
161 * Handle trap of EL0 IC IVAU instructions to EL3 by executing a TLB
162 * inner-shareable invalidation to an arbitrary address followed by a DSB.
163 *
164 * x1: Exception Syndrome
165 */
166func rainier_errata_ic_trap_handler
167	cmp	x1, #RAINIER_EC_IC_TRAP
168	b.ne	1f
169	tlbi	vae3is, xzr
170	dsb	sy
171
172        # Skip the IC instruction itself
173        mrs     x3, elr_el3
174        add     x3, x3, #4
175        msr     elr_el3, x3
176
177	ldp	x0, x1, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X0]
178	ldp	x2, x3, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X2]
179	ldp	x4, x5, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_X4]
180	ldr	x30, [sp, #CTX_GPREGS_OFFSET + CTX_GPREG_LR]
181
182#if IMAGE_BL31 && RAS_EXTENSION
183	/*
184	 * Issue Error Synchronization Barrier to synchronize SErrors before
185	 * exiting EL3. We're running with EAs unmasked, so any synchronized
186	 * errors would be taken immediately; therefore no need to inspect
187	 * DISR_EL1 register.
188	 */
189	esb
190#endif
191	eret
1921:
193	ret
194endfunc rainier_errata_ic_trap_handler
195
196	/* ---------------------------------------------
197	 * This function provides Rainier specific
198	 * register information for crash reporting.
199	 * It needs to return with x6 pointing to
200	 * a list of register names in ascii and
201	 * x8 - x15 having values of registers to be
202	 * reported.
203	 * ---------------------------------------------
204	 */
205.section .rodata.rainier_regs, "aS"
206rainier_regs:  /* The ascii list of register names to be reported */
207	.asciz	"cpuectlr_el1", ""
208
209func rainier_cpu_reg_dump
210	adr	x6, rainier_regs
211	mrs	x8, RAINIER_CPUECTLR_EL1
212	ret
213endfunc rainier_cpu_reg_dump
214
215declare_cpu_ops_eh rainier, RAINIER_MIDR, \
216	rainier_reset_func, \
217	rainier_errata_ic_trap_handler, \
218	rainier_core_pwr_dwn
219