blob: 6c8c4f018defc1667a436830ee35cf7027dd85e3 [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 Wadekara78bb1b2015-08-07 10:03:00 +0530128 * unsigned int plat_is_my_cpu_primary(void);
Varun Wadekarb316e242015-05-19 16:48:04 +0530129 *
130 * This function checks if this is the Primary CPU
131 * -----------------------------------------------------
132 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530133func plat_is_my_cpu_primary
134 mrs x0, mpidr_el1
Varun Wadekarb316e242015-05-19 16:48:04 +0530135 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
136 cmp x0, #TEGRA_PRIMARY_CPU
137 cset x0, eq
138 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530139endfunc plat_is_my_cpu_primary
Varun Wadekarb316e242015-05-19 16:48:04 +0530140
Varun Wadekarfa99b222017-08-23 16:02:06 -0700141 /* ----------------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530142 * unsigned int plat_my_core_pos(void);
143 *
Varun Wadekarfa99b222017-08-23 16:02:06 -0700144 * result: CorePos = CoreId + (ClusterId * cpus per cluster)
Kalyani Chidambaram7f8d8482018-10-03 17:00:17 -0700145 * Registers clobbered: x0, x8
Varun Wadekarfa99b222017-08-23 16:02:06 -0700146 * ----------------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530147 */
148func plat_my_core_pos
Kalyani Chidambaram7f8d8482018-10-03 17:00:17 -0700149 mov x8, x30
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530150 mrs x0, mpidr_el1
Kalyani Chidambaram7f8d8482018-10-03 17:00:17 -0700151 bl plat_core_pos_by_mpidr
152 ret x8
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530153endfunc plat_my_core_pos
154
155 /* -----------------------------------------------------
156 * unsigned long plat_get_my_entrypoint (void);
157 *
158 * Main job of this routine is to distinguish between
159 * a cold and warm boot. If the tegra_sec_entry_point for
160 * this CPU is present, then it's a warm boot.
Varun Wadekarb316e242015-05-19 16:48:04 +0530161 *
Varun Wadekarb316e242015-05-19 16:48:04 +0530162 * -----------------------------------------------------
163 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530164func plat_get_my_entrypoint
165 adr x1, tegra_sec_entry_point
166 ldr x0, [x1]
Varun Wadekarb316e242015-05-19 16:48:04 +0530167 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530168endfunc plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530169
170 /* -----------------------------------------------------
171 * void plat_secondary_cold_boot_setup (void);
172 *
173 * This function performs any platform specific actions
174 * needed for a secondary cpu after a cold reset. Right
175 * now this is a stub function.
176 * -----------------------------------------------------
177 */
178func plat_secondary_cold_boot_setup
179 mov x0, #0
180 ret
181endfunc plat_secondary_cold_boot_setup
182
Varun Wadekarb316e242015-05-19 16:48:04 +0530183 /* --------------------------------------------------------
184 * void platform_mem_init (void);
185 *
186 * Any memory init, relocation to be done before the
187 * platform boots. Called very early in the boot process.
188 * --------------------------------------------------------
189 */
190func platform_mem_init
191 mov x0, #0
192 ret
193endfunc platform_mem_init
194
Varun Wadekarb316e242015-05-19 16:48:04 +0530195 /* ---------------------------------------------------
196 * Function to handle a platform reset and store
197 * input parameters passed by BL2.
198 * ---------------------------------------------------
199 */
200func plat_reset_handler
201
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700202 /* ----------------------------------------------------
203 * Verify if we are running from BL31_BASE address
204 * ----------------------------------------------------
205 */
206 adr x18, bl31_entrypoint
207 mov x17, #BL31_BASE
208 cmp x18, x17
209 b.eq 1f
210
211 /* ----------------------------------------------------
212 * Copy the entire BL31 code to BL31_BASE if we are not
213 * running from it already
214 * ----------------------------------------------------
215 */
216 mov x0, x17
217 mov x1, x18
anzhouc9f29532020-08-04 22:05:19 +0800218 adr x2, __RELA_END__
219 sub x2, x2, x18
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700220_loop16:
221 cmp x2, #16
Douglas Raillard2bb9f472017-03-20 10:38:29 +0000222 b.lo _loop1
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700223 ldp x3, x4, [x1], #16
224 stp x3, x4, [x0], #16
225 sub x2, x2, #16
226 b _loop16
227 /* copy byte per byte */
228_loop1:
229 cbz x2, _end
230 ldrb w3, [x1], #1
231 strb w3, [x0], #1
232 subs x2, x2, #1
233 b.ne _loop1
234
235 /* ----------------------------------------------------
236 * Jump to BL31_BASE and start execution again
237 * ----------------------------------------------------
238 */
239_end: mov x0, x20
240 mov x1, x21
241 br x17
2421:
243
Varun Wadekarb316e242015-05-19 16:48:04 +0530244 /* -----------------------------------
245 * derive and save the phys_base addr
246 * -----------------------------------
247 */
248 adr x17, tegra_bl31_phys_base
249 ldr x18, [x17]
250 cbnz x18, 1f
251 adr x18, bl31_entrypoint
252 str x18, [x17]
253
2541: cpu_init_common
255
256 ret
257endfunc plat_reset_handler
258
Varun Wadekarad2d5f32018-11-27 15:47:26 -0800259 /* ------------------------------------------------------
260 * int32_t plat_core_pos_by_mpidr(u_register_t mpidr)
261 *
262 * This function implements a part of the critical
263 * interface between the psci generic layer and the
264 * platform that allows the former to query the platform
265 * to convert an MPIDR to a unique linear index. An error
266 * code (-1) is returned in case the MPIDR is invalid.
267 *
268 * Clobbers: x0-x3
269 * ------------------------------------------------------
270 */
271func plat_core_pos_by_mpidr
272 lsr x1, x0, #MPIDR_AFF0_SHIFT
273 and x1, x1, #MPIDR_AFFLVL_MASK /* core id */
274 lsr x2, x0, #MPIDR_AFF1_SHIFT
275 and x2, x2, #MPIDR_AFFLVL_MASK /* cluster id */
276
277 /* core_id >= PLATFORM_MAX_CPUS_PER_CLUSTER */
278 mov x0, #-1
279 cmp x1, #(PLATFORM_MAX_CPUS_PER_CLUSTER - 1)
280 b.gt 1f
281
282 /* cluster_id >= PLATFORM_CLUSTER_COUNT */
283 cmp x2, #(PLATFORM_CLUSTER_COUNT - 1)
284 b.gt 1f
285
286 /* CorePos = CoreId + (ClusterId * cpus per cluster) */
287 mov x3, #PLATFORM_MAX_CPUS_PER_CLUSTER
288 mul x3, x3, x2
289 add x0, x1, x3
290
2911:
292 ret
293endfunc plat_core_pos_by_mpidr
294
Varun Wadekarb316e242015-05-19 16:48:04 +0530295 /* ----------------------------------------
296 * Secure entrypoint function for CPU boot
297 * ----------------------------------------
298 */
Julius Wernerb4c75e92017-08-01 15:16:36 -0700299func tegra_secure_entrypoint _align=6
Varun Wadekarb316e242015-05-19 16:48:04 +0530300
301#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
302
Harvey Hsieh6dc0d762017-04-24 19:35:51 +0800303 /* --------------------------------------------------------
304 * Skip the invalidate BTB workaround for Tegra210B01 SKUs.
305 * --------------------------------------------------------
306 */
307 mov x0, #TEGRA_MISC_BASE
308 add x0, x0, #HARDWARE_REVISION_OFFSET
309 ldr w1, [x0]
310 lsr w1, w1, #CHIP_ID_SHIFT
311 and w1, w1, #CHIP_ID_MASK
312 cmp w1, #TEGRA_CHIPID_TEGRA21 /* T210? */
313 b.ne 2f
314 ldr w1, [x0]
315 lsr w1, w1, #MAJOR_VERSION_SHIFT
316 and w1, w1, #MAJOR_VERSION_MASK
317 cmp w1, #0x02 /* T210 B01? */
318 b.eq 2f
319
Varun Wadekarb316e242015-05-19 16:48:04 +0530320 /* -------------------------------------------------------
321 * Invalidate BTB along with I$ to remove any stale
322 * entries from the branch predictor array.
323 * -------------------------------------------------------
324 */
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100325 mrs x0, CORTEX_A57_CPUACTLR_EL1
Varun Wadekarb316e242015-05-19 16:48:04 +0530326 orr x0, x0, #1
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100327 msr CORTEX_A57_CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */
Varun Wadekarb316e242015-05-19 16:48:04 +0530328 dsb sy
329 isb
330 ic iallu /* actual invalidate */
331 dsb sy
332 isb
333
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100334 mrs x0, CORTEX_A57_CPUACTLR_EL1
Varun Wadekarb316e242015-05-19 16:48:04 +0530335 bic x0, x0, #1
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100336 msr CORTEX_A57_CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */
Varun Wadekarb316e242015-05-19 16:48:04 +0530337 dsb sy
338 isb
339
340 .rept 7
341 nop /* wait */
342 .endr
343
344 /* -----------------------------------------------
345 * Extract OSLK bit and check if it is '1'. This
346 * bit remains '0' for A53 on warm-resets. If '1',
347 * turn off regional clock gating and request warm
348 * reset.
349 * -----------------------------------------------
350 */
351 mrs x0, oslsr_el1
352 and x0, x0, #2
353 mrs x1, mpidr_el1
354 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */
355 b.eq restore_oslock
356 mov x0, xzr
357 msr oslar_el1, x0 /* os lock stays 0 across warm reset */
358 mov x3, #3
359 movz x4, #0x8000, lsl #48
Eleanor Bonnici91b11c32017-08-10 14:46:26 +0100360 msr CORTEX_A57_CPUACTLR_EL1, x4 /* turn off RCG */
Varun Wadekarb316e242015-05-19 16:48:04 +0530361 isb
362 msr rmr_el3, x3 /* request warm reset */
363 isb
364 dsb sy
3651: wfi
366 b 1b
367
368 /* --------------------------------------------------
369 * These nops are here so that speculative execution
370 * won't harm us before we are done with warm reset.
371 * --------------------------------------------------
372 */
373 .rept 65
374 nop
375 .endr
Harvey Hsieh6dc0d762017-04-24 19:35:51 +08003762:
Varun Wadekarb316e242015-05-19 16:48:04 +0530377 /* --------------------------------------------------
378 * Do not insert instructions here
379 * --------------------------------------------------
380 */
381#endif
382
383 /* --------------------------------------------------
384 * Restore OS Lock bit
385 * --------------------------------------------------
386 */
387restore_oslock:
388 mov x0, #1
389 msr oslar_el1, x0
390
Varun Wadekarb316e242015-05-19 16:48:04 +0530391 /* --------------------------------------------------
392 * Get secure world's entry point and jump to it
393 * --------------------------------------------------
394 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530395 bl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530396 br x0
397endfunc tegra_secure_entrypoint
398
399 .data
400 .align 3
401
402 /* --------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530403 * CPU Secure entry point - resume from suspend
Varun Wadekarb316e242015-05-19 16:48:04 +0530404 * --------------------------------------------------
405 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530406tegra_sec_entry_point:
Varun Wadekarb316e242015-05-19 16:48:04 +0530407 .quad 0
Varun Wadekarb316e242015-05-19 16:48:04 +0530408
409 /* --------------------------------------------------
410 * NS world's cold boot entry point
411 * --------------------------------------------------
412 */
413ns_image_entrypoint:
414 .quad 0
415
416 /* --------------------------------------------------
417 * BL31's physical base address
418 * --------------------------------------------------
419 */
420tegra_bl31_phys_base:
421 .quad 0
Varun Wadekard2014c62015-10-29 10:37:28 +0530422
423 /* --------------------------------------------------
424 * UART controller base for console init
425 * --------------------------------------------------
426 */
427tegra_console_base:
428 .quad 0