Patch queue for efi - 2016-11-17

Highlights this time around:
 
   - x86 efi_loader support
   - hello world efi test case
   - network device name is now representative
   - terminal output reports modes correctly
   - fix psci reset for ls1043/ls1046
   - fix efi_add_runtime_mmio definition for x86
   - efi_loader support for ls2080
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABAgAGBQJYLa6qAAoJECszeR4D/txgF+4QAKpHJXY/1V+McEsLga2iwePZ
 lZu5NuuLeDA9IMH+ufOOGxDIoc/llZCTsqw5l8Vnkaz0JEH6v9svyEy4zC1Nqtj2
 r4pOhGLAyVlGAh4O3hFFi/eHNEDyTrMoPO6JCy8ce+fEGE21VBlWed0+/c/KdV7F
 85joTg3X+6htFMkLybzKZS1yiJyoROe7zUZdzPrn4ogwDGbazmYbED+P2u09dDzB
 WjlpIbmEDWJEska6Cbgl/ee6dBXSVl8Q/SY3V77T5TB554sZozrKDsNUehiUMEbh
 ggCT5VzPhsm4gb/7RBpTqqCabBT5ml8iKfB8Y7fwL43sDiMXJ1LgJyVnHuz65sCS
 aPPsPjQujBSiqr+k/571yhgFNLVydrs9IYNumZr+Li4UZCvx3xtCjACJVYkbLUd1
 SZrpKts0V45nZcE4IoiwDKOUxavUbLEef2SJTOAOppB3DG9L3O0TWkyH00hTkaxR
 oDIVNSZPt9wSd4Q7FQ2MYxQ/sk+B6PrN6Gm/NMSfCnvP8DkyTzHo514qrWnEjlhQ
 ndVmyJh3hpipNDfFDeF6r5lLtPkTrzNxOVZcsUGQC5jvrvwLWguD+Kuv9Qq4gSDp
 uDawZmRwDGEGpR/yJhqj8r6/e7bZ0fOE6nPqbWLlyF+Oc4yFTz+D2CNPGR4CR0iF
 DFGQN/lNkYbu+HfyZOFO
 =xmR3
 -----END PGP SIGNATURE-----

Merge tag 'signed-efi-next' of git://github.com/agraf/u-boot

Patch queue for efi - 2016-11-17

Highlights this time around:

  - x86 efi_loader support
  - hello world efi test case
  - network device name is now representative
  - terminal output reports modes correctly
  - fix psci reset for ls1043/ls1046
  - fix efi_add_runtime_mmio definition for x86
  - efi_loader support for ls2080
This commit is contained in:
Tom Rini 2016-11-17 11:46:45 -05:00
commit 9e40ea04e9
54 changed files with 1021 additions and 86 deletions

View file

@ -56,6 +56,7 @@ config CC_OPTIMIZE_FOR_SIZE
config DISTRO_DEFAULTS
bool "Select defaults suitable for booting general purpose Linux distributions"
default y if ARCH_SUNXI
default y if ARCH_LS2080A
default n
select CMD_BOOTZ if ARM && !ARM64
select CMD_BOOTI if ARM64

View file

@ -527,6 +527,15 @@ endif
endif
endif
# These are set by the arch-specific config.mk. Make sure they are exported
# so they can be used when building an EFI application.
export EFI_LDS # Filename of EFI link script in arch/$(ARCH)/lib
export EFI_CRT0 # Filename of EFI CRT0 in arch/$(ARCH)/lib
export EFI_RELOC # Filename of EFU relocation code in arch/$(ARCH)/lib
export CFLAGS_EFI # Compiler flags to add when building EFI app
export CFLAGS_NON_EFI # Compiler flags to remove when building EFI app
export EFI_TARGET # binutils target if EFI is natively supported
# If board code explicitly specified LDSCRIPT or CONFIG_SYS_LDSCRIPT, use
# that (or fail if absent). Otherwise, search for a linker script in a
# standard location.
@ -1131,7 +1140,7 @@ quiet_cmd_u-boot_payload ?= LD $@
cmd_u-boot_payload ?= $(LD) $(LDFLAGS_EFI_PAYLOAD) -o $@ \
-T u-boot-payload.lds arch/x86/cpu/call32.o \
lib/efi/efi.o lib/efi/efi_stub.o u-boot.bin.o \
$(addprefix arch/$(ARCH)/lib/efi/,$(EFISTUB))
$(addprefix arch/$(ARCH)/lib/,$(EFISTUB))
u-boot-payload: u-boot.bin.o u-boot-payload.lds FORCE
$(call if_changed,u-boot_payload)

View file

@ -13,6 +13,9 @@ CONFIG_STANDALONE_LOAD_ADDR = 0xc100000
endif
endif
CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections
CFLAGS_EFI := -fpic -fshort-wchar
LDFLAGS_FINAL += --gc-sections
PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \
-fno-common -ffixed-r9
@ -148,3 +151,7 @@ ifneq ($(CONFIG_VF610),)
ALL-y += u-boot.vyb
endif
endif
EFI_LDS := elf_arm_efi.lds
EFI_CRT0 := crt0_arm_efi.o
EFI_RELOC := reloc_arm_efi.o

View file

@ -28,8 +28,9 @@ config PSCI_RESET
!TARGET_LS2080A_SIMU && !TARGET_LS2080AQDS && \
!TARGET_LS2080ARDB && !TARGET_LS1012AQDS && \
!TARGET_LS1012ARDB && !TARGET_LS1012AFRDM && \
!TARGET_LS1043ARDB && !ARCH_UNIPHIER && !ARCH_SNAPDRAGON && \
!TARGET_S32V234EVB
!TARGET_LS1043ARDB && !TARGET_LS1043AQDS && \
!TARGET_LS1046ARDB && !TARGET_LS1046AQDS && \
!ARCH_UNIPHIER && !ARCH_SNAPDRAGON && !TARGET_S32V234EVB
help
Most armv8 systems have PSCI support enabled in EL3, either through
ARM Trusted Firmware or other firmware.

View file

@ -8,3 +8,7 @@ PLATFORM_RELFLAGS += -fno-common -ffixed-x18
PF_NO_UNALIGNED := $(call cc-option, -mstrict-align)
PLATFORM_CPPFLAGS += $(PF_NO_UNALIGNED)
EFI_LDS := elf_aarch64_efi.lds
EFI_CRT0 := crt0_aarch64_efi.o
EFI_RELOC := reloc_aarch64_efi.o

View file

