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