Fork us on GitHub Follow us on Facebook Follow us on Twitter

Changeset 95b7d4df in mainline for boot/arch/arm64/src/asm.S


Ignore:
Timestamp:
2021-08-22T17:05:13Z (8 weeks ago)
Author:
Martin Decky <martin@…>
Branches:
master
Children:
06f10ac
Parents:
99589a9
Message:

Improve boot loader versatility

Add support for booting from EL3 and EL2, make sure instruction and
data caches are coherent on real hardware.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • boot/arch/arm64/src/asm.S

    r99589a9 r95b7d4df  
    135135        add x1, x1, #:lo12:_DYNAMIC
    136136        bl self_relocate
    137         cbnz x0, 0f
     137        cbnz x0, __uefi_exit
     138
     139        /*
     140         * Flush the instruction cache of the relocated boot loader image.
     141         */
     142        adr x0, msdos_stub
     143        adrp x1, payload_end
     144        sub x1, x1, x0
     145        bl smc_coherence
    138146
    139147        /*
     
    145153        bl bootstrap
    146154
    147 0:
    148         ldp x29, x30, [sp], #32
    149         ret
     155        __uefi_exit:
     156                ldp x29, x30, [sp], #32
     157                ret
    150158
    151159FUNCTION_BEGIN(halt)
     
    155163FUNCTION_END(halt)
    156164
     165/** Flush instruction caches
     166 *
     167 * @param x0 Starting address of the flushing.
     168 * @param x1 Number of bytes to flush.
     169 *
     170 */
     171FUNCTION_BEGIN(smc_coherence)
     172        .hidden smc_coherence
     173
     174        /* Initialize loop */
     175        mov x9, x0
     176        mov x10, xzr
     177
     178        __dc_loop:
     179                /* Data or Unified Cache Line Clean */
     180                dc cvau, x9
     181                add x9, x9, #4
     182                add x10, x10, #4
     183                cmp x10, x1
     184                blo __dc_loop
     185
     186        dsb ish
     187
     188        /* Initialize loop */
     189        mov x9, x0
     190        mov x10, xzr
     191
     192        __ic_loop:
     193                /* Instruction Cache Line Invalidate */
     194                ic ivau, x9
     195                add x9, x9, #4
     196                add x10, x10, #4
     197                cmp x10, x1
     198                blo __ic_loop
     199
     200        dsb ish
     201        isb
     202        ret
     203FUNCTION_END(smc_coherence)
     204
     205/** Flush data caches
     206 *
     207 * @param x0 Starting address of the flushing.
     208 * @param x1 Number of bytes to flush.
     209 *
     210 */
     211FUNCTION_BEGIN(dcache_flush)
     212        .hidden dcache_flush
     213
     214        mov x9, x0
     215        mov x10, xzr
     216
     217        __dc_flush_loop:
     218                /* Data or Unified Cache Line Clean */
     219                dc cvau, x9
     220                add x9, x9, #4
     221                add x10, x10, #4
     222                cmp x10, x1
     223                blo __dc_flush_loop
     224
     225        dsb ish
     226        isb
     227        ret
     228FUNCTION_END(dcache_flush)
     229
     230/** Kernel entry
     231 *
     232 * @param x0 Kernel entry point.
     233 * @param x1 Pointer to the bootinfo structure.
     234 *
     235 */
    157236FUNCTION_BEGIN(jump_to_kernel)
    158237        .hidden jump_to_kernel
    159238
    160         /*
    161          * Parameters:
    162          * x0 is kernel entry point.
    163          * x1 is pointer to the bootinfo structure.
    164          */
    165 
    166         /* Disable MMU (removes the identity mapping provided by UEFI). */
    167         mrs x2, sctlr_el1
    168         bic x2, x2, #SCTLR_M_FLAG
    169         msr sctlr_el1, x2
    170         isb
    171 
    172         br x0
     239        mrs x9, CurrentEL
     240        lsr x9, x9, 2
     241
     242        cmp x9, #3
     243        b.eq __el3
     244
     245        cmp x9, #2
     246        b.eq __el2
     247
     248        cmp x9, #1
     249        b.eq __el1
     250
     251        b halt
     252
     253        __el3:
     254                msr sctlr_el2, xzr
     255                msr hcr_el2, xzr
     256                isb
     257
     258                /* EL2 is AArch64, EL1 is Non-secure World */
     259                mov x9, #(1 << 10)
     260                orr x9, x9, #(1 << 0)
     261                msr scr_el3, x9
     262                isb
     263
     264                /* EL2h */
     265                mov x9, #0x9
     266                msr spsr_el3, x9
     267                isb
     268
     269                adr x9, __el2
     270                msr elr_el3, x9
     271                isb
     272
     273                /* Switch to EL2 */
     274                eret
     275
     276        __el2:
     277                msr sctlr_el1, xzr
     278                isb
     279
     280                /* EL1 is AArch64 */
     281                mov x9, #(1 << 31)
     282                msr hcr_el2, x9
     283                isb
     284
     285                /* EL1h */
     286                mov x9, #0x5
     287                msr spsr_el2, x9
     288                isb
     289
     290                adr x9, __el1
     291                msr elr_el2, x9
     292                isb
     293
     294                /* Switch to EL1 */
     295                eret
     296
     297        __el1:
     298                /* Do not trap on FPU instructions */
     299                mrs x9, cpacr_el1
     300                orr x9, x9, #(3 << 20)
     301                msr cpacr_el1, x9
     302                dmb ish
     303
     304                /* Disable MMU (removes the identity mapping provided by UEFI) */
     305                mrs x9, sctlr_el1
     306                bic x9, x9, #SCTLR_M_FLAG
     307                msr sctlr_el1, x9
     308                isb
     309
     310                br x0
    173311FUNCTION_END(jump_to_kernel)
Note: See TracChangeset for help on using the changeset viewer.