@ -17,6 +17,7 @@
#ifdef CONFIG_MP
#include <asm/arch/mp.h>
#endif
#include <efi_loader.h>
#include <fm_eth.h>
#include <fsl-mc/fsl_mc.h>
#ifdef CONFIG_FSL_ESDHC
@ -462,9 +463,10 @@ int timer_init(void)
return 0;
}
void reset_cpu(ulong addr)
__efi_runtime_data u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR;
void __efi_runtime reset_cpu(ulong addr)
{
u32 __iomem *rstcr = (u32 *)CONFIG_SYS_FSL_RST_ADDR;
u32 val;
/* Raise RESET_REQ_B */
@ -473,6 +475,33 @@ void reset_cpu(ulong addr)
scfg_out32(rstcr, val);
}
#ifdef CONFIG_EFI_LOADER
void __efi_runtime EFIAPI efi_reset_system(
enum efi_reset_type reset_type,
efi_status_t reset_status,
unsigned long data_size, void *reset_data)
{
switch (reset_type) {
case EFI_RESET_COLD:
case EFI_RESET_WARM:
reset_cpu(0);
break;
case EFI_RESET_SHUTDOWN:
/* Nothing we can do */
break;
}
while (1) { }
}
void efi_reset_system_init(void)
{
efi_add_runtime_mmio(&rstcr, sizeof(*rstcr));
}
#endif
phys_size_t board_reserve_ram_top(phys_size_t ram_size)
{
phys_size_t ram_top = ram_size;

View file

@ -5,6 +5,7 @@
*/
#include <common.h>
#include <efi_loader.h>
#include <libfdt.h>
#include <fdt_support.h>
#include <phy.h>
@ -105,6 +106,11 @@ remove_psci_node:
fdt_add_mem_rsv(blob, (uintptr_t)&secondary_boot_code,
*boot_code_size);
#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
efi_add_memory_map((uintptr_t)&secondary_boot_code,
ALIGN(*boot_code_size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT,
EFI_RESERVED_MEMORY_TYPE, false);
#endif
}
#endif

View file

@ -37,6 +37,7 @@ int arch_early_init_r(void);
/* board/.../... */
int board_init(void);
void dram_init_banksize (void);
void board_quiesce_devices(void);
/* cpu/.../interrupt.c */
int arch_interrupt_init (void);

View file

@ -92,3 +92,13 @@ AFLAGS_memset.o := -DMEMSET_NO_THUMB_BUILD
AFLAGS_memcpy.o := -DMEMCPY_NO_THUMB_BUILD
endif
endif
# For building EFI apps
CFLAGS_$(EFI_CRT0) := $(CFLAGS_EFI)
CFLAGS_REMOVE_$(EFI_CRT0) := $(CFLAGS_NON_EFI)
CFLAGS_$(EFI_RELOC) := $(CFLAGS_EFI)
CFLAGS_REMOVE_$(EFI_RELOC) := $(CFLAGS_NON_EFI)
extra-$(CONFIG_CMD_BOOTEFI_HELLO) += $(EFI_CRT0) $(EFI_RELOC)
extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC)

View file

