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