xref: /rk3399_ARM-atf/plat/nvidia/tegra/common/aarch64/tegra_helpers.S (revision 532ed6183868036e4a4f83cd7a71b93266a3bdb7)
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	plat_is_my_cpu_primary
40	.globl	plat_my_core_pos
41	.globl	plat_get_my_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	tegra_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#if ENABLE_L2_DYNAMIC_RETENTION
61	/* ---------------------------
62	 * Enable processor retention
63	 * ---------------------------
64	*/
65	mrs	x0, L2ECTLR_EL1
66	mov	x1, #RETENTION_ENTRY_TICKS_512 << L2ECTLR_RET_CTRL_SHIFT
67	bic	x0, x0, #L2ECTLR_RET_CTRL_MASK
68	orr	x0, x0, x1
69	msr	L2ECTLR_EL1, x0
70	isb
71#endif
72
73#if ENABLE_CPU_DYNAMIC_RETENTION
74	mrs	x0, CPUECTLR_EL1
75	mov	x1, #RETENTION_ENTRY_TICKS_512 << CPUECTLR_CPU_RET_CTRL_SHIFT
76	bic	x0, x0, #CPUECTLR_CPU_RET_CTRL_MASK
77	orr	x0, x0, x1
78	msr	CPUECTLR_EL1, x0
79	isb
80#endif
81
82#if ENABLE_NS_L2_CPUECTRL_RW_ACCESS
83	/* -------------------------------------------------------
84	 * Enable L2 and CPU ECTLR RW access from non-secure world
85	 * -------------------------------------------------------
86	*/
87	mov	x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
88	msr	actlr_el3, x0
89	msr	actlr_el2, x0
90	isb
91#endif
92
93	/* --------------------------------
94	 * Enable the cycle count register
95	 * --------------------------------
96	 */
97	mrs	x0, pmcr_el0
98	ubfx	x0, x0, #11, #5		// read PMCR.N field
99	mov	x1, #1
100	lsl	x0, x1, x0
101	sub	x0, x0, #1		// mask of event counters
102	orr	x0, x0, #0x80000000	// disable overflow intrs
103	msr	pmintenclr_el1, x0
104	msr	pmuserenr_el0, x1	// enable user mode access
105
106	/* ----------------------------------------------------------------
107	 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count
108	 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ
109	 * registers from EL0.
110	 * ----------------------------------------------------------------
111	 */
112	mrs	x0, cntkctl_el1
113	orr	x0, x0, #EL0VCTEN_BIT
114	msr	cntkctl_el1, x0
115.endm
116
117	/* -----------------------------------------------------
118	 * unsigned int plat_is_my_cpu_primary(void);
119	 *
120	 * This function checks if this is the Primary CPU
121	 * -----------------------------------------------------
122	 */
123func plat_is_my_cpu_primary
124	mrs	x0, mpidr_el1
125	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
126	cmp	x0, #TEGRA_PRIMARY_CPU
127	cset	x0, eq
128	ret
129endfunc plat_is_my_cpu_primary
130
131	/* -----------------------------------------------------
132	 * unsigned int plat_my_core_pos(void);
133	 *
134	 * result: CorePos = CoreId + (ClusterId << 2)
135	 * -----------------------------------------------------
136	 */
137func plat_my_core_pos
138	mrs	x0, mpidr_el1
139	and	x1, x0, #MPIDR_CPU_MASK
140	and	x0, x0, #MPIDR_CLUSTER_MASK
141	add	x0, x1, x0, LSR #6
142	ret
143endfunc plat_my_core_pos
144
145	/* -----------------------------------------------------
146	 * unsigned long plat_get_my_entrypoint (void);
147	 *
148	 * Main job of this routine is to distinguish between
149	 * a cold and warm boot. If the tegra_sec_entry_point for
150	 * this CPU is present, then it's a warm boot.
151	 *
152	 * -----------------------------------------------------
153	 */
154func plat_get_my_entrypoint
155	adr	x1, tegra_sec_entry_point
156	ldr	x0, [x1]
157	ret
158endfunc plat_get_my_entrypoint
159
160	/* -----------------------------------------------------
161	 * void plat_secondary_cold_boot_setup (void);
162	 *
163	 * This function performs any platform specific actions
164	 * needed for a secondary cpu after a cold reset. Right
165	 * now this is a stub function.
166	 * -----------------------------------------------------
167	 */
168func plat_secondary_cold_boot_setup
169	mov	x0, #0
170	ret
171endfunc plat_secondary_cold_boot_setup
172
173	/* --------------------------------------------------------
174	 * void platform_mem_init (void);
175	 *
176	 * Any memory init, relocation to be done before the
177	 * platform boots. Called very early in the boot process.
178	 * --------------------------------------------------------
179	 */
180func platform_mem_init
181	mov	x0, #0
182	ret
183endfunc platform_mem_init
184
185	/* ---------------------------------------------
186	 * int plat_crash_console_init(void)
187	 * Function to initialize the crash console
188	 * without a C Runtime to print crash report.
189	 * Clobber list : x0 - x4
190	 * ---------------------------------------------
191	 */
192func plat_crash_console_init
193	mov_imm	x0, TEGRA_BOOT_UART_BASE
194	mov_imm	x1, TEGRA_BOOT_UART_CLK_IN_HZ
195	mov_imm	x2, TEGRA_CONSOLE_BAUDRATE
196	b	console_core_init
197endfunc plat_crash_console_init
198
199	/* ---------------------------------------------
200	 * int plat_crash_console_putc(void)
201	 * Function to print a character on the crash
202	 * console without a C Runtime.
203	 * Clobber list : x1, x2
204	 * ---------------------------------------------
205	 */
206func plat_crash_console_putc
207	mov_imm	x1, TEGRA_BOOT_UART_BASE
208	b	console_core_putc
209endfunc plat_crash_console_putc
210
211	/* ---------------------------------------------------
212	 * Function to handle a platform reset and store
213	 * input parameters passed by BL2.
214	 * ---------------------------------------------------
215	 */
216func plat_reset_handler
217
218	/* -----------------------------------
219	 * derive and save the phys_base addr
220	 * -----------------------------------
221	 */
222	adr	x17, tegra_bl31_phys_base
223	ldr	x18, [x17]
224	cbnz	x18, 1f
225	adr	x18, bl31_entrypoint
226	str	x18, [x17]
227
2281:	cpu_init_common
229
230	ret
231endfunc plat_reset_handler
232
233	/* ----------------------------------------
234	 * Secure entrypoint function for CPU boot
235	 * ----------------------------------------
236	 */
237	.align 6
238func tegra_secure_entrypoint
239
240#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
241
242	/* -------------------------------------------------------
243	 * Invalidate BTB along with I$ to remove any stale
244	 * entries from the branch predictor array.
245	 * -------------------------------------------------------
246	 */
247	mrs	x0, CPUACTLR_EL1
248	orr	x0, x0, #1
249	msr	CPUACTLR_EL1, x0	/* invalidate BTB and I$ together */
250	dsb	sy
251	isb
252	ic	iallu			/* actual invalidate */
253	dsb	sy
254	isb
255
256	mrs	x0, CPUACTLR_EL1
257	bic	x0, x0, #1
258	msr	CPUACTLR_EL1, X0	/* restore original CPUACTLR_EL1 */
259	dsb	sy
260	isb
261
262	.rept	7
263	nop				/* wait */
264	.endr
265
266	/* -----------------------------------------------
267	 * Extract OSLK bit and check if it is '1'. This
268	 * bit remains '0' for A53 on warm-resets. If '1',
269	 * turn off regional clock gating and request warm
270	 * reset.
271	 * -----------------------------------------------
272	 */
273	mrs	x0, oslsr_el1
274	and	x0, x0, #2
275	mrs	x1, mpidr_el1
276	bics	xzr, x0, x1, lsr #7	/* 0 = slow cluster or warm reset */
277	b.eq	restore_oslock
278	mov	x0, xzr
279	msr	oslar_el1, x0		/* os lock stays 0 across warm reset */
280	mov	x3, #3
281	movz	x4, #0x8000, lsl #48
282	msr	CPUACTLR_EL1, x4	/* turn off RCG */
283	isb
284	msr	rmr_el3, x3		/* request warm reset */
285	isb
286	dsb	sy
2871:	wfi
288	b	1b
289
290	/* --------------------------------------------------
291	 * These nops are here so that speculative execution
292	 * won't harm us before we are done with warm reset.
293	 * --------------------------------------------------
294	 */
295	.rept	65
296	nop
297	.endr
298
299	/* --------------------------------------------------
300	 * Do not insert instructions here
301	 * --------------------------------------------------
302	 */
303#endif
304
305	/* --------------------------------------------------
306	 * Restore OS Lock bit
307	 * --------------------------------------------------
308	 */
309restore_oslock:
310	mov	x0, #1
311	msr	oslar_el1, x0
312
313	cpu_init_common
314
315	/* ---------------------------------------------------------------------
316	 * The initial state of the Architectural feature trap register
317	 * (CPTR_EL3) is unknown and it must be set to a known state. All
318	 * feature traps are disabled. Some bits in this register are marked as
319	 * Reserved and should not be modified.
320	 *
321	 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
322	 *  or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
323	 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
324	 *  to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
325	 *  access to trace functionality is not supported, this bit is RES0.
326	 * CPTR_EL3.TFP: This causes instructions that access the registers
327	 *  associated with Floating Point and Advanced SIMD execution to trap
328	 *  to EL3 when executed from any exception level, unless trapped to EL1
329	 *  or EL2.
330	 * ---------------------------------------------------------------------
331	 */
332	mrs	x1, cptr_el3
333	bic	w1, w1, #TCPAC_BIT
334	bic	w1, w1, #TTA_BIT
335	bic	w1, w1, #TFP_BIT
336	msr	cptr_el3, x1
337
338	/* --------------------------------------------------
339	 * Get secure world's entry point and jump to it
340	 * --------------------------------------------------
341	 */
342	bl	plat_get_my_entrypoint
343	br	x0
344endfunc tegra_secure_entrypoint
345
346	.data
347	.align 3
348
349	/* --------------------------------------------------
350	 * CPU Secure entry point - resume from suspend
351	 * --------------------------------------------------
352	 */
353tegra_sec_entry_point:
354	.quad	0
355
356	/* --------------------------------------------------
357	 * NS world's cold boot entry point
358	 * --------------------------------------------------
359	 */
360ns_image_entrypoint:
361	.quad	0
362
363	/* --------------------------------------------------
364	 * BL31's physical base address
365	 * --------------------------------------------------
366	 */
367tegra_bl31_phys_base:
368	.quad	0
369