@ -64,6 +64,10 @@ void arch_lmb_reserve(struct lmb *lmb)
gd->bd->bi_dram[0].start + gd->bd->bi_dram[0].size - sp);
}
__weak void board_quiesce_devices(void)
{
}
/**
* announce_and_cleanup() - Print message and prepare for kernel boot
*
@ -84,6 +88,9 @@ static void announce_and_cleanup(int fake)
#ifdef CONFIG_USB_DEVICE
udc_disconnect();
#endif
board_quiesce_devices();
cleanup_before_linux();
}

View file

@ -0,0 +1,135 @@
/*
* crt0-efi-aarch64.S - PE/COFF header for aarch64 EFI applications
*
* Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
*
* SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
*
* This file is taken and modified from the gnu-efi project.
*/
.section .text.head
/*
* Magic "MZ" signature for PE/COFF
*/
.globl ImageBase
ImageBase:
.ascii "MZ"
.skip 58 /* 'MZ' + pad + offset == 64 */
.long pe_header - ImageBase /* Offset to the PE header */
pe_header:
.ascii "PE"
.short 0
coff_header:
.short 0xaa64 /* AArch64 */
.short 2 /* nr_sections */
.long 0 /* TimeDateStamp */
.long 0 /* PointerToSymbolTable */
.long 1 /* NumberOfSymbols */
.short section_table - optional_header /* SizeOfOptionalHeader */
/*
* Characteristics: IMAGE_FILE_DEBUG_STRIPPED |
* IMAGE_FILE_EXECUTABLE_IMAGE | IMAGE_FILE_LINE_NUMS_STRIPPED
*/
.short 0x206
optional_header:
.short 0x20b /* PE32+ format */
.byte 0x02 /* MajorLinkerVersion */
.byte 0x14 /* MinorLinkerVersion */
.long _edata - _start /* SizeOfCode */
.long 0 /* SizeOfInitializedData */
.long 0 /* SizeOfUninitializedData */
.long _start - ImageBase /* AddressOfEntryPoint */
.long _start - ImageBase /* BaseOfCode */
extra_header_fields:
.quad 0 /* ImageBase */
.long 0x20 /* SectionAlignment */
.long 0x8 /* FileAlignment */
.short 0 /* MajorOperatingSystemVersion */
.short 0 /* MinorOperatingSystemVersion */
.short 0 /* MajorImageVersion */
.short 0 /* MinorImageVersion */
.short 0 /* MajorSubsystemVersion */
.short 0 /* MinorSubsystemVersion */
.long 0 /* Win32VersionValue */
.long _edata - ImageBase /* SizeOfImage */
/*
* Everything before the kernel image is considered part of the header
*/
.long _start - ImageBase /* SizeOfHeaders */
.long 0 /* CheckSum */
.short EFI_SUBSYSTEM /* Subsystem */
.short 0 /* DllCharacteristics */
.quad 0 /* SizeOfStackReserve */
.quad 0 /* SizeOfStackCommit */
.quad 0 /* SizeOfHeapReserve */
.quad 0 /* SizeOfHeapCommit */
.long 0 /* LoaderFlags */
.long 0x6 /* NumberOfRvaAndSizes */
.quad 0 /* ExportTable */
.quad 0 /* ImportTable */
.quad 0 /* ResourceTable */
.quad 0 /* ExceptionTable */
.quad 0 /* CertificationTable */
.quad 0 /* BaseRelocationTable */
/* Section table */
section_table:
/*
* The EFI application loader requires a relocation section
* because EFI applications must be relocatable. This is a
* dummy section as far as we are concerned.
*/
.ascii ".reloc"
.byte 0
.byte 0 /* end of 0 padding of section name */
.long 0
.long 0
.long 0 /* SizeOfRawData */
.long 0 /* PointerToRawData */
.long 0 /* PointerToRelocations */
.long 0 /* PointerToLineNumbers */
.short 0 /* NumberOfRelocations */
.short 0 /* NumberOfLineNumbers */
.long 0x42100040 /* Characteristics (section flags) */
.ascii ".text"
.byte 0
.byte 0
.byte 0 /* end of 0 padding of section name */
.long _edata - _start /* VirtualSize */
.long _start - ImageBase /* VirtualAddress */
.long _edata - _start /* SizeOfRawData */
.long _start - ImageBase /* PointerToRawData */
.long 0 /* PointerToRelocations (0 for executables) */
.long 0 /* PointerToLineNumbers (0 for executables) */
.short 0 /* NumberOfRelocations (0 for executables) */
.short 0 /* NumberOfLineNumbers (0 for executables) */
.long 0xe0500020 /* Characteristics (section flags) */
_start:
stp x29, x30, [sp, #-32]!
mov x29, sp
stp x0, x1, [sp, #16]
mov x2, x0
mov x3, x1
adr x0, ImageBase
adrp x1, _DYNAMIC
add x1, x1, #:lo12:_DYNAMIC
bl _relocate
cbnz x0, 0f
ldp x0, x1, [sp, #16]
bl efi_main
0: ldp x29, x30, [sp], #32
ret

138
arch/arm/lib/crt0_arm_efi.S Normal file
View file

@ -0,0 +1,138 @@
/*
* crt0-efi-arm.S - PE/COFF header for ARM EFI applications
*
* Copright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
*
* SPDX-License-Identifier: GPL-2.0+ BSD-2-Clause
*
* This file is taken and modified from the gnu-efi project.
*/
.section .text.head
/*
* Magic "MZ" signature for PE/COFF
*/
.globl image_base
image_base:
.ascii "MZ"
.skip 58 /* 'MZ' + pad + offset == 64 */
.long pe_header - image_base /* Offset to the PE header */
pe_header:
.ascii "PE"
.short 0
coff_header:
.short 0x1c2 /* Mixed ARM/Thumb */
.short 2 /* nr_sections */
.long 0 /* TimeDateStamp */
.long 0 /* PointerToSymbolTable */
.long 1 /* NumberOfSymbols */
.short section_table - optional_header /* SizeOfOptionalHeader */
/*
* Characteristics: IMAGE_FILE_32BIT_MACHINE |
* IMAGE_FILE_DEBUG_STRIPPED | IMAGE_FILE_EXECUTABLE_IMAGE |
* IMAGE_FILE_LINE_NUMS_STRIPPED
*/
.short 0x306
optional_header:
.short 0x10b /* PE32+ format */
.byte 0x02 /* MajorLinkerVersion */
.byte 0x14 /* MinorLinkerVersion */
.long _edata - _start /* SizeOfCode */
.long 0 /* SizeOfInitializedData */
.long 0 /* SizeOfUninitializedData */
.long _start - image_base /* AddressOfEntryPoint */
.long _start - image_base /* BaseOfCode */
.long 0 /* BaseOfData */
extra_header_fields:
.long 0 /* image_base */
.long 0x20 /* SectionAlignment */
.long 0x8 /* FileAlignment */
.short 0 /* MajorOperatingSystemVersion */
.short 0 /* MinorOperatingSystemVersion */
.short 0 /* MajorImageVersion */
.short 0 /* MinorImageVersion */
.short 0 /* MajorSubsystemVersion */
.short 0 /* MinorSubsystemVersion */
.long 0 /* Win32VersionValue */
.long _edata - image_base /* SizeOfImage */
/*
* Everything before the kernel image is considered part of the header
*/
.long _start - image_base /* SizeOfHeaders */
.long 0 /* CheckSum */
.short EFI_SUBSYSTEM /* Subsystem */
.short 0 /* DllCharacteristics */
.long 0 /* SizeOfStackReserve */
.long 0 /* SizeOfStackCommit */
.long 0 /* SizeOfHeapReserve */
.long 0 /* SizeOfHeapCommit */
.long 0 /* LoaderFlags */
.long 0x6 /* NumberOfRvaAndSizes */
.quad 0 /* ExportTable */
.quad 0 /* ImportTable */
.quad 0 /* ResourceTable */
.quad 0 /* ExceptionTable */
.quad 0 /* CertificationTable */
.quad 0 /* BaseRelocationTable */
section_table:
/*
* The EFI application loader requires a relocation section
* because EFI applications must be relocatable. This is a
* dummy section as far as we are concerned.
*/
.ascii ".reloc"
.byte 0
.byte 0 /* end of 0 padding of section name */
.long 0
.long 0
.long 0 /* SizeOfRawData */
.long 0 /* PointerToRawData */
.long 0 /* PointerToRelocations */
.long 0 /* PointerToLineNumbers */
.short 0 /* NumberOfRelocations */
.short 0 /* NumberOfLineNumbers */
.long 0x42100040 /* Characteristics (section flags) */
.ascii ".text"
.byte 0
.byte 0
.byte 0 /* end of 0 padding of section name */
.long _edata - _start /* VirtualSize */
.long _start - image_base /* VirtualAddress */
.long _edata - _start /* SizeOfRawData */
.long _start - image_base /* PointerToRawData */
.long 0 /* PointerToRelocations (0 for executables) */
.long 0 /* PointerToLineNumbers (0 for executables) */
.short 0 /* NumberOfRelocations (0 for executables) */
.short 0 /* NumberOfLineNumbers (0 for executables) */
.long 0xe0500020 /* Characteristics (section flags) */
_start:
stmfd sp!, {r0-r2, lr}
mov r2, r0
mov r3, r1
adr r1, .L_DYNAMIC
ldr r0, [r1]
add r1, r0, r1
adr r0, image_base
bl _relocate
teq r0, #0
bne 0f
ldmfd sp, {r0-r1}
bl efi_main
0: add sp, sp, #12
ldr pc, [sp], #4
.L_DYNAMIC:
.word _DYNAMIC - .

View file

@ -0,0 +1,70 @@
/*
* U-Boot aarch64 EFI linker script
*
* SPDX-License-Identifier: BSD-2-Clause
*
* Modified from elf_aarch64_efi.lds in gnu-efi
*/
OUTPUT_FORMAT("elf64-littleaarch64", "elf64-littleaarch64", "elf64-littleaarch64")
OUTPUT_ARCH(aarch64)
ENTRY(_start)
SECTIONS
{
.text 0x0 : {
_text = .;
*(.text.head)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.srodata)
*(.rodata*)
. = ALIGN(16);
}
_etext = .;
_text_size = . - _text;
.dynamic : { *(.dynamic) }
.data : {
_data = .;
*(.sdata)
*(.data)
*(.data1)
*(.data.*)
*(.got.plt)
*(.got)
/*
* The EFI loader doesn't seem to like a .bss section, so we
* stick it all into .data:
*/
. = ALIGN(16);
_bss = .;
*(.sbss)
*(.scommon)
*(.dynbss)
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(16);
_bss_end = .;
_edata = .;
}
.rela.dyn : { *(.rela.dyn) }
.rela.plt : { *(.rela.plt) }
.rela.got : { *(.rela.got) }
.rela.data : { *(.rela.data) *(.rela.data*) }
_data_size = . - _etext;
. = ALIGN(4096);
.dynsym : { *(.dynsym) }
. = ALIGN(4096);
.dynstr : { *(.dynstr) }
. = ALIGN(4096);
.note.gnu.build-id : { *(.note.gnu.build-id) }
/DISCARD/ : {
*(.rel.reloc)
*(.eh_frame)
*(.note.GNU-stack)
}
.comment 0 : { *(.comment) }
}

View file

@ -0,0 +1,70 @@
/*
* U-Boot ARM EFI linker script
*
* SPDX-License-Identifier: BSD-2-Clause
*
* Modified from elf_arm_efi.lds in gnu-efi
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
.text 0x0 : {
_text = .;
*(.text.head)
*(.text)
*(.text.*)
*(.gnu.linkonce.t.*)
*(.srodata)
*(.rodata*)
. = ALIGN(16);
}
_etext = .;
_text_size = . - _text;
.dynamic : { *(.dynamic) }
.data : {
_data = .;
*(.sdata)
*(.data)
*(.data1)
*(.data.*)
*(.got.plt)
*(.got)
/*
* The EFI loader doesn't seem to like a .bss section, so we
* stick it all into .data:
*/
. = ALIGN(16);
_bss = .;
*(.sbss)
*(.scommon)
*(.dynbss)
*(.bss)
*(.bss.*)
*(COMMON)
. = ALIGN(16);
_bss_end = .;
_edata = .;
}
.rel.dyn : { *(.rel.dyn) }
.rel.plt : { *(.rel.plt) }
.rel.got : { *(.rel.got) }
.rel.data : { *(.rel.data) *(.rel.data*) }
_data_size = . - _etext;
. = ALIGN(4096);
.dynsym : { *(.dynsym) }
. = ALIGN(4096);
.dynstr : { *(.dynstr) }
. = ALIGN(4096);
.note.gnu.build-id : { *(.note.gnu.build-id) }
/DISCARD/ : {
*(.rel.reloc)
*(.eh_frame)
*(.note.GNU-stack)
}
.comment 0 : { *(.comment) }
}

