blob: ae0d675d35674b9cffb574d5473f9d4819f344a6 [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
Marek Vasut24b17992018-12-28 20:23:36 +0100220 /* Switch to SP_EL0 */
221 msr spsel, #0
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200222#if IMAGE_BL2
223 mov w1, #FIQ_SP_EL0
224 cmp w0, w1
225 beq rep_exec_fiq_elx
226 b rep_exec_panic_type
227rep_exec_fiq_elx:
228 bl gicv2_acknowledge_interrupt
229 mov x2, #INT_ID_MASK
230 and x0, x0, x2
231 mov x1, #ARM_IRQ_SEC_WDT
232 cmp x0, x1
233 bne rep_exec_panic_id
234 mrs x0, ELR_EL3
235 b rcar_swdt_exec
236rep_exec_panic_type:
237 /* x0 is interrupt TYPE */
238 b bl2_interrupt_error_type
239rep_exec_panic_id:
240 /* x0 is interrupt ID */
241 b bl2_interrupt_error_id
242rep_exec_end:
243#endif
244 ret
245endfunc plat_report_exception
246
247 /* ---------------------------------------------
248 * int plat_crash_console_init(void)
249 * Function to initialize log area
250 * ---------------------------------------------
251 */
252func plat_crash_console_init
253#if IMAGE_BL2
254 mov x0, #0
255#else
256 mov x1, sp
257 mov_imm x2, RCAR_CRASH_STACK
258 mov sp, x2
259 str x1, [sp, #-16]!
260 str x30, [sp, #-16]!
261 bl console_core_init
262 ldr x30, [sp], #16
263 ldr x1, [sp], #16
264 mov sp, x1
265#endif
266 ret
267endfunc plat_crash_console_init
268
269 /* ---------------------------------------------
270 * int plat_crash_console_putc(int c)
271 * Function to store a character to log area
272 * ---------------------------------------------
273 */
274func plat_crash_console_putc
275 mov x1, sp
276 mov_imm x2, RCAR_CRASH_STACK
277 mov sp, x2
278 str x1, [sp, #-16]!
279 str x30, [sp, #-16]!
280 str x3, [sp, #-16]!
281 str x4, [sp, #-16]!
282 str x5, [sp, #-16]!
283 bl console_core_putc
284 ldr x5, [sp], #16
285 ldr x4, [sp], #16
286 ldr x3, [sp], #16
287 ldr x30, [sp], #16
288 ldr x1, [sp], #16
289 mov sp, x1
290 ret
291endfunc plat_crash_console_putc
292
ldts17227cc2018-11-06 11:01:19 +0100293 /* ---------------------------------------------
294 * int plat_crash_console_flush()
295 *
296 * ---------------------------------------------
297 */
298func plat_crash_console_flush
299 b console_flush
300endfunc plat_crash_console_flush
301
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200302 /* --------------------------------------------------------------------
303 * void plat_reset_handler(void);
304 *
305 * Before adding code in this function, refer to the guidelines in
306 * docs/firmware-design.md to determine whether the code should reside
307 * within the FIRST_RESET_HANDLER_CALL block or not.
308 *
309 * For R-Car H3:
310 * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
311 * - Set the L2 Data setup latency to 1 (i.e. 1 cycles) for Cortex-A57
312 * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57
313 * For R-Car M3/M3N:
314 * - Set the L2 Tag RAM latency to 2 (i.e. 3 cycles) for Cortex-A57
315 * - Set the L2 Data setup latency to 0 (i.e. 0 cycles) for Cortex-A57
316 * - Set the L2 Data RAM latency to 3 (i.e. 4 cycles) for Cortex-A57
317 *
318 * --------------------------------------------------------------------
319 */
320func plat_reset_handler
321 /*
322 * On R-Car H3 : x2 := 0
323 * On R-Car M3/M3N: x2 := 1
324 */
325 /* read PRR */
326 ldr x0, =0xFFF00044
327 ldr w0, [x0]
328 ubfx w0, w0, 8, 8
329 /* H3? */
330 cmp w0, #0x4F
Marek Vasut4a20f352019-01-08 14:05:39 +0100331 b.eq RCARH3
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200332 /* set R-Car M3/M3N */
333 mov x2, #1
334 b CHK_A5x
Marek Vasut4a20f352019-01-08 14:05:39 +0100335RCARH3:
Jorge Ramirez-Ortizbf084dc2018-09-23 09:36:13 +0200336 /* set R-Car H3 */
337 mov x2, #0
338 /* --------------------------------------------------------------------
339 * Determine whether this code is executed on a Cortex-A53 or on a
340 * Cortex-A57 core.
341 * --------------------------------------------------------------------
342 */
343CHK_A5x:
344 mrs x0, midr_el1
345 ubfx x1, x0, MIDR_PN_SHIFT, #12
346 cmp w1, #((CORTEX_A57_MIDR >> MIDR_PN_SHIFT) & MIDR_PN_MASK)
347 b.eq A57
348 ret
349A57:
350 /* Get data from CORTEX_A57_L2CTLR_EL1 */
351 mrs x0, CORTEX_A57_L2CTLR_EL1
352 /*
353 * On R-Car H3/M3/M3N
354 *
355 * L2 Tag RAM latency is bit8-6 of CORTEX_A57_L2CTLR_EL1
356 * L2 Data RAM setup is bit5 of CORTEX_A57_L2CTLR_EL1
357 * L2 Data RAM latency is bit2-0 of CORTEX_A57_L2CTLR_EL1
358 */
359 /* clear bit of L2 RAM */
360 /* ~(0x1e7) -> x1 */
361 mov x1, #0x1e7
362 neg x1, x1
363 /* clear bit of L2 RAM -> x0 */
364 and x0, x0, x1
365 /* L2 Tag RAM latency (3 cycles) */
366 orr x0, x0, #0x2 << 6
367 /* If M3/M3N then L2 RAM setup is 0 */
368 cbnz x2, M3_L2
369 /* L2 Data RAM setup (1 cycle) */
370 orr x0, x0, #0x1 << 5
371M3_L2:
372 /* L2 Data RAM latency (4 cycles) */
373 orr x0, x0, #0x3
374 /* Store data to L2CTLR_EL1 */
375 msr CORTEX_A57_L2CTLR_EL1, x0
376apply_l2_ram_latencies:
377 ret
378endfunc plat_reset_handler
379
380 /* ---------------------------------------------
381 * void plat_invalidate_icache(void)
382 * Instruction Cache Invalidate All to PoU
383 * ---------------------------------------------
384 */
385func plat_invalidate_icache
386 ic iallu
387
388 ret
389endfunc plat_invalidate_icache