blob: 4bf1a9df406120335d5ddac134e2b2bd1e087d8c [file] [log] [blame]
Varun Wadekar08438e22015-05-19 16:48:04 +05301/*
Antonio Nino Diaz9c675b32018-10-17 15:29:34 +01002 * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved.
Varun Wadekar08438e22015-05-19 16:48:04 +05303 *
dp-arm82cb2c12017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekar08438e22015-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 Wadekar08438e22015-05-19 16:48:04 +053010#include <cortex_a53.h>
Isla Mitchellee1ebbd2017-07-14 10:46:32 +010011#include <cortex_a57.h>
Varun Wadekar11bd24b2016-04-26 11:38:38 -070012#include <platform_def.h>
Varun Wadekar08438e22015-05-19 16:48:04 +053013#include <tegra_def.h>
Harvey Hsiehc195fec2017-04-24 19:35:51 +080014#include <tegra_platform.h>
Varun Wadekar08438e22015-05-19 16:48:04 +053015
Varun Wadekar0cd61382015-09-22 13:33:56 +053016#define MIDR_PN_CORTEX_A57 0xD07
17
18/*******************************************************************************
19 * Implementation defined ACTLR_EL3 bit definitions
20 ******************************************************************************/
Steven Kao75516c32017-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 Wadekar0cd61382015-09-22 13:33:56 +053031#define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \
Steven Kao75516c32017-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 Wadekar0cd61382015-09-22 13:33:56 +053036
Varun Wadekar08438e22015-05-19 16:48:04 +053037 /* Global functions */
Varun Wadekar71cb26e2015-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 Wadekar08438e22015-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 Diaz9c675b32018-10-17 15:29:34 +010045 .globl plat_crash_console_flush
Varun Wadekar08438e22015-05-19 16:48:04 +053046 .globl tegra_secure_entrypoint
47 .globl plat_reset_handler
48
49 /* Global variables */
Varun Wadekar71cb26e2015-08-07 10:03:00 +053050 .globl tegra_sec_entry_point
Varun Wadekar08438e22015-05-19 16:48:04 +053051 .globl ns_image_entrypoint
52 .globl tegra_bl31_phys_base
Varun Wadekare1084212015-10-29 10:37:28 +053053 .globl tegra_console_base
Varun Wadekar08438e22015-05-19 16:48:04 +053054
55 /* ---------------------
56 * Common CPU init code
57 * ---------------------
58 */
59.macro cpu_init_common
60
Varun Wadekar0cd61382015-09-22 13:33:56 +053061 /* ------------------------------------------------
Varun Wadekar018b8482016-05-12 13:43:33 -070062 * We enable procesor retention, L2/CPUECTLR NS
63 * access and ECC/Parity protection for A57 CPUs
Varun Wadekar0cd61382015-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 Wadekarb42192b2015-08-21 15:56:02 +053073 /* ---------------------------
74 * Enable processor retention
75 * ---------------------------
Varun Wadekar018b8482016-05-12 13:43:33 -070076 */
Varun Wadekarfb7d32e2017-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 Wadekarb42192b2015-08-21 15:56:02 +053080 orr x0, x0, x1
Varun Wadekarfb7d32e2017-06-05 14:54:46 -070081 msr CORTEX_A57_L2ECTLR_EL1, x0
Varun Wadekarb42192b2015-08-21 15:56:02 +053082 isb
Varun Wadekarb42192b2015-08-21 15:56:02 +053083
Varun Wadekarfb7d32e2017-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 Wadekarb42192b2015-08-21 15:56:02 +053087 orr x0, x0, x1
Varun Wadekarfb7d32e2017-06-05 14:54:46 -070088 msr CORTEX_A57_ECTLR_EL1, x0
Varun Wadekarb42192b2015-08-21 15:56:02 +053089 isb
Varun Wadekarb42192b2015-08-21 15:56:02 +053090
Varun Wadekar08438e22015-05-19 16:48:04 +053091 /* -------------------------------------------------------
92 * Enable L2 and CPU ECTLR RW access from non-secure world
93 * -------------------------------------------------------
Varun Wadekar018b8482016-05-12 13:43:33 -070094 */
Steven Kao75516c32017-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 Wadekar08438e22015-05-19 16:48:04 +0530100 msr actlr_el3, x0
Steven Kao75516c32017-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 Wadekar08438e22015-05-19 16:48:04 +0530106 msr actlr_el2, x0
107 isb
Varun Wadekar08438e22015-05-19 16:48:04 +0530108
109 /* --------------------------------
110 * Enable the cycle count register
111 * --------------------------------
112 */
Varun Wadekar0cd61382015-09-22 13:33:56 +05301131: mrs x0, pmcr_el0
Varun Wadekar08438e22015-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 Wadekar71cb26e2015-08-07 10:03:00 +0530134 * unsigned int plat_is_my_cpu_primary(void);
Varun Wadekar08438e22015-05-19 16:48:04 +0530135 *
136 * This function checks if this is the Primary CPU
137 * -----------------------------------------------------
138 */
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530139func plat_is_my_cpu_primary
140 mrs x0, mpidr_el1
Varun Wadekar08438e22015-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 Wadekar71cb26e2015-08-07 10:03:00 +0530145endfunc plat_is_my_cpu_primary
Varun Wadekar08438e22015-05-19 16:48:04 +0530146
147 /* -----------------------------------------------------
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530148 * unsigned int plat_my_core_pos(void);
Varun Wadekar08438e22015-05-19 16:48:04 +0530149 *
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530150 * result: CorePos = CoreId + (ClusterId << 2)
Varun Wadekar08438e22015-05-19 16:48:04 +0530151 * -----------------------------------------------------
152 */
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530153func plat_my_core_pos
154 mrs x0, mpidr_el1
155 and x1, x0, #MPIDR_CPU_MASK
156 and x0, x0, #MPIDR_CLUSTER_MASK
157 add x0, x1, x0, LSR #6
Varun Wadekar08438e22015-05-19 16:48:04 +0530158 ret
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530159endfunc plat_my_core_pos
160
161 /* -----------------------------------------------------
162 * unsigned long plat_get_my_entrypoint (void);
163 *
164 * Main job of this routine is to distinguish between
165 * a cold and warm boot. If the tegra_sec_entry_point for
166 * this CPU is present, then it's a warm boot.
167 *
168 * -----------------------------------------------------
169 */
170func plat_get_my_entrypoint
171 adr x1, tegra_sec_entry_point
172 ldr x0, [x1]
173 ret
174endfunc plat_get_my_entrypoint
Varun Wadekar08438e22015-05-19 16:48:04 +0530175
176 /* -----------------------------------------------------
Varun Wadekarbde81dc2015-09-22 13:45:07 +0530177 * int platform_get_core_pos(int mpidr);
178 *
179 * With this function: CorePos = (ClusterId * 4) +
180 * CoreId
181 * -----------------------------------------------------
182 */
183func platform_get_core_pos
184 and x1, x0, #MPIDR_CPU_MASK
185 and x0, x0, #MPIDR_CLUSTER_MASK
186 add x0, x1, x0, LSR #6
187 ret
188endfunc platform_get_core_pos
189
190 /* -----------------------------------------------------
Varun Wadekar08438e22015-05-19 16:48:04 +0530191 * void plat_secondary_cold_boot_setup (void);
192 *
193 * This function performs any platform specific actions
194 * needed for a secondary cpu after a cold reset. Right
195 * now this is a stub function.
196 * -----------------------------------------------------
197 */
198func plat_secondary_cold_boot_setup
199 mov x0, #0
200 ret
201endfunc plat_secondary_cold_boot_setup
202
Varun Wadekar08438e22015-05-19 16:48:04 +0530203 /* --------------------------------------------------------
204 * void platform_mem_init (void);
205 *
206 * Any memory init, relocation to be done before the
207 * platform boots. Called very early in the boot process.
208 * --------------------------------------------------------
209 */
210func platform_mem_init
211 mov x0, #0
212 ret
213endfunc platform_mem_init
214
215 /* ---------------------------------------------
216 * int plat_crash_console_init(void)
217 * Function to initialize the crash console
218 * without a C Runtime to print crash report.
Juan Castillo9400b402015-11-26 14:52:15 +0000219 * Clobber list : x0 - x4
Varun Wadekar08438e22015-05-19 16:48:04 +0530220 * ---------------------------------------------
221 */
222func plat_crash_console_init
Varun Wadekare87dac62017-04-04 13:40:12 -0700223 mov x0, #0
224 adr x1, tegra_console_base
225 ldr x1, [x1]
226 cbz x1, 1f
227 mov w0, #1
2281: ret
Varun Wadekar08438e22015-05-19 16:48:04 +0530229endfunc plat_crash_console_init
230
231 /* ---------------------------------------------
232 * int plat_crash_console_putc(void)
233 * Function to print a character on the crash
234 * console without a C Runtime.
235 * Clobber list : x1, x2
236 * ---------------------------------------------
237 */
238func plat_crash_console_putc
Varun Wadekare1084212015-10-29 10:37:28 +0530239 adr x1, tegra_console_base
240 ldr x1, [x1]
Varun Wadekar08438e22015-05-19 16:48:04 +0530241 b console_core_putc
242endfunc plat_crash_console_putc
243
Antonio Nino Diaz9c675b32018-10-17 15:29:34 +0100244 /* ---------------------------------------------
245 * int plat_crash_console_flush()
246 * Function to force a write of all buffered
247 * data that hasn't been output.
248 * Out : return -1 on error else return 0.
249 * Clobber list : x0, x1
250 * ---------------------------------------------
251 */
252func plat_crash_console_flush
253 adr x0, tegra_console_base
254 ldr x0, [x0]
255 b console_core_flush
256endfunc plat_crash_console_flush
257
Varun Wadekar08438e22015-05-19 16:48:04 +0530258 /* ---------------------------------------------------
259 * Function to handle a platform reset and store
260 * input parameters passed by BL2.
261 * ---------------------------------------------------
262 */
263func plat_reset_handler
264
Varun Wadekar939dcf22016-03-24 15:34:24 -0700265 /* ----------------------------------------------------
266 * Verify if we are running from BL31_BASE address
267 * ----------------------------------------------------
268 */
269 adr x18, bl31_entrypoint
270 mov x17, #BL31_BASE
271 cmp x18, x17
272 b.eq 1f
273
274 /* ----------------------------------------------------
275 * Copy the entire BL31 code to BL31_BASE if we are not
276 * running from it already
277 * ----------------------------------------------------
278 */
279 mov x0, x17
280 mov x1, x18
281 mov x2, #BL31_SIZE
282_loop16:
283 cmp x2, #16
Douglas Raillard768baf62017-03-20 10:38:29 +0000284 b.lo _loop1
Varun Wadekar939dcf22016-03-24 15:34:24 -0700285 ldp x3, x4, [x1], #16
286 stp x3, x4, [x0], #16
287 sub x2, x2, #16
288 b _loop16
289 /* copy byte per byte */
290_loop1:
291 cbz x2, _end
292 ldrb w3, [x1], #1
293 strb w3, [x0], #1
294 subs x2, x2, #1
295 b.ne _loop1
296
297 /* ----------------------------------------------------
298 * Jump to BL31_BASE and start execution again
299 * ----------------------------------------------------
300 */
301_end: mov x0, x20
302 mov x1, x21
303 br x17
3041:
305
Varun Wadekar08438e22015-05-19 16:48:04 +0530306 /* -----------------------------------
307 * derive and save the phys_base addr
308 * -----------------------------------
309 */
310 adr x17, tegra_bl31_phys_base
311 ldr x18, [x17]
312 cbnz x18, 1f
313 adr x18, bl31_entrypoint
314 str x18, [x17]
315
3161: cpu_init_common
317
318 ret
319endfunc plat_reset_handler
320
321 /* ----------------------------------------
322 * Secure entrypoint function for CPU boot
323 * ----------------------------------------
324 */
Julius Werner64726e62017-08-01 15:16:36 -0700325func tegra_secure_entrypoint _align=6
Varun Wadekar08438e22015-05-19 16:48:04 +0530326
327#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
328
Harvey Hsiehc195fec2017-04-24 19:35:51 +0800329 /* --------------------------------------------------------
330 * Skip the invalidate BTB workaround for Tegra210B01 SKUs.
331 * --------------------------------------------------------
332 */
333 mov x0, #TEGRA_MISC_BASE
334 add x0, x0, #HARDWARE_REVISION_OFFSET
335 ldr w1, [x0]
336 lsr w1, w1, #CHIP_ID_SHIFT
337 and w1, w1, #CHIP_ID_MASK
338 cmp w1, #TEGRA_CHIPID_TEGRA21 /* T210? */
339 b.ne 2f
340 ldr w1, [x0]
341 lsr w1, w1, #MAJOR_VERSION_SHIFT
342 and w1, w1, #MAJOR_VERSION_MASK
343 cmp w1, #0x02 /* T210 B01? */
344 b.eq 2f
345
Varun Wadekar08438e22015-05-19 16:48:04 +0530346 /* -------------------------------------------------------
347 * Invalidate BTB along with I$ to remove any stale
348 * entries from the branch predictor array.
349 * -------------------------------------------------------
350 */
Eleanor Bonnicid0e10942017-08-10 14:46:26 +0100351 mrs x0, CORTEX_A57_CPUACTLR_EL1
Varun Wadekar08438e22015-05-19 16:48:04 +0530352 orr x0, x0, #1
Eleanor Bonnicid0e10942017-08-10 14:46:26 +0100353 msr CORTEX_A57_CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */
Varun Wadekar08438e22015-05-19 16:48:04 +0530354 dsb sy
355 isb
356 ic iallu /* actual invalidate */
357 dsb sy
358 isb
359
Eleanor Bonnicid0e10942017-08-10 14:46:26 +0100360 mrs x0, CORTEX_A57_CPUACTLR_EL1
Varun Wadekar08438e22015-05-19 16:48:04 +0530361 bic x0, x0, #1
Eleanor Bonnicid0e10942017-08-10 14:46:26 +0100362 msr CORTEX_A57_CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */
Varun Wadekar08438e22015-05-19 16:48:04 +0530363 dsb sy
364 isb
365
366 .rept 7
367 nop /* wait */
368 .endr
369
370 /* -----------------------------------------------
371 * Extract OSLK bit and check if it is '1'. This
372 * bit remains '0' for A53 on warm-resets. If '1',
373 * turn off regional clock gating and request warm
374 * reset.
375 * -----------------------------------------------
376 */
377 mrs x0, oslsr_el1
378 and x0, x0, #2
379 mrs x1, mpidr_el1
380 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */
381 b.eq restore_oslock
382 mov x0, xzr
383 msr oslar_el1, x0 /* os lock stays 0 across warm reset */
384 mov x3, #3
385 movz x4, #0x8000, lsl #48
Eleanor Bonnicid0e10942017-08-10 14:46:26 +0100386 msr CORTEX_A57_CPUACTLR_EL1, x4 /* turn off RCG */
Varun Wadekar08438e22015-05-19 16:48:04 +0530387 isb
388 msr rmr_el3, x3 /* request warm reset */
389 isb
390 dsb sy
3911: wfi
392 b 1b
393
394 /* --------------------------------------------------
395 * These nops are here so that speculative execution
396 * won't harm us before we are done with warm reset.
397 * --------------------------------------------------
398 */
399 .rept 65
400 nop
401 .endr
Harvey Hsiehc195fec2017-04-24 19:35:51 +08004022:
Varun Wadekar08438e22015-05-19 16:48:04 +0530403 /* --------------------------------------------------
404 * Do not insert instructions here
405 * --------------------------------------------------
406 */
407#endif
408
409 /* --------------------------------------------------
410 * Restore OS Lock bit
411 * --------------------------------------------------
412 */
413restore_oslock:
414 mov x0, #1
415 msr oslar_el1, x0
416
417 cpu_init_common
418
419 /* ---------------------------------------------------------------------
420 * The initial state of the Architectural feature trap register
421 * (CPTR_EL3) is unknown and it must be set to a known state. All
422 * feature traps are disabled. Some bits in this register are marked as
423 * Reserved and should not be modified.
424 *
425 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
426 * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
427 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
428 * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
429 * access to trace functionality is not supported, this bit is RES0.
430 * CPTR_EL3.TFP: This causes instructions that access the registers
431 * associated with Floating Point and Advanced SIMD execution to trap
432 * to EL3 when executed from any exception level, unless trapped to EL1
433 * or EL2.
434 * ---------------------------------------------------------------------
435 */
436 mrs x1, cptr_el3
437 bic w1, w1, #TCPAC_BIT
438 bic w1, w1, #TTA_BIT
439 bic w1, w1, #TFP_BIT
440 msr cptr_el3, x1
441
442 /* --------------------------------------------------
443 * Get secure world's entry point and jump to it
444 * --------------------------------------------------
445 */
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530446 bl plat_get_my_entrypoint
Varun Wadekar08438e22015-05-19 16:48:04 +0530447 br x0
448endfunc tegra_secure_entrypoint
449
450 .data
451 .align 3
452
453 /* --------------------------------------------------
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530454 * CPU Secure entry point - resume from suspend
Varun Wadekar08438e22015-05-19 16:48:04 +0530455 * --------------------------------------------------
456 */
Varun Wadekar71cb26e2015-08-07 10:03:00 +0530457tegra_sec_entry_point:
Varun Wadekar08438e22015-05-19 16:48:04 +0530458 .quad 0
Varun Wadekar08438e22015-05-19 16:48:04 +0530459
460 /* --------------------------------------------------
461 * NS world's cold boot entry point
462 * --------------------------------------------------
463 */
464ns_image_entrypoint:
465 .quad 0
466
467 /* --------------------------------------------------
468 * BL31's physical base address
469 * --------------------------------------------------
470 */
471tegra_bl31_phys_base:
472 .quad 0
Varun Wadekare1084212015-10-29 10:37:28 +0530473
474 /* --------------------------------------------------
475 * UART controller base for console init
476 * --------------------------------------------------
477 */
478tegra_console_base:
479 .quad 0