xref: /rk3399_ARM-atf/plat/nvidia/tegra/common/aarch64/tegra_helpers.S (revision 08438e24e10504642634da9ee3dde794ac6fa8f0)
1/*
2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30#include <arch.h>
31#include <asm_macros.S>
32#include <assert_macros.S>
33#include <cpu_macros.S>
34#include <cortex_a57.h>
35#include <cortex_a53.h>
36#include <tegra_def.h>
37
38	/* Global functions */
39	.globl	platform_is_primary_cpu
40	.globl	platform_get_core_pos
41	.globl	platform_get_entrypoint
42	.globl	plat_secondary_cold_boot_setup
43	.globl	platform_mem_init
44	.globl	plat_crash_console_init
45	.globl	plat_crash_console_putc
46	.globl	tegra_secure_entrypoint
47	.globl	plat_reset_handler
48
49	/* Global variables */
50	.globl	sec_entry_point
51	.globl	ns_image_entrypoint
52	.globl	tegra_bl31_phys_base
53
54	/* ---------------------
55	 * Common CPU init code
56	 * ---------------------
57	 */
58.macro	cpu_init_common
59
60	/* -------------------------------------------------------
61	 * Enable L2 and CPU ECTLR RW access from non-secure world
62	 * -------------------------------------------------------
63	*/
64	mov	x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
65	msr	actlr_el3, x0
66	msr	actlr_el2, x0
67	isb
68
69	/* --------------------------------
70	 * Enable the cycle count register
71	 * --------------------------------
72	 */
73	mrs	x0, pmcr_el0
74	ubfx	x0, x0, #11, #5		// read PMCR.N field
75	mov	x1, #1
76	lsl	x0, x1, x0
77	sub	x0, x0, #1		// mask of event counters
78	orr	x0, x0, #0x80000000	// disable overflow intrs
79	msr	pmintenclr_el1, x0
80	msr	pmuserenr_el0, x1	// enable user mode access
81
82	/* ----------------------------------------------------------------
83	 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count
84	 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ
85	 * registers from EL0.
86	 * ----------------------------------------------------------------
87	 */
88	mrs	x0, cntkctl_el1
89	orr	x0, x0, #EL0VCTEN_BIT
90	msr	cntkctl_el1, x0
91.endm
92
93	/* -----------------------------------------------------
94	 * int platform_is_primary_cpu(int mpidr);
95	 *
96	 * This function checks if this is the Primary CPU
97	 * -----------------------------------------------------
98	 */
99func platform_is_primary_cpu
100	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
101	cmp	x0, #TEGRA_PRIMARY_CPU
102	cset	x0, eq
103	ret
104endfunc platform_is_primary_cpu
105
106	/* -----------------------------------------------------
107	 * int platform_get_core_pos(int mpidr);
108	 *
109	 * With this function: CorePos = CoreId
110	 * -----------------------------------------------------
111	 */
112func platform_get_core_pos
113	and	x0, x0, #MPIDR_CPU_MASK
114	ret
115endfunc platform_get_core_pos
116
117	/* -----------------------------------------------------
118	 * void plat_secondary_cold_boot_setup (void);
119	 *
120	 * This function performs any platform specific actions
121	 * needed for a secondary cpu after a cold reset. Right
122	 * now this is a stub function.
123	 * -----------------------------------------------------
124	 */
125func plat_secondary_cold_boot_setup
126	mov	x0, #0
127	ret
128endfunc plat_secondary_cold_boot_setup
129
130	/* -----------------------------------------------------
131	 * void platform_get_entrypoint (unsigned int mpidr);
132	 *
133	 * Main job of this routine is to distinguish between
134	 * a cold and warm boot. If the sec_entry_point for
135	 * this CPU is present, then it's a warm boot.
136	 *
137	 * -----------------------------------------------------
138	 */
139func platform_get_entrypoint
140	and	x0, x0, #MPIDR_CPU_MASK
141	adr	x1, sec_entry_point
142	ldr	x0, [x1, x0, lsl #3]
143	ret
144endfunc platform_get_entrypoint
145
146	/* --------------------------------------------------------
147	 * void platform_mem_init (void);
148	 *
149	 * Any memory init, relocation to be done before the
150	 * platform boots. Called very early in the boot process.
151	 * --------------------------------------------------------
152	 */
153func platform_mem_init
154	mov	x0, #0
155	ret
156endfunc platform_mem_init
157
158	/* ---------------------------------------------
159	 * int plat_crash_console_init(void)
160	 * Function to initialize the crash console
161	 * without a C Runtime to print crash report.
162	 * Clobber list : x0, x1, x2
163	 * ---------------------------------------------
164	 */
165func plat_crash_console_init
166	mov_imm	x0, TEGRA_BOOT_UART_BASE
167	mov_imm	x1, TEGRA_BOOT_UART_CLK_IN_HZ
168	mov_imm	x2, TEGRA_CONSOLE_BAUDRATE
169	b	console_core_init
170endfunc plat_crash_console_init
171
172	/* ---------------------------------------------
173	 * int plat_crash_console_putc(void)
174	 * Function to print a character on the crash
175	 * console without a C Runtime.
176	 * Clobber list : x1, x2
177	 * ---------------------------------------------
178	 */
179func plat_crash_console_putc
180	mov_imm	x1, TEGRA_BOOT_UART_BASE
181	b	console_core_putc
182endfunc plat_crash_console_putc
183
184	/* ---------------------------------------------------
185	 * Function to handle a platform reset and store
186	 * input parameters passed by BL2.
187	 * ---------------------------------------------------
188	 */
189func plat_reset_handler
190
191	/* -----------------------------------
192	 * derive and save the phys_base addr
193	 * -----------------------------------
194	 */
195	adr	x17, tegra_bl31_phys_base
196	ldr	x18, [x17]
197	cbnz	x18, 1f
198	adr	x18, bl31_entrypoint
199	str	x18, [x17]
200
2011:	cpu_init_common
202
203	ret
204endfunc plat_reset_handler
205
206	/* ----------------------------------------
207	 * Secure entrypoint function for CPU boot
208	 * ----------------------------------------
209	 */
210	.align 6
211func tegra_secure_entrypoint
212
213#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
214
215	/* -------------------------------------------------------
216	 * Invalidate BTB along with I$ to remove any stale
217	 * entries from the branch predictor array.
218	 * -------------------------------------------------------
219	 */
220	mrs	x0, CPUACTLR_EL1
221	orr	x0, x0, #1
222	msr	CPUACTLR_EL1, x0	/* invalidate BTB and I$ together */
223	dsb	sy
224	isb
225	ic	iallu			/* actual invalidate */
226	dsb	sy
227	isb
228
229	mrs	x0, CPUACTLR_EL1
230	bic	x0, x0, #1
231	msr	CPUACTLR_EL1, X0	/* restore original CPUACTLR_EL1 */
232	dsb	sy
233	isb
234
235	.rept	7
236	nop				/* wait */
237	.endr
238
239	/* -----------------------------------------------
240	 * Extract OSLK bit and check if it is '1'. This
241	 * bit remains '0' for A53 on warm-resets. If '1',
242	 * turn off regional clock gating and request warm
243	 * reset.
244	 * -----------------------------------------------
245	 */
246	mrs	x0, oslsr_el1
247	and	x0, x0, #2
248	mrs	x1, mpidr_el1
249	bics	xzr, x0, x1, lsr #7	/* 0 = slow cluster or warm reset */
250	b.eq	restore_oslock
251	mov	x0, xzr
252	msr	oslar_el1, x0		/* os lock stays 0 across warm reset */
253	mov	x3, #3
254	movz	x4, #0x8000, lsl #48
255	msr	CPUACTLR_EL1, x4	/* turn off RCG */
256	isb
257	msr	rmr_el3, x3		/* request warm reset */
258	isb
259	dsb	sy
2601:	wfi
261	b	1b
262
263	/* --------------------------------------------------
264	 * These nops are here so that speculative execution
265	 * won't harm us before we are done with warm reset.
266	 * --------------------------------------------------
267	 */
268	.rept	65
269	nop
270	.endr
271
272	/* --------------------------------------------------
273	 * Do not insert instructions here
274	 * --------------------------------------------------
275	 */
276#endif
277
278	/* --------------------------------------------------
279	 * Restore OS Lock bit
280	 * --------------------------------------------------
281	 */
282restore_oslock:
283	mov	x0, #1
284	msr	oslar_el1, x0
285
286	cpu_init_common
287
288	/* ---------------------------------------------------------------------
289	 * The initial state of the Architectural feature trap register
290	 * (CPTR_EL3) is unknown and it must be set to a known state. All
291	 * feature traps are disabled. Some bits in this register are marked as
292	 * Reserved and should not be modified.
293	 *
294	 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
295	 *  or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
296	 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
297	 *  to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
298	 *  access to trace functionality is not supported, this bit is RES0.
299	 * CPTR_EL3.TFP: This causes instructions that access the registers
300	 *  associated with Floating Point and Advanced SIMD execution to trap
301	 *  to EL3 when executed from any exception level, unless trapped to EL1
302	 *  or EL2.
303	 * ---------------------------------------------------------------------
304	 */
305	mrs	x1, cptr_el3
306	bic	w1, w1, #TCPAC_BIT
307	bic	w1, w1, #TTA_BIT
308	bic	w1, w1, #TFP_BIT
309	msr	cptr_el3, x1
310
311	/* --------------------------------------------------
312	 * Get secure world's entry point and jump to it
313	 * --------------------------------------------------
314	 */
315	mrs	x0, mpidr_el1
316	bl	platform_get_entrypoint
317	br	x0
318endfunc tegra_secure_entrypoint
319
320	.data
321	.align 3
322
323	/* --------------------------------------------------
324	 * Per-CPU Secure entry point - resume from suspend
325	 * --------------------------------------------------
326	 */
327sec_entry_point:
328	.rept	PLATFORM_CORE_COUNT
329	.quad	0
330	.endr
331
332	/* --------------------------------------------------
333	 * NS world's cold boot entry point
334	 * --------------------------------------------------
335	 */
336ns_image_entrypoint:
337	.quad	0
338
339	/* --------------------------------------------------
340	 * BL31's physical base address
341	 * --------------------------------------------------
342	 */
343tegra_bl31_phys_base:
344	.quad	0
345