blob: d9f287c9321d0692f92cdb64baf1351f51a96d8c [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 */
39 .globl platform_is_primary_cpu
40 .globl platform_get_core_pos
41 .globl platform_get_entrypoint
42 .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 */
50 .globl sec_entry_point
51 .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 /* -----------------------------------------------------
118 * int platform_is_primary_cpu(int mpidr);
119 *
120 * This function checks if this is the Primary CPU
121 * -----------------------------------------------------
122 */
123func platform_is_primary_cpu
124 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)
125 cmp x0, #TEGRA_PRIMARY_CPU
126 cset x0, eq
127 ret
128endfunc platform_is_primary_cpu
129
130 /* -----------------------------------------------------
131 * int platform_get_core_pos(int mpidr);
132 *
133 * With this function: CorePos = CoreId
134 * -----------------------------------------------------
135 */
136func platform_get_core_pos
137 and x0, x0, #MPIDR_CPU_MASK
138 ret
139endfunc platform_get_core_pos
140
141 /* -----------------------------------------------------
142 * void plat_secondary_cold_boot_setup (void);
143 *
144 * This function performs any platform specific actions
145 * needed for a secondary cpu after a cold reset. Right
146 * now this is a stub function.
147 * -----------------------------------------------------
148 */
149func plat_secondary_cold_boot_setup
150 mov x0, #0
151 ret
152endfunc plat_secondary_cold_boot_setup
153
154 /* -----------------------------------------------------
155 * void platform_get_entrypoint (unsigned int mpidr);
156 *
157 * Main job of this routine is to distinguish between
158 * a cold and warm boot. If the sec_entry_point for
159 * this CPU is present, then it's a warm boot.
160 *
161 * -----------------------------------------------------
162 */
163func platform_get_entrypoint
164 and x0, x0, #MPIDR_CPU_MASK
165 adr x1, sec_entry_point
166 ldr x0, [x1, x0, lsl #3]
167 ret
168endfunc platform_get_entrypoint
169
170 /* --------------------------------------------------------
171 * void platform_mem_init (void);
172 *
173 * Any memory init, relocation to be done before the
174 * platform boots. Called very early in the boot process.
175 * --------------------------------------------------------
176 */
177func platform_mem_init
178 mov x0, #0
179 ret
180endfunc platform_mem_init
181
182 /* ---------------------------------------------
183 * int plat_crash_console_init(void)
184 * Function to initialize the crash console
185 * without a C Runtime to print crash report.
186 * Clobber list : x0, x1, x2
187 * ---------------------------------------------
188 */
189func plat_crash_console_init
190 mov_imm x0, TEGRA_BOOT_UART_BASE
191 mov_imm x1, TEGRA_BOOT_UART_CLK_IN_HZ
192 mov_imm x2, TEGRA_CONSOLE_BAUDRATE
193 b console_core_init
194endfunc plat_crash_console_init
195
196 /* ---------------------------------------------
197 * int plat_crash_console_putc(void)
198 * Function to print a character on the crash
199 * console without a C Runtime.
200 * Clobber list : x1, x2
201 * ---------------------------------------------
202 */
203func plat_crash_console_putc
204 mov_imm x1, TEGRA_BOOT_UART_BASE
205 b console_core_putc
206endfunc plat_crash_console_putc
207
208 /* ---------------------------------------------------
209 * Function to handle a platform reset and store
210 * input parameters passed by BL2.
211 * ---------------------------------------------------
212 */
213func plat_reset_handler
214
215 /* -----------------------------------
216 * derive and save the phys_base addr
217 * -----------------------------------
218 */
219 adr x17, tegra_bl31_phys_base
220 ldr x18, [x17]
221 cbnz x18, 1f
222 adr x18, bl31_entrypoint
223 str x18, [x17]
224
2251: cpu_init_common
226
227 ret
228endfunc plat_reset_handler
229
230 /* ----------------------------------------
231 * Secure entrypoint function for CPU boot
232 * ----------------------------------------
233 */
234 .align 6
235func tegra_secure_entrypoint
236
237#if ERRATA_TEGRA_INVALIDATE_BTB_AT_BOOT
238
239 /* -------------------------------------------------------
240 * Invalidate BTB along with I$ to remove any stale
241 * entries from the branch predictor array.
242 * -------------------------------------------------------
243 */
244 mrs x0, CPUACTLR_EL1
245 orr x0, x0, #1
246 msr CPUACTLR_EL1, x0 /* invalidate BTB and I$ together */
247 dsb sy
248 isb
249 ic iallu /* actual invalidate */
250 dsb sy
251 isb
252
253 mrs x0, CPUACTLR_EL1
254 bic x0, x0, #1
255 msr CPUACTLR_EL1, X0 /* restore original CPUACTLR_EL1 */
256 dsb sy
257 isb
258
259 .rept 7
260 nop /* wait */
261 .endr
262
263 /* -----------------------------------------------
264 * Extract OSLK bit and check if it is '1'. This
265 * bit remains '0' for A53 on warm-resets. If '1',
266 * turn off regional clock gating and request warm
267 * reset.
268 * -----------------------------------------------
269 */
270 mrs x0, oslsr_el1
271 and x0, x0, #2
272 mrs x1, mpidr_el1
273 bics xzr, x0, x1, lsr #7 /* 0 = slow cluster or warm reset */
274 b.eq restore_oslock
275 mov x0, xzr
276 msr oslar_el1, x0 /* os lock stays 0 across warm reset */
277 mov x3, #3
278 movz x4, #0x8000, lsl #48
279 msr CPUACTLR_EL1, x4 /* turn off RCG */
280 isb
281 msr rmr_el3, x3 /* request warm reset */
282 isb
283 dsb sy
2841: wfi
285 b 1b
286
287 /* --------------------------------------------------
288 * These nops are here so that speculative execution
289 * won't harm us before we are done with warm reset.
290 * --------------------------------------------------
291 */
292 .rept 65
293 nop
294 .endr
295
296 /* --------------------------------------------------
297 * Do not insert instructions here
298 * --------------------------------------------------
299 */
300#endif
301
302 /* --------------------------------------------------
303 * Restore OS Lock bit
304 * --------------------------------------------------
305 */
306restore_oslock:
307 mov x0, #1
308 msr oslar_el1, x0
309
310 cpu_init_common
311
312 /* ---------------------------------------------------------------------
313 * The initial state of the Architectural feature trap register
314 * (CPTR_EL3) is unknown and it must be set to a known state. All
315 * feature traps are disabled. Some bits in this register are marked as
316 * Reserved and should not be modified.
317 *
318 * CPTR_EL3.TCPAC: This causes a direct access to the CPACR_EL1 from EL1
319 * or the CPTR_EL2 from EL2 to trap to EL3 unless it is trapped at EL2.
320 * CPTR_EL3.TTA: This causes access to the Trace functionality to trap
321 * to EL3 when executed from EL0, EL1, EL2, or EL3. If system register
322 * access to trace functionality is not supported, this bit is RES0.
323 * CPTR_EL3.TFP: This causes instructions that access the registers
324 * associated with Floating Point and Advanced SIMD execution to trap
325 * to EL3 when executed from any exception level, unless trapped to EL1
326 * or EL2.
327 * ---------------------------------------------------------------------
328 */
329 mrs x1, cptr_el3
330 bic w1, w1, #TCPAC_BIT
331 bic w1, w1, #TTA_BIT
332 bic w1, w1, #TFP_BIT
333 msr cptr_el3, x1
334
335 /* --------------------------------------------------
336 * Get secure world's entry point and jump to it
337 * --------------------------------------------------
338 */
339 mrs x0, mpidr_el1
340 bl platform_get_entrypoint
341 br x0
342endfunc tegra_secure_entrypoint
343
344 .data
345 .align 3
346
347 /* --------------------------------------------------
348 * Per-CPU Secure entry point - resume from suspend
349 * --------------------------------------------------
350 */
351sec_entry_point:
352 .rept PLATFORM_CORE_COUNT
353 .quad 0
354 .endr
355
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