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