entry_point.S 8.6 KB
Newer Older
1
/*
S
Shell 已提交
2
 * Copyright (c) 2006-2020, RT-Thread Development Team
3 4 5 6 7 8 9 10
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Date           Author       Notes
 * 2020-01-15     bigmagic     the first version
 * 2020-08-10     SummerGift   support clang compiler
 */

G
GuEe-GUI 已提交
11
#include "rtconfig.h"
S
Shell 已提交
12 13
.section ".text.entrypoint","ax"
.global __start
14

S
Shell 已提交
15 16 17 18 19 20 21 22 23 24 25 26 27 28
__start:
#ifdef ARCH_ARM_BOOTWITH_FLUSH_CACHE
    bl      __asm_flush_dcache_all
#endif
    bl      rt_hw_cpu_id_set
    /* read cpu id, stop slave cores */
    mrs     x0, tpidr_el1
    cbz     x0, .L__cpu_0           /* .L prefix is the local label in ELF */

    /* cpu id > 0, stop */
    /* cpu id == 0 will also goto here after returned from entry() if possible */
.L__current_cpu_idle:
    wfe
    b       .L__current_cpu_idle
G
GuEe-GUI 已提交
29

S
Shell 已提交
30 31 32
.L__cpu_0:
    /* set stack before our code, Define stack pointer for current exception level */
    adr     x1, __start
33

S
Shell 已提交
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
    /* set up EL1 */
    mrs     x0, CurrentEL           /* CurrentEL Register. bit 2, 3. Others reserved */
    and     x0, x0, #12             /* clear reserved bits */

    /* running at EL3? */
    cmp     x0, #12                 /* 1100b. So, EL3 */
    bne     .L__not_in_el3          /* 11?  !EL3 -> 5: */

    /* should never be executed, just for completeness. (EL3) */
    mov     x2, #0x5b1
    msr     scr_el3, x2             /* SCR_ELn  Secure Configuration Register */
    mov     x2, #0x3c9
    msr     spsr_el3, x2            /* SPSR_ELn. Saved Program Status Register. 1111001001 */
    adr     x2, .L__not_in_el3
    msr     elr_el3, x2
    eret                            /* Exception Return: from EL3, continue from .L__not_in_el3 */

.L__not_in_el3:                     /* running at EL2 or EL1 */
    cmp     x0, #4                  /* 0x04  0100 EL1 */
    beq     .L__in_el1              /* EL1 -> 5: */

    mrs     x0, hcr_el2
    bic     x0, x0, #0xff
    msr     hcr_el2, x0

    msr     sp_el1, x1              /* in EL2, set sp of EL1 to _start */

    /* enable CNTP for EL1 */
    mrs     x0, cnthctl_el2         /* Counter-timer Hypervisor Control register */
    orr     x0, x0, #3
    msr     cnthctl_el2, x0
    msr     cntvoff_el2, xzr

    /* enable AArch64 in EL1 */
    mov     x0, #(1 << 31)          /* AArch64 */
    orr     x0, x0, #(1 << 1)       /* SWIO hardwired on Pi3 */
    msr     hcr_el2, x0
    mrs     x0, hcr_el2

    /* change execution level to EL1 */
    mov     x2, #0x3c4
    msr     spsr_el2, x2            /* 1111000100 */
    adr     x2, .L__in_el1
    msr     elr_el2, x2

    eret                            /* exception return. from EL2. continue from .L__in_el1 */

.L__in_el1:
#ifdef RT_USING_LWP
    ldr     x9, =PV_OFFSET
#else
    mov     x9, #0
#endif
    mov     sp, x1                  /* in EL1. Set sp to _start */

    /* Set CPACR_EL1 (Architecture Feature Access Control Register) to avoid trap from SIMD or float point instruction */
    mov     x1, #0x00300000         /* Don't trap any SIMD/FP instructions in both EL0 and EL1 */
    msr     cpacr_el1, x1

    /* clear bss */
    ldr     x1, =__bss_start     /* get bss start address */
    ldr     x2, =__bss_end
    sub     x2, x2, x1            /* get bss size          */
    add     x1, x1, x9

    and     x3, x2, #7           /* x3 is < 7 */
    ldr     x4, =~0x7
    and     x2, x2, x4            /* mask ~7 */

