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