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