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