blob: 72ecd54e9b462691bdd1273af9467f77c30e25cc [file] [log] [blame]
Varun Wadekarb316e242015-05-19 16:48:04 +05301/*
Ambroise Vincent09a22e72019-05-29 14:04:16 +01002 * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
Varun Wadekarc9bd0aa2018-06-07 11:21:02 -07003 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
Varun Wadekarb316e242015-05-19 16:48:04 +05304 *
dp-armfa3cf0b2017-05-03 09:38:09 +01005 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekarb316e242015-05-19 16:48:04 +05306 */
Varun Wadekar1b3196f2019-11-18 11:55:02 -08007
Varun Wadekarb316e242015-05-19 16:48:04 +05308#include <arch.h>
9#include <asm_macros.S>
10#include <assert_macros.S>
Isla Mitchelle3631462017-07-14 10:46:32 +010011#include <cortex_a57.h>
Varun Wadekar1b3196f2019-11-18 11:55:02 -080012#include <cpu_macros.S>
13
Varun Wadekar25e658e2016-04-26 11:38:38 -070014#include <platform_def.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053015#include <tegra_def.h>
Harvey Hsieh6dc0d762017-04-24 19:35:51 +080016#include <tegra_platform.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053017
Varun Wadekarb24dea92015-09-22 13:33:56 +053018#define MIDR_PN_CORTEX_A57 0xD07
19
20/*******************************************************************************
21 * Implementation defined ACTLR_EL3 bit definitions
22 ******************************************************************************/
Varun Wadekarc9bd0aa2018-06-07 11:21:02 -070023#define ACTLR_ELx_L2ACTLR_BIT (U(1) << 6)
24#define ACTLR_ELx_L2ECTLR_BIT (U(1) << 5)
25#define ACTLR_ELx_L2CTLR_BIT (U(1) << 4)
26#define ACTLR_ELx_CPUECTLR_BIT (U(1) << 1)
27#define ACTLR_ELx_CPUACTLR_BIT (U(1) << 0)
28#define ACTLR_ELx_ENABLE_ALL_ACCESS (ACTLR_ELx_L2ACTLR_BIT | \
29 ACTLR_ELx_L2ECTLR_BIT | \
30 ACTLR_ELx_L2CTLR_BIT | \
31 ACTLR_ELx_CPUECTLR_BIT | \
32 ACTLR_ELx_CPUACTLR_BIT)
Varun Wadekarb24dea92015-09-22 13:33:56 +053033
Varun Wadekarb316e242015-05-19 16:48:04 +053034 /* Global functions */
Varun Wadekara78bb1b2015-08-07 10:03:00 +053035 .globl plat_is_my_cpu_primary
36 .globl plat_my_core_pos
37 .globl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +053038 .globl plat_secondary_cold_boot_setup
39 .globl platform_mem_init
40 .globl plat_crash_console_init
41 .globl plat_crash_console_putc
Antonio Nino Diaz1eb64a12018-10-17 15:29:34 +010042 .globl plat_crash_console_flush
Varun Wadekarad2d5f32018-11-27 15:47:26 -080043 .weak plat_core_pos_by_mpidr
Varun Wadekarb316e242015-05-19 16:48:04 +053044 .globl tegra_secure_entrypoint
45 .globl plat_reset_handler
46
47 /* Global variables */
Varun Wadekara78bb1b2015-08-07 10:03:00 +053048 .globl tegra_sec_entry_point
Varun Wadekarb316e242015-05-19 16:48:04 +053049 .globl ns_image_entrypoint
50 .globl tegra_bl31_phys_base
Varun Wadekard2014c62015-10-29 10:37:28 +053051 .globl tegra_console_base
Varun Wadekarb316e242015-05-19 16:48:04 +053052
53 /* ---------------------
54 * Common CPU init code
55 * ---------------------
56 */
57.macro cpu_init_common
58
Varun Wadekarb24dea92015-09-22 13:33:56 +053059 /* ------------------------------------------------
Varun Wadekar69ce1012016-05-12 13:43:33 -070060 * We enable procesor retention, L2/CPUECTLR NS
61 * access and ECC/Parity protection for A57 CPUs
Varun Wadekarb24dea92015-09-22 13:33:56 +053062 * ------------------------------------------------
63 */
64 mrs x0, midr_el1
65 mov x1, #(MIDR_PN_MASK << MIDR_PN_SHIFT)
66 and x0, x0, x1
67 lsr x0, x0, #MIDR_PN_SHIFT
68 cmp x0, #MIDR_PN_CORTEX_A57
69 b.ne 1f
70
Varun Wadekar4e9c2312015-08-21 15:56:02 +053071 /* ---------------------------
72 * Enable processor retention
73 * ---------------------------
Varun Wadekar69ce1012016-05-12 13:43:33 -070074 */
Varun Wadekar1384a162017-06-05 14:54:46 -070075 mrs x0, CORTEX_A57_L2ECTLR_EL1
76 mov x1, #RETENTION_ENTRY_TICKS_512
77 bic x0, x0, #CORTEX_A57_L2ECTLR_RET_CTRL_MASK
Varun Wadekar4e9c2312015-08-21 15:56:02 +053078 orr x0, x0, x1
Varun Wadekar1384a162017-06-05 14:54:46 -070079 msr CORTEX_A57_L2ECTLR_EL1, x0
Varun Wadekar4e9c2312015-08-21 15:56:02 +053080 isb
Varun Wadekar4e9c2312015-08-21 15:56:02 +053081
Varun Wadekar1384a162017-06-05 14:54:46 -070082 mrs x0, CORTEX_A57_ECTLR_EL1
83 mov x1, #RETENTION_ENTRY_TICKS_512
84 bic x0, x0, #CORTEX_A57_ECTLR_CPU_RET_CTRL_MASK
Varun Wadekar4e9c2312015-08-21 15:56:02 +053085 orr x0, x0, x1
Varun Wadekar1384a162017-06-05 14:54:46 -070086 msr CORTEX_A57_ECTLR_EL1, x0
Varun Wadekar4e9c2312015-08-21 15:56:02 +053087 isb
Varun Wadekar4e9c2312015-08-21 15:56:02 +053088
Varun Wadekarb316e242015-05-19 16:48:04 +053089 /* -------------------------------------------------------
90 * Enable L2 and CPU ECTLR RW access from non-secure world
91 * -------------------------------------------------------
Varun Wadekar69ce1012016-05-12 13:43:33 -070092 */
Steven Kaod417cea2017-06-14 14:02:23 +080093 mrs x0, actlr_el3
Varun Wadekarc9bd0aa2018-06-07 11:21:02 -070094 mov x1, #ACTLR_ELx_ENABLE_ALL_ACCESS
Steven Kaod417cea2017-06-14 14:02:23 +080095 orr x0, x0, x1
Varun Wadekarb316e242015-05-19 16:48:04 +053096 msr actlr_el3, x0
Steven Kaod417cea2017-06-14 14:02:23 +080097 mrs x0, actlr_el2
Varun Wadekarc9bd0aa2018-06-07 11:21:02 -070098 mov x1, #ACTLR_ELx_ENABLE_ALL_ACCESS
Steven Kaod417cea2017-06-14 14:02:23 +080099 orr x0, x0, x1
Varun Wadekarb316e242015-05-19 16:48:04 +0530100 msr actlr_el2, x0
101 isb
Varun Wadekarb316e242015-05-19 16:48:04 +0530102
103 /* --------------------------------
104 * Enable the cycle count register
105 * --------------------------------
106 */
Varun Wadekarb24dea92015-09-22 13:33:56 +05301071: mrs x0, pmcr_el0
Varun Wadekarb316e242015-05-19 16:48:04 +0530108 ubfx x0, x0, #11, #5 // read PMCR.N field
109 mov x1, #1
110 lsl x0, x1, x0
111 sub x0, x0, #1 // mask of event counters
112 orr x0, x0, #0x80000000 // disable overflow intrs
113 msr pmintenclr_el1, x0
114 msr pmuserenr_el0, x1 // enable user mode access
115
116 /* ----------------------------------------------------------------
117 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count
118 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ
119 * registers from EL0.
120 * ----------------------------------------------------------------
121 */
122 mrs x0, cntkctl_el1
123 orr x0, x0, #EL0VCTEN_BIT
124 msr cntkctl_el1, x0
125.endm
126
127 /* -----------------------------------------------------
Varun Wadekarcb2dd3a2023-04-25 14:58:33 +0100128 * bool plat_is_my_cpu_primary(void);
Varun Wadekarb316e242015-05-19 16:48:04 +0530129 *
130 * This function checks if this is the Primary CPU
Varun Wadekarcb2dd3a2023-04-25 14:58:33 +0100131 *
132 * Registers clobbered: x0, x1
Varun Wadekarb316e242015-05-19 16:48:04 +0530133 * -----------------------------------------------------
134 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530135func plat_is_my_cpu_primary
136 mrs x0, mpidr_el1
Varun Wadekarcb2dd3a2023-04-25 14:58:33 +0100137 adr x1, tegra_primary_cpu_mpid
138 ldr x1, [x1]
139 cmp x0, x1
Varun Wadekarb316e242015-05-19 16:48:04 +0530140 cset x0, eq
141 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530142endfunc plat_is_my_cpu_primary
Varun Wadekarb316e242015-05-19 16:48:04 +0530143
Varun Wadekarfa99b222017-08-23 16:02:06 -0700144 /* ----------------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530145 * unsigned int plat_my_core_pos(void);
146 *
Varun Wadekarfa99b222017-08-23 16:02:06 -0700147 * result: CorePos = CoreId + (ClusterId * cpus per cluster)
Kalyani Chidambaram7f8d8482018-10-03 17:00:17 -0700148 * Registers clobbered: x0, x8
Varun Wadekarfa99b222017-08-23 16:02:06 -0700149 * ----------------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530150 */
151func plat_my_core_pos
Kalyani Chidambaram7f8d8482018-10-03 17:00:17 -0700152 mov x8, x30
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530153 mrs x0, mpidr_el1
Kalyani Chidambaram7f8d8482018-10-03 17:00:17 -0700154 bl plat_core_pos_by_mpidr
155 ret x8
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530156endfunc plat_my_core_pos
157
158 /* -----------------------------------------------------
159 * unsigned long plat_get_my_entrypoint (void);
160 *
161 * Main job of this routine is to distinguish between
162 * a cold and warm boot. If the tegra_sec_entry_point for
163 * this CPU is present, then it's a warm boot.
Varun Wadekarb316e242015-05-19 16:48:04 +0530164 *
Varun Wadekarb316e242015-05-19 16:48:04 +0530165 * -----------------------------------------------------
166 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530167func plat_get_my_entrypoint
168 adr x1, tegra_sec_entry_point
169 ldr x0, [x1]
Varun Wadekarb316e242015-05-19 16:48:04 +0530170 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530171endfunc plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530172
173 /* -----------------------------------------------------
174 * void plat_secondary_cold_boot_setup (void);
175 *
176 * This function performs any platform specific actions
177 * needed for a secondary cpu after a cold reset. Right
178 * now this is a stub function.
179 * -----------------------------------------------------
180 */
181func plat_secondary_cold_boot_setup
182 mov x0, #0
183 ret
184endfunc plat_secondary_cold_boot_setup
185
Varun Wadekarb316e242015-05-19 16:48:04 +0530186 /* --------------------------------------------------------
187 * void platform_mem_init (void);
188 *
189 * Any memory init, relocation to be done before the
190 * platform boots. Called very early in the boot process.
191 * --------------------------------------------------------
192 */
193func platform_mem_init
194 mov x0, #0
195 ret
196endfunc platform_mem_init
197
Varun Wadekarb316e242015-05-19 16:48:04 +0530198 /* ---------------------------------------------------
199 * Function to handle a platform reset and store
200 * input parameters passed by BL2.
201 * ---------------------------------------------------
202 */
203func plat_reset_handler
204
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700205 /* ----------------------------------------------------
206 * Verify if we are running from BL31_BASE address
207 * ----------------------------------------------------
208 */
209 adr x18, bl31_entrypoint
210 mov x17, #BL31_BASE
211 cmp x18, x17
212 b.eq 1f
213
214 /* ----------------------------------------------------
215 * Copy the entire BL31 code to BL31_BASE if we are not
216 * running from it already
217 * ----------------------------------------------------
218 */
219 mov x0, x17
220 mov x1, x18
anzhouc9f29532020-08-04 22:05:19 +0800221 adr x2, __RELA_END__
222 sub x2, x2, x18
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700223_loop16:
224 cmp x2, #16
Douglas Raillard2bb9f472017-03-20 10:38:29 +0000225 b.lo _loop1
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700226 ldp x3, x4, [x1], #16
227 stp x3, x4, [x0], #16
228 sub x2, x2, #16
229 b _loop16
230 /* copy byte per byte */
231_loop1:
232 cbz x2, _end
233 ldrb w3, [x1], #1
234 strb w3, [x0], #1
235 subs x2, x2, #1
236 b.ne _loop1
237
238 /* ----------------------------------------------------
239 * Jump to BL31_BASE and start execution again
240 * ----------------------------------------------------
241 */
242_end: mov x0, x20
243 mov x1, x21
244 br x17
2451:
246
Varun Wadekarb316e242015-05-19 16:48:04 +0530247 /* -----------------------------------
248 * derive and save the phys_base addr
249 * -----------------------------------
250 */
251 adr x17, tegra_bl31_phys_base
252 ldr x18, [x17]
253 cbnz x18, 1f
254 adr x18, bl31_entrypoint
255 str x18, [x17]
256
Varun Wadekarcb2dd3a2023-04-25 14:58:33 +0100257 /* -----------------------------------
258 * save the boot CPU MPID value
259 * -----------------------------------
260 */
261 mrs x0, mpidr_el1
262 adr x1, tegra_primary_cpu_mpid
263 str x0, [x1]
264
Varun Wadekarb316e242015-05-19 16:48:04 +05302651: cpu_init_common
266
267 ret
268endfunc plat_reset_handler
269
Varun Wadekarad2d5f32018-11-27 15:47:26 -0800270 /* ------------------------------------------------------
271 * int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
272 *
273 * This function implements a part of the critical
274 * interface between the psci generic layer and the
275 * platform that allows the former to query the platform
276 * to convert an MPIDR to a unique linear index. An error
277 * code (-1) is returned in case the MPIDR is invalid.
278 *
279 * Clobbers: x0-x3
280 * ------------------------------------------------------
281 */
282func plat_core_pos_by_mpidr
283 lsr x1, x0, #MPIDR_AFF0_SHIFT
284 and x1, x1, #MPIDR_AFFLVL_MASK /* core id */
285 lsr x2, x0, #MPIDR_AFF1_SHIFT
286 and x2, x2, #MPIDR_AFFLVL_MASK /* cluster id */
287
288 /* core_id >= PLATFORM_MAX_CPUS_PER_CLUSTER */
289 mov x0, #-1
290 cmp x1, #(PLATFORM_MAX_CPUS_PER_CLUSTER - 1)
291 b.gt 1f
292
293 /* cluster_id >= PLATFORM_CLUSTER_COUNT */
294 cmp x2, #(PLATFORM_CLUSTER_COUNT - 1)
295 b.gt 1f
296
297 /* CorePos = CoreId + (ClusterId * cpus per cluster) */
298 mov x3, #PLATFORM_MAX_CPUS_PER_CLUSTER
299 mul x3, x3, x2
300 add x0, x1, x3
301
3021:
303 ret
304endfunc plat_core_pos_by_mpidr
305
Varun Wadekarb316e242015-05-19 16:48:04 +0530306 /* ----------------------------------------
307 * Secure entrypoint function for CPU boot
308 * ----------------------------------------
309 */
Julius Wernerb4c75e92017-08-01 15:16:36 -0700310func tegra_secure_entrypoint _align=6
Varun Wadekarb316e242015-05-19 16:48:04 +0530311
312#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
313
Harvey Hsieh6dc0d762017-04-24 19:35:51 +0800314 /* --------------------------------------------------------
315 * Skip the invalidate BTB workaround for Tegra210B01 SKUs.
316 * --------------------------------------------------------
317 */
318 mov x0, #TEGRA_MISC_BASE
319 add x0, x0, #HARDWARE_REVISION_OFFSET
320 ldr w1, [x0]
321 lsr w1, w1, #CHIP_ID_SHIFT
322 and w1, w1, #CHIP_ID_MASK
323 cmp w1, #TEGRA_CHIPID_TEGRA21 /* T210? */
324 b.ne 2f
325 ldr w1, [x0]
326 lsr w1, w1, #MAJOR_VERSION_SHIFT
327 and w1, w1, #MAJOR_VERSION_MASK
328 cmp w1, #0x02 /* T210 B01? */
329 b.eq 2f
330
Varun Wadekarb316e242015-05-19 16:48:04 +0530331 /* -------------------------------------------------------
332 * Invalidate BTB along with I$ to remove any stale
333 * entries from the branch predictor array.
334 * -------------------------------------------------------
335 */
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100336 mrs x0, CORTEX_A57_CPUACTLR_EL1
Varun Wadekarb316e242015-05-19 16:48:04 +0530337 orr x0, x0, #1
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100338 msr CORTEX_A57_CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */
Varun Wadekarb316e242015-05-19 16:48:04 +0530339 dsb sy
340 isb
341 ic iallu /* actual invalidate */
342 dsb sy
343 isb
344
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100345 mrs x0, CORTEX_A57_CPUACTLR_EL1
Varun Wadekarb316e242015-05-19 16:48:04 +0530346 bic x0, x0, #1
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100347 msr CORTEX_A57_CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */
Varun Wadekarb316e242015-05-19 16:48:04 +0530348 dsb sy
349 isb
350
351 .rept 7
352 nop /* wait */
353 .endr
354
355 /* -----------------------------------------------
356 * Extract OSLK bit and check if it is '1'. This
357 * bit remains '0' for A53 on warm-resets. If '1',
358 * turn off regional clock gating and request warm
359 * reset.
360 * -----------------------------------------------
361 */
362 mrs x0, oslsr_el1
363 and x0, x0, #2
364 mrs x1, mpidr_el1
365 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */
366 b.eq restore_oslock
367 mov x0, xzr
368 msr oslar_el1, x0 /* os lock stays 0 across warm reset */
369 mov x3, #3
370 movz x4, #0x8000, lsl #48
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100371 msr CORTEX_A57_CPUACTLR_EL1, x4 /* turn off RCG */
Varun Wadekarb316e242015-05-19 16:48:04 +0530372 isb
373 msr rmr_el3, x3 /* request warm reset */
374 isb
375 dsb sy
3761: wfi
377 b 1b
378
379 /* --------------------------------------------------
380 * These nops are here so that speculative execution
381 * won't harm us before we are done with warm reset.
382 * --------------------------------------------------
383 */
384 .rept 65
385 nop
386 .endr
Harvey Hsieh6dc0d762017-04-24 19:35:51 +08003872:
Varun Wadekarb316e242015-05-19 16:48:04 +0530388 /* --------------------------------------------------
389 * Do not insert instructions here
390 * --------------------------------------------------
391 */
392#endif
393
394 /* --------------------------------------------------
395 * Restore OS Lock bit
396 * --------------------------------------------------
397 */
398restore_oslock:
399 mov x0, #1
400 msr oslar_el1, x0
401
Varun Wadekarb316e242015-05-19 16:48:04 +0530402 /* --------------------------------------------------
403 * Get secure world's entry point and jump to it
404 * --------------------------------------------------
405 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530406 bl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530407 br x0
408endfunc tegra_secure_entrypoint
409
410 .data
411 .align 3
412
413 /* --------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530414 * CPU Secure entry point - resume from suspend
Varun Wadekarb316e242015-05-19 16:48:04 +0530415 * --------------------------------------------------
416 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530417tegra_sec_entry_point:
Varun Wadekarb316e242015-05-19 16:48:04 +0530418 .quad 0
Varun Wadekarb316e242015-05-19 16:48:04 +0530419
420 /* --------------------------------------------------
421 * NS world's cold boot entry point
422 * --------------------------------------------------
423 */
424ns_image_entrypoint:
425 .quad 0
426
427 /* --------------------------------------------------
428 * BL31's physical base address
429 * --------------------------------------------------
430 */
431tegra_bl31_phys_base:
432 .quad 0
Varun Wadekard2014c62015-10-29 10:37:28 +0530433
434 /* --------------------------------------------------
435 * UART controller base for console init
436 * --------------------------------------------------
437 */
438tegra_console_base:
439 .quad 0
Varun Wadekarcb2dd3a2023-04-25 14:58:33 +0100440
441 /* --------------------------------------------------
442 * MPID value for the boot CPU
443 * --------------------------------------------------
444 */
445tegra_primary_cpu_mpid:
446 .quad 0