View file

@ -0,0 +1,87 @@
/* reloc_aarch64.c - position independent x86 ELF shared object relocator
Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
Copyright (C) 1999 Hewlett-Packard Co.
Contributed by David Mosberger <davidm@hpl.hp.com>.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
* Neither the name of Hewlett-Packard Co. nor the names of its
contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
BE LIABLE FOR ANYDIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/
#include <efi.h>
#include <elf.h>
efi_status_t _relocate(long ldbase, Elf64_Dyn *dyn, efi_handle_t image,
struct efi_system_table *systab)
{
long relsz = 0, relent = 0;
Elf64_Rela *rel = 0;
unsigned long *addr;
int i;
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
switch (dyn[i].d_tag) {
case DT_RELA:
rel = (Elf64_Rela *)((ulong)dyn[i].d_un.d_ptr + ldbase);
break;
case DT_RELASZ:
relsz = dyn[i].d_un.d_val;
break;
case DT_RELAENT:
relent = dyn[i].d_un.d_val;
break;
default:
break;
}
}
if (!rel && relent == 0)
return EFI_SUCCESS;
if (!rel || relent == 0)
return EFI_LOAD_ERROR;
while (relsz > 0) {
/* apply the relocs */
switch (ELF64_R_TYPE(rel->r_info)) {
case R_AARCH64_NONE:
break;
case R_AARCH64_RELATIVE:
addr = (ulong *)(ldbase + rel->r_offset);
*addr = ldbase + rel->r_addend;
break;
default:
break;
}
rel = (Elf64_Rela *)((char *)rel + relent);
relsz -= relent;
}
return EFI_SUCCESS;
}

View file

@ -0,0 +1,66 @@
/*
* reloc_arm.c - position-independent ARM ELF shared object relocator
*
* Copyright (C) 2014 Linaro Ltd. <ard.biesheuvel@linaro.org>
* Copyright (C) 1999 Hewlett-Packard Co.
* Contributed by David Mosberger <davidm@hpl.hp.com>.
*
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*
* This file is taken and modified from the gnu-efi project.
*/
#include <efi.h>
#include <elf.h>
efi_status_t _relocate(long ldbase, Elf32_Dyn *dyn, efi_handle_t image,
struct efi_system_table *systab)
{
long relsz = 0, relent = 0;
Elf32_Rel *rel = 0;
ulong *addr;
int i;
for (i = 0; dyn[i].d_tag != DT_NULL; ++i) {
switch (dyn[i].d_tag) {
case DT_REL:
rel = (Elf32_Rel *)((ulong)dyn[i].d_un.d_ptr
+ ldbase);
break;
case DT_RELSZ:
relsz = dyn[i].d_un.d_val;
break;
case DT_RELENT:
relent = dyn[i].d_un.d_val;
break;
default:
break;
}
}
if (!rel && relent == 0)
return EFI_SUCCESS;
if (!rel || relent == 0)
return EFI_LOAD_ERROR;
while (relsz > 0) {
/* apply the relocs */
switch (ELF32_R_TYPE(rel->r_info)) {
case R_ARM_NONE:
break;
case R_ARM_RELATIVE:
addr = (ulong *)(ldbase + rel->r_offset);
*addr += ldbase;
break;
default:
break;
}
rel = (Elf32_Rel *)((char *)rel + relent);
relsz -= relent;
}
return EFI_SUCCESS;
}

View file

@ -8,6 +8,7 @@
#include <asm-offsets.h>
#include <config.h>
#include <elf.h>
#include <linux/linkage.h>
#ifdef CONFIG_CPU_V7M
#include <asm/armv7m.h>
@ -96,7 +97,7 @@ copy_loop:
fixloop:
ldmia r2!, {r0-r1} /* (r0,r1) <- (SRC location,fixup) */
and r1, r1, #0xff
cmp r1, #23 /* relative fixup? */
cmp r1, #R_ARM_RELATIVE
bne fixnext
/* relative fix: increase location by offset */

View file

@ -10,6 +10,7 @@
#include <asm-offsets.h>
#include <config.h>
#include <elf.h>
#include <linux/linkage.h>
#include <asm/macro.h>
@ -47,7 +48,7 @@ fixloop:
ldp x0, x1, [x2], #16 /* (x0,x1) <- (SRC location, fixup) */
ldr x4, [x2], #8 /* x4 <- addend */
and x1, x1, #0xffffffff
cmp x1, #1027 /* relative fixup? */
cmp x1, #R_AARCH64_RELATIVE
bne fixnext
/* relative fix: store addend plus offset at dest location */

View file

@ -45,8 +45,8 @@ endif
EFIPAYLOAD_BFDARCH = i386
LDSCRIPT_EFI := $(srctree)/$(CPUDIR)/efi/elf_$(EFIARCH)_efi.lds
EFISTUB := crt0-efi-$(EFIARCH).o reloc_$(EFIARCH).o
LDSCRIPT_EFI := $(srctree)/arch/x86/lib/elf_$(EFIARCH)_efi.lds
EFISTUB := crt0_$(EFIARCH)_efi.o reloc_$(EFIARCH)_efi.o
OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
CPPFLAGS_REMOVE_crt0-efi-$(EFIARCH).o += $(CFLAGS_NON_EFI)
@ -65,3 +65,19 @@ PLATFORM_LDFLAGS += --emit-relocs
LDFLAGS_FINAL += --gc-sections -pie
endif
ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO),)
ifneq ($(CONFIG_EFI_STUB_64BIT),)
EFI_LDS := elf_x86_64_efi.lds
EFI_CRT0 := crt0_x86_64_efi.o
EFI_RELOC := reloc_x86_64_efi.o
EFI_TARGET := --target=efi-app-ia32
else
EFI_LDS := elf_ia32_efi.lds
EFI_CRT0 := crt0_ia32_efi.o
EFI_RELOC := reloc_ia32_efi.o
EFI_TARGET := --target=efi-app-x86_64
endif
endif

View file

@ -74,6 +74,7 @@ static inline __attribute__((no_instrument_function)) uint64_t rdtsc(void)
/* board/... */
void timer_set_tsc_base(uint64_t new_base);
uint64_t timer_get_tsc(void);
void board_quiesce_devices(void);
void quick_ram_check(void);

View file

@ -44,3 +44,26 @@ NORMAL_LIBGCC = $(shell $(CC) $(PLATFORM_CPPFLAGS) -print-libgcc-file-name)
OBJCOPYFLAGS := --prefix-symbols=__normal_
$(obj)/lib.a: $(NORMAL_LIBGCC) FORCE
$(call if_changed,objcopy)
obj-$(CONFIG_EFI_APP) += crt0_ia32_efi.o reloc_ia32_efi.o
ifneq ($(CONFIG_EFI_STUB),)
CFLAGS_REMOVE_reloc_ia32_efi.o += -mregparm=3
CFLAGS_reloc_ia32_efi.o += -fpic -fshort-wchar
# When building for 64-bit we must remove the i386-specific flags
CFLAGS_REMOVE_reloc_x86_64_efi.o += -mregparm=3 -march=i386 -m32
CFLAGS_reloc_x86_64_efi.o += -fpic -fshort-wchar
AFLAGS_REMOVE_crt0_x86_64_efi.o += -mregparm=3 -march=i386 -m32
AFLAGS_crt0_x86_64_efi.o += -fpic -fshort-wchar
extra-$(CONFIG_EFI_STUB_32BIT) += crt0_ia32_efi.o reloc_ia32_efi.o
extra-$(CONFIG_EFI_STUB_64BIT) += crt0_x86_64_efi.o reloc_x86_64_efi.o
endif
ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO),)
extra-y += $(EFI_CRT0) $(EFI_RELOC)
endif

