blob: d40f8f2e3d8ff5a79209ad631a9c5e1c29649853 [file] [log] [blame]
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +02001/*
2 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
3 * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved.
4 *
5 * SPDX-License-Identifier: BSD-3-Clause
6 */
7
8#include <arch.h>
9#include <asm_macros.S>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010#include <common/bl_common.h>
11#include <common/runtime_svc.h>
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020012#include <cortex_a57.h>
13#include <platform_def.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000014
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020015#include "rcar_def.h"
16
17 .globl plat_get_my_entrypoint
18 .extern plat_set_my_stack
19 .globl platform_mem_init
20
21 .globl plat_crash_console_init
22 .globl plat_crash_console_putc
ldts17227cc2018-11-06 11:01:19 +010023 .globl plat_crash_console_flush
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +020024 .globl plat_invalidate_icache
25 .globl plat_report_exception
26 .globl plat_secondary_reset
27 .globl plat_reset_handler
28 .globl plat_my_core_pos
29 .extern rcar_log_init
30
31#if IMAGE_BL2
32 #define INT_ID_MASK (0x3ff)
33 .extern bl2_interrupt_error_type
34 .extern bl2_interrupt_error_id
35 .globl bl2_enter_bl31
36 .extern gicv2_acknowledge_interrupt
37 .extern rcar_swdt_exec
38#endif
39
40 /* -----------------------------------------------------
41 * void platform_get_core_pos (mpidr)
42 * -----------------------------------------------------
43 */
44func platform_get_core_pos
45 and x1, x0, #MPIDR_CPU_MASK
46 and x0, x0, #MPIDR_CLUSTER_MASK
47 add x0, x1, x0, LSR #6
48 ret
49endfunc platform_get_core_pos
50
51 /* -----------------------------------------------------
52 * void platform_my_core_pos
53 * -----------------------------------------------------
54 */
55func plat_my_core_pos
56 mrs x0, mpidr_el1
57 b platform_get_core_pos
58endfunc plat_my_core_pos
59
60 /* -----------------------------------------------------
61 * void platform_get_my_entrypoint (unsigned int mpid);
62 *
63 * Main job of this routine is to distinguish between
64 * a cold and warm boot.
65 * On a cold boot the secondaries first wait for the
66 * platform to be initialized after which they are
67 * hotplugged in. The primary proceeds to perform the
68 * platform initialization.
69 * On a warm boot, each cpu jumps to the address in its
70 * mailbox.
71 *
72 * TODO: Not a good idea to save lr in a temp reg
73 * -----------------------------------------------------
74 */
75func plat_get_my_entrypoint
76 mrs x0, mpidr_el1
77 mov x9, x30 /* lr */
78
79#if defined(IMAGE_BL2)
80 /* always cold boot on bl2 */
81 mov x0, #0
82 ret x9
83#else
84 ldr x1, =BOOT_KIND_BASE
85 ldr x21, [x1]
86
87 /* Check the reset info */
88 and x1, x21, #0x000c
89 cmp x1, #0x0008
90 beq el3_panic
91 cmp x1, #0x000c
92 beq el3_panic
93
94 /* Check the boot kind */
95 and x1, x21, #0x0003
96 cmp x1, #0x0002
97 beq el3_panic
98 cmp x1, #0x0003
99 beq el3_panic
100
101 /* warm boot or cold boot */
102 and x1, x21, #1
103 cmp x1, #0
104 bne warm_reset
105
106 /* Cold boot */
107 mov x0, #0
108 b exit
109
110warm_reset:
111 /* --------------------------------------------------------------------
112 * A per-cpu mailbox is maintained in the trusted SDRAM. Its flushed out
113 * of the caches after every update using normal memory so its safe to
114 * read it here with SO attributes
115 * ---------------------------------------------------------------------
116 */
117 ldr x10, =MBOX_BASE
118 bl platform_get_core_pos
119 lsl x0, x0, #CACHE_WRITEBACK_SHIFT
120 ldr x0, [x10, x0]
121 cbz x0, _panic
122exit:
123 ret x9
124_panic:
125 b do_panic
126#endif
127
128endfunc plat_get_my_entrypoint
129
130 /* ---------------------------------------------
131 * plat_secondary_reset
132 *
133 * ---------------------------------------------
134 */
135func plat_secondary_reset
136 mrs x0, sctlr_el3
137 bic x0, x0, #SCTLR_EE_BIT
138 msr sctlr_el3, x0
139 isb
140
141 mrs x0, cptr_el3
142 bic w0, w0, #TCPAC_BIT
143 bic w0, w0, #TTA_BIT
144 bic w0, w0, #TFP_BIT
145 msr cptr_el3, x0
146
147 mov_imm x0, PARAMS_BASE
148 mov_imm x2, BL31_BASE
149 ldr x3, =BOOT_KIND_BASE
150 mov x1, #0x1
151 str x1, [x3]
152 br x2 /* jump to BL31 */
153 nop
154 nop
155 nop
156endfunc plat_secondary_reset
157
158 /* ---------------------------------------------
159 * plat_enter_bl31
160 *
161 * ---------------------------------------------
162 */
163func bl2_enter_bl31
164 mov x20, x0
165 /*
166 * MMU needs to be disabled because both BL2 and BL31 execute
167 * in EL3, and therefore share the same address space.
168 * BL31 will initialize the address space according to its
169 * own requirement.
170 */
171#if RCAR_BL2_DCACHE == 1
172 /* Disable mmu and data cache */
173 bl disable_mmu_el3
174 /* Data cache clean and invalidate */
175 mov x0, #DCCISW
176 bl dcsw_op_all
177 /* TLB invalidate all, EL3 */
178 tlbi alle3
179#endif /* RCAR_BL2_DCACHE == 1 */
180 bl disable_mmu_icache_el3
181 /* Invalidate instruction cache */
182 ic iallu
183 dsb sy
184 isb
185 ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET]
186 msr elr_el3, x0
187 msr spsr_el3, x1
188 eret
189endfunc bl2_enter_bl31
190
191 /* -----------------------------------------------------
192 * void platform_mem_init (void);
193 *
194 * Zero out the mailbox registers in the shared memory
195 * and set the rcar_boot_kind_flag.
196 * The mmu is turned off right now and only the primary can
197 * ever execute this code. Secondaries will read the
198 * mailboxes using SO accesses.
199 * -----------------------------------------------------
200 */
201func platform_mem_init
202#if !IMAGE_BL2
203 ldr x0, =MBOX_BASE
204 mov w1, #PLATFORM_CORE_COUNT
205loop:
206 str xzr, [x0], #CACHE_WRITEBACK_GRANULE
207 subs w1, w1, #1
208 b.gt loop
209#endif
210 ret
211endfunc platform_mem_init
212
213 /* ---------------------------------------------
214 * void plat_report_exception(unsigned int type)
215 * Function to report an unhandled exception
216 * with platform-specific means.
217 * ---------------------------------------------
218 */
219func plat_report_exception
220#if IMAGE_BL2
221 mov w1, #FIQ_SP_EL0
222 cmp w0, w1
223 beq rep_exec_fiq_elx
224 b rep_exec_panic_type
225rep_exec_fiq_elx:
226 bl gicv2_acknowledge_interrupt
227 mov x2, #INT_ID_MASK
228 and x0, x0, x2
229 mov x1, #ARM_IRQ_SEC_WDT
230 cmp x0, x1
231 bne rep_exec_panic_id
232 mrs x0, ELR_EL3
233 b rcar_swdt_exec
234rep_exec_panic_type:
235 /* x0 is interrupt TYPE */
236 b bl2_interrupt_error_type
237rep_exec_panic_id:
238 /* x0 is interrupt ID */
239 b bl2_interrupt_error_id
240rep_exec_end:
241#endif
242 ret
243endfunc plat_report_exception
244
245 /* ---------------------------------------------
246 * int plat_crash_console_init(void)
247 * Function to initialize log area
248 * ---------------------------------------------
249 */
250func plat_crash_console_init
251#if IMAGE_BL2
252 mov x0, #0
253#else
254 mov x1, sp
255 mov_imm x2, RCAR_CRASH_STACK
256 mov sp, x2
257 str x1, [sp, #-16]!
258 str x30, [sp, #-16]!
259 bl console_core_init
260 ldr x30, [sp], #16
261 ldr x1, [sp], #16
262 mov sp, x1
263#endif
264 ret
265endfunc plat_crash_console_init
266
267 /* ---------------------------------------------
268 * int plat_crash_console_putc(int c)
269 * Function to store a character to log area
270 * ---------------------------------------------
271 */
272func plat_crash_console_putc
273 mov x1, sp
274 mov_imm x2, RCAR_CRASH_STACK
275 mov sp, x2
276 str x1, [sp, #-16]!
277 str x30, [sp, #-16]!
278 str x3, [sp, #-16]!
279 str x4, [sp, #-16]!
280 str x5, [sp, #-16]!
281 bl console_core_putc
282 ldr x5, [sp], #16
283 ldr x4, [sp], #16
284 ldr x3, [sp], #16
285 ldr x30, [sp], #16
286 ldr x1, [sp], #16
287 mov sp, x1
288 ret
289endfunc plat_crash_console_putc
290
ldts17227cc2018-11-06 11:01:19 +0100291 /* ---------------------------------------------
292 * int plat_crash_console_flush()
293 *
294 * ---------------------------------------------
295 */
296func plat_crash_console_flush
297 b console_flush
298endfunc plat_crash_console_flush
299
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200300 /* --------------------------------------------------------------------
301 * void plat_reset_handler(void);
302 *
303 * Before adding code in this function, refer to the guidelines in
304 * docs/firmware-design.md to determine whether the code should reside
305 * within the FIRST_RESET_HANDLER_CALL block or not.
306 *
307 * For R-Car H3:
308 * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
309 * - Set the L2 Data setup latency to 1 (i.e. 1 cycles) for Cortex-A57
310 * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57
311 * For R-Car M3/M3N:
312 * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
313 * - Set the L2 Data setup latency to 0 (i.e. 0 cycles) for Cortex-A57
314 * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57
315 *
316 * --------------------------------------------------------------------
317 */
318func plat_reset_handler
319 /*
320 * On R-Car H3 : x2 := 0
321 * On R-Car M3/M3N: x2 := 1
322 */
323 /* read PRR */
324 ldr x0, =0xFFF00044
325 ldr w0, [x0]
326 ubfx w0, w0, 8, 8
327 /* H3? */
328 cmp w0, #0x4F
329 b.eq H3
330 /* set R-Car M3/M3N */
331 mov x2, #1
332 b CHK_A5x
333H3:
334 /* set R-Car H3 */
335 mov x2, #0
336 /* --------------------------------------------------------------------
337 * Determine whether this code is executed on a Cortex-A53 or on a
338 * Cortex-A57 core.
339 * --------------------------------------------------------------------
340 */
341CHK_A5x:
342 mrs x0, midr_el1
343 ubfx x1, x0, MIDR_PN_SHIFT, #12
344 cmp w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
345 b.eq A57
346 ret
347A57:
348 /* Get data from CORTEX_A57_L2CTLR_EL1 */
349 mrs x0, CORTEX_A57_L2CTLR_EL1
350 /*
351 * On R-Car H3/M3/M3N
352 *
353 * L2 Tag RAM latency is bit8-6 of CORTEX_A57_L2CTLR_EL1
354 * L2 Data RAM setup is bit5 of CORTEX_A57_L2CTLR_EL1
355 * L2 Data RAM latency is bit2-0 of CORTEX_A57_L2CTLR_EL1
356 */
357 /* clear bit of L2 RAM */
358 /* ~(0x1e7) -> x1 */
359 mov x1, #0x1e7
360 neg x1, x1
361 /* clear bit of L2 RAM -> x0 */
362 and x0, x0, x1
363 /* L2 Tag RAM latency (3 cycles) */
364 orr x0, x0, #0x2 << 6
365 /* If M3/M3N then L2 RAM setup is 0 */
366 cbnz x2, M3_L2
367 /* L2 Data RAM setup (1 cycle) */
368 orr x0, x0, #0x1 << 5
369M3_L2:
370 /* L2 Data RAM latency (4 cycles) */
371 orr x0, x0, #0x3
372 /* Store data to L2CTLR_EL1 */
373 msr CORTEX_A57_L2CTLR_EL1, x0
374apply_l2_ram_latencies:
375 ret
376endfunc plat_reset_handler
377
378 /* ---------------------------------------------
379 * void plat_invalidate_icache(void)
380 * Instruction Cache Invalidate All to PoU
381 * ---------------------------------------------
382 */
383func plat_invalidate_icache
384 ic iallu
385
386 ret
387endfunc plat_invalidate_icache