.L__clean_bss_loop:
    cbz     x2, .L__clean_bss_loop_1
    str     xzr, [x1], #8
    sub     x2, x2, #8
    b       .L__clean_bss_loop

.L__clean_bss_loop_1:
    cbz     x3, .L__jump_to_entry
    strb    wzr, [x1], #1
    sub     x3, x3, #1
    b       .L__clean_bss_loop_1

.L__jump_to_entry:          /* jump to C code, should not return */        
    bl mmu_tcr_init

    adr x1, __start
    ldr x0, =~0x1fffff
    and x0, x1, x0
    add x1, x0, #0x1000

    msr ttbr0_el1, x0
    msr ttbr1_el1, x1
    dsb sy

    ldr x2, =0x40000000      /* map 1G memory for kernel space */
#ifdef RT_USING_LWP
    ldr x3, =PV_OFFSET
130
#endif
S
Shell 已提交
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
    bl rt_hw_mmu_setup_early

    ldr x30, =after_mmu_enable  /* set LR to after_mmu_enable function, it's a v_addr */

    mrs x1, sctlr_el1
    bic x1, x1, #(3 << 3)    /* dis SA, SA0 */
    bic x1, x1, #(1 << 1)    /* dis A */
    orr x1, x1, #(1 << 12)   /* I */
    orr x1, x1, #(1 << 2)    /* C */
    orr x1, x1, #(1 << 0)    /* M */
    msr sctlr_el1, x1        /* enable MMU */

    dsb sy
    isb sy
    ic ialluis               /* Invalidate all instruction caches in Inner Shareable domain to Point of Unification */
    dsb sy
    isb sy
    tlbi vmalle1             /* Invalidate all stage 1 translations used at EL1 with the current VMID */
    dsb sy
    isb sy
    ret

after_mmu_enable:
#ifdef RT_USING_LWP
    mrs x0, tcr_el1          /* disable ttbr0, only using kernel space */
    orr x0, x0, #(1 << 7)
    msr tcr_el1, x0
    msr ttbr0_el1, xzr
    dsb sy
#endif

    mov     x0, #1
    msr     spsel, x0
    adr     x1, __start
    mov     sp, x1           /* sp_el1 set to _start */
166

S
Shell 已提交
167
    b  rtthread_startup
G
GuEe-GUI 已提交
168 169

#ifdef RT_USING_SMP
S
Shell 已提交
170 171 172
/**
 *  secondary cpu
 */
173

S
Shell 已提交
174 175 176 177
.globl _secondary_cpu_entry
_secondary_cpu_entry:
    bl      rt_hw_cpu_id_set
    adr     x1, __start
178

S
Shell 已提交
179
    /* set up EL1 */
180
    mrs     x0, CurrentEL           /* CurrentEL Register. bit 2, 3. Others reserved */
S
Shell 已提交
181 182 183 184 185 186 187 188 189 190 191 192
    and     x0, x0, #12             /* clear reserved bits */

    /* running at EL3? */
    cmp     x0, #12                 /* 1100b. So, EL3 */
    bne     .L__not_in_el3_cpux          /* 11?  !EL3 -> 5: */

    /* should never be executed, just for completeness. (EL3) */
    mov     x2, #0x5b1
    msr     scr_el3, x2             /* SCR_ELn  Secure Configuration Register */
    mov     x2, #0x3c9
    msr     spsr_el3, x2            /* SPSR_ELn. Saved Program Status Register. 1111001001 */
    adr     x2, .L__not_in_el3_cpux
193
    msr     elr_el3, x2
S
Shell 已提交
194 195 196 197 198 199 200 201 202
    eret                            /* Exception Return: from EL3, continue from .L__not_in_el3 */