View file

@ -26,6 +26,10 @@ DECLARE_GLOBAL_DATA_PTR;
#define COMMAND_LINE_OFFSET 0x9000
__weak void board_quiesce_devices(void)
{
}
void bootm_announce_and_cleanup(void)
{
printf("\nStarting kernel ...\n\n");

View file

@ -7,21 +7,3 @@
obj-$(CONFIG_EFI_STUB) += car.o
obj-$(CONFIG_EFI_STUB) += efi.o
obj-$(CONFIG_EFI_APP) += crt0-efi-ia32.o reloc_ia32.o
ifneq ($(CONFIG_EFI_STUB),)
CFLAGS_REMOVE_reloc_ia32.o += -mregparm=3
CFLAGS_reloc_ia32.o += -fpic -fshort-wchar
# When building for 64-bit we must remove the i386-specific flags
CFLAGS_REMOVE_reloc_x86_64.o += -mregparm=3 -march=i386 -m32
CFLAGS_reloc_x86_64.o += -fpic -fshort-wchar
AFLAGS_REMOVE_crt0-efi-x86_64.o += -mregparm=3 -march=i386 -m32
AFLAGS_crt0-efi-x86_64.o += -fpic -fshort-wchar
extra-$(CONFIG_EFI_STUB_32BIT) += crt0-efi-ia32.o reloc_ia32.o
extra-$(CONFIG_EFI_STUB_64BIT) += crt0-efi-x86_64.o reloc_x86_64.o
endif

View file

@ -6,8 +6,6 @@
* Modified from usr/lib32/elf_ia32_efi.lds in gnu-efi
*/
#include <config.h>
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)

View file

@ -6,8 +6,6 @@
* Modified from usr/lib32/elf_x86_64_efi.lds in gnu-efi
*/
#include <config.h>
OUTPUT_FORMAT("elf64-x86-64", "elf64-x86-64", "elf64-x86-64")
OUTPUT_ARCH(i386:x86-64)
ENTRY(_start)

View file

