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