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