hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
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
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
/*
 * (C) Copyright 2013
 * David Feng <fenghua@phytium.com.cn>
 *
 * SPDX-License-Identifier:    GPL-2.0+
 */
 
#include <asm-offsets.h>
#include <config.h>
#include <linux/linkage.h>
#include <asm/macro.h>
#include <asm/armv8/mmu.h>
 
/*************************************************************************
 *
 * Startup Code (reset vector)
 *
 *************************************************************************/
 
.globl    _start
_start:
#ifdef CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK
/*
 * Various SoCs need something special and SoC-specific up front in
 * order to boot, allow them to set that in their boot0.h file and then
 * use it here.
 */
#include <asm/arch/boot0.h>
#else
   b    reset
#endif
 
#if !CONFIG_IS_ENABLED(TINY_FRAMEWORK)
   .align 3
 
.globl    _TEXT_BASE
_TEXT_BASE:
#if defined(CONFIG_SPL_BUILD)
   .quad   CONFIG_SPL_TEXT_BASE
#else
   .quad    CONFIG_SYS_TEXT_BASE
#endif
 
/*
 * These are defined in the linker script.
 */
.globl    _end_ofs
_end_ofs:
   .quad    _end - _start
 
.globl    _bss_start_ofs
_bss_start_ofs:
   .quad    __bss_start - _start
 
.globl    _bss_end_ofs
_bss_end_ofs:
   .quad    __bss_end - _start
 
reset:
   /* Allow the board to save important registers */
   b    save_boot_params
.globl    save_boot_params_ret
save_boot_params_ret:
 
#if CONFIG_POSITION_INDEPENDENT
   /*
    * Fix .rela.dyn relocations. This allows U-Boot to be loaded to and
    * executed at a different address than it was linked at.
    */
pie_fixup:
   adr    x0, _start        /* x0 <- Runtime value of _start */
   ldr    x1, _TEXT_BASE        /* x1 <- Linked value of _start */
   sub    x9, x0, x1        /* x9 <- Run-vs-link offset */
   adr    x2, __rel_dyn_start    /* x2 <- Runtime &__rel_dyn_start */
   adr    x3, __rel_dyn_end    /* x3 <- Runtime &__rel_dyn_end */
pie_fix_loop:
   ldp    x0, x1, [x2], #16    /* (x0, x1) <- (Link location, fixup) */
   ldr    x4, [x2], #8        /* x4 <- addend */
   cmp    w1, #1027        /* relative fixup? */
   bne    pie_skip_reloc
   /* relative fix: store addend plus offset at dest location */
   add    x0, x0, x9
   add    x4, x4, x9
   str    x4, [x0]
pie_skip_reloc:
   cmp    x2, x3
   b.lo    pie_fix_loop
pie_fixup_done:
#endif
 
#ifdef CONFIG_SYS_RESET_SCTRL
   bl reset_sctrl
#endif
   /*
    * Could be EL3/EL2/EL1, Initial State:
    * Little Endian, MMU Disabled, i/dCache Disabled
    */
   adr    x0, vectors
   switch_el x1, 3f, 2f, 1f
3:    msr    vbar_el3, x0
   mrs    x0, scr_el3
   orr    x0, x0, #0xf            /* SCR_EL3.NS|IRQ|FIQ|EA */
   msr    scr_el3, x0
   msr    cptr_el3, xzr            /* Enable FP/SIMD */
#ifdef COUNTER_FREQUENCY
   ldr    x0, =COUNTER_FREQUENCY
   msr    cntfrq_el0, x0            /* Initialize CNTFRQ */
#endif
   b    0f
2:    msr    vbar_el2, x0
   mov    x0, #0x33ff
   msr    cptr_el2, x0            /* Enable FP/SIMD */
   b    0f
1:    msr    vbar_el1, x0
   mov    x0, #3 << 20
   msr    cpacr_el1, x0            /* Enable FP/SIMD */
0:
 
   /*
    * Enable instruction cache (if required), stack pointer,
    * data access alignment checks and SError.
    */
#ifndef CONFIG_SYS_ICACHE_OFF
   mov x1, #CR_I
#else
   mov x1, #0
#endif
   switch_el x2, 3f, 2f, 1f
3:    mrs    x0, sctlr_el3
   orr    x0, x0, x1
   msr    sctlr_el3, x0
#ifndef CONFIG_SUPPORT_USBPLUG
   msr    daifclr, #4            /* Enable SError. SCR_EL3.EA=1 was already set in start.S */
#endif
   b    0f
