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