blob: 2b3901a24512b7c6d2edfafef6122bc714ef36d5 [file] [log] [blame]
Varun Wadekarb316e242015-05-19 16:48:04 +05301/*
2 * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30#include <arch.h>
31#include <asm_macros.S>
32#include <assert_macros.S>
33#include <cpu_macros.S>
34#include <cortex_a57.h>
35#include <cortex_a53.h>
Varun Wadekar25e658e2016-04-26 11:38:38 -070036#include <platform_def.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053037#include <tegra_def.h>
38
Varun Wadekarb24dea92015-09-22 13:33:56 +053039#define MIDR_PN_CORTEX_A57 0xD07
40
41/*******************************************************************************
42 * Implementation defined ACTLR_EL3 bit definitions
43 ******************************************************************************/
44#define ACTLR_EL3_L2ACTLR_BIT (1 << 6)
45#define ACTLR_EL3_L2ECTLR_BIT (1 << 5)
46#define ACTLR_EL3_L2CTLR_BIT (1 << 4)
47#define ACTLR_EL3_CPUECTLR_BIT (1 << 1)
48#define ACTLR_EL3_CPUACTLR_BIT (1 << 0)
49#define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \
50 ACTLR_EL3_L2ECTLR_BIT | \
51 ACTLR_EL3_L2CTLR_BIT | \
52 ACTLR_EL3_CPUECTLR_BIT | \
53 ACTLR_EL3_CPUACTLR_BIT)
54
Varun Wadekarb316e242015-05-19 16:48:04 +053055 /* Global functions */
Varun Wadekara78bb1b2015-08-07 10:03:00 +053056 .globl plat_is_my_cpu_primary
57 .globl plat_my_core_pos
58 .globl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +053059 .globl plat_secondary_cold_boot_setup
60 .globl platform_mem_init
61 .globl plat_crash_console_init
62 .globl plat_crash_console_putc
63 .globl tegra_secure_entrypoint
64 .globl plat_reset_handler
65
66 /* Global variables */
Varun Wadekara78bb1b2015-08-07 10:03:00 +053067 .globl tegra_sec_entry_point
Varun Wadekarb316e242015-05-19 16:48:04 +053068 .globl ns_image_entrypoint
69 .globl tegra_bl31_phys_base
Varun Wadekard2014c62015-10-29 10:37:28 +053070 .globl tegra_console_base
Varun Wadekar69ce1012016-05-12 13:43:33 -070071 .globl tegra_enable_l2_ecc_parity_prot
Varun Wadekarb316e242015-05-19 16:48:04 +053072
73 /* ---------------------
74 * Common CPU init code
75 * ---------------------
76 */
77.macro cpu_init_common
78
Varun Wadekarb24dea92015-09-22 13:33:56 +053079 /* ------------------------------------------------
Varun Wadekar69ce1012016-05-12 13:43:33 -070080 * We enable procesor retention, L2/CPUECTLR NS
81 * access and ECC/Parity protection for A57 CPUs
Varun Wadekarb24dea92015-09-22 13:33:56 +053082 * ------------------------------------------------
83 */
84 mrs x0, midr_el1
85 mov x1, #(MIDR_PN_MASK << MIDR_PN_SHIFT)
86 and x0, x0, x1
87 lsr x0, x0, #MIDR_PN_SHIFT
88 cmp x0, #MIDR_PN_CORTEX_A57
89 b.ne 1f
90
Varun Wadekar4e9c2312015-08-21 15:56:02 +053091 /* ---------------------------
92 * Enable processor retention
93 * ---------------------------
Varun Wadekar69ce1012016-05-12 13:43:33 -070094 */
Varun Wadekar4e9c2312015-08-21 15:56:02 +053095 mrs x0, L2ECTLR_EL1
96 mov x1, #RETENTION_ENTRY_TICKS_512 << L2ECTLR_RET_CTRL_SHIFT
97 bic x0, x0, #L2ECTLR_RET_CTRL_MASK
98 orr x0, x0, x1
99 msr L2ECTLR_EL1, x0
100 isb
Varun Wadekar4e9c2312015-08-21 15:56:02 +0530101
Varun Wadekar4e9c2312015-08-21 15:56:02 +0530102 mrs x0, CPUECTLR_EL1
103 mov x1, #RETENTION_ENTRY_TICKS_512 << CPUECTLR_CPU_RET_CTRL_SHIFT
104 bic x0, x0, #CPUECTLR_CPU_RET_CTRL_MASK
105 orr x0, x0, x1
106 msr CPUECTLR_EL1, x0
107 isb
Varun Wadekar4e9c2312015-08-21 15:56:02 +0530108
Varun Wadekarb316e242015-05-19 16:48:04 +0530109 /* -------------------------------------------------------
110 * Enable L2 and CPU ECTLR RW access from non-secure world
111 * -------------------------------------------------------
Varun Wadekar69ce1012016-05-12 13:43:33 -0700112 */
Varun Wadekarb316e242015-05-19 16:48:04 +0530113 mov x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
114 msr actlr_el3, x0
115 msr actlr_el2, x0
116 isb
Varun Wadekarb316e242015-05-19 16:48:04 +0530117
Varun Wadekar69ce1012016-05-12 13:43:33 -0700118 /* -------------------------------------------------------
119 * Enable L2 ECC and Parity Protection
120 * -------------------------------------------------------
121 */
122 adr x0, tegra_enable_l2_ecc_parity_prot
123 ldr x0, [x0]
124 cbz x0, 1f
125 mrs x0, L2CTLR_EL1
126 and x1, x0, #L2_ECC_PARITY_PROTECTION_BIT
127 cbnz x1, 1f
128 orr x0, x0, #L2_ECC_PARITY_PROTECTION_BIT
129 msr L2CTLR_EL1, x0
130 isb
131
Varun Wadekarb316e242015-05-19 16:48:04 +0530132 /* --------------------------------
133 * Enable the cycle count register
134 * --------------------------------
135 */
Varun Wadekarb24dea92015-09-22 13:33:56 +05301361: mrs x0, pmcr_el0
Varun Wadekarb316e242015-05-19 16:48:04 +0530137 ubfx x0, x0, #11, #5 // read PMCR.N field
138 mov x1, #1
139 lsl x0, x1, x0
140 sub x0, x0, #1 // mask of event counters
141 orr x0, x0, #0x80000000 // disable overflow intrs
142 msr pmintenclr_el1, x0
143 msr pmuserenr_el0, x1 // enable user mode access
144
145 /* ----------------------------------------------------------------
146 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count
147 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ
148 * registers from EL0.
149 * ----------------------------------------------------------------
150 */
151 mrs x0, cntkctl_el1
152 orr x0, x0, #EL0VCTEN_BIT
153 msr cntkctl_el1, x0
154.endm
155
156 /* -----------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530157 * unsigned int plat_is_my_cpu_primary(void);
Varun Wadekarb316e242015-05-19 16:48:04 +0530158 *
159 * This function checks if this is the Primary CPU
160 * -----------------------------------------------------
161 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530162func plat_is_my_cpu_primary
163 mrs x0, mpidr_el1
Varun Wadekarb316e242015-05-19 16:48:04 +0530164 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
165 cmp x0, #TEGRA_PRIMARY_CPU
166 cset x0, eq
167 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530168endfunc plat_is_my_cpu_primary
Varun Wadekarb316e242015-05-19 16:48:04 +0530169
170 /* -----------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530171 * unsigned int plat_my_core_pos(void);
172 *
173 * result: CorePos = CoreId + (ClusterId << 2)
174 * -----------------------------------------------------
175 */
176func plat_my_core_pos
177 mrs x0, mpidr_el1
178 and x1, x0, #MPIDR_CPU_MASK
179 and x0, x0, #MPIDR_CLUSTER_MASK
180 add x0, x1, x0, LSR #6
181 ret
182endfunc plat_my_core_pos
183
184 /* -----------------------------------------------------
185 * unsigned long plat_get_my_entrypoint (void);
186 *
187 * Main job of this routine is to distinguish between
188 * a cold and warm boot. If the tegra_sec_entry_point for
189 * this CPU is present, then it's a warm boot.
Varun Wadekarb316e242015-05-19 16:48:04 +0530190 *
Varun Wadekarb316e242015-05-19 16:48:04 +0530191 * -----------------------------------------------------
192 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530193func plat_get_my_entrypoint
194 adr x1, tegra_sec_entry_point
195 ldr x0, [x1]
Varun Wadekarb316e242015-05-19 16:48:04 +0530196 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530197endfunc plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530198
199 /* -----------------------------------------------------
Varun Wadekar39f87d12015-09-22 13:45:07 +0530200 * int platform_get_core_pos(int mpidr);
201 *
202 * With this function: CorePos = (ClusterId * 4) +
203 * CoreId
204 * -----------------------------------------------------
205 */
206func platform_get_core_pos
207 and x1, x0, #MPIDR_CPU_MASK
208 and x0, x0, #MPIDR_CLUSTER_MASK
209 add x0, x1, x0, LSR #6
210 ret
211endfunc platform_get_core_pos
212
213 /* -----------------------------------------------------
Varun Wadekarb316e242015-05-19 16:48:04 +0530214 * void plat_secondary_cold_boot_setup (void);
215 *
216 * This function performs any platform specific actions
217 * needed for a secondary cpu after a cold reset. Right
218 * now this is a stub function.
219 * -----------------------------------------------------
220 */
221func plat_secondary_cold_boot_setup
222 mov x0, #0
223 ret
224endfunc plat_secondary_cold_boot_setup
225
Varun Wadekarb316e242015-05-19 16:48:04 +0530226 /* --------------------------------------------------------
227 * void platform_mem_init (void);
228 *
229 * Any memory init, relocation to be done before the
230 * platform boots. Called very early in the boot process.
231 * --------------------------------------------------------
232 */
233func platform_mem_init
234 mov x0, #0
235 ret
236endfunc platform_mem_init
237
238 /* ---------------------------------------------
239 * int plat_crash_console_init(void)
240 * Function to initialize the crash console
241 * without a C Runtime to print crash report.
Juan Castilloe7ae6db2015-11-26 14:52:15 +0000242 * Clobber list : x0 - x4
Varun Wadekarb316e242015-05-19 16:48:04 +0530243 * ---------------------------------------------
244 */
245func plat_crash_console_init
Varun Wadekar4e6ae182017-04-04 13:40:12 -0700246 mov x0, #0
247 adr x1, tegra_console_base
248 ldr x1, [x1]
249 cbz x1, 1f
250 mov w0, #1
2511: ret
Varun Wadekarb316e242015-05-19 16:48:04 +0530252endfunc plat_crash_console_init
253
254 /* ---------------------------------------------
255 * int plat_crash_console_putc(void)
256 * Function to print a character on the crash
257 * console without a C Runtime.
258 * Clobber list : x1, x2
259 * ---------------------------------------------
260 */
261func plat_crash_console_putc
Varun Wadekard2014c62015-10-29 10:37:28 +0530262 adr x1, tegra_console_base
263 ldr x1, [x1]
Varun Wadekarb316e242015-05-19 16:48:04 +0530264 b console_core_putc
265endfunc plat_crash_console_putc
266
267 /* ---------------------------------------------------
268 * Function to handle a platform reset and store
269 * input parameters passed by BL2.
270 * ---------------------------------------------------
271 */
272func plat_reset_handler
273
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700274 /* ----------------------------------------------------
275 * Verify if we are running from BL31_BASE address
276 * ----------------------------------------------------
277 */
278 adr x18, bl31_entrypoint
279 mov x17, #BL31_BASE
280 cmp x18, x17
281 b.eq 1f
282
283 /* ----------------------------------------------------
284 * Copy the entire BL31 code to BL31_BASE if we are not
285 * running from it already
286 * ----------------------------------------------------
287 */
288 mov x0, x17
289 mov x1, x18
290 mov x2, #BL31_SIZE
291_loop16:
292 cmp x2, #16
Douglas Raillard2bb9f472017-03-20 10:38:29 +0000293 b.lo _loop1
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700294 ldp x3, x4, [x1], #16
295 stp x3, x4, [x0], #16
296 sub x2, x2, #16
297 b _loop16
298 /* copy byte per byte */
299_loop1:
300 cbz x2, _end
301 ldrb w3, [x1], #1
302 strb w3, [x0], #1
303 subs x2, x2, #1
304 b.ne _loop1
305
306 /* ----------------------------------------------------
307 * Jump to BL31_BASE and start execution again
308 * ----------------------------------------------------
309 */
310_end: mov x0, x20
311 mov x1, x21
312 br x17
3131:
314
Varun Wadekarb316e242015-05-19 16:48:04 +0530315 /* -----------------------------------
316 * derive and save the phys_base addr
317 * -----------------------------------
318 */
319 adr x17, tegra_bl31_phys_base
320 ldr x18, [x17]
321 cbnz x18, 1f
322 adr x18, bl31_entrypoint
323 str x18, [x17]
324
3251: cpu_init_common
326
327 ret
328endfunc plat_reset_handler
329
330 /* ----------------------------------------
331 * Secure entrypoint function for CPU boot
332 * ----------------------------------------
333 */
334 .align 6
335func tegra_secure_entrypoint
336
337#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
338
339 /* -------------------------------------------------------
340 * Invalidate BTB along with I$ to remove any stale
341 * entries from the branch predictor array.
342 * -------------------------------------------------------
343 */
344 mrs x0, CPUACTLR_EL1
345 orr x0, x0, #1
346 msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */
347 dsb sy
348 isb
349 ic iallu /* actual invalidate */
350 dsb sy
351 isb
352
353 mrs x0, CPUACTLR_EL1
354 bic x0, x0, #1
355 msr CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */
356 dsb sy
357 isb
358
359 .rept 7
360 nop /* wait */
361 .endr
362
363 /* -----------------------------------------------
364 * Extract OSLK bit and check if it is '1'. This
365 * bit remains '0' for A53 on warm-resets. If '1',
366 * turn off regional clock gating and request warm
367 * reset.
368 * -----------------------------------------------
369 */
370 mrs x0, oslsr_el1
371 and x0, x0, #2
372 mrs x1, mpidr_el1
373 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */
374 b.eq restore_oslock
375 mov x0, xzr
376 msr oslar_el1, x0 /* os lock stays 0 across warm reset */
377 mov x3, #3
378 movz x4, #0x8000, lsl #48
379 msr CPUACTLR_EL1, x4 /* turn off RCG */
380 isb
381 msr rmr_el3, x3 /* request warm reset */
382 isb
383 dsb sy
3841: wfi
385 b 1b
386
387 /* --------------------------------------------------
388 * These nops are here so that speculative execution
389 * won't harm us before we are done with warm reset.
390 * --------------------------------------------------
391 */
392 .rept 65
393 nop
394 .endr
395
396 /* --------------------------------------------------
397 * Do not insert instructions here
398 * --------------------------------------------------
399 */
400#endif
401
402 /* --------------------------------------------------
403 * Restore OS Lock bit
404 * --------------------------------------------------
405 */
406restore_oslock:
407 mov x0, #1
408 msr oslar_el1, x0
409
410 cpu_init_common
411
412 /* ---------------------------------------------------------------------
413 * The initial state of the Architectural feature trap register
414 * (CPTR_EL3) is unknown and it must be set to a known state. All
415 * feature traps are disabled. Some bits in this register are marked as
416 * Reserved and should not be modified.
417 *
418 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
419 * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
420 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
421 * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
422 * access to trace functionality is not supported, this bit is RES0.
423 * CPTR_EL3.TFP: This causes instructions that access the registers
424 * associated with Floating Point and Advanced SIMD execution to trap
425 * to EL3 when executed from any exception level, unless trapped to EL1
426 * or EL2.
427 * ---------------------------------------------------------------------
428 */
429 mrs x1, cptr_el3
430 bic w1, w1, #TCPAC_BIT
431 bic w1, w1, #TTA_BIT
432 bic w1, w1, #TFP_BIT
433 msr cptr_el3, x1
434
435 /* --------------------------------------------------
436 * Get secure world's entry point and jump to it
437 * --------------------------------------------------
438 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530439 bl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530440 br x0
441endfunc tegra_secure_entrypoint
442
443 .data
444 .align 3
445
446 /* --------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530447 * CPU Secure entry point - resume from suspend
Varun Wadekarb316e242015-05-19 16:48:04 +0530448 * --------------------------------------------------
449 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530450tegra_sec_entry_point:
Varun Wadekarb316e242015-05-19 16:48:04 +0530451 .quad 0
Varun Wadekarb316e242015-05-19 16:48:04 +0530452
453 /* --------------------------------------------------
454 * NS world's cold boot entry point
455 * --------------------------------------------------
456 */
457ns_image_entrypoint:
458 .quad 0
459
460 /* --------------------------------------------------
461 * BL31's physical base address
462 * --------------------------------------------------
463 */
464tegra_bl31_phys_base:
465 .quad 0
Varun Wadekard2014c62015-10-29 10:37:28 +0530466
467 /* --------------------------------------------------
468 * UART controller base for console init
469 * --------------------------------------------------
470 */
471tegra_console_base:
472 .quad 0
Varun Wadekar69ce1012016-05-12 13:43:33 -0700473
474 /* --------------------------------------------------
475 * Enable L2 ECC and Parity Protection
476 * --------------------------------------------------
477 */
478tegra_enable_l2_ecc_parity_prot:
479 .quad 0