2:    mrs    x0, sctlr_el2
   orr    x0, x0, x1
   msr    sctlr_el2, x0
 
   mrs    x0, hcr_el2
   orr    x0, x0, #HCR_EL2_TGE
   orr    x0, x0, #HCR_EL2_AMO
#if CONFIG_IS_ENABLED(IRQ)
   orr    x0, x0, #HCR_EL2_IMO
#endif
   msr    hcr_el2, x0
   msr    daifclr, #4
   b    0f
1:    mrs    x0, sctlr_el1
   orr    x0, x0, x1
   msr    sctlr_el1, x0
   msr    daifclr, #4
0:
   isb
 
   /*
    * Enable SMPEN bit for coherency.
    * This register is not architectural but at the moment
    * this bit should be set for A53/A57/A72.
    */
#ifdef CONFIG_ARMV8_SET_SMPEN
   switch_el x1, 3f, 1f, 1f
3:
   mrs     x0, S3_1_c15_c2_1               /* cpuectlr_el1 */
   orr     x0, x0, #0x40
   msr     S3_1_c15_c2_1, x0
1:
#endif
 
   /* Apply ARM core specific erratas */
   bl    apply_core_errata
 
   /*
    * Cache/BPB/TLB Invalidate
    * i-cache is invalidated before enabled in icache_enable()
    * tlb is invalidated before mmu is enabled in dcache_enable()
    * d-cache is invalidated before enabled in dcache_enable()
    */
 
   /* Processor specific initialization */
   bl    lowlevel_init
 
#if defined(CONFIG_ARMV8_SPIN_TABLE) && !defined(CONFIG_SPL_BUILD)
   branch_if_master x0, x1, master_cpu
   b    spin_table_secondary_jump
   /* never return */
#elif defined(CONFIG_ARMV8_MULTIENTRY)
   branch_if_master x0, x1, master_cpu
 
   /*
    * Slave CPUs
    */
slave_cpu:
   wfe
   ldr    x1, =CPU_RELEASE_ADDR
   ldr    x0, [x1]
   cbz    x0, slave_cpu
   br    x0            /* branch to the given address */
#endif /* CONFIG_ARMV8_MULTIENTRY */
 
#if defined(CONFIG_SPL_BUILD) && defined(CONFIG_ARM_SMP)
   mrs    x0, mpidr_el1
   and x0, x0, #0xfff
   cmp x0, #0
   beq master_cpu
 
#ifdef SMP_CPU1
   cmp x0, #(SMP_CPU1)
   ldr x1, =(SMP_CPU1_STACK)
   beq slave_cpu
#endif
 
#ifdef SMP_CPU2
   cmp x0, #(SMP_CPU2)
   ldr x1, =(SMP_CPU2_STACK)
   beq slave_cpu
#endif
 
#ifdef SMP_CPU3
   cmp x0, #(SMP_CPU3)
   ldr x1, =(SMP_CPU3_STACK)
   beq slave_cpu
#endif
   dsb sy
   isb
 
loop:
   wfe
   b loop
 
slave_cpu:
   bic    sp, x1, #0xf
   bl    smp_entry
   b    loop
#endif
 
master_cpu:
   bl    _main
 
#ifdef CONFIG_SYS_RESET_SCTRL
reset_sctrl:
   switch_el x1, 3f, 2f, 1f
3:
   mrs    x0, sctlr_el3
   b    0f
2:
   mrs    x0, sctlr_el2
   b    0f
1:
   mrs    x0, sctlr_el1
 
0:
   ldr    x1, =0xfdfffffa
   and    x0, x0, x1
 
   switch_el x1, 6f, 5f, 4f
6:
   msr    sctlr_el3, x0
   b    7f
5:
   msr    sctlr_el2, x0
   b    7f
4:
   msr    sctlr_el1, x0
 
7:
   dsb    sy
   isb
   b    __asm_invalidate_tlb_all
   ret
#endif
 
/*-----------------------------------------------------------------------*/
 
WEAK(apply_core_errata)
 
   mov    x29, lr            /* Save LR */
   /* For now, we support Cortex-A57 specific errata only */
 
   /* Check if we are running on a Cortex-A57 core */
   branch_if_a57_core x0, apply_a57_core_errata
0:
   mov    lr, x29            /* Restore LR */
   ret
 
apply_a57_core_errata:
 