.L__not_in_el3_cpux:                     /* running at EL2 or EL1 */
    cmp     x0, #4                  /* 0x04  0100 EL1 */
    beq     .L__in_el1_cpux              /* EL1 -> 5: */
 
    mrs     x0, hcr_el2
    bic     x0, x0, #0xff
    msr     hcr_el2, x0
203

S
Shell 已提交
204
    msr     sp_el1, x1              /* in EL2, set sp of EL1 to _start */
205

S
Shell 已提交
206
    /* enable CNTP for EL1 */
207 208 209 210 211
    mrs     x0, cnthctl_el2         /* Counter-timer Hypervisor Control register */
    orr     x0, x0, #3
    msr     cnthctl_el2, x0
    msr     cntvoff_el2, xzr

S
Shell 已提交
212 213
    /* enable AArch64 in EL1 */
    mov     x0, #(1 << 31)          /* AArch64 */
214 215
    orr     x0, x0, #(1 << 1)       /* SWIO hardwired on Pi3 */
    msr     hcr_el2, x0
S
Shell 已提交
216
    mrs     x0, hcr_el2
217

S
Shell 已提交
218 219 220 221
    /* change execution level to EL1 */
    mov     x2, #0x3c4
    msr     spsr_el2, x2            /* 1111000100 */
    adr     x2, .L__in_el1_cpux
222 223
    msr     elr_el2, x2

S
Shell 已提交
224
    eret                            /* exception return. from EL2. continue from .L__in_el1 */
225

S
Shell 已提交
226 227 228 229
.L__in_el1_cpux:
    adr     x19, .L__in_el1_cpux
    ldr     x8, =.L__in_el1_cpux
    sub     x19, x19, x8            /* get PV_OFFSET            */
230

S
Shell 已提交
231 232 233 234
    mrs     x0, tpidr_el1
    /* each cpu init stack is 8k */
    sub     x1, x1, x0, lsl #13
    mov     sp, x1                  /* in EL1. Set sp to _start */
235

S
Shell 已提交
236 237 238
    /* Set CPACR_EL1 (Architecture Feature Access Control Register) to avoid trap from SIMD or float point instruction */
    mov     x1, #0x00300000         /* Don't trap any SIMD/FP instructions in both EL0 and EL1 */
    msr     cpacr_el1, x1
G
GuEe-GUI 已提交
239

S
Shell 已提交
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
.L__jump_to_entry_cpux:                   /* jump to C code, should not return */

    /* init mmu early */

    bl mmu_tcr_init

    adr x1, __start
    ldr x0, =~0x1fffff
    and x0, x1, x0
    add x1, x0, #0x1000

    msr ttbr0_el1, x0
    msr ttbr1_el1, x1
    dsb sy

    ldr x30, =after_mmu_enable_cpux  /* set LR to after_mmu_enable function, it's a v_addr */

    mrs x1, sctlr_el1
    bic x1, x1, #(3 << 3)    /* dis SA, SA0 */
    bic x1, x1, #(1 << 1)    /* dis A */
    orr x1, x1, #(1 << 12)   /* I */
    orr x1, x1, #(1 << 2)    /* C */
    orr x1, x1, #(1 << 0)    /* M */
    msr sctlr_el1, x1        /* enable MMU */

    dsb sy
    isb sy
    ic ialluis               /* Invalidate all instruction caches in Inner Shareable domain to Point of Unification */
    dsb sy
    isb sy
    tlbi vmalle1             /* Invalidate all stage 1 translations used at EL1 with the current VMID */
    dsb sy
    isb sy
    ret

after_mmu_enable_cpux:
    mrs x0, tcr_el1          /* disable ttbr0, only using kernel space */
    orr x0, x0, #(1 << 7)
    msr tcr_el1, x0
    msr ttbr0_el1, xzr
    dsb sy

    mov     x0, #1
    msr     spsel, x0
    mrs     x0, tpidr_el1
    /* each cpu init stack is 8k */
    adr     x1, __start
    sub     x1, x1, x0, lsl #13
    mov     sp, x1                  /* in EL1. Set sp to _start */

    b rt_hw_secondary_cpu_bsp_start
G
GuEe-GUI 已提交
291
#endif