• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
3 *
4 * SPDX-License-Identifier: BSD-3-Clause
5 */
6#include <arch.h>
7#include <asm_macros.S>
8#include <assert_macros.S>
9#include <cpu_macros.S>
10#include <cortex_a53.h>
11#include <cortex_a57.h>
12#include <platform_def.h>
13#include <tegra_def.h>
14
15#define MIDR_PN_CORTEX_A57		0xD07
16
17/*******************************************************************************
18 * Implementation defined ACTLR_EL3 bit definitions
19 ******************************************************************************/
20#define ACTLR_EL3_L2ACTLR_BIT		(1 << 6)
21#define ACTLR_EL3_L2ECTLR_BIT		(1 << 5)
22#define ACTLR_EL3_L2CTLR_BIT		(1 << 4)
23#define ACTLR_EL3_CPUECTLR_BIT		(1 << 1)
24#define ACTLR_EL3_CPUACTLR_BIT		(1 << 0)
25#define ACTLR_EL3_ENABLE_ALL_ACCESS	(ACTLR_EL3_L2ACTLR_BIT | \
26					 ACTLR_EL3_L2ECTLR_BIT | \
27					 ACTLR_EL3_L2CTLR_BIT | \
28					 ACTLR_EL3_CPUECTLR_BIT | \
29					 ACTLR_EL3_CPUACTLR_BIT)
30
31	/* Global functions */
32	.globl	plat_is_my_cpu_primary
33	.globl	plat_my_core_pos
34	.globl	plat_get_my_entrypoint
35	.globl	plat_secondary_cold_boot_setup
36	.globl	platform_mem_init
37	.globl	plat_crash_console_init
38	.globl	plat_crash_console_putc
39	.globl	tegra_secure_entrypoint
40	.globl	plat_reset_handler
41
42	/* Global variables */
43	.globl	tegra_sec_entry_point
44	.globl	ns_image_entrypoint
45	.globl	tegra_bl31_phys_base
46	.globl	tegra_console_base
47	.globl	tegra_enable_l2_ecc_parity_prot
48
49	/* ---------------------
50	 * Common CPU init code
51	 * ---------------------
52	 */
53.macro	cpu_init_common
54
55	/* ------------------------------------------------
56	 * We enable procesor retention, L2/CPUECTLR NS
57	 * access and ECC/Parity protection for A57 CPUs
58	 * ------------------------------------------------
59	 */
60	mrs	x0, midr_el1
61	mov	x1, #(MIDR_PN_MASK << MIDR_PN_SHIFT)
62	and	x0, x0, x1
63	lsr	x0, x0, #MIDR_PN_SHIFT
64	cmp	x0, #MIDR_PN_CORTEX_A57
65	b.ne	1f
66
67	/* ---------------------------
68	 * Enable processor retention
69	 * ---------------------------
70	 */
71	mrs	x0, CORTEX_A57_L2ECTLR_EL1
72	mov	x1, #RETENTION_ENTRY_TICKS_512
73	bic	x0, x0, #CORTEX_A57_L2ECTLR_RET_CTRL_MASK
74	orr	x0, x0, x1
75	msr	CORTEX_A57_L2ECTLR_EL1, x0
76	isb
77
78	mrs	x0, CORTEX_A57_ECTLR_EL1
79	mov	x1, #RETENTION_ENTRY_TICKS_512
80	bic	x0, x0, #CORTEX_A57_ECTLR_CPU_RET_CTRL_MASK
81	orr	x0, x0, x1
82	msr	CORTEX_A57_ECTLR_EL1, x0
83	isb
84
85	/* -------------------------------------------------------
86	 * Enable L2 and CPU ECTLR RW access from non-secure world
87	 * -------------------------------------------------------
88	 */
89	mov	x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
90	msr	actlr_el3, x0
91	msr	actlr_el2, x0
92	isb
93
94	/* -------------------------------------------------------
95	 * Enable L2 ECC and Parity Protection
96	 * -------------------------------------------------------
97	 */
98	adr	x0, tegra_enable_l2_ecc_parity_prot
99	ldr	x0, [x0]
100	cbz	x0, 1f
101	mrs	x0, CORTEX_A57_L2CTLR_EL1
102	and	x1, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT
103	cbnz	x1, 1f
104	orr	x0, x0, #CORTEX_A57_L2_ECC_PARITY_PROTECTION_BIT
105	msr	CORTEX_A57_L2CTLR_EL1, x0
106	isb
107
108	/* --------------------------------
109	 * Enable the cycle count register
110	 * --------------------------------
111	 */
1121:	mrs	x0, pmcr_el0
113	ubfx	x0, x0, #11, #5		// read PMCR.N field
114	mov	x1, #1
115	lsl	x0, x1, x0
116	sub	x0, x0, #1		// mask of event counters
117	orr	x0, x0, #0x80000000	// disable overflow intrs
118	msr	pmintenclr_el1, x0
119	msr	pmuserenr_el0, x1	// enable user mode access
120
121	/* ----------------------------------------------------------------
122	 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count
123	 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ
124	 * registers from EL0.
125	 * ----------------------------------------------------------------
126	 */
127	mrs	x0, cntkctl_el1
128	orr	x0, x0, #EL0VCTEN_BIT
129	msr	cntkctl_el1, x0
130.endm
131
132	/* -----------------------------------------------------
133	 * unsigned int plat_is_my_cpu_primary(void);
134	 *
135	 * This function checks if this is the Primary CPU
136	 * -----------------------------------------------------
137	 */
138func plat_is_my_cpu_primary
139	mrs	x0, mpidr_el1
140	and	x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
141	cmp	x0, #TEGRA_PRIMARY_CPU
142	cset	x0, eq
143	ret
144endfunc plat_is_my_cpu_primary
145
146	/* -----------------------------------------------------
147	 * unsigned int plat_my_core_pos(void);
148	 *
149	 * result: CorePos = CoreId + (ClusterId << 2)
150	 * -----------------------------------------------------
151	 */
152func plat_my_core_pos
153	mrs	x0, mpidr_el1
154	and	x1, x0, #MPIDR_CPU_MASK
155	and	x0, x0, #MPIDR_CLUSTER_MASK
156	add	x0, x1, x0, LSR #6
157	ret
158endfunc plat_my_core_pos
159
160	/* -----------------------------------------------------
161	 * unsigned long plat_get_my_entrypoint (void);
162	 *
163	 * Main job of this routine is to distinguish between
164	 * a cold and warm boot. If the tegra_sec_entry_point for
165	 * this CPU is present, then it's a warm boot.
166	 *
167	 * -----------------------------------------------------
168	 */
169func plat_get_my_entrypoint
170	adr	x1, tegra_sec_entry_point
171	ldr	x0, [x1]
172	ret
173endfunc plat_get_my_entrypoint
174
175	/* -----------------------------------------------------
176	 * int platform_get_core_pos(int mpidr);
177	 *
178	 * With this function: CorePos = (ClusterId * 4) +
179	 *                                CoreId
180	 * -----------------------------------------------------
181	 */
182func platform_get_core_pos
183	and	x1, x0, #MPIDR_CPU_MASK
184	and	x0, x0, #MPIDR_CLUSTER_MASK
185	add	x0, x1, x0, LSR #6
186	ret
187endfunc platform_get_core_pos
188
189	/* -----------------------------------------------------
190	 * void plat_secondary_cold_boot_setup (void);
191	 *
192	 * This function performs any platform specific actions
193	 * needed for a secondary cpu after a cold reset. Right
194	 * now this is a stub function.
195	 * -----------------------------------------------------
196	 */
197func plat_secondary_cold_boot_setup
198	mov	x0, #0
199	ret
200endfunc plat_secondary_cold_boot_setup
201
202	/* --------------------------------------------------------
203	 * void platform_mem_init (void);
204	 *
205	 * Any memory init, relocation to be done before the
206	 * platform boots. Called very early in the boot process.
207	 * --------------------------------------------------------
208	 */
209func platform_mem_init
210	mov	x0, #0
211	ret
212endfunc platform_mem_init
213
214	/* ---------------------------------------------
215	 * int plat_crash_console_init(void)
216	 * Function to initialize the crash console
217	 * without a C Runtime to print crash report.
218	 * Clobber list : x0 - x4
219	 * ---------------------------------------------
220	 */
221func plat_crash_console_init
222	mov	x0, #0
223	adr	x1, tegra_console_base
224	ldr	x1, [x1]
225	cbz	x1, 1f
226	mov	w0, #1
2271:	ret
228endfunc plat_crash_console_init
229
230	/* ---------------------------------------------
231	 * int plat_crash_console_putc(void)
232	 * Function to print a character on the crash
233	 * console without a C Runtime.
234	 * Clobber list : x1, x2
235	 * ---------------------------------------------
236	 */
237func plat_crash_console_putc
238	adr	x1, tegra_console_base
239	ldr	x1, [x1]
240	b	console_core_putc
241endfunc plat_crash_console_putc
242
243	/* ---------------------------------------------------
244	 * Function to handle a platform reset and store
245	 * input parameters passed by BL2.
246	 * ---------------------------------------------------
247	 */
248func plat_reset_handler
249
250	/* ----------------------------------------------------
251	 * Verify if we are running from BL31_BASE address
252	 * ----------------------------------------------------
253	 */
254	adr	x18, bl31_entrypoint
255	mov	x17, #BL31_BASE
256	cmp	x18, x17
257	b.eq	1f
258
259	/* ----------------------------------------------------
260	 * Copy the entire BL31 code to BL31_BASE if we are not
261	 * running from it already
262	 * ----------------------------------------------------
263	 */
264	mov	x0, x17
265	mov	x1, x18
266	mov	x2, #BL31_SIZE
267_loop16:
268	cmp	x2, #16
269	b.lo	_loop1
270	ldp	x3, x4, [x1], #16
271	stp	x3, x4, [x0], #16
272	sub	x2, x2, #16
273	b	_loop16
274	/* copy byte per byte */
275_loop1:
276	cbz	x2, _end
277	ldrb	w3, [x1], #1
278	strb	w3, [x0], #1
279	subs	x2, x2, #1
280	b.ne	_loop1
281
282	/* ----------------------------------------------------
283	 * Jump to BL31_BASE and start execution again
284	 * ----------------------------------------------------
285	 */
286_end:	mov	x0, x20
287	mov	x1, x21
288	br	x17
2891:
290
291	/* -----------------------------------
292	 * derive and save the phys_base addr
293	 * -----------------------------------
294	 */
295	adr	x17, tegra_bl31_phys_base
296	ldr	x18, [x17]
297	cbnz	x18, 1f
298	adr	x18, bl31_entrypoint
299	str	x18, [x17]
300
3011:	cpu_init_common
302
303	ret
304endfunc plat_reset_handler
305
306	/* ----------------------------------------
307	 * Secure entrypoint function for CPU boot
308	 * ----------------------------------------
309	 */
310func tegra_secure_entrypoint _align=6
311
312#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
313
314	/* -------------------------------------------------------
315	 * Invalidate BTB along with I$ to remove any stale
316	 * entries from the branch predictor array.
317	 * -------------------------------------------------------
318	 */
319	mrs	x0, CORTEX_A57_CPUACTLR_EL1
320	orr	x0, x0, #1
321	msr	CORTEX_A57_CPUACTLR_EL1, x0	/* invalidate BTB and I$ together */
322	dsb	sy
323	isb
324	ic	iallu			/* actual invalidate */
325	dsb	sy
326	isb
327
328	mrs	x0, CORTEX_A57_CPUACTLR_EL1
329	bic	x0, x0, #1
330	msr	CORTEX_A57_CPUACTLR_EL1, X0	/* restore original CPUACTLR_EL1 */
331	dsb	sy
332	isb
333
334	.rept	7
335	nop				/* wait */
336	.endr
337
338	/* -----------------------------------------------
339	 * Extract OSLK bit and check if it is '1'. This
340	 * bit remains '0' for A53 on warm-resets. If '1',
341	 * turn off regional clock gating and request warm
342	 * reset.
343	 * -----------------------------------------------
344	 */
345	mrs	x0, oslsr_el1
346	and	x0, x0, #2
347	mrs	x1, mpidr_el1
348	bics	xzr, x0, x1, lsr #7	/* 0 = slow cluster or warm reset */
349	b.eq	restore_oslock
350	mov	x0, xzr
351	msr	oslar_el1, x0		/* os lock stays 0 across warm reset */
352	mov	x3, #3
353	movz	x4, #0x8000, lsl #48
354	msr	CORTEX_A57_CPUACTLR_EL1, x4	/* turn off RCG */
355	isb
356	msr	rmr_el3, x3		/* request warm reset */
357	isb
358	dsb	sy
3591:	wfi
360	b	1b
361
362	/* --------------------------------------------------
363	 * These nops are here so that speculative execution
364	 * won't harm us before we are done with warm reset.
365	 * --------------------------------------------------
366	 */
367	.rept	65
368	nop
369	.endr
370
371	/* --------------------------------------------------
372	 * Do not insert instructions here
373	 * --------------------------------------------------
374	 */
375#endif
376
377	/* --------------------------------------------------
378	 * Restore OS Lock bit
379	 * --------------------------------------------------
380	 */
381restore_oslock:
382	mov	x0, #1
383	msr	oslar_el1, x0
384
385	cpu_init_common
386
387	/* ---------------------------------------------------------------------
388	 * The initial state of the Architectural feature trap register
389	 * (CPTR_EL3) is unknown and it must be set to a known state. All
390	 * feature traps are disabled. Some bits in this register are marked as
391	 * Reserved and should not be modified.
392	 *
393	 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
394	 *  or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
395	 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
396	 *  to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
397	 *  access to trace functionality is not supported, this bit is RES0.
398	 * CPTR_EL3.TFP: This causes instructions that access the registers
399	 *  associated with Floating Point and Advanced SIMD execution to trap
400	 *  to EL3 when executed from any exception level, unless trapped to EL1
401	 *  or EL2.
402	 * ---------------------------------------------------------------------
403	 */
404	mrs	x1, cptr_el3
405	bic	w1, w1, #TCPAC_BIT
406	bic	w1, w1, #TTA_BIT
407	bic	w1, w1, #TFP_BIT
408	msr	cptr_el3, x1
409
410	/* --------------------------------------------------
411	 * Get secure world's entry point and jump to it
412	 * --------------------------------------------------
413	 */
414	bl	plat_get_my_entrypoint
415	br	x0
416endfunc tegra_secure_entrypoint
417
418	.data
419	.align 3
420
421	/* --------------------------------------------------
422	 * CPU Secure entry point - resume from suspend
423	 * --------------------------------------------------
424	 */
425tegra_sec_entry_point:
426	.quad	0
427
428	/* --------------------------------------------------
429	 * NS world's cold boot entry point
430	 * --------------------------------------------------
431	 */
432ns_image_entrypoint:
433	.quad	0
434
435	/* --------------------------------------------------
436	 * BL31's physical base address
437	 * --------------------------------------------------
438	 */
439tegra_bl31_phys_base:
440	.quad	0
441
442	/* --------------------------------------------------
443	 * UART controller base for console init
444	 * --------------------------------------------------
445	 */
446tegra_console_base:
447	.quad	0
448
449	/* --------------------------------------------------
450	 * Enable L2 ECC and Parity Protection
451	 * --------------------------------------------------
452	 */
453tegra_enable_l2_ecc_parity_prot:
454	.quad	0
455