#ifdef CONFIG_ARM_ERRATA_828024
   mrs    x0, S3_1_c15_c2_0    /* cpuactlr_el1 */
   /* Disable non-allocate hint of w-b-n-a memory type */
   orr    x0, x0, #1 << 49
   /* Disable write streaming no L1-allocate threshold */
   orr    x0, x0, #3 << 25
   /* Disable write streaming no-allocate threshold */
   orr    x0, x0, #3 << 27
   msr    S3_1_c15_c2_0, x0    /* cpuactlr_el1 */
#endif
 
#ifdef CONFIG_ARM_ERRATA_826974
   mrs    x0, S3_1_c15_c2_0    /* cpuactlr_el1 */
   /* Disable speculative load execution ahead of a DMB */
   orr    x0, x0, #1 << 59
   msr    S3_1_c15_c2_0, x0    /* cpuactlr_el1 */
#endif
 
#ifdef CONFIG_ARM_ERRATA_833471
   mrs    x0, S3_1_c15_c2_0    /* cpuactlr_el1 */
   /* FPSCR write flush.
    * Note that in some cases where a flush is unnecessary this
       could impact performance. */
   orr    x0, x0, #1 << 38
   msr    S3_1_c15_c2_0, x0    /* cpuactlr_el1 */
#endif
 
#ifdef CONFIG_ARM_ERRATA_829520
   mrs    x0, S3_1_c15_c2_0    /* cpuactlr_el1 */
   /* Disable Indirect Predictor bit will prevent this erratum
       from occurring
    * Note that in some cases where a flush is unnecessary this
       could impact performance. */
   orr    x0, x0, #1 << 4
   msr    S3_1_c15_c2_0, x0    /* cpuactlr_el1 */
#endif
 
#ifdef CONFIG_ARM_ERRATA_833069
   mrs    x0, S3_1_c15_c2_0    /* cpuactlr_el1 */
   /* Disable Enable Invalidates of BTB bit */
   and    x0, x0, #0xE
   msr    S3_1_c15_c2_0, x0    /* cpuactlr_el1 */
#endif
   b 0b
ENDPROC(apply_core_errata)
 
/*-----------------------------------------------------------------------*/
 
WEAK(lowlevel_init)
   mov    x29, lr            /* Save LR */
 
#if CONFIG_IS_ENABLED(IRQ)
   branch_if_slave x0, 1f
   ldr    x0, =GICD_BASE
   bl    gic_init_secure
1:
#if defined(CONFIG_GICV3)
   ldr    x0, =GICR_BASE
   bl    gic_init_secure_percpu
#elif defined(CONFIG_GICV2)
   ldr    x0, =GICD_BASE
   ldr    x1, =GICC_BASE
   bl    gic_init_secure_percpu
#endif
#endif
 
#ifdef CONFIG_ARMV8_MULTIENTRY
   branch_if_master x0, x1, 2f
 
   /*
    * Slave should wait for master clearing spin table.
    * This sync prevent salves observing incorrect
    * value of spin table and jumping to wrong place.
    */
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
#ifdef CONFIG_GICV2
   ldr    x0, =GICC_BASE
#endif
   bl    gic_wait_for_interrupt
#endif
 
   /*
    * All slaves will enter EL2 and optionally EL1.
    */
   adr    x4, lowlevel_in_el2
   ldr    x5, =ES_TO_AARCH64
   bl    armv8_switch_to_el2
 
lowlevel_in_el2:
#ifdef CONFIG_ARMV8_SWITCH_TO_EL1
   adr    x4, lowlevel_in_el1
   ldr    x5, =ES_TO_AARCH64
   bl    armv8_switch_to_el1
 
lowlevel_in_el1:
#endif
 
#endif /* CONFIG_ARMV8_MULTIENTRY */
 
2:
   mov    lr, x29            /* Restore LR */
   ret
ENDPROC(lowlevel_init)
 
WEAK(smp_kick_all_cpus)
   /* Kick secondary cpus up by SGI 0 interrupt */
#if defined(CONFIG_GICV2) || defined(CONFIG_GICV3)
   ldr    x0, =GICD_BASE
   b    gic_kick_secondary_cpus
#endif
   ret
ENDPROC(smp_kick_all_cpus)
 
/*-----------------------------------------------------------------------*/
 
ENTRY(c_runtime_cpu_setup)
   /* Relocate vBAR */
   adr    x0, vectors
   switch_el x1, 3f, 2f, 1f
3:    msr    vbar_el3, x0
   b    0f
2:    msr    vbar_el2, x0
   b    0f
1:    msr    vbar_el1, x0
0:
 
   ret
ENDPROC(c_runtime_cpu_setup)
 
WEAK(save_boot_params)
   b    save_boot_params_ret    /* back to my caller */
ENDPROC(save_boot_params)
#endif