-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'arm64-efi-for-linus' of git://git.kernel.org/pub/scm/li…
…nux/kernel/git/tip/tip into next Pull ARM64 EFI update from Peter Anvin: "By agreement with the ARM64 EFI maintainers, we have agreed to make -tip the upstream for all EFI patches. That is why this patchset comes from me :) This patchset enables EFI stub support for ARM64, like we already have on x86" * 'arm64-efi-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: arm64: efi: only attempt efi map setup if booting via EFI efi/arm64: ignore dtb= when UEFI SecureBoot is enabled doc: arm64: add description of EFI stub support arm64: efi: add EFI stub doc: arm: add UEFI support documentation arm64: add EFI runtime services efi: Add shared FDT related functions for ARM/ARM64 arm64: Add function to create identity mappings efi: add helper function to get UEFI params from FDT doc: efi-stub.txt updates for ARM lib: add fdt_empty_tree.c
- Loading branch information
Showing
21 changed files
with
1,619 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
UEFI, the Unified Extensible Firmware Interface, is a specification | ||
governing the behaviours of compatible firmware interfaces. It is | ||
maintained by the UEFI Forum - http://www.uefi.org/. | ||
|
||
UEFI is an evolution of its predecessor 'EFI', so the terms EFI and | ||
UEFI are used somewhat interchangeably in this document and associated | ||
source code. As a rule, anything new uses 'UEFI', whereas 'EFI' refers | ||
to legacy code or specifications. | ||
|
||
UEFI support in Linux | ||
===================== | ||
Booting on a platform with firmware compliant with the UEFI specification | ||
makes it possible for the kernel to support additional features: | ||
- UEFI Runtime Services | ||
- Retrieving various configuration information through the standardised | ||
interface of UEFI configuration tables. (ACPI, SMBIOS, ...) | ||
|
||
For actually enabling [U]EFI support, enable: | ||
- CONFIG_EFI=y | ||
- CONFIG_EFI_VARS=y or m | ||
|
||
The implementation depends on receiving information about the UEFI environment | ||
in a Flattened Device Tree (FDT) - so is only available with CONFIG_OF. | ||
|
||
UEFI stub | ||
========= | ||
The "stub" is a feature that extends the Image/zImage into a valid UEFI | ||
PE/COFF executable, including a loader application that makes it possible to | ||
load the kernel directly from the UEFI shell, boot menu, or one of the | ||
lightweight bootloaders like Gummiboot or rEFInd. | ||
|
||
The kernel image built with stub support remains a valid kernel image for | ||
booting in non-UEFI environments. | ||
|
||
UEFI kernel support on ARM | ||
========================== | ||
UEFI kernel support on the ARM architectures (arm and arm64) is only available | ||
when boot is performed through the stub. | ||
|
||
When booting in UEFI mode, the stub deletes any memory nodes from a provided DT. | ||
Instead, the kernel reads the UEFI memory map. | ||
|
||
The stub populates the FDT /chosen node with (and the kernel scans for) the | ||
following parameters: | ||
________________________________________________________________________________ | ||
Name | Size | Description | ||
================================================================================ | ||
linux,uefi-system-table | 64-bit | Physical address of the UEFI System Table. | ||
-------------------------------------------------------------------------------- | ||
linux,uefi-mmap-start | 64-bit | Physical address of the UEFI memory map, | ||
| | populated by the UEFI GetMemoryMap() call. | ||
-------------------------------------------------------------------------------- | ||
linux,uefi-mmap-size | 32-bit | Size in bytes of the UEFI memory map | ||
| | pointed to in previous entry. | ||
-------------------------------------------------------------------------------- | ||
linux,uefi-mmap-desc-size | 32-bit | Size in bytes of each entry in the UEFI | ||
| | memory map. | ||
-------------------------------------------------------------------------------- | ||
linux,uefi-mmap-desc-ver | 32-bit | Version of the mmap descriptor format. | ||
-------------------------------------------------------------------------------- | ||
linux,uefi-stub-kern-ver | string | Copy of linux_banner from build. | ||
-------------------------------------------------------------------------------- | ||
|
||
For verbose debug messages, specify 'uefi_debug' on the kernel command line. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
#ifndef _ASM_EFI_H | ||
#define _ASM_EFI_H | ||
|
||
#include <asm/io.h> | ||
|
||
#ifdef CONFIG_EFI | ||
extern void efi_init(void); | ||
extern void efi_idmap_init(void); | ||
#else | ||
#define efi_init() | ||
#define efi_idmap_init() | ||
#endif | ||
|
||
#endif /* _ASM_EFI_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
/* | ||
* EFI entry point. | ||
* | ||
* Copyright (C) 2013, 2014 Red Hat, Inc. | ||
* Author: Mark Salter <msalter@redhat.com> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
* | ||
*/ | ||
#include <linux/linkage.h> | ||
#include <linux/init.h> | ||
|
||
#include <asm/assembler.h> | ||
|
||
#define EFI_LOAD_ERROR 0x8000000000000001 | ||
|
||
__INIT | ||
|
||
/* | ||
* We arrive here from the EFI boot manager with: | ||
* | ||
* * CPU in little-endian mode | ||
* * MMU on with identity-mapped RAM | ||
* * Icache and Dcache on | ||
* | ||
* We will most likely be running from some place other than where | ||
* we want to be. The kernel image wants to be placed at TEXT_OFFSET | ||
* from start of RAM. | ||
*/ | ||
ENTRY(efi_stub_entry) | ||
/* | ||
* Create a stack frame to save FP/LR with extra space | ||
* for image_addr variable passed to efi_entry(). | ||
*/ | ||
stp x29, x30, [sp, #-32]! | ||
|
||
/* | ||
* Call efi_entry to do the real work. | ||
* x0 and x1 are already set up by firmware. Current runtime | ||
* address of image is calculated and passed via *image_addr. | ||
* | ||
* unsigned long efi_entry(void *handle, | ||
* efi_system_table_t *sys_table, | ||
* unsigned long *image_addr) ; | ||
*/ | ||
adrp x8, _text | ||
add x8, x8, #:lo12:_text | ||
add x2, sp, 16 | ||
str x8, [x2] | ||
bl efi_entry | ||
cmn x0, #1 | ||
b.eq efi_load_fail | ||
|
||
/* | ||
* efi_entry() will have relocated the kernel image if necessary | ||
* and we return here with device tree address in x0 and the kernel | ||
* entry point stored at *image_addr. Save those values in registers | ||
* which are callee preserved. | ||
*/ | ||
mov x20, x0 // DTB address | ||
ldr x0, [sp, #16] // relocated _text address | ||
mov x21, x0 | ||
|
||
/* | ||
* Flush dcache covering current runtime addresses | ||
* of kernel text/data. Then flush all of icache. | ||
*/ | ||
adrp x1, _text | ||
add x1, x1, #:lo12:_text | ||
adrp x2, _edata | ||
add x2, x2, #:lo12:_edata | ||
sub x1, x2, x1 | ||
|
||
bl __flush_dcache_area | ||
ic ialluis | ||
|
||
/* Turn off Dcache and MMU */ | ||
mrs x0, CurrentEL | ||
cmp x0, #PSR_MODE_EL2t | ||
ccmp x0, #PSR_MODE_EL2h, #0x4, ne | ||
b.ne 1f | ||
mrs x0, sctlr_el2 | ||
bic x0, x0, #1 << 0 // clear SCTLR.M | ||
bic x0, x0, #1 << 2 // clear SCTLR.C | ||
msr sctlr_el2, x0 | ||
isb | ||
b 2f | ||
1: | ||
mrs x0, sctlr_el1 | ||
bic x0, x0, #1 << 0 // clear SCTLR.M | ||
bic x0, x0, #1 << 2 // clear SCTLR.C | ||
msr sctlr_el1, x0 | ||
isb | ||
2: | ||
/* Jump to kernel entry point */ | ||
mov x0, x20 | ||
mov x1, xzr | ||
mov x2, xzr | ||
mov x3, xzr | ||
br x21 | ||
|
||
efi_load_fail: | ||
mov x0, #EFI_LOAD_ERROR | ||
ldp x29, x30, [sp], #32 | ||
ret | ||
|
||
ENDPROC(efi_stub_entry) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
/* | ||
* Copyright (C) 2013, 2014 Linaro Ltd; <roy.franz@linaro.org> | ||
* | ||
* This file implements the EFI boot stub for the arm64 kernel. | ||
* Adapted from ARM version by Mark Salter <msalter@redhat.com> | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU General Public License version 2 as | ||
* published by the Free Software Foundation. | ||
* | ||
*/ | ||
#include <linux/efi.h> | ||
#include <linux/libfdt.h> | ||
#include <asm/sections.h> | ||
#include <generated/compile.h> | ||
#include <generated/utsrelease.h> | ||
|
||
/* | ||
* AArch64 requires the DTB to be 8-byte aligned in the first 512MiB from | ||
* start of kernel and may not cross a 2MiB boundary. We set alignment to | ||
* 2MiB so we know it won't cross a 2MiB boundary. | ||
*/ | ||
#define EFI_FDT_ALIGN SZ_2M /* used by allocate_new_fdt_and_exit_boot() */ | ||
#define MAX_FDT_OFFSET SZ_512M | ||
|
||
#define efi_call_early(f, ...) sys_table_arg->boottime->f(__VA_ARGS__) | ||
|
||
static void efi_char16_printk(efi_system_table_t *sys_table_arg, | ||
efi_char16_t *str); | ||
|
||
static efi_status_t efi_open_volume(efi_system_table_t *sys_table, | ||
void *__image, void **__fh); | ||
static efi_status_t efi_file_close(void *handle); | ||
|
||
static efi_status_t | ||
efi_file_read(void *handle, unsigned long *size, void *addr); | ||
|
||
static efi_status_t | ||
efi_file_size(efi_system_table_t *sys_table, void *__fh, | ||
efi_char16_t *filename_16, void **handle, u64 *file_sz); | ||
|
||
/* Include shared EFI stub code */ | ||
#include "../../../drivers/firmware/efi/efi-stub-helper.c" | ||
#include "../../../drivers/firmware/efi/fdt.c" | ||
#include "../../../drivers/firmware/efi/arm-stub.c" | ||
|
||
|
||
static efi_status_t handle_kernel_image(efi_system_table_t *sys_table, | ||
unsigned long *image_addr, | ||
unsigned long *image_size, | ||
unsigned long *reserve_addr, | ||
unsigned long *reserve_size, | ||
unsigned long dram_base, | ||
efi_loaded_image_t *image) | ||
{ | ||
efi_status_t status; | ||
unsigned long kernel_size, kernel_memsize = 0; | ||
|
||
/* Relocate the image, if required. */ | ||
kernel_size = _edata - _text; | ||
if (*image_addr != (dram_base + TEXT_OFFSET)) { | ||
kernel_memsize = kernel_size + (_end - _edata); | ||
status = efi_relocate_kernel(sys_table, image_addr, | ||
kernel_size, kernel_memsize, | ||
dram_base + TEXT_OFFSET, | ||
PAGE_SIZE); | ||
if (status != EFI_SUCCESS) { | ||
pr_efi_err(sys_table, "Failed to relocate kernel\n"); | ||
return status; | ||
} | ||
if (*image_addr != (dram_base + TEXT_OFFSET)) { | ||
pr_efi_err(sys_table, "Failed to alloc kernel memory\n"); | ||
efi_free(sys_table, kernel_memsize, *image_addr); | ||
return EFI_ERROR; | ||
} | ||
*image_size = kernel_memsize; | ||
} | ||
|
||
|
||
return EFI_SUCCESS; | ||
} |
Oops, something went wrong.