blob: 905c4c5fe5c7ea86a68d217050297f8fb924128e [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
38 /* Global functions */
Varun Wadekara78bb1b2015-08-07 10:03:00 +053039 .globl plat_is_my_cpu_primary
40 .globl plat_my_core_pos
41 .globl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +053042 .globl plat_secondary_cold_boot_setup
43 .globl platform_mem_init
44 .globl plat_crash_console_init
45 .globl plat_crash_console_putc
46 .globl tegra_secure_entrypoint
47 .globl plat_reset_handler
48
49 /* Global variables */
Varun Wadekara78bb1b2015-08-07 10:03:00 +053050 .globl tegra_sec_entry_point
Varun Wadekarb316e242015-05-19 16:48:04 +053051 .globl ns_image_entrypoint
52 .globl tegra_bl31_phys_base
53
54 /* ---------------------
55 * Common CPU init code
56 * ---------------------
57 */
58.macro cpu_init_common
59
Varun Wadekar4e9c2312015-08-21 15:56:02 +053060#if ENABLE_L2_DYNAMIC_RETENTION
61 /* ---------------------------
62 * Enable processor retention
63 * ---------------------------
64 */
65 mrs x0, L2ECTLR_EL1
66 mov x1, #RETENTION_ENTRY_TICKS_512 << L2ECTLR_RET_CTRL_SHIFT
67 bic x0, x0, #L2ECTLR_RET_CTRL_MASK
68 orr x0, x0, x1
69 msr L2ECTLR_EL1, x0
70 isb
71#endif
72
73#if ENABLE_CPU_DYNAMIC_RETENTION
74 mrs x0, CPUECTLR_EL1
75 mov x1, #RETENTION_ENTRY_TICKS_512 << CPUECTLR_CPU_RET_CTRL_SHIFT
76 bic x0, x0, #CPUECTLR_CPU_RET_CTRL_MASK
77 orr x0, x0, x1
78 msr CPUECTLR_EL1, x0
79 isb
80#endif
81
Varun Wadekard1b61502015-07-16 09:46:28 +053082#if ENABLE_NS_L2_CPUECTRL_RW_ACCESS
Varun Wadekarb316e242015-05-19 16:48:04 +053083 /* -------------------------------------------------------
84 * Enable L2 and CPU ECTLR RW access from non-secure world
85 * -------------------------------------------------------
86 */
87 mov x0, #ACTLR_EL3_ENABLE_ALL_ACCESS
88 msr actlr_el3, x0
89 msr actlr_el2, x0
90 isb
Varun Wadekard1b61502015-07-16 09:46:28 +053091#endif
Varun Wadekarb316e242015-05-19 16:48:04 +053092
93 /* --------------------------------
94 * Enable the cycle count register
95 * --------------------------------
96 */
97 mrs x0, pmcr_el0
98 ubfx x0, x0, #11, #5 // read PMCR.N field
99 mov x1, #1
100 lsl x0, x1, x0
101 sub x0, x0, #1 // mask of event counters
102 orr x0, x0, #0x80000000 // disable overflow intrs
103 msr pmintenclr_el1, x0
104 msr pmuserenr_el0, x1 // enable user mode access
105
106 /* ----------------------------------------------------------------
107 * Allow non-privileged access to CNTVCT: Set CNTKCTL (Kernel Count
108 * register), bit 1 (EL0VCTEN) to enable access to CNTVCT/CNTFRQ
109 * registers from EL0.
110 * ----------------------------------------------------------------
111 */
112 mrs x0, cntkctl_el1
113 orr x0, x0, #EL0VCTEN_BIT
114 msr cntkctl_el1, x0
115.endm
116
117 /* -----------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530118 * unsigned int plat_is_my_cpu_primary(void);
Varun Wadekarb316e242015-05-19 16:48:04 +0530119 *
120 * This function checks if this is the Primary CPU
121 * -----------------------------------------------------
122 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530123func plat_is_my_cpu_primary
124 mrs x0, mpidr_el1
Varun Wadekarb316e242015-05-19 16:48:04 +0530125 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
126 cmp x0, #TEGRA_PRIMARY_CPU
127 cset x0, eq
128 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530129endfunc plat_is_my_cpu_primary
Varun Wadekarb316e242015-05-19 16:48:04 +0530130
131 /* -----------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530132 * unsigned int plat_my_core_pos(void);
133 *
134 * result: CorePos = CoreId + (ClusterId << 2)
135 * -----------------------------------------------------
136 */
137func plat_my_core_pos
138 mrs x0, mpidr_el1
139 and x1, x0, #MPIDR_CPU_MASK
140 and x0, x0, #MPIDR_CLUSTER_MASK
141 add x0, x1, x0, LSR #6
142 ret
143endfunc plat_my_core_pos
144
145 /* -----------------------------------------------------
146 * unsigned long plat_get_my_entrypoint (void);
147 *
148 * Main job of this routine is to distinguish between
149 * a cold and warm boot. If the tegra_sec_entry_point for
150 * this CPU is present, then it's a warm boot.
Varun Wadekarb316e242015-05-19 16:48:04 +0530151 *
Varun Wadekarb316e242015-05-19 16:48:04 +0530152 * -----------------------------------------------------
153 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530154func plat_get_my_entrypoint
155 adr x1, tegra_sec_entry_point
156 ldr x0, [x1]
Varun Wadekarb316e242015-05-19 16:48:04 +0530157 ret
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530158endfunc plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530159
160 /* -----------------------------------------------------
161 * void plat_secondary_cold_boot_setup (void);
162 *
163 * This function performs any platform specific actions
164 * needed for a secondary cpu after a cold reset. Right
165 * now this is a stub function.
166 * -----------------------------------------------------
167 */
168func plat_secondary_cold_boot_setup
169 mov x0, #0
170 ret
171endfunc plat_secondary_cold_boot_setup
172
Varun Wadekarb316e242015-05-19 16:48:04 +0530173 /* --------------------------------------------------------
174 * void platform_mem_init (void);
175 *
176 * Any memory init, relocation to be done before the
177 * platform boots. Called very early in the boot process.
178 * --------------------------------------------------------
179 */
180func platform_mem_init
181 mov x0, #0
182 ret
183endfunc platform_mem_init
184
185 /* ---------------------------------------------
186 * int plat_crash_console_init(void)
187 * Function to initialize the crash console
188 * without a C Runtime to print crash report.
Juan Castilloe7ae6db2015-11-26 14:52:15 +0000189 * Clobber list : x0 - x4
Varun Wadekarb316e242015-05-19 16:48:04 +0530190 * ---------------------------------------------
191 */
192func plat_crash_console_init
193 mov_imm x0, TEGRA_BOOT_UART_BASE
194 mov_imm x1, TEGRA_BOOT_UART_CLK_IN_HZ
195 mov_imm x2, TEGRA_CONSOLE_BAUDRATE
196 b console_core_init
197endfunc plat_crash_console_init
198
199 /* ---------------------------------------------
200 * int plat_crash_console_putc(void)
201 * Function to print a character on the crash
202 * console without a C Runtime.
203 * Clobber list : x1, x2
204 * ---------------------------------------------
205 */
206func plat_crash_console_putc
207 mov_imm x1, TEGRA_BOOT_UART_BASE
208 b console_core_putc
209endfunc plat_crash_console_putc
210
211 /* ---------------------------------------------------
212 * Function to handle a platform reset and store
213 * input parameters passed by BL2.
214 * ---------------------------------------------------
215 */
216func plat_reset_handler
217
218 /* -----------------------------------
219 * derive and save the phys_base addr
220 * -----------------------------------
221 */
222 adr x17, tegra_bl31_phys_base
223 ldr x18, [x17]
224 cbnz x18, 1f
225 adr x18, bl31_entrypoint
226 str x18, [x17]
227
2281: cpu_init_common
229
230 ret
231endfunc plat_reset_handler
232
233 /* ----------------------------------------
234 * Secure entrypoint function for CPU boot
235 * ----------------------------------------
236 */
237 .align 6
238func tegra_secure_entrypoint
239
240#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
241
242 /* -------------------------------------------------------
243 * Invalidate BTB along with I$ to remove any stale
244 * entries from the branch predictor array.
245 * -------------------------------------------------------
246 */
247 mrs x0, CPUACTLR_EL1
248 orr x0, x0, #1
249 msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */
250 dsb sy
251 isb
252 ic iallu /* actual invalidate */
253 dsb sy
254 isb
255
256 mrs x0, CPUACTLR_EL1
257 bic x0, x0, #1
258 msr CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */
259 dsb sy
260 isb
261
262 .rept 7
263 nop /* wait */
264 .endr
265
266 /* -----------------------------------------------
267 * Extract OSLK bit and check if it is '1'. This
268 * bit remains '0' for A53 on warm-resets. If '1',
269 * turn off regional clock gating and request warm
270 * reset.
271 * -----------------------------------------------
272 */
273 mrs x0, oslsr_el1
274 and x0, x0, #2
275 mrs x1, mpidr_el1
276 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */
277 b.eq restore_oslock
278 mov x0, xzr
279 msr oslar_el1, x0 /* os lock stays 0 across warm reset */
280 mov x3, #3
281 movz x4, #0x8000, lsl #48
282 msr CPUACTLR_EL1, x4 /* turn off RCG */
283 isb
284 msr rmr_el3, x3 /* request warm reset */
285 isb
286 dsb sy
2871: wfi
288 b 1b
289
290 /* --------------------------------------------------
291 * These nops are here so that speculative execution
292 * won't harm us before we are done with warm reset.
293 * --------------------------------------------------
294 */
295 .rept 65
296 nop
297 .endr
298
299 /* --------------------------------------------------
300 * Do not insert instructions here
301 * --------------------------------------------------
302 */
303#endif
304
305 /* --------------------------------------------------
306 * Restore OS Lock bit
307 * --------------------------------------------------
308 */
309restore_oslock:
310 mov x0, #1
311 msr oslar_el1, x0
312
313 cpu_init_common
314
315 /* ---------------------------------------------------------------------
316 * The initial state of the Architectural feature trap register
317 * (CPTR_EL3) is unknown and it must be set to a known state. All
318 * feature traps are disabled. Some bits in this register are marked as
319 * Reserved and should not be modified.
320 *
321 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
322 * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
323 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
324 * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
325 * access to trace functionality is not supported, this bit is RES0.
326 * CPTR_EL3.TFP: This causes instructions that access the registers
327 * associated with Floating Point and Advanced SIMD execution to trap
328 * to EL3 when executed from any exception level, unless trapped to EL1
329 * or EL2.
330 * ---------------------------------------------------------------------
331 */
332 mrs x1, cptr_el3
333 bic w1, w1, #TCPAC_BIT
334 bic w1, w1, #TTA_BIT
335 bic w1, w1, #TFP_BIT
336 msr cptr_el3, x1
337
338 /* --------------------------------------------------
339 * Get secure world's entry point and jump to it
340 * --------------------------------------------------
341 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530342 bl plat_get_my_entrypoint
Varun Wadekarb316e242015-05-19 16:48:04 +0530343 br x0
344endfunc tegra_secure_entrypoint
345
346 .data
347 .align 3
348
349 /* --------------------------------------------------
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530350 * CPU Secure entry point - resume from suspend
Varun Wadekarb316e242015-05-19 16:48:04 +0530351 * --------------------------------------------------
352 */
Varun Wadekara78bb1b2015-08-07 10:03:00 +0530353tegra_sec_entry_point:
Varun Wadekarb316e242015-05-19 16:48:04 +0530354 .quad 0
Varun Wadekarb316e242015-05-19 16:48:04 +0530355
356 /* --------------------------------------------------
357 * NS world's cold boot entry point
358 * --------------------------------------------------
359 */
360ns_image_entrypoint:
361 .quad 0
362
363 /* --------------------------------------------------
364 * BL31's physical base address
365 * --------------------------------------------------
366 */
367tegra_bl31_phys_base:
368 .quad 0