blob: a57d1cb0a3109c6ce63ca9d8a07e6cf6c8990e16 [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 Wadekarb316e242015-05-19 16:48:04 +053071
72 /* ---------------------
73 * Common CPU init code
74 * ---------------------
75 */
76.macro cpu_init_common
77
Varun Wadekarb24dea92015-09-22 13:33:56 +053078 /* ------------------------------------------------
79 * We enable procesor retention and L2/CPUECTLR NS
80 * access for A57 CPUs only.
81 * ------------------------------------------------
82 */
83 mrs x0, midr_el1
84 mov x1, #(MIDR_PN_MASK << MIDR_PN_SHIFT)
85 and x0, x0, x1
86 lsr x0, x0, #MIDR_PN_SHIFT
87 cmp x0, #MIDR_PN_CORTEX_A57
88 b.ne 1f
89
Varun Wadekar4e9c2312015-08-21 15:56:02 +053090 /* ---------------------------
91 * Enable processor retention
92 * ---------------------------
93 */
94 mrs x0, L2ECTLR_EL1
95 mov x1, #RETENTION_ENTRY_TICKS_512 << L2ECTLR_RET_CTRL_SHIFT
96 bic x0, x0, #L2ECTLR_RET_CTRL_MASK
97 orr x0, x0, x1
98 msr L2ECTLR_EL1, x0
99 isb
Varun Wadekar4e9c2312015-08-21 15:56:02 +0530100
Varun Wadekar4e9c2312015-08-21 15:56:02 +0530101 mrs x0, CPUECTLR_EL1
102 mov x1, #RETENTION_ENTRY_TICKS_512 << CPUECTLR_CPU_RET_CTRL_SHIFT
103 bic x0, x0, #CPUECTLR_CPU_RET_CTRL_MASK
104 orr x0, x0, x1
105 msr CPUECTLR_EL1, x0
106 isb
Varun Wadekar4e9c2312015-08-21 15:56:02 +0530107
Varun Wadekarb316e242015-05-19 16:48:04 +0530108 /* -------------------------------------------------------
109 * Enable L2 and CPU ECTLR RW access from non-secure world
110 * -------------------------------------------------------
111 */
112 mov x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
113 msr actlr_el3, x0
114 msr actlr_el2, x0
115 isb
Varun Wadekarb316e242015-05-19 16:48:04 +0530116
117 /* --------------------------------
118 * Enable the cycle count register
119 * --------------------------------
120 */
Varun Wadekarb24dea92015-09-22 13:33:56 +05301211: mrs x0, pmcr_el0
Varun Wadekarb316e242015-05-19 16:48:04 +0530122 ubfx x0, x0, #11, #5 // read PMCR.N field
123 mov x1, #1
124 lsl x0, x1, x0
125 sub x0, x0, #1 // mask of event counters
126 orr x0, x0, #0x80000000 // disable overflow intrs
127 msr pmintenclr_el1, x0
128 msr pmuserenr_el0, x1 // enable user mode access
129
130 /* ----------------------------------------------------------------
131 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count
132 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ
133 * registers from EL0.
134 * ----------------------------------------------------------------
135 */
136 mrs x0, cntkctl_el1
137 orr x0, x0, #EL0VCTEN_BIT
138 msr cntkctl_el1, x0
139.endm
140
141 /* -----------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530142 * unsigned int plat_is_my_cpu_primary(void);
Varun Wadekarb316e242015-05-19 16:48:04 +0530143 *
144 * This function checks if this is the Primary CPU
145 * -----------------------------------------------------
146 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530147func plat_is_my_cpu_primary
148 mrs x0, mpidr_el1
Varun Wadekarb316e242015-05-19 16:48:04 +0530149 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
150 cmp x0, #TEGRA_PRIMARY_CPU
151 cset x0, eq
152 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530153endfunc plat_is_my_cpu_primary
Varun Wadekarb316e242015-05-19 16:48:04 +0530154
155 /* -----------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530156 * unsigned int plat_my_core_pos(void);
157 *
158 * result: CorePos = CoreId + (ClusterId << 2)
159 * -----------------------------------------------------
160 */
161func plat_my_core_pos
162 mrs x0, mpidr_el1
163 and x1, x0, #MPIDR_CPU_MASK
164 and x0, x0, #MPIDR_CLUSTER_MASK
165 add x0, x1, x0, LSR #6
166 ret
167endfunc plat_my_core_pos
168
169 /* -----------------------------------------------------
170 * unsigned long plat_get_my_entrypoint (void);
171 *
172 * Main job of this routine is to distinguish between
173 * a cold and warm boot. If the tegra_sec_entry_point for
174 * this CPU is present, then it's a warm boot.
Varun Wadekarb316e242015-05-19 16:48:04 +0530175 *
Varun Wadekarb316e242015-05-19 16:48:04 +0530176 * -----------------------------------------------------
177 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530178func plat_get_my_entrypoint
179 adr x1, tegra_sec_entry_point
180 ldr x0, [x1]
Varun Wadekarb316e242015-05-19 16:48:04 +0530181 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530182endfunc plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530183
184 /* -----------------------------------------------------
Varun Wadekar39f87d12015-09-22 13:45:07 +0530185 * int platform_get_core_pos(int mpidr);
186 *
187 * With this function: CorePos = (ClusterId * 4) +
188 * CoreId
189 * -----------------------------------------------------
190 */
191func platform_get_core_pos
192 and x1, x0, #MPIDR_CPU_MASK
193 and x0, x0, #MPIDR_CLUSTER_MASK
194 add x0, x1, x0, LSR #6
195 ret
196endfunc platform_get_core_pos
197
198 /* -----------------------------------------------------
Varun Wadekarb316e242015-05-19 16:48:04 +0530199 * void plat_secondary_cold_boot_setup (void);
200 *
201 * This function performs any platform specific actions
202 * needed for a secondary cpu after a cold reset. Right
203 * now this is a stub function.
204 * -----------------------------------------------------
205 */
206func plat_secondary_cold_boot_setup
207 mov x0, #0
208 ret
209endfunc plat_secondary_cold_boot_setup
210
Varun Wadekarb316e242015-05-19 16:48:04 +0530211 /* --------------------------------------------------------
212 * void platform_mem_init (void);
213 *
214 * Any memory init, relocation to be done before the
215 * platform boots. Called very early in the boot process.
216 * --------------------------------------------------------
217 */
218func platform_mem_init
219 mov x0, #0
220 ret
221endfunc platform_mem_init
222
223 /* ---------------------------------------------
224 * int plat_crash_console_init(void)
225 * Function to initialize the crash console
226 * without a C Runtime to print crash report.
Juan Castilloe7ae6db2015-11-26 14:52:15 +0000227 * Clobber list : x0 - x4
Varun Wadekarb316e242015-05-19 16:48:04 +0530228 * ---------------------------------------------
229 */
230func plat_crash_console_init
Varun Wadekard2014c62015-10-29 10:37:28 +0530231 adr x0, tegra_console_base
232 ldr x0, [x0]
Varun Wadekarb316e242015-05-19 16:48:04 +0530233 mov_imm x1, TEGRA_BOOT_UART_CLK_IN_HZ
234 mov_imm x2, TEGRA_CONSOLE_BAUDRATE
235 b console_core_init
236endfunc plat_crash_console_init
237
238 /* ---------------------------------------------
239 * int plat_crash_console_putc(void)
240 * Function to print a character on the crash
241 * console without a C Runtime.
242 * Clobber list : x1, x2
243 * ---------------------------------------------
244 */
245func plat_crash_console_putc
Varun Wadekard2014c62015-10-29 10:37:28 +0530246 adr x1, tegra_console_base
247 ldr x1, [x1]
Varun Wadekarb316e242015-05-19 16:48:04 +0530248 b console_core_putc
249endfunc plat_crash_console_putc
250
251 /* ---------------------------------------------------
252 * Function to handle a platform reset and store
253 * input parameters passed by BL2.
254 * ---------------------------------------------------
255 */
256func plat_reset_handler
257
Varun Wadekar1ec441e2016-03-24 15:34:24 -0700258 /* ----------------------------------------------------
259 * Verify if we are running from BL31_BASE address
260 * ----------------------------------------------------
261 */
262 adr x18, bl31_entrypoint
263 mov x17, #BL31_BASE
264 cmp x18, x17
265 b.eq 1f
266
267 /* ----------------------------------------------------
268 * Copy the entire BL31 code to BL31_BASE if we are not
269 * running from it already
270 * ----------------------------------------------------
271 */
272 mov x0, x17
273 mov x1, x18
274 mov x2, #BL31_SIZE
275_loop16:
276 cmp x2, #16
277 b.lt _loop1
278 ldp x3, x4, [x1], #16
279 stp x3, x4, [x0], #16
280 sub x2, x2, #16
281 b _loop16
282 /* copy byte per byte */
283_loop1:
284 cbz x2, _end
285 ldrb w3, [x1], #1
286 strb w3, [x0], #1
287 subs x2, x2, #1
288 b.ne _loop1
289
290 /* ----------------------------------------------------
291 * Jump to BL31_BASE and start execution again
292 * ----------------------------------------------------
293 */
294_end: mov x0, x20
295 mov x1, x21
296 br x17
2971:
298
Varun Wadekarb316e242015-05-19 16:48:04 +0530299 /* -----------------------------------
300 * derive and save the phys_base addr
301 * -----------------------------------
302 */
303 adr x17, tegra_bl31_phys_base
304 ldr x18, [x17]
305 cbnz x18, 1f
306 adr x18, bl31_entrypoint
307 str x18, [x17]
308
3091: cpu_init_common
310
311 ret
312endfunc plat_reset_handler
313
314 /* ----------------------------------------
315 * Secure entrypoint function for CPU boot
316 * ----------------------------------------
317 */
318 .align 6
319func tegra_secure_entrypoint
320
321#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
322
323 /* -------------------------------------------------------
324 * Invalidate BTB along with I$ to remove any stale
325 * entries from the branch predictor array.
326 * -------------------------------------------------------
327 */
328 mrs x0, CPUACTLR_EL1
329 orr x0, x0, #1
330 msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */
331 dsb sy
332 isb
333 ic iallu /* actual invalidate */
334 dsb sy
335 isb
336
337 mrs x0, CPUACTLR_EL1
338 bic x0, x0, #1
339 msr CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */
340 dsb sy
341 isb
342
343 .rept 7
344 nop /* wait */
345 .endr
346
347 /* -----------------------------------------------
348 * Extract OSLK bit and check if it is '1'. This
349 * bit remains '0' for A53 on warm-resets. If '1',
350 * turn off regional clock gating and request warm
351 * reset.
352 * -----------------------------------------------
353 */
354 mrs x0, oslsr_el1
355 and x0, x0, #2
356 mrs x1, mpidr_el1
357 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */
358 b.eq restore_oslock
359 mov x0, xzr
360 msr oslar_el1, x0 /* os lock stays 0 across warm reset */
361 mov x3, #3
362 movz x4, #0x8000, lsl #48
363 msr CPUACTLR_EL1, x4 /* turn off RCG */
364 isb
365 msr rmr_el3, x3 /* request warm reset */
366 isb
367 dsb sy
3681: wfi
369 b 1b
370
371 /* --------------------------------------------------
372 * These nops are here so that speculative execution
373 * won't harm us before we are done with warm reset.
374 * --------------------------------------------------
375 */
376 .rept 65
377 nop
378 .endr
379
380 /* --------------------------------------------------
381 * Do not insert instructions here
382 * --------------------------------------------------
383 */
384#endif
385
386 /* --------------------------------------------------
387 * Restore OS Lock bit
388 * --------------------------------------------------
389 */
390restore_oslock:
391 mov x0, #1
392 msr oslar_el1, x0
393
394 cpu_init_common
395
396 /* ---------------------------------------------------------------------
397 * The initial state of the Architectural feature trap register
398 * (CPTR_EL3) is unknown and it must be set to a known state. All
399 * feature traps are disabled. Some bits in this register are marked as
400 * Reserved and should not be modified.
401 *
402 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
403 * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
404 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
405 * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
406 * access to trace functionality is not supported, this bit is RES0.
407 * CPTR_EL3.TFP: This causes instructions that access the registers
408 * associated with Floating Point and Advanced SIMD execution to trap
409 * to EL3 when executed from any exception level, unless trapped to EL1
410 * or EL2.
411 * ---------------------------------------------------------------------
412 */
413 mrs x1, cptr_el3
414 bic w1, w1, #TCPAC_BIT
415 bic w1, w1, #TTA_BIT
416 bic w1, w1, #TFP_BIT
417 msr cptr_el3, x1
418
419 /* --------------------------------------------------
420 * Get secure world's entry point and jump to it
421 * --------------------------------------------------
422 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530423 bl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530424 br x0
425endfunc tegra_secure_entrypoint
426
427 .data
428 .align 3
429
430 /* --------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530431 * CPU Secure entry point - resume from suspend
Varun Wadekarb316e242015-05-19 16:48:04 +0530432 * --------------------------------------------------
433 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530434tegra_sec_entry_point:
Varun Wadekarb316e242015-05-19 16:48:04 +0530435 .quad 0
Varun Wadekarb316e242015-05-19 16:48:04 +0530436
437 /* --------------------------------------------------
438 * NS world's cold boot entry point
439 * --------------------------------------------------
440 */
441ns_image_entrypoint:
442 .quad 0
443
444 /* --------------------------------------------------
445 * BL31's physical base address
446 * --------------------------------------------------
447 */
448tegra_bl31_phys_base:
449 .quad 0
Varun Wadekard2014c62015-10-29 10:37:28 +0530450
451 /* --------------------------------------------------
452 * UART controller base for console init
453 * --------------------------------------------------
454 */
455tegra_console_base:
456 .quad 0