blob: b47be6dc4b9a8e22c5330592cf6613c87bafc296 [file] [log] [blame]
Varun Wadekarb316e242015-05-19 16:48:04 +05301/*
Antonio Nino Diaz1eb64a12018-10-17 15:29:34 +01002 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
Varun Wadekarb316e242015-05-19 16:48:04 +05303 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekarb316e242015-05-19 16:48:04 +05305 */
6#include <arch.h>
7#include <asm_macros.S>
8#include <assert_macros.S>
9#include <cpu_macros.S>
Varun Wadekarb316e242015-05-19 16:48:04 +053010#include <cortex_a53.h>
Isla Mitchelle3631462017-07-14 10:46:32 +010011#include <cortex_a57.h>
Varun Wadekar25e658e2016-04-26 11:38:38 -070012#include <platform_def.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053013#include <tegra_def.h>
Harvey Hsieh6dc0d762017-04-24 19:35:51 +080014#include <tegra_platform.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053015
Varun Wadekarb24dea92015-09-22 13:33:56 +053016#define MIDR_PN_CORTEX_A57 0xD07
17
18/*******************************************************************************
19 * Implementation defined ACTLR_EL3 bit definitions
20 ******************************************************************************/
Steven Kaod417cea2017-06-14 14:02:23 +080021#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)
Varun Wadekarb24dea92015-09-22 13:33:56 +053031#define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \
Steven Kaod417cea2017-06-14 14:02:23 +080032 ACTLR_EL3_L2ECTLR_BIT | \
33 ACTLR_EL3_L2CTLR_BIT | \
34 ACTLR_EL3_CPUECTLR_BIT | \
35 ACTLR_EL3_CPUACTLR_BIT)
Varun Wadekarb24dea92015-09-22 13:33:56 +053036
Varun Wadekarb316e242015-05-19 16:48:04 +053037 /* Global functions */
Varun Wadekara78bb1b2015-08-07 10:03:00 +053038 .globl plat_is_my_cpu_primary
39 .globl plat_my_core_pos
40 .globl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +053041 .globl plat_secondary_cold_boot_setup
42 .globl platform_mem_init
43 .globl plat_crash_console_init
44 .globl plat_crash_console_putc
Antonio Nino Diaz1eb64a12018-10-17 15:29:34 +010045 .globl plat_crash_console_flush
Varun Wadekarb316e242015-05-19 16:48:04 +053046 .globl tegra_secure_entrypoint
47 .globl plat_reset_handler
48
49 /* Global variables */
Varun Wadekara78bb1b2015-08-07 10:03:00 +053050 .globl tegra_sec_entry_point
Varun Wadekarb316e242015-05-19 16:48:04 +053051 .globl ns_image_entrypoint
52 .globl tegra_bl31_phys_base
Varun Wadekard2014c62015-10-29 10:37:28 +053053 .globl tegra_console_base
Varun Wadekarb316e242015-05-19 16:48:04 +053054
55 /* ---------------------
56 * Common CPU init code
57 * ---------------------
58 */
59.macro cpu_init_common
60
Varun Wadekarb24dea92015-09-22 13:33:56 +053061 /* ------------------------------------------------
Varun Wadekar69ce1012016-05-12 13:43:33 -070062 * We enable procesor retention, L2/CPUECTLR NS
63 * access and ECC/Parity protection for A57 CPUs
Varun Wadekarb24dea92015-09-22 13:33:56 +053064 * ------------------------------------------------
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
Varun Wadekar4e9c2312015-08-21 15:56:02 +053073 /* ---------------------------
74 * Enable processor retention
75 * ---------------------------
Varun Wadekar69ce1012016-05-12 13:43:33 -070076 */
Varun Wadekar1384a162017-06-05 14:54:46 -070077 mrs x0, CORTEX_A57_L2ECTLR_EL1
78 mov x1, #RETENTION_ENTRY_TICKS_512
79 bic x0, x0, #CORTEX_A57_L2ECTLR_RET_CTRL_MASK
Varun Wadekar4e9c2312015-08-21 15:56:02 +053080 orr x0, x0, x1
Varun Wadekar1384a162017-06-05 14:54:46 -070081 msr CORTEX_A57_L2ECTLR_EL1, x0
Varun Wadekar4e9c2312015-08-21 15:56:02 +053082 isb
Varun Wadekar4e9c2312015-08-21 15:56:02 +053083
Varun Wadekar1384a162017-06-05 14:54:46 -070084 mrs x0, CORTEX_A57_ECTLR_EL1
85 mov x1, #RETENTION_ENTRY_TICKS_512
86 bic x0, x0, #CORTEX_A57_ECTLR_CPU_RET_CTRL_MASK
Varun Wadekar4e9c2312015-08-21 15:56:02 +053087 orr x0, x0, x1
Varun Wadekar1384a162017-06-05 14:54:46 -070088 msr CORTEX_A57_ECTLR_EL1, x0
Varun Wadekar4e9c2312015-08-21 15:56:02 +053089 isb
Varun Wadekar4e9c2312015-08-21 15:56:02 +053090
Varun Wadekarb316e242015-05-19 16:48:04 +053091 /* -------------------------------------------------------
92 * Enable L2 and CPU ECTLR RW access from non-secure world
93 * -------------------------------------------------------
Varun Wadekar69ce1012016-05-12 13:43:33 -070094 */
Steven Kaod417cea2017-06-14 14:02:23 +080095 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
Varun Wadekarb316e242015-05-19 16:48:04 +0530100 msr actlr_el3, x0
Steven Kaod417cea2017-06-14 14:02:23 +0800101 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
Varun Wadekarb316e242015-05-19 16:48:04 +0530106 msr actlr_el2, x0
107 isb
Varun Wadekarb316e242015-05-19 16:48:04 +0530108
109 /* --------------------------------
110 * Enable the cycle count register
111 * --------------------------------
112 */
Varun Wadekarb24dea92015-09-22 13:33:56 +05301131: mrs x0, pmcr_el0
Varun Wadekarb316e242015-05-19 16:48:04 +0530114 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 /* -----------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530134 * unsigned int plat_is_my_cpu_primary(void);
Varun Wadekarb316e242015-05-19 16:48:04 +0530135 *
136 * This function checks if this is the Primary CPU
137 * -----------------------------------------------------
138 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530139func plat_is_my_cpu_primary
140 mrs x0, mpidr_el1
Varun Wadekarb316e242015-05-19 16:48:04 +0530141 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
142 cmp x0, #TEGRA_PRIMARY_CPU
143 cset x0, eq
144 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530145endfunc plat_is_my_cpu_primary
Varun Wadekarb316e242015-05-19 16:48:04 +0530146
Varun Wadekarfa99b222017-08-23 16:02:06 -0700147 /* ----------------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530148 * unsigned int plat_my_core_pos(void);
149 *
Varun Wadekarfa99b222017-08-23 16:02:06 -0700150 * result: CorePos = CoreId + (ClusterId * cpus per cluster)
151 * ----------------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530152 */
153func plat_my_core_pos
154 mrs x0, mpidr_el1
155 and x1, x0, #MPIDR_CPU_MASK
156 and x0, x0, #MPIDR_CLUSTER_MASK
Varun Wadekarfa99b222017-08-23 16:02:06 -0700157 lsr x0, x0, #MPIDR_AFFINITY_BITS
158 mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
159 mul x0, x0, x2
160 add x0, x1, x0
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530161 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.
Varun Wadekarb316e242015-05-19 16:48:04 +0530170 *
Varun Wadekarb316e242015-05-19 16:48:04 +0530171 * -----------------------------------------------------
172 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530173func plat_get_my_entrypoint
174 adr x1, tegra_sec_entry_point
175 ldr x0, [x1]
Varun Wadekarb316e242015-05-19 16:48:04 +0530176 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530177endfunc plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530178
179 /* -----------------------------------------------------
Varun Wadekar39f87d12015-09-22 13:45:07 +0530180 * int platform_get_core_pos(int mpidr);
181 *
Varun Wadekarfa99b222017-08-23 16:02:06 -0700182 * result: CorePos = (ClusterId * cpus per cluster) +
183 * CoreId
Varun Wadekar39f87d12015-09-22 13:45:07 +0530184 * -----------------------------------------------------
185 */
186func platform_get_core_pos
187 and x1, x0, #MPIDR_CPU_MASK
188 and x0, x0, #MPIDR_CLUSTER_MASK
Varun Wadekarfa99b222017-08-23 16:02:06 -0700189 lsr x0, x0, #MPIDR_AFFINITY_BITS
190 mov x2, #PLATFORM_MAX_CPUS_PER_CLUSTER
191 mul x0, x0, x2
192 add x0, x1, x0
Varun Wadekar39f87d12015-09-22 13:45:07 +0530193 ret
194endfunc platform_get_core_pos
195
196 /* -----------------------------------------------------
Varun Wadekarb316e242015-05-19 16:48:04 +0530197 * 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
Varun Wadekarb316e242015-05-19 16:48:04 +0530209 /* --------------------------------------------------------
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 * int plat_crash_console_init(void)
223 * Function to initialize the crash console
224 * without a C Runtime to print crash report.
Juan Castilloe7ae6db2015-11-26 14:52:15 +0000225 * Clobber list : x0 - x4
Varun Wadekarb316e242015-05-19 16:48:04 +0530226 * ---------------------------------------------
227 */
228func plat_crash_console_init
Varun Wadekar4e6ae182017-04-04 13:40:12 -0700229 mov x0, #0
230 adr x1, tegra_console_base
231 ldr x1, [x1]
232 cbz x1, 1f
233 mov w0, #1
2341: ret
Varun Wadekarb316e242015-05-19 16:48:04 +0530235endfunc plat_crash_console_init
236
237 /* ---------------------------------------------
238 * int plat_crash_console_putc(void)
239 * Function to print a character on the crash
240 * console without a C Runtime.
241 * Clobber list : x1, x2
242 * ---------------------------------------------
243 */
244func plat_crash_console_putc
Varun Wadekard2014c62015-10-29 10:37:28 +0530245 adr x1, tegra_console_base
246 ldr x1, [x1]
Varun Wadekarb316e242015-05-19 16:48:04 +0530247 b console_core_putc
248endfunc plat_crash_console_putc
249
Antonio Nino Diaz1eb64a12018-10-17 15:29:34 +0100250 /* ---------------------------------------------
251 * int plat_crash_console_flush()
252 * Function to force a write of all buffered
253 * data that hasn't been output.
254 * Out : return -1 on error else return 0.
255 * Clobber list : x0, x1
256 * ---------------------------------------------
257 */
258func plat_crash_console_flush
259 adr x0, tegra_console_base
260 ldr x0, [x0]
261 b console_core_flush
262endfunc plat_crash_console_flush
263
Varun Wadekarb316e242015-05-19 16:48:04 +0530264 /* ---------------------------------------------------
265 * Function to handle a platform reset and store
266 * input parameters passed by BL2.
267 * ---------------------------------------------------
268 */
269func plat_reset_handler
270
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700271 /* ----------------------------------------------------
272 * Verify if we are running from BL31_BASE address
273 * ----------------------------------------------------
274 */
275 adr x18, bl31_entrypoint
276 mov x17, #BL31_BASE
277 cmp x18, x17
278 b.eq 1f
279
280 /* ----------------------------------------------------
281 * Copy the entire BL31 code to BL31_BASE if we are not
282 * running from it already
283 * ----------------------------------------------------
284 */
285 mov x0, x17
286 mov x1, x18
287 mov x2, #BL31_SIZE
288_loop16:
289 cmp x2, #16
Douglas Raillard2bb9f472017-03-20 10:38:29 +0000290 b.lo _loop1
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700291 ldp x3, x4, [x1], #16
292 stp x3, x4, [x0], #16
293 sub x2, x2, #16
294 b _loop16
295 /* copy byte per byte */
296_loop1:
297 cbz x2, _end
298 ldrb w3, [x1], #1
299 strb w3, [x0], #1
300 subs x2, x2, #1
301 b.ne _loop1
302
303 /* ----------------------------------------------------
304 * Jump to BL31_BASE and start execution again
305 * ----------------------------------------------------
306 */
307_end: mov x0, x20
308 mov x1, x21
309 br x17
3101:
311
Varun Wadekarb316e242015-05-19 16:48:04 +0530312 /* -----------------------------------
313 * derive and save the phys_base addr
314 * -----------------------------------
315 */
316 adr x17, tegra_bl31_phys_base
317 ldr x18, [x17]
318 cbnz x18, 1f
319 adr x18, bl31_entrypoint
320 str x18, [x17]
321
3221: cpu_init_common
323
324 ret
325endfunc plat_reset_handler
326
327 /* ----------------------------------------
328 * Secure entrypoint function for CPU boot
329 * ----------------------------------------
330 */
Julius Wernerb4c75e92017-08-01 15:16:36 -0700331func tegra_secure_entrypoint _align=6
Varun Wadekarb316e242015-05-19 16:48:04 +0530332
333#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
334
Harvey Hsieh6dc0d762017-04-24 19:35:51 +0800335 /* --------------------------------------------------------
336 * Skip the invalidate BTB workaround for Tegra210B01 SKUs.
337 * --------------------------------------------------------
338 */
339 mov x0, #TEGRA_MISC_BASE
340 add x0, x0, #HARDWARE_REVISION_OFFSET
341 ldr w1, [x0]
342 lsr w1, w1, #CHIP_ID_SHIFT
343 and w1, w1, #CHIP_ID_MASK
344 cmp w1, #TEGRA_CHIPID_TEGRA21 /* T210? */
345 b.ne 2f
346 ldr w1, [x0]
347 lsr w1, w1, #MAJOR_VERSION_SHIFT
348 and w1, w1, #MAJOR_VERSION_MASK
349 cmp w1, #0x02 /* T210 B01? */
350 b.eq 2f
351
Varun Wadekarb316e242015-05-19 16:48:04 +0530352 /* -------------------------------------------------------
353 * Invalidate BTB along with I$ to remove any stale
354 * entries from the branch predictor array.
355 * -------------------------------------------------------
356 */
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100357 mrs x0, CORTEX_A57_CPUACTLR_EL1
Varun Wadekarb316e242015-05-19 16:48:04 +0530358 orr x0, x0, #1
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100359 msr CORTEX_A57_CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */
Varun Wadekarb316e242015-05-19 16:48:04 +0530360 dsb sy
361 isb
362 ic iallu /* actual invalidate */
363 dsb sy
364 isb
365
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100366 mrs x0, CORTEX_A57_CPUACTLR_EL1
Varun Wadekarb316e242015-05-19 16:48:04 +0530367 bic x0, x0, #1
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100368 msr CORTEX_A57_CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */
Varun Wadekarb316e242015-05-19 16:48:04 +0530369 dsb sy
370 isb
371
372 .rept 7
373 nop /* wait */
374 .endr
375
376 /* -----------------------------------------------
377 * Extract OSLK bit and check if it is '1'. This
378 * bit remains '0' for A53 on warm-resets. If '1',
379 * turn off regional clock gating and request warm
380 * reset.
381 * -----------------------------------------------
382 */
383 mrs x0, oslsr_el1
384 and x0, x0, #2
385 mrs x1, mpidr_el1
386 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */
387 b.eq restore_oslock
388 mov x0, xzr
389 msr oslar_el1, x0 /* os lock stays 0 across warm reset */
390 mov x3, #3
391 movz x4, #0x8000, lsl #48
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100392 msr CORTEX_A57_CPUACTLR_EL1, x4 /* turn off RCG */
Varun Wadekarb316e242015-05-19 16:48:04 +0530393 isb
394 msr rmr_el3, x3 /* request warm reset */
395 isb
396 dsb sy
3971: wfi
398 b 1b
399
400 /* --------------------------------------------------
401 * These nops are here so that speculative execution
402 * won't harm us before we are done with warm reset.
403 * --------------------------------------------------
404 */
405 .rept 65
406 nop
407 .endr
Harvey Hsieh6dc0d762017-04-24 19:35:51 +08004082:
Varun Wadekarb316e242015-05-19 16:48:04 +0530409 /* --------------------------------------------------
410 * Do not insert instructions here
411 * --------------------------------------------------
412 */
413#endif
414
415 /* --------------------------------------------------
416 * Restore OS Lock bit
417 * --------------------------------------------------
418 */
419restore_oslock:
420 mov x0, #1
421 msr oslar_el1, x0
422
Varun Wadekarb316e242015-05-19 16:48:04 +0530423 /* --------------------------------------------------
424 * Get secure world's entry point and jump to it
425 * --------------------------------------------------
426 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530427 bl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530428 br x0
429endfunc tegra_secure_entrypoint
430
431 .data
432 .align 3
433
434 /* --------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530435 * CPU Secure entry point - resume from suspend
Varun Wadekarb316e242015-05-19 16:48:04 +0530436 * --------------------------------------------------
437 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530438tegra_sec_entry_point:
Varun Wadekarb316e242015-05-19 16:48:04 +0530439 .quad 0
Varun Wadekarb316e242015-05-19 16:48:04 +0530440
441 /* --------------------------------------------------
442 * NS world's cold boot entry point
443 * --------------------------------------------------
444 */
445ns_image_entrypoint:
446 .quad 0
447
448 /* --------------------------------------------------
449 * BL31's physical base address
450 * --------------------------------------------------
451 */
452tegra_bl31_phys_base:
453 .quad 0
Varun Wadekard2014c62015-10-29 10:37:28 +0530454
455 /* --------------------------------------------------
456 * UART controller base for console init
457 * --------------------------------------------------
458 */
459tegra_console_base:
460 .quad 0