root/arch/arm64/kernel/efi-entry.S

/* [<][>][^][v][top][bottom][index][help] */
   1 /* SPDX-License-Identifier: GPL-2.0-only */
   2 /*
   3  * EFI entry point.
   4  *
   5  * Copyright (C) 2013, 2014 Red Hat, Inc.
   6  * Author: Mark Salter <msalter@redhat.com>
   7  */
   8 #include <linux/linkage.h>
   9 #include <linux/init.h>
  10 
  11 #include <asm/assembler.h>
  12 
  13 #define EFI_LOAD_ERROR 0x8000000000000001
  14 
  15         __INIT
  16 
  17         /*
  18          * We arrive here from the EFI boot manager with:
  19          *
  20          *    * CPU in little-endian mode
  21          *    * MMU on with identity-mapped RAM
  22          *    * Icache and Dcache on
  23          *
  24          * We will most likely be running from some place other than where
  25          * we want to be. The kernel image wants to be placed at TEXT_OFFSET
  26          * from start of RAM.
  27          */
  28 ENTRY(entry)
  29         /*
  30          * Create a stack frame to save FP/LR with extra space
  31          * for image_addr variable passed to efi_entry().
  32          */
  33         stp     x29, x30, [sp, #-32]!
  34         mov     x29, sp
  35 
  36         /*
  37          * Call efi_entry to do the real work.
  38          * x0 and x1 are already set up by firmware. Current runtime
  39          * address of image is calculated and passed via *image_addr.
  40          *
  41          * unsigned long efi_entry(void *handle,
  42          *                         efi_system_table_t *sys_table,
  43          *                         unsigned long *image_addr) ;
  44          */
  45         adr_l   x8, _text
  46         add     x2, sp, 16
  47         str     x8, [x2]
  48         bl      efi_entry
  49         cmn     x0, #1
  50         b.eq    efi_load_fail
  51 
  52         /*
  53          * efi_entry() will have copied the kernel image if necessary and we
  54          * return here with device tree address in x0 and the kernel entry
  55          * point stored at *image_addr. Save those values in registers which
  56          * are callee preserved.
  57          */
  58         mov     x20, x0         // DTB address
  59         ldr     x0, [sp, #16]   // relocated _text address
  60         ldr     w21, =stext_offset
  61         add     x21, x0, x21
  62 
  63         /*
  64          * Calculate size of the kernel Image (same for original and copy).
  65          */
  66         adr_l   x1, _text
  67         adr_l   x2, _edata
  68         sub     x1, x2, x1
  69 
  70         /*
  71          * Flush the copied Image to the PoC, and ensure it is not shadowed by
  72          * stale icache entries from before relocation.
  73          */
  74         bl      __flush_dcache_area
  75         ic      ialluis
  76 
  77         /*
  78          * Ensure that the rest of this function (in the original Image) is
  79          * visible when the caches are disabled. The I-cache can't have stale
  80          * entries for the VA range of the current image, so no maintenance is
  81          * necessary.
  82          */
  83         adr     x0, entry
  84         adr     x1, entry_end
  85         sub     x1, x1, x0
  86         bl      __flush_dcache_area
  87 
  88         /* Turn off Dcache and MMU */
  89         mrs     x0, CurrentEL
  90         cmp     x0, #CurrentEL_EL2
  91         b.ne    1f
  92         mrs     x0, sctlr_el2
  93         bic     x0, x0, #1 << 0 // clear SCTLR.M
  94         bic     x0, x0, #1 << 2 // clear SCTLR.C
  95         pre_disable_mmu_workaround
  96         msr     sctlr_el2, x0
  97         isb
  98         b       2f
  99 1:
 100         mrs     x0, sctlr_el1
 101         bic     x0, x0, #1 << 0 // clear SCTLR.M
 102         bic     x0, x0, #1 << 2 // clear SCTLR.C
 103         pre_disable_mmu_workaround
 104         msr     sctlr_el1, x0
 105         isb
 106 2:
 107         /* Jump to kernel entry point */
 108         mov     x0, x20
 109         mov     x1, xzr
 110         mov     x2, xzr
 111         mov     x3, xzr
 112         br      x21
 113 
 114 efi_load_fail:
 115         mov     x0, #EFI_LOAD_ERROR
 116         ldp     x29, x30, [sp], #32
 117         ret
 118 
 119 entry_end:
 120 ENDPROC(entry)

/* [<][>][^][v][top][bottom][index][help] */