@ -12,10 +12,12 @@
#include <asm/acpi_table.h>
#include <asm/coreboot_tables.h>
#ifdef CONFIG_GENERATE_SMBIOS_TABLE
static u32 write_smbios_table_wrapper(u32 addr)
{
return write_smbios_table(addr);
}
#endif
/**
* Function prototype to write a specific configuration table

View file

@ -102,6 +102,11 @@ void fdt_fixup_board_enet(void *fdt)
else
fdt_status_fail(fdt, offset);
}
void board_quiesce_devices(void)
{
fsl_mc_ldpaa_exit(gd->bd);
}
#endif
#ifdef CONFIG_OF_BOARD_SETUP
@ -122,7 +127,6 @@ int ft_board_setup(void *blob, bd_t *bd)
#ifdef CONFIG_FSL_MC_ENET
fdt_fixup_board_enet(blob);
fsl_mc_ldpaa_exit(bd);
#endif
return 0;

View file

@ -292,14 +292,16 @@ void fdt_fixup_board_enet(void *fdt)
else
fdt_status_fail(fdt, offset);
}
void board_quiesce_devices(void)
{
fsl_mc_ldpaa_exit(gd->bd);
}
#endif
#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, bd_t *bd)
{
#ifdef CONFIG_FSL_MC_ENET
int err;
#endif
u64 base[CONFIG_NR_DRAM_BANKS];
u64 size[CONFIG_NR_DRAM_BANKS];
@ -317,9 +319,6 @@ int ft_board_setup(void *blob, bd_t *bd)
#ifdef CONFIG_FSL_MC_ENET
fdt_fixup_board_enet(blob);
err = fsl_mc_ldpaa_exit(bd);
if (err)
return err;
#endif
return 0;

View file

@ -15,6 +15,7 @@
#include <libfdt.h>
#include <fsl-mc/fsl_mc.h>
#include <environment.h>
#include <efi_loader.h>
#include <i2c.h>
#include <asm/arch/soc.h>
#include <fsl_sec.h>
@ -201,6 +202,14 @@ int misc_init_r(void)
if (adjust_vdd(0))
printf("Warning: Adjusting core voltage failed.\n");
#if defined(CONFIG_EFI_LOADER) && !defined(CONFIG_SPL_BUILD)
if (soc_has_dp_ddr() && gd->bd->bi_dram[2].size) {
efi_add_memory_map(gd->bd->bi_dram[2].start,
gd->bd->bi_dram[2].size >> EFI_PAGE_SHIFT,
EFI_RESERVED_MEMORY_TYPE, false);
}
#endif
return 0;
}
@ -256,14 +265,16 @@ void fdt_fixup_board_enet(void *fdt)
else
fdt_status_fail(fdt, offset);
}
void board_quiesce_devices(void)
{
fsl_mc_ldpaa_exit(gd->bd);
}
#endif
#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, bd_t *bd)
{
#ifdef CONFIG_FSL_MC_ENET
int err;
#endif
u64 base[CONFIG_NR_DRAM_BANKS];
u64 size[CONFIG_NR_DRAM_BANKS];
@ -281,9 +292,6 @@ int ft_board_setup(void *blob, bd_t *bd)
#ifdef CONFIG_FSL_MC_ENET
fdt_fixup_board_enet(blob);
err = fsl_mc_ldpaa_exit(bd);
if (err)
return err;
#endif
return 0;

View file

@ -181,6 +181,15 @@ config CMD_BOOTEFI
help
Boot an EFI image from memory.
config CMD_BOOTEFI_HELLO
bool "Allow booting a standard EFI hello world for testing"
depends on CMD_BOOTEFI && (ARM || X86)
help
This adds a standard EFI hello world application to U-Boot so that
it can be used with the 'bootefi hello' command. This is useful
for testing that EFI is working at a basic level, and for bringing
up EFI support on a new architecture.
config CMD_ELF
bool "bootelf, bootvx"
default y

View file

@ -226,6 +226,17 @@ static unsigned long do_bootefi_exec(void *efi, void *fdt)
return status == EFI_SUCCESS ? 0 : -EINVAL;
}
#ifdef CONFIG_ARM64
/* On AArch64 we need to make sure we call our payload in < EL3 */
if (current_el() == 3) {
smp_kick_all_cpus();
dcache_disable(); /* flush cache before switch to EL2 */
armv8_switch_to_el2();
/* Enable caches again */
dcache_enable();
}
#endif
return entry(&loaded_image_info, &systab);
}
@ -239,16 +250,26 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (argc < 2)
return CMD_RET_USAGE;
saddr = argv[1];
#ifdef CONFIG_CMD_BOOTEFI_HELLO
if (!strcmp(argv[1], "hello")) {
ulong size = __efi_hello_world_end - __efi_hello_world_begin;
addr = simple_strtoul(saddr, NULL, 16);
addr = CONFIG_SYS_LOAD_ADDR;
memcpy((char *)addr, __efi_hello_world_begin, size);
} else
#endif
{
saddr = argv[1];
if (argc > 2) {
sfdt = argv[2];
fdt_addr = simple_strtoul(sfdt, NULL, 16);
addr = simple_strtoul(saddr, NULL, 16);
if (argc > 2) {
sfdt = argv[2];
fdt_addr = simple_strtoul(sfdt, NULL, 16);
}
}
printf("## Starting EFI application at 0x%08lx ...\n", addr);
printf("## Starting EFI application at %08lx ...\n", addr);
r = do_bootefi_exec((void *)addr, (void*)fdt_addr);
printf("## Application terminated, r = %d\n", r);
@ -263,7 +284,12 @@ static char bootefi_help_text[] =
"<image address> [fdt address]\n"
" - boot EFI payload stored at address <image address>.\n"
" If specified, the device tree located at <fdt address> gets\n"
" exposed as EFI configuration table.\n";
" exposed as EFI configuration table.\n"
#ifdef CONFIG_CMD_BOOTEFI_HELLO
"hello\n"
" - boot a sample Hello World application stored within U-Boot"
#endif
;
#endif
U_BOOT_CMD(

View file

@ -34,3 +34,4 @@ CONFIG_USB=y
CONFIG_USB_STORAGE=y
CONFIG_USB_KEYBOARD=y
CONFIG_EFI=y
# CONFIG_EFI_LOADER is not set

View file

@ -310,6 +310,20 @@ Removable media booting (search for /efi/boot/boota{a64,arm}.efi) is supported.
Simple use cases like "Plug this SD card into my ARM device and it just
boots into grub which boots into Linux", work very well.
Running HelloWord.efi
---------------------
You can run a simple 'hello world' EFI program in U-Boot.
Enable the option CONFIG_CMD_BOOTEFI_HELLO.
Then you can boot into U-Boot and type:
> bootefi hello
The 'hello world EFI' program will then run, print a message and exit.
Future work
-----------

View file

@ -1077,7 +1077,6 @@ TODO List
---------
- Audio
- Chrome OS verified boot
- Support for CONFIG_EFI_LOADER
- Building U-Boot to run in 64-bit mode
References

View file

@ -40,6 +40,7 @@ int child_dprc_id;
struct fsl_dpbp_obj *dflt_dpbp = NULL;
struct fsl_dpio_obj *dflt_dpio = NULL;
struct fsl_dpni_obj *dflt_dpni = NULL;
static u64 mc_lazy_dpl_addr;
#ifdef DEBUG
void dump_ram_words(const char *title, void *addr)
@ -572,6 +573,9 @@ int mc_apply_dpl(u64 mc_dpl_addr)
u64 mc_ram_addr = mc_get_dram_addr();
size_t mc_ram_size = mc_get_dram_block_size();
if (!mc_dpl_addr)
return -1;
error = load_mc_dpl(mc_ram_addr, mc_ram_size, mc_dpl_addr);
if (error != 0)
return error;
@ -1156,6 +1160,11 @@ int fsl_mc_ldpaa_exit(bd_t *bd)
{
int err = 0;
if (bd && mc_lazy_dpl_addr && !fsl_mc_ldpaa_exit(NULL)) {
mc_apply_dpl(mc_lazy_dpl_addr);
mc_lazy_dpl_addr = 0;
}
/* MC is not loaded intentionally, So return success. */
if (bd && get_mc_boot_status() != 0)
return 0;
@ -1259,6 +1268,7 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
break;
case 'l':
case 'a': {
u64 mc_dpl_addr;
@ -1279,8 +1289,17 @@ static int do_fsl_mc(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return -ENODEV;
}
if (!fsl_mc_ldpaa_exit(NULL))
err = mc_apply_dpl(mc_dpl_addr);
if (argv[1][0] == 'l') {
/*
* We will do the actual dpaa exit and dpl apply
* later from announce_and_cleanup().
*/
mc_lazy_dpl_addr = mc_dpl_addr;
} else {
/* The user wants it applied now */
if (!fsl_mc_ldpaa_exit(NULL))
err = mc_apply_dpl(mc_dpl_addr);
}
break;
}
default:
@ -1298,5 +1317,6 @@ U_BOOT_CMD(
"DPAA2 command to manage Management Complex (MC)",
"start mc [FW_addr] [DPC_addr] - Start Management Complex\n"
"fsl_mc apply DPL [DPL_addr] - Apply DPL file\n"
"fsl_mc lazyapply DPL [DPL_addr] - Apply DPL file on exit\n"
"fsl_mc start aiop [FW_addr] - Start AIOP\n"
);

View file

@ -22,6 +22,8 @@ extern char __kprobes_text_start[], __kprobes_text_end[];
extern char __entry_text_start[], __entry_text_end[];
extern char __initdata_begin[], __initdata_end[];
extern char __start_rodata[], __end_rodata[];
extern char __efi_hello_world_begin[];
extern char __efi_hello_world_end[];
/* Start and end of .ctors section - used for constructor calls. */
extern char __ctors_start[], __ctors_end[];

View file

@ -316,10 +316,25 @@ unsigned long get_board_sys_clk(void);
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
#define CONFIG_SYS_USB_XHCI_MAX_ROOT_PORTS 2
#undef CONFIG_CMDLINE_EDITING
#include <config_distro_defaults.h>
#define BOOT_TARGET_DEVICES(func) \
func(USB, usb, 0) \
func(MMC, mmc, 0) \
func(SCSI, scsi, 0) \
func(DHCP, dhcp, na)
#include <config_distro_bootcmd.h>
/* Initial environment variables */
#undef CONFIG_EXTRA_ENV_SETTINGS
#define CONFIG_EXTRA_ENV_SETTINGS \
"hwconfig=fsl_ddr:bank_intlv=auto\0" \
"scriptaddr=0x80800000\0" \
"kernel_addr_r=0x81000000\0" \
"pxefile_addr_r=0x81000000\0" \
"fdt_addr_r=0x88000000\0" \
"ramdisk_addr_r=0x89000000\0" \
"loadaddr=0x80100000\0" \
"kernel_addr=0x100000\0" \
"ramdisk_addr=0x800000\0" \
@ -329,8 +344,10 @@ unsigned long get_board_sys_clk(void);
"kernel_start=0x581100000\0" \
"kernel_load=0xa0000000\0" \
"kernel_size=0x2800000\0" \
"fdtfile=fsl-ls2080a-rdb.dtb\0" \
"mcinitcmd=fsl_mc start mc 0x580300000" \
" 0x580800000 \0"
" 0x580800000 \0" \
BOOTENV
#undef CONFIG_BOOTARGS
#define CONFIG_BOOTARGS "console=ttyS1,115200 root=/dev/ram0 " \
@ -338,6 +355,13 @@ unsigned long get_board_sys_clk(void);
"ramdisk_size=0x2000000 default_hugepagesz=2m" \
" hugepagesz=2m hugepages=256"
#undef CONFIG_BOOTCOMMAND
/* Try to boot an on-NOR kernel first, then do normal distro boot */
#define CONFIG_BOOTCOMMAND "run mcinitcmd && fsl_mc lazyapply dpl 0x580700000" \
" && cp.b $kernel_start $kernel_load $kernel_size" \
" && bootm $kernel_load" \
" || run distro_bootcmd"
/* MAC/PHY configuration */
#ifdef CONFIG_FSL_MC_ENET
#define CONFIG_PHYLIB_10G

View file

@ -30,8 +30,11 @@ struct efi_device_path;
#define EFI_BITS_PER_LONG BITS_PER_LONG
/* With 64-bit EFI stub, EFI_BITS_PER_LONG has to be 64 */
#ifdef CONFIG_EFI_STUB_64BIT
/*
* With 64-bit EFI stub, EFI_BITS_PER_LONG has to be 64. EFI_STUB is set
* in lib/efi/Makefile, when building the stub.
*/
#if defined(CONFIG_EFI_STUB_64BIT) && defined(EFI_STUB)
#undef EFI_BITS_PER_LONG
#define EFI_BITS_PER_LONG 64
#endif

View file

@ -268,6 +268,19 @@ struct efi_device_path {
u16 length;
};
struct efi_mac_addr {
u8 addr[32];
};
#define DEVICE_PATH_TYPE_MESSAGING_DEVICE 0x03
# define DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR 0x0b
struct efi_device_path_mac_addr {
struct efi_device_path dp;
struct efi_mac_addr mac;
u8 if_type;
};
#define DEVICE_PATH_TYPE_MEDIA_DEVICE 0x04
# define DEVICE_PATH_SUB_TYPE_FILE_PATH 0x04

View file

@ -181,7 +181,7 @@ void efi_get_time_init(void);
/* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */
#define __efi_runtime_data
#define __efi_runtime
static inline void efi_add_runtime_mmio(void **mmio_ptr, u64 len) { }
static inline void efi_add_runtime_mmio(void *mmio_ptr, u64 len) { }
/* No loader configured, stub out EFI_ENTRY */
static inline void efi_restore_gd(void) { }

View file

@ -13,6 +13,7 @@
#ifndef _ELF_H
#define _ELF_H
#ifndef __ASSEMBLER__
#include "compiler.h"
/*
@ -517,6 +518,8 @@ unsigned long elf_hash(const unsigned char *name);
#define ELF_TARG_VER 1 /* The ver for which this code is intended */
#endif /* __ASSEMBLER */
/*
* XXX - PowerPC defines really don't belong in here,
* but we'll put them in for simplicity.
@ -602,6 +605,16 @@ unsigned long elf_hash(const unsigned char *name);
that may still be in object files. */
#define R_PPC_TOC16 255
/* ARM relocs */
#define R_ARM_NONE 0 /* No reloc */
#define R_ARM_RELATIVE 23 /* Adjust by program base */
/* AArch64 relocs */
#define R_AARCH64_NONE 0 /* No relocation. */
#define R_AARCH64_RELATIVE 1027 /* Adjust by program base. */
#ifndef __ASSEMBLER__
int valid_elf_image(unsigned long addr);
#endif
#endif /* _ELF_H */

View file

@ -9,9 +9,9 @@ obj-$(CONFIG_EFI_STUB) += efi_info.o
CFLAGS_REMOVE_efi_stub.o := -mregparm=3 \
$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
CFLAGS_efi_stub.o := -fpic -fshort-wchar
CFLAGS_efi_stub.o := -fpic -fshort-wchar -DEFI_STUB
CFLAGS_REMOVE_efi.o := -mregparm=3 \
$(if $(CONFIG_EFI_STUB_64BIT),-march=i386 -m32)
CFLAGS_efi.o := -fpic -fshort-wchar
CFLAGS_efi.o := -fpic -fshort-wchar -DEFI_STUB
extra-$(CONFIG_EFI_STUB) += efi_stub.o efi.o

View file

@ -1,6 +1,6 @@
config EFI_LOADER
bool "Support running EFI Applications in U-Boot"
depends on (ARM64 || ARM) && OF_LIBFDT
depends on (ARM || X86) && OF_LIBFDT
default y
help
Select this option if you want to run EFI applications (like grub2)

View file

@ -7,6 +7,10 @@
# This file only gets included with CONFIG_EFI_LOADER set, so all
# object inclusion implicitly depends on it
CFLAGS_helloworld.o := $(CFLAGS_EFI)
CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI)
obj-$(CONFIG_CMD_BOOTEFI_HELLO) += helloworld_efi.o
obj-y += efi_image_loader.o efi_boottime.o efi_runtime.o efi_console.o
obj-y += efi_memory.o
obj-$(CONFIG_LCD) += efi_gop.o

View file

@ -538,6 +538,8 @@ static efi_status_t EFIAPI efi_exit_boot_services(void *image_handle,
{
EFI_ENTRY("%p, %ld", image_handle, map_key);
board_quiesce_devices();
/* Fix up caches for EFI payloads if necessary */
efi_exit_caches();

View file

@ -9,11 +9,38 @@
#include <common.h>
#include <efi_loader.h>
/* If we can't determine the console size, default to 80x24 */
static int console_columns = 80;
static int console_rows = 24;
static bool console_size_queried;
#define EFI_COUT_MODE_2 2
#define EFI_MAX_COUT_MODE 3
struct cout_mode {
unsigned long columns;
unsigned long rows;
int present;
};
static struct cout_mode efi_cout_modes[] = {
/* EFI Mode 0 is 80x25 and always present */
{
.columns = 80,
.rows = 25,
.present = 1,
},
/* EFI Mode 1 is always 80x50 */
{
.columns = 80,
.rows = 50,
.present = 0,
},
/* Value are unknown until we query the console */
{
.columns = 0,
.rows = 0,
.present = 0,
},
};
const efi_guid_t efi_guid_console_control = CONSOLE_CONTROL_GUID;
#define cESC '\x1b'
@ -56,8 +83,9 @@ const struct efi_console_control_protocol efi_console_control = {
.lock_std_in = efi_cin_lock_std_in,
};
/* Default to mode 0 */
static struct simple_text_output_mode efi_con_mode = {
.max_mode = 0,
.max_mode = 1,
.mode = 0,
.attribute = 0,
.cursor_column = 0,
@ -131,8 +159,10 @@ static efi_status_t EFIAPI efi_cout_output_string(
struct efi_simple_text_output_protocol *this,
const unsigned short *string)
{
struct cout_mode *mode;
u16 ch;
mode = &efi_cout_modes[efi_con_mode.mode];
EFI_ENTRY("%p, %p", this, string);
for (;(ch = *string); string++) {
print_unicode_in_utf8(ch);
@ -140,13 +170,12 @@ static efi_status_t EFIAPI efi_cout_output_string(
if (ch == '\n') {
efi_con_mode.cursor_column = 1;
efi_con_mode.cursor_row++;
} else if (efi_con_mode.cursor_column > console_columns) {
} else if (efi_con_mode.cursor_column > mode->columns) {
efi_con_mode.cursor_column = 1;
efi_con_mode.cursor_row++;
}
if (efi_con_mode.cursor_row > console_rows) {
efi_con_mode.cursor_row = console_rows;
}
if (efi_con_mode.cursor_row > mode->rows)
efi_con_mode.cursor_row = mode->rows;
}
return EFI_EXIT(EFI_SUCCESS);
@ -160,6 +189,14 @@ static efi_status_t EFIAPI efi_cout_test_string(
return EFI_EXIT(EFI_SUCCESS);
}
static bool cout_mode_matches(struct cout_mode *mode, int rows, int cols)
{
if (!mode->present)
return false;
return (mode->rows == rows) && (mode->columns == cols);
}
static efi_status_t EFIAPI efi_cout_query_mode(
struct efi_simple_text_output_protocol *this,
unsigned long mode_number, unsigned long *columns,
@ -170,6 +207,8 @@ static efi_status_t EFIAPI efi_cout_query_mode(
if (!console_size_queried) {
/* Ask the terminal about its size */
int n[3];
int cols;
int rows;
u64 timeout;
console_size_queried = true;
@ -191,15 +230,40 @@ static efi_status_t EFIAPI efi_cout_query_mode(
goto out;
}
console_columns = n[2];
console_rows = n[1];
cols = n[2];
rows = n[1];
/* Test if we can have Mode 1 */
if (cols >= 80 && rows >= 50) {
efi_cout_modes[1].present = 1;
efi_con_mode.max_mode = 2;
}
/*
* Install our mode as mode 2 if it is different
* than mode 0 or 1 and set it as the currently selected mode
*/
if (!cout_mode_matches(&efi_cout_modes[0], rows, cols) &&
!cout_mode_matches(&efi_cout_modes[1], rows, cols)) {
efi_cout_modes[EFI_COUT_MODE_2].columns = cols;
efi_cout_modes[EFI_COUT_MODE_2].rows = rows;
efi_cout_modes[EFI_COUT_MODE_2].present = 1;
efi_con_mode.max_mode = EFI_MAX_COUT_MODE;
efi_con_mode.mode = EFI_COUT_MODE_2;
}
}
if (mode_number >= efi_con_mode.max_mode)
return EFI_EXIT(EFI_UNSUPPORTED);
if (efi_cout_modes[mode_number].present != 1)
return EFI_EXIT(EFI_UNSUPPORTED);
out:
if (columns)
*columns = console_columns;
*columns = efi_cout_modes[mode_number].columns;
if (rows)
*rows = console_rows;
*rows = efi_cout_modes[mode_number].rows;
return EFI_EXIT(EFI_SUCCESS);
}
@ -210,11 +274,15 @@ static efi_status_t EFIAPI efi_cout_set_mode(
{
EFI_ENTRY("%p, %ld", this, mode_number);
/* We only support text output for now */
if (mode_number == EFI_CONSOLE_MODE_TEXT)
return EFI_EXIT(EFI_SUCCESS);
return EFI_EXIT(EFI_UNSUPPORTED);
if (mode_number > efi_con_mode.max_mode)
return EFI_EXIT(EFI_UNSUPPORTED);
efi_con_mode.mode = mode_number;
efi_con_mode.cursor_column = 0;
efi_con_mode.cursor_row = 0;
return EFI_EXIT(EFI_SUCCESS);
}
static efi_status_t EFIAPI efi_cout_set_attribute(

View file

@ -174,7 +174,8 @@ void *efi_load_pe(void *efi, struct efi_loaded_image *loaded_image_info)
efi_loader_relocate(rel, rel_size, efi_reloc);
/* Flush cache */
flush_cache((ulong)efi_reloc, virt_size);
flush_cache((ulong)efi_reloc,
ALIGN(virt_size, CONFIG_SYS_CACHELINE_SIZE));
invalidate_icache_all();
/* Populate the loaded image interface bits */

View file

@ -27,7 +27,8 @@ struct efi_net_obj {
struct efi_simple_network net;
struct efi_simple_network_mode net_mode;
/* Device path to the network adapter */
struct efi_device_path_file_path dp[2];
struct efi_device_path_mac_addr dp_mac;
struct efi_device_path_file_path dp_end;
/* PXE struct to transmit dhcp data */
struct efi_pxe pxe;
struct efi_pxe_mode pxe_mode;
@ -205,7 +206,7 @@ static efi_status_t EFIAPI efi_net_open_dp(void *handle, efi_guid_t *protocol,
struct efi_simple_network *net = handle;
struct efi_net_obj *netobj = container_of(net, struct efi_net_obj, net);
*protocol_interface = netobj->dp;
*protocol_interface = &netobj->dp_mac;
return EFI_SUCCESS;
}
@ -236,11 +237,10 @@ void efi_net_set_dhcp_ack(void *pkt, int len)
int efi_net_register(void **handle)
{
struct efi_net_obj *netobj;
struct efi_device_path_file_path dp_net = {
.dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE,
.dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH,
struct efi_device_path_mac_addr dp_net = {
.dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE,
.dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR,
.dp.length = sizeof(dp_net),
.str = { 'N', 'e', 't' },
};
struct efi_device_path_file_path dp_end = {
.dp.type = DEVICE_PATH_TYPE_END,
@ -279,8 +279,9 @@ int efi_net_register(void **handle)
netobj->net.receive = efi_net_receive;
netobj->net.mode = &netobj->net_mode;
netobj->net_mode.state = EFI_NETWORK_STARTED;
netobj->dp[0] = dp_net;
netobj->dp[1] = dp_end;
netobj->dp_mac = dp_net;
netobj->dp_end = dp_end;
memcpy(netobj->dp_mac.mac.addr, eth_get_ethaddr(), 6);
memcpy(netobj->net_mode.current_address.mac_addr, eth_get_ethaddr(), 6);
netobj->net_mode.max_packet_size = PKTSIZE;

View file

@ -0,0 +1,24 @@
/*
* EFI hello world
*
* Copyright (c) 2016 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <part_efi.h>
#include <efi_api.h>
efi_status_t EFIAPI efi_main(efi_handle_t handle,
struct efi_system_table *systable)
{
struct efi_simple_text_output_protocol *con_out = systable->con_out;
struct efi_boot_services *boottime = systable->boottime;
con_out->output_string(con_out, L"Hello, world!\n");
boottime->exit(handle, 0, 0, NULL);
return EFI_SUCCESS;
}

View file

@ -321,6 +321,39 @@ cmd_S_ttf= \
$(obj)/%.S: $(src)/%.ttf
$(call cmd,S_ttf)
# EFI Hello World application
# ---------------------------------------------------------------------------
# Generate an assembly file to wrap the EFI app
cmd_S_efi= \
( \
echo '.section .rodata.efi.init,"a"'; \
echo '.balign 16'; \
echo '.global __efi_hello_world_begin'; \
echo '__efi_hello_world_begin:'; \
echo '.incbin "$<" '; \
echo '__efi_hello_world_end:'; \
echo '.global __efi_hello_world_end'; \
echo '.balign 16'; \
) > $@
$(obj)/%_efi.S: $(obj)/%.efi
$(call cmd,S_efi)
$(obj)/%.efi: $(obj)/%.so
$(OBJCOPY) -j .header -j .text -j .sdata -j .data -j .dynamic \
-j .dynsym -j .rel* -j .rela* -j .reloc \
$(if $(EFI_TARGET),$(EFI_TARGET),-O binary) $^ $@
EFI_LDS_PATH = $(srctree)/arch/$(ARCH)/lib/$(EFI_LDS)
$(obj)/helloworld.so: $(EFI_LDS_PATH)
$(obj)/helloworld.so: $(obj)/helloworld.o arch/$(ARCH)/lib/$(EFI_CRT0) \
arch/$(ARCH)/lib/$(EFI_RELOC)
$(LD) -nostdlib -znocombreloc -T $(EFI_LDS_PATH) -shared -Bsymbolic \
$^ -o $@
# ACPI
# ---------------------------------------------------------------------------
quiet_cmd_acpi_c_asl= ASL $<