blob: b2fc9a75bc6284ccc760838fa26082e18d01f330 [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>
36#include <tegra_def.h>
37
Varun Wadekarb24dea92015-09-22 13:33:56 +053038#define MIDR_PN_CORTEX_A57 0xD07
39
40/*******************************************************************************
41 * Implementation defined ACTLR_EL3 bit definitions
42 ******************************************************************************/
43#define ACTLR_EL3_L2ACTLR_BIT (1 << 6)
44#define ACTLR_EL3_L2ECTLR_BIT (1 << 5)
45#define ACTLR_EL3_L2CTLR_BIT (1 << 4)
46#define ACTLR_EL3_CPUECTLR_BIT (1 << 1)
47#define ACTLR_EL3_CPUACTLR_BIT (1 << 0)
48#define ACTLR_EL3_ENABLE_ALL_ACCESS (ACTLR_EL3_L2ACTLR_BIT | \
49 ACTLR_EL3_L2ECTLR_BIT | \
50 ACTLR_EL3_L2CTLR_BIT | \
51 ACTLR_EL3_CPUECTLR_BIT | \
52 ACTLR_EL3_CPUACTLR_BIT)
53
Varun Wadekarb316e242015-05-19 16:48:04 +053054 /* Global functions */
Varun Wadekara78bb1b2015-08-07 10:03:00 +053055 .globl plat_is_my_cpu_primary
56 .globl plat_my_core_pos
57 .globl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +053058 .globl plat_secondary_cold_boot_setup
59 .globl platform_mem_init
60 .globl plat_crash_console_init
61 .globl plat_crash_console_putc
62 .globl tegra_secure_entrypoint
63 .globl plat_reset_handler
64
65 /* Global variables */
Varun Wadekara78bb1b2015-08-07 10:03:00 +053066 .globl tegra_sec_entry_point
Varun Wadekarb316e242015-05-19 16:48:04 +053067 .globl ns_image_entrypoint
68 .globl tegra_bl31_phys_base
69
70 /* ---------------------
71 * Common CPU init code
72 * ---------------------
73 */
74.macro cpu_init_common
75
Varun Wadekarb24dea92015-09-22 13:33:56 +053076 /* ------------------------------------------------
77 * We enable procesor retention and L2/CPUECTLR NS
78 * access for A57 CPUs only.
79 * ------------------------------------------------
80 */
81 mrs x0, midr_el1
82 mov x1, #(MIDR_PN_MASK << MIDR_PN_SHIFT)
83 and x0, x0, x1
84 lsr x0, x0, #MIDR_PN_SHIFT
85 cmp x0, #MIDR_PN_CORTEX_A57
86 b.ne 1f
87
Varun Wadekar4e9c2312015-08-21 15:56:02 +053088 /* ---------------------------
89 * Enable processor retention
90 * ---------------------------
91 */
92 mrs x0, L2ECTLR_EL1
93 mov x1, #RETENTION_ENTRY_TICKS_512 << L2ECTLR_RET_CTRL_SHIFT
94 bic x0, x0, #L2ECTLR_RET_CTRL_MASK
95 orr x0, x0, x1
96 msr L2ECTLR_EL1, x0
97 isb
Varun Wadekar4e9c2312015-08-21 15:56:02 +053098
Varun Wadekar4e9c2312015-08-21 15:56:02 +053099 mrs x0, CPUECTLR_EL1
100 mov x1, #RETENTION_ENTRY_TICKS_512 << CPUECTLR_CPU_RET_CTRL_SHIFT
101 bic x0, x0, #CPUECTLR_CPU_RET_CTRL_MASK
102 orr x0, x0, x1
103 msr CPUECTLR_EL1, x0
104 isb
Varun Wadekar4e9c2312015-08-21 15:56:02 +0530105
Varun Wadekarb316e242015-05-19 16:48:04 +0530106 /* -------------------------------------------------------
107 * Enable L2 and CPU ECTLR RW access from non-secure world
108 * -------------------------------------------------------
109 */
110 mov x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
111 msr actlr_el3, x0
112 msr actlr_el2, x0
113 isb
Varun Wadekarb316e242015-05-19 16:48:04 +0530114
115 /* --------------------------------
116 * Enable the cycle count register
117 * --------------------------------
118 */
Varun Wadekarb24dea92015-09-22 13:33:56 +05301191: mrs x0, pmcr_el0
Varun Wadekarb316e242015-05-19 16:48:04 +0530120 ubfx x0, x0, #11, #5 // read PMCR.N field
121 mov x1, #1
122 lsl x0, x1, x0
123 sub x0, x0, #1 // mask of event counters
124 orr x0, x0, #0x80000000 // disable overflow intrs
125 msr pmintenclr_el1, x0
126 msr pmuserenr_el0, x1 // enable user mode access
127
128 /* ----------------------------------------------------------------
129 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count
130 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ
131 * registers from EL0.
132 * ----------------------------------------------------------------
133 */
134 mrs x0, cntkctl_el1
135 orr x0, x0, #EL0VCTEN_BIT
136 msr cntkctl_el1, x0
137.endm
138
139 /* -----------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530140 * unsigned int plat_is_my_cpu_primary(void);
Varun Wadekarb316e242015-05-19 16:48:04 +0530141 *
142 * This function checks if this is the Primary CPU
143 * -----------------------------------------------------
144 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530145func plat_is_my_cpu_primary
146 mrs x0, mpidr_el1
Varun Wadekarb316e242015-05-19 16:48:04 +0530147 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
148 cmp x0, #TEGRA_PRIMARY_CPU
149 cset x0, eq
150 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530151endfunc plat_is_my_cpu_primary
Varun Wadekarb316e242015-05-19 16:48:04 +0530152
153 /* -----------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530154 * unsigned int plat_my_core_pos(void);
155 *
156 * result: CorePos = CoreId + (ClusterId << 2)
157 * -----------------------------------------------------
158 */
159func plat_my_core_pos
160 mrs x0, mpidr_el1
161 and x1, x0, #MPIDR_CPU_MASK
162 and x0, x0, #MPIDR_CLUSTER_MASK
163 add x0, x1, x0, LSR #6
164 ret
165endfunc plat_my_core_pos
166
167 /* -----------------------------------------------------
168 * unsigned long plat_get_my_entrypoint (void);
169 *
170 * Main job of this routine is to distinguish between
171 * a cold and warm boot. If the tegra_sec_entry_point for
172 * this CPU is present, then it's a warm boot.
Varun Wadekarb316e242015-05-19 16:48:04 +0530173 *
Varun Wadekarb316e242015-05-19 16:48:04 +0530174 * -----------------------------------------------------
175 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530176func plat_get_my_entrypoint
177 adr x1, tegra_sec_entry_point
178 ldr x0, [x1]
Varun Wadekarb316e242015-05-19 16:48:04 +0530179 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530180endfunc plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530181
182 /* -----------------------------------------------------
Varun Wadekar39f87d12015-09-22 13:45:07 +0530183 * int platform_get_core_pos(int mpidr);
184 *
185 * With this function: CorePos = (ClusterId * 4) +
186 * CoreId
187 * -----------------------------------------------------
188 */
189func platform_get_core_pos
190 and x1, x0, #MPIDR_CPU_MASK
191 and x0, x0, #MPIDR_CLUSTER_MASK
192 add x0, x1, x0, LSR #6
193 ret
194endfunc platform_get_core_pos
195
196 /* -----------------------------------------------------
Varun Wadekarb316e242015-05-19 16:48:04 +0530197 * void plat_secondary_cold_boot_setup (void);
198 *
199 * This function performs any platform specific actions
200 * needed for a secondary cpu after a cold reset. Right
201 * now this is a stub function.
202 * -----------------------------------------------------
203 */
204func plat_secondary_cold_boot_setup
205 mov x0, #0
206 ret
207endfunc plat_secondary_cold_boot_setup
208
Varun Wadekarb316e242015-05-19 16:48:04 +0530209 /* --------------------------------------------------------
210 * void platform_mem_init (void);
211 *
212 * Any memory init, relocation to be done before the
213 * platform boots. Called very early in the boot process.
214 * --------------------------------------------------------
215 */
216func platform_mem_init
217 mov x0, #0
218 ret
219endfunc platform_mem_init
220
221 /* ---------------------------------------------
222 * int plat_crash_console_init(void)
223 * Function to initialize the crash console
224 * without a C Runtime to print crash report.
Juan Castilloe7ae6db2015-11-26 14:52:15 +0000225 * Clobber list : x0 - x4
Varun Wadekarb316e242015-05-19 16:48:04 +0530226 * ---------------------------------------------
227 */
228func plat_crash_console_init
229 mov_imm x0, TEGRA_BOOT_UART_BASE
230 mov_imm x1, TEGRA_BOOT_UART_CLK_IN_HZ
231 mov_imm x2, TEGRA_CONSOLE_BAUDRATE
232 b console_core_init
233endfunc plat_crash_console_init
234
235 /* ---------------------------------------------
236 * int plat_crash_console_putc(void)
237 * Function to print a character on the crash
238 * console without a C Runtime.
239 * Clobber list : x1, x2
240 * ---------------------------------------------
241 */
242func plat_crash_console_putc
243 mov_imm x1, TEGRA_BOOT_UART_BASE
244 b console_core_putc
245endfunc plat_crash_console_putc
246
247 /* ---------------------------------------------------
248 * Function to handle a platform reset and store
249 * input parameters passed by BL2.
250 * ---------------------------------------------------
251 */
252func plat_reset_handler
253
254 /* -----------------------------------
255 * derive and save the phys_base addr
256 * -----------------------------------
257 */
258 adr x17, tegra_bl31_phys_base
259 ldr x18, [x17]
260 cbnz x18, 1f
261 adr x18, bl31_entrypoint
262 str x18, [x17]
263
2641: cpu_init_common
265
266 ret
267endfunc plat_reset_handler
268
269 /* ----------------------------------------
270 * Secure entrypoint function for CPU boot
271 * ----------------------------------------
272 */
273 .align 6
274func tegra_secure_entrypoint
275
276#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
277
278 /* -------------------------------------------------------
279 * Invalidate BTB along with I$ to remove any stale
280 * entries from the branch predictor array.
281 * -------------------------------------------------------
282 */
283 mrs x0, CPUACTLR_EL1
284 orr x0, x0, #1
285 msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */
286 dsb sy
287 isb
288 ic iallu /* actual invalidate */
289 dsb sy
290 isb
291
292 mrs x0, CPUACTLR_EL1
293 bic x0, x0, #1
294 msr CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */
295 dsb sy
296 isb
297
298 .rept 7
299 nop /* wait */
300 .endr
301
302 /* -----------------------------------------------
303 * Extract OSLK bit and check if it is '1'. This
304 * bit remains '0' for A53 on warm-resets. If '1',
305 * turn off regional clock gating and request warm
306 * reset.
307 * -----------------------------------------------
308 */
309 mrs x0, oslsr_el1
310 and x0, x0, #2
311 mrs x1, mpidr_el1
312 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */
313 b.eq restore_oslock
314 mov x0, xzr
315 msr oslar_el1, x0 /* os lock stays 0 across warm reset */
316 mov x3, #3
317 movz x4, #0x8000, lsl #48
318 msr CPUACTLR_EL1, x4 /* turn off RCG */
319 isb
320 msr rmr_el3, x3 /* request warm reset */
321 isb
322 dsb sy
3231: wfi
324 b 1b
325
326 /* --------------------------------------------------
327 * These nops are here so that speculative execution
328 * won't harm us before we are done with warm reset.
329 * --------------------------------------------------
330 */
331 .rept 65
332 nop
333 .endr
334
335 /* --------------------------------------------------
336 * Do not insert instructions here
337 * --------------------------------------------------
338 */
339#endif
340
341 /* --------------------------------------------------
342 * Restore OS Lock bit
343 * --------------------------------------------------
344 */
345restore_oslock:
346 mov x0, #1
347 msr oslar_el1, x0
348
349 cpu_init_common
350
351 /* ---------------------------------------------------------------------
352 * The initial state of the Architectural feature trap register
353 * (CPTR_EL3) is unknown and it must be set to a known state. All
354 * feature traps are disabled. Some bits in this register are marked as
355 * Reserved and should not be modified.
356 *
357 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
358 * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
359 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
360 * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
361 * access to trace functionality is not supported, this bit is RES0.
362 * CPTR_EL3.TFP: This causes instructions that access the registers
363 * associated with Floating Point and Advanced SIMD execution to trap
364 * to EL3 when executed from any exception level, unless trapped to EL1
365 * or EL2.
366 * ---------------------------------------------------------------------
367 */
368 mrs x1, cptr_el3
369 bic w1, w1, #TCPAC_BIT
370 bic w1, w1, #TTA_BIT
371 bic w1, w1, #TFP_BIT
372 msr cptr_el3, x1
373
374 /* --------------------------------------------------
375 * Get secure world's entry point and jump to it
376 * --------------------------------------------------
377 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530378 bl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530379 br x0
380endfunc tegra_secure_entrypoint
381
382 .data
383 .align 3
384
385 /* --------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530386 * CPU Secure entry point - resume from suspend
Varun Wadekarb316e242015-05-19 16:48:04 +0530387 * --------------------------------------------------
388 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530389tegra_sec_entry_point:
Varun Wadekarb316e242015-05-19 16:48:04 +0530390 .quad 0
Varun Wadekarb316e242015-05-19 16:48:04 +0530391
392 /* --------------------------------------------------
393 * NS world's cold boot entry point
394 * --------------------------------------------------
395 */
396ns_image_entrypoint:
397 .quad 0
398
399 /* --------------------------------------------------
400 * BL31's physical base address
401 * --------------------------------------------------
402 */
403tegra_bl31_phys_base:
404 .quad 0