Changeset 95b7d4df in mainline


Ignore:
Timestamp:
2021-08-22T17:05:13Z (3 years ago)
Author:
Martin Decky <martin@…>
Branches:
master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
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.

Location:
boot/arch/arm64
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • boot/arch/arm64/include/arch/barrier.h

    • Property mode changed from 120000 to 100644
    r99589a9 r95b7d4df  
    1 ../../../../../kernel/arch/arm64/include/arch/barrier.h
     1/*
     2 * Copyright (c) 2015 Petr Pavlu
     3 * All rights reserved.
     4 *
     5 * Redistribution and use in source and binary forms, with or without
     6 * modification, are permitted provided that the following conditions
     7 * are met:
     8 *
     9 * - Redistributions of source code must retain the above copyright
     10 *   notice, this list of conditions and the following disclaimer.
     11 * - Redistributions in binary form must reproduce the above copyright
     12 *   notice, this list of conditions and the following disclaimer in the
     13 *   documentation and/or other materials provided with the distribution.
     14 * - The name of the author may not be used to endorse or promote products
     15 *   derived from this software without specific prior written permission.
     16 *
     17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 */
     28
     29/** @addtogroup boot_arm64
     30 * @{
     31 */
     32/** @file
     33 * @brief Memory barriers.
     34 */
     35
     36#ifndef BOOT_arm64_BARRIER_H_
     37#define BOOT_arm64_BARRIER_H_
     38
     39#include <stddef.h>
     40
     41extern void smc_coherence(void *, size_t);
     42extern void dcache_flush(void *, size_t);
     43
     44#endif
     45
     46/** @}
     47 */
  • 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)
  • boot/arch/arm64/src/main.c

    r99589a9 r95b7d4df  
    116116{
    117117        efi_status_t status;
    118         uint64_t current_el;
    119118        uint64_t memmap = 0;
    120119        sysarg_t memmap_size;
     
    143142        printf(" %p|%p: UEFI system table\n", efi_system_table_in,
    144143            efi_system_table_in);
    145 
    146         /* Validate the exception level. */
    147         current_el = CurrentEL_read();
    148         if (current_el != CURRENT_EL_EL1) {
    149                 printf("Error: Unexpected CurrentEL value %0#18" PRIx64 ".\n",
    150                     current_el);
    151                 status = EFI_UNSUPPORTED;
    152                 goto fail;
    153         }
    154144
    155145        /* Obtain memory map. */
     
    187177
    188178        /*
    189          * Check that everything is aligned on a 4kB boundary and the kernel can
     179         * Check that everything is aligned on a 4 KiB boundary and the kernel can
    190180         * be placed by the decompression code at a correct address.
    191181         */
     
    199189         * Dynamically check the memory base. The condition should be always
    200190         * true because UEFI guarantees each physical/virtual address in the
    201          * memory map is aligned on a 4kB boundary.
     191         * memory map is aligned on a 4 KiB boundary.
    202192         */
    203193        if (!IS_ALIGNED(memory_base, PAGE_SIZE)) {
    204194                printf("Error: Start of usable RAM (%p) is not aligned on a "
    205                     "4kB boundary.\n", (void *) memory_base);
     195                    "4 KiB boundary.\n", (void *) memory_base);
    206196                status = EFI_UNSUPPORTED;
    207197                goto fail;
     
    243233
    244234        extract_payload(&bootinfo->taskmap, kernel_dest, ram_end,
    245             (uintptr_t) kernel_dest, ensure_visibility);
     235            (uintptr_t) kernel_dest, smc_coherence);
    246236
    247237        /* Get final memory map. */
     
    301291        bootinfo->memmap.cnt = cnt;
    302292
     293        /* Flush the data cache containing bootinfo. */
     294        dcache_flush(bootinfo, sizeof(*bootinfo));
     295
    303296        uintptr_t entry = check_kernel_translated((void *) decompress_base,
    304297            BOOT_OFFSET);
Note: See TracChangeset for help on using the changeset viewer.