aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MAINTAINERS1
-rw-r--r--arch/arm/config.mk4
-rw-r--r--arch/arm/cpu/armv7/Kconfig2
-rw-r--r--arch/arm/cpu/armv7/nonsec_virt.S2
-rw-r--r--arch/arm/cpu/armv8/u-boot.lds24
-rw-r--r--arch/arm/cpu/u-boot.lds36
-rw-r--r--arch/arm/mach-zynq/u-boot.lds36
-rw-r--r--arch/riscv/cpu/ax25/u-boot.lds26
-rw-r--r--arch/sandbox/config.mk3
-rw-r--r--arch/sandbox/cpu/u-boot.lds9
-rw-r--r--arch/x86/config.mk2
-rw-r--r--arch/x86/cpu/start.S2
-rw-r--r--arch/x86/cpu/start64.S2
-rw-r--r--arch/x86/cpu/u-boot-64.lds37
-rw-r--r--arch/x86/cpu/u-boot.lds34
-rw-r--r--arch/x86/include/asm/elf.h45
-rw-r--r--arch/x86/lib/reloc_ia32_efi.c1
-rw-r--r--arch/x86/lib/reloc_x86_64_efi.c1
-rw-r--r--board/qualcomm/dragonboard410c/u-boot.lds17
-rw-r--r--board/qualcomm/dragonboard820c/u-boot.lds24
-rw-r--r--board/ti/am335x/u-boot.lds36
-rw-r--r--cmd/bootefi.c90
-rw-r--r--doc/README.uefi2
-rw-r--r--drivers/rtc/at91sam9_rtt.c4
-rw-r--r--drivers/rtc/davinci.c2
-rw-r--r--drivers/rtc/ds1302.c4
-rw-r--r--drivers/rtc/ds1306.c4
-rw-r--r--drivers/rtc/ds1307.c4
-rw-r--r--drivers/rtc/ds1337.c4
-rw-r--r--drivers/rtc/ds1374.c3
-rw-r--r--drivers/rtc/ds164x.c4
-rw-r--r--drivers/rtc/ds174x.c4
-rw-r--r--drivers/rtc/ds3231.c4
-rw-r--r--drivers/rtc/imxdi.c4
-rw-r--r--drivers/rtc/m41t11.c3
-rw-r--r--drivers/rtc/m41t60.c3
-rw-r--r--drivers/rtc/m41t62.c4
-rw-r--r--drivers/rtc/m48t35ax.c4
-rw-r--r--drivers/rtc/max6900.c4
-rw-r--r--drivers/rtc/mc146818.c3
-rw-r--r--drivers/rtc/mcfrtc.c4
-rw-r--r--drivers/rtc/mk48t59.c4
-rw-r--r--drivers/rtc/pcf8563.c4
-rw-r--r--drivers/rtc/rs5c372.c3
-rw-r--r--drivers/rtc/rx8025.c4
-rw-r--r--drivers/rtc/s3c24x0_rtc.c4
-rw-r--r--drivers/rtc/x1205.c4
-rw-r--r--fs/fat/fat_write.c16
-rw-r--r--include/efi.h8
-rw-r--r--include/efi_api.h16
-rw-r--r--include/efi_loader.h13
-rw-r--r--include/elf.h35
-rw-r--r--lib/efi_driver/efi_block_device.c2
-rw-r--r--lib/efi_loader/Kconfig2
-rw-r--r--lib/efi_loader/Makefile3
-rw-r--r--lib/efi_loader/efi_boottime.c169
-rw-r--r--lib/efi_loader/efi_console.c9
-rw-r--r--lib/efi_loader/efi_image_loader.c12
-rw-r--r--lib/efi_loader/efi_memory.c65
-rw-r--r--lib/efi_loader/efi_runtime.c83
-rw-r--r--lib/efi_loader/efi_smbios.c11
-rw-r--r--lib/efi_selftest/.gitignore4
-rw-r--r--lib/efi_selftest/Makefile5
-rw-r--r--lib/efi_selftest/efi_selftest.c14
-rw-r--r--lib/efi_selftest/efi_selftest_block_device.c70
-rw-r--r--lib/efi_selftest/efi_selftest_config_table.c266
-rw-r--r--lib/efi_selftest/efi_selftest_console.c33
-rw-r--r--lib/efi_selftest/efi_selftest_crc32.c141
-rw-r--r--lib/efi_selftest/efi_selftest_rtc.c67
-rw-r--r--lib/vsprintf.c5
70 files changed, 1172 insertions, 402 deletions
diff --git a/MAINTAINERS b/MAINTAINERS
index e44280ceb6d..fe8423530c1 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -368,6 +368,7 @@ F: doc/README.iscsi
F: include/efi*
F: include/pe.h
F: include/asm-generic/pe.h
+F: lib/charset.c
F: lib/efi*/
F: test/py/tests/test_efi*
F: cmd/bootefi.c
diff --git a/arch/arm/config.mk b/arch/arm/config.mk
index efafc69d1b3..f25603109e0 100644
--- a/arch/arm/config.mk
+++ b/arch/arm/config.mk
@@ -134,11 +134,11 @@ endif
ifdef CONFIG_ARM64
OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .data \
-j .u_boot_list -j .rela.dyn -j .got -j .got.plt \
- -j .binman_sym_table
+ -j .binman_sym_table -j .text_rest
else
OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \
-j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn \
- -j .binman_sym_table
+ -j .binman_sym_table -j .text_rest
endif
# if a dtb section exists we always have to include it
diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig
index 37a0be932e4..73d57a2aae3 100644
--- a/arch/arm/cpu/armv7/Kconfig
+++ b/arch/arm/cpu/armv7/Kconfig
@@ -53,7 +53,7 @@ config ARMV7_PSCI_NR_CPUS
config ARMV7_LPAE
bool "Use LPAE page table format" if EXPERT
depends on CPU_V7A
- default n
+ default y if ARMV7_VIRT
---help---
Say Y here to use the long descriptor page table format. This is
required if U-Boot runs in HYP mode.
diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
index 56bdba1d38d..1773fae205c 100644
--- a/arch/arm/cpu/armv7/nonsec_virt.S
+++ b/arch/arm/cpu/armv7/nonsec_virt.S
@@ -80,6 +80,8 @@ _secure_monitor:
#ifdef CONFIG_ARMV7_VIRT
orreq r5, r5, #0x100 @ allow HVC instruction
moveq r6, #HYP_MODE @ Enter the kernel as HYP
+ mrseq r3, sp_svc
+ msreq sp_hyp, r3 @ migrate SP
#endif
mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set)
diff --git a/arch/arm/cpu/armv8/u-boot.lds b/arch/arm/cpu/armv8/u-boot.lds
index eb926b3c148..53de80f745e 100644
--- a/arch/arm/cpu/armv8/u-boot.lds
+++ b/arch/arm/cpu/armv8/u-boot.lds
@@ -25,6 +25,19 @@ SECTIONS
{
*(.__image_copy_start)
CPUDIR/start.o (.text*)
+ }
+
+ /* This needs to come before *(.text*) */
+ .efi_runtime : {
+ __efi_runtime_start = .;
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ __efi_runtime_stop = .;
+ }
+
+ .text_rest :
+ {
*(.text*)
}
@@ -98,17 +111,10 @@ SECTIONS
. = ALIGN(8);
- .efi_runtime : {
- __efi_runtime_start = .;
- *(efi_runtime_text)
- *(efi_runtime_data)
- __efi_runtime_stop = .;
- }
-
.efi_runtime_rel : {
__efi_runtime_rel_start = .;
- *(.relaefi_runtime_text)
- *(.relaefi_runtime_data)
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
__efi_runtime_rel_stop = .;
}
diff --git a/arch/arm/cpu/u-boot.lds b/arch/arm/cpu/u-boot.lds
index 4157374d21d..834dc99554c 100644
--- a/arch/arm/cpu/u-boot.lds
+++ b/arch/arm/cpu/u-boot.lds
@@ -43,6 +43,25 @@ SECTIONS
*(.__image_copy_start)
*(.vectors)
CPUDIR/start.o (.text*)
+ }
+
+ /* This needs to come before *(.text*) */
+ .__efi_runtime_start : {
+ *(.__efi_runtime_start)
+ }
+
+ .efi_runtime : {
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ }
+
+ .__efi_runtime_stop : {
+ *(.__efi_runtime_stop)
+ }
+
+ .text_rest :
+ {
*(.text*)
}
@@ -136,27 +155,14 @@ SECTIONS
. = ALIGN(4);
- .__efi_runtime_start : {
- *(.__efi_runtime_start)
- }
-
- .efi_runtime : {
- *(efi_runtime_text)
- *(efi_runtime_data)
- }
-
- .__efi_runtime_stop : {
- *(.__efi_runtime_stop)
- }
-
.efi_runtime_rel_start :
{
*(.__efi_runtime_rel_start)
}
.efi_runtime_rel : {
- *(.relefi_runtime_text)
- *(.relefi_runtime_data)
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
}
.efi_runtime_rel_stop :
diff --git a/arch/arm/mach-zynq/u-boot.lds b/arch/arm/mach-zynq/u-boot.lds
index ec9a0a01610..91c32e89e8f 100644
--- a/arch/arm/mach-zynq/u-boot.lds
+++ b/arch/arm/mach-zynq/u-boot.lds
@@ -19,6 +19,25 @@ SECTIONS
*(.__image_copy_start)
*(.vectors)
CPUDIR/start.o (.text*)
+ }
+
+ /* This needs to come before *(.text*) */
+ .__efi_runtime_start : {
+ *(.__efi_runtime_start)
+ }
+
+ .efi_runtime : {
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ }
+
+ .__efi_runtime_stop : {
+ *(.__efi_runtime_stop)
+ }
+
+ .text_rest :
+ {
*(.text*)
}
@@ -41,27 +60,14 @@ SECTIONS
. = ALIGN(4);
- .__efi_runtime_start : {
- *(.__efi_runtime_start)
- }
-
- .efi_runtime : {
- *(efi_runtime_text)
- *(efi_runtime_data)
- }
-
- .__efi_runtime_stop : {
- *(.__efi_runtime_stop)
- }
-
.efi_runtime_rel_start :
{
*(.__efi_runtime_rel_start)
}
.efi_runtime_rel : {
- *(.relefi_runtime_text)
- *(.relefi_runtime_data)
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
}
.efi_runtime_rel_stop :
diff --git a/arch/riscv/cpu/ax25/u-boot.lds b/arch/riscv/cpu/ax25/u-boot.lds
index 1589babf6c3..3cc89746b16 100644
--- a/arch/riscv/cpu/ax25/u-boot.lds
+++ b/arch/riscv/cpu/ax25/u-boot.lds
@@ -12,7 +12,20 @@ SECTIONS
.text :
{
arch/riscv/cpu/ax25/start.o (.text)
- *(.text)
+ }
+
+ /* This needs to come before *(.text*) */
+ .efi_runtime : {
+ __efi_runtime_start = .;
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ __efi_runtime_stop = .;
+ }
+
+ .text_rest :
+ {
+ *(.text*)
}
. = ALIGN(4);
@@ -39,17 +52,10 @@ SECTIONS
. = ALIGN(4);
- .efi_runtime : {
- __efi_runtime_start = .;
- *(efi_runtime_text)
- *(efi_runtime_data)
- __efi_runtime_stop = .;
- }
-
.efi_runtime_rel : {
__efi_runtime_rel_start = .;
- *(.relaefi_runtime_text)
- *(.relaefi_runtime_data)
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
__efi_runtime_rel_stop = .;
}
diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
index 2babcde8815..5e7077bfe75 100644
--- a/arch/sandbox/config.mk
+++ b/arch/sandbox/config.mk
@@ -5,6 +5,9 @@ PLATFORM_CPPFLAGS += -D__SANDBOX__ -U_FORTIFY_SOURCE
PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM
PLATFORM_LIBS += -lrt
+LDFLAGS_FINAL += --gc-sections
+PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
+
# Define this to avoid linking with SDL, which requires SDL libraries
# This can solve 'sdl-config: Command not found' errors
ifneq ($(NO_SDL),)
diff --git a/arch/sandbox/cpu/u-boot.lds b/arch/sandbox/cpu/u-boot.lds
index 3a6cf55eb99..727bcc35981 100644
--- a/arch/sandbox/cpu/u-boot.lds
+++ b/arch/sandbox/cpu/u-boot.lds
@@ -24,8 +24,9 @@ SECTIONS
}
.efi_runtime : {
- *(efi_runtime_text)
- *(efi_runtime_data)
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
}
.__efi_runtime_stop : {
@@ -38,8 +39,8 @@ SECTIONS
}
.efi_runtime_rel : {
- *(.relefi_runtime_text)
- *(.relefi_runtime_data)
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
}
.efi_runtime_rel_stop :
diff --git a/arch/x86/config.mk b/arch/x86/config.mk
index 5f77f98e60a..586e11a0dda 100644
--- a/arch/x86/config.mk
+++ b/arch/x86/config.mk
@@ -23,6 +23,8 @@ endif
ifeq ($(IS_32BIT),y)
PLATFORM_CPPFLAGS += -march=i386 -m32
+# TODO: These break on x86_64; need to debug further
+PLATFORM_RELFLAGS += -fdata-sections
else
PLATFORM_CPPFLAGS += $(if $(CONFIG_SPL_BUILD),,-fpic) -fno-common -m64
endif
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index e4e997e3e88..e1f634ffcd5 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -17,7 +17,7 @@
#include <generated/generic-asm-offsets.h>
#include <generated/asm-offsets.h>
-.section .text
+.section .text.start
.code32
.globl _start
.type _start, @function
diff --git a/arch/x86/cpu/start64.S b/arch/x86/cpu/start64.S
index 234482b793a..a473fd166d3 100644
--- a/arch/x86/cpu/start64.S
+++ b/arch/x86/cpu/start64.S
@@ -8,7 +8,7 @@
#include <config.h>
-.section .text
+.section .text.start
.code64
.globl _start
.type _start, @function
diff --git a/arch/x86/cpu/u-boot-64.lds b/arch/x86/cpu/u-boot-64.lds
index 3f38681669a..862aa2d35e1 100644
--- a/arch/x86/cpu/u-boot-64.lds
+++ b/arch/x86/cpu/u-boot-64.lds
@@ -17,6 +17,23 @@ SECTIONS
. = CONFIG_SYS_TEXT_BASE; /* Location of bootcode in flash */
__text_start = .;
+
+ .text.start : { *(.text.start); }
+
+ .__efi_runtime_start : {
+ *(.__efi_runtime_start)
+ }
+
+ .efi_runtime : {
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ }
+
+ .__efi_runtime_stop : {
+ *(.__efi_runtime_stop)
+ }
+
.text : { *(.text*); }
. = ALIGN(4);
@@ -27,7 +44,10 @@ SECTIONS
}
. = ALIGN(4);
- .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
+ .rodata : {
+ *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
+ KEEP(*(.rodata.efi.init));
+ }
. = ALIGN(4);
.data : { *(.data*) }
@@ -38,6 +58,21 @@ SECTIONS
. = ALIGN(4);
.got : { *(.got*) }
+ .efi_runtime_rel_start :
+ {
+ *(.__efi_runtime_rel_start)
+ }
+
+ .efi_runtime_rel : {
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
+ }
+
+ .efi_runtime_rel_stop :
+ {
+ *(.__efi_runtime_rel_stop)
+ }
+
. = ALIGN(4);
__data_end = .;
__init_end = .;
diff --git a/arch/x86/cpu/u-boot.lds b/arch/x86/cpu/u-boot.lds
index f0719368ba6..a1cc19ce4cb 100644
--- a/arch/x86/cpu/u-boot.lds
+++ b/arch/x86/cpu/u-boot.lds
@@ -17,6 +17,23 @@ SECTIONS
. = CONFIG_SYS_TEXT_BASE; /* Location of bootcode in flash */
__text_start = .;
+
+ .text.start : { *(.text.start); }
+
+ .__efi_runtime_start : {
+ *(.__efi_runtime_start)
+ }
+
+ .efi_runtime : {
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ }
+
+ .__efi_runtime_stop : {
+ *(.__efi_runtime_stop)
+ }
+
.text : { *(.text*); }
. = ALIGN(4);
@@ -43,27 +60,14 @@ SECTIONS
. = ALIGN(4);
- .__efi_runtime_start : {
- *(.__efi_runtime_start)
- }
-
- .efi_runtime : {
- *(efi_runtime_text)
- *(efi_runtime_data)
- }
-
- .__efi_runtime_stop : {
- *(.__efi_runtime_stop)
- }
-
.efi_runtime_rel_start :
{
*(.__efi_runtime_rel_start)
}
.efi_runtime_rel : {
- *(.relefi_runtime_text)
- *(.relefi_runtime_data)
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
}
.efi_runtime_rel_stop :
diff --git a/arch/x86/include/asm/elf.h b/arch/x86/include/asm/elf.h
deleted file mode 100644
index 7ae9c7d6da3..00000000000
--- a/arch/x86/include/asm/elf.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0+ */
-/*
- * Brought in from Linux 4.1, removed things not useful to U-Boot.
- * The definitions perhaps came from the GNU Library which is GPL.
- */
-
-#ifndef _ASM_X86_ELF_H
-#define _ASM_X86_ELF_H
-
-/* ELF register definitions */
-#define R_386_NONE 0
-#define R_386_32 1
-#define R_386_PC32 2
-#define R_386_GOT32 3
-#define R_386_PLT32 4
-#define R_386_COPY 5
-#define R_386_GLOB_DAT 6
-#define R_386_JMP_SLOT 7
-#define R_386_RELATIVE 8
-#define R_386_GOTOFF 9
-#define R_386_GOTPC 10
-#define R_386_NUM 11
-
-/* x86-64 relocation types */
-#define R_X86_64_NONE 0 /* No reloc */
-#define R_X86_64_64 1 /* Direct 64 bit */
-#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
-#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
-#define R_X86_64_PLT32 4 /* 32 bit PLT address */
-#define R_X86_64_COPY 5 /* Copy symbol at runtime */
-#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
-#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
-#define R_X86_64_RELATIVE 8 /* Adjust by program base */
-/* 32 bit signed pc relative offset to GOT */
-#define R_X86_64_GOTPCREL 9
-#define R_X86_64_32 10 /* Direct 32 bit zero extended */
-#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
-#define R_X86_64_16 12 /* Direct 16 bit zero extended */
-#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
-#define R_X86_64_8 14 /* Direct 8 bit sign extended */
-#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
-
-#define R_X86_64_NUM 16
-
-#endif
diff --git a/arch/x86/lib/reloc_ia32_efi.c b/arch/x86/lib/reloc_ia32_efi.c
index a262533c0fd..d56cd50bd93 100644
--- a/arch/x86/lib/reloc_ia32_efi.c
+++ b/arch/x86/lib/reloc_ia32_efi.c
@@ -10,7 +10,6 @@
#include <common.h>
#include <efi.h>
#include <elf.h>
-#include <asm/elf.h>
efi_status_t EFIAPI _relocate(long ldbase, Elf32_Dyn *dyn)
{
diff --git a/arch/x86/lib/reloc_x86_64_efi.c b/arch/x86/lib/reloc_x86_64_efi.c
index 59d6f8d3d34..2694de71104 100644
--- a/arch/x86/lib/reloc_x86_64_efi.c
+++ b/arch/x86/lib/reloc_x86_64_efi.c
@@ -12,7 +12,6 @@
#include <common.h>
#include <efi.h>
#include <elf.h>
-#include <asm/elf.h>
efi_status_t EFIAPI _relocate(long ldbase, Elf64_Dyn *dyn)
{
diff --git a/board/qualcomm/dragonboard410c/u-boot.lds b/board/qualcomm/dragonboard410c/u-boot.lds
index dc3f718b056..fc1bba8cf08 100644
--- a/board/qualcomm/dragonboard410c/u-boot.lds
+++ b/board/qualcomm/dragonboard410c/u-boot.lds
@@ -20,6 +20,19 @@ SECTIONS
*(.__image_copy_start)
board/qualcomm/dragonboard410c/head.o (.text*)
CPUDIR/start.o (.text*)
+ }
+
+ /* This needs to come before *(.text*) */
+ .efi_runtime : {
+ __efi_runtime_start = .;
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ __efi_runtime_stop = .;
+ }
+
+ .text_rest :
+ {
*(.text*)
}
@@ -51,8 +64,8 @@ SECTIONS
.efi_runtime_rel : {
__efi_runtime_rel_start = .;
- *(.relaefi_runtime_text)
- *(.relaefi_runtime_data)
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
__efi_runtime_rel_stop = .;
}
diff --git a/board/qualcomm/dragonboard820c/u-boot.lds b/board/qualcomm/dragonboard820c/u-boot.lds
index bcf5738d387..dcf8256cec3 100644
--- a/board/qualcomm/dragonboard820c/u-boot.lds
+++ b/board/qualcomm/dragonboard820c/u-boot.lds
@@ -20,6 +20,19 @@ SECTIONS
*(.__image_copy_start)
board/qualcomm/dragonboard820c/head.o (.text*)
CPUDIR/start.o (.text*)
+ }
+
+ /* This needs to come before *(.text*) */
+ .efi_runtime : {
+ __efi_runtime_start = .;
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ __efi_runtime_stop = .;
+ }
+
+ .text_rest :
+ {
*(.text*)
}
@@ -42,17 +55,10 @@ SECTIONS
. = ALIGN(8);
- .efi_runtime : {
- __efi_runtime_start = .;
- *(efi_runtime_text)
- *(efi_runtime_data)
- __efi_runtime_stop = .;
- }
-
.efi_runtime_rel : {
__efi_runtime_rel_start = .;
- *(.relaefi_runtime_text)
- *(.relaefi_runtime_data)
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
__efi_runtime_rel_stop = .;
}
diff --git a/board/ti/am335x/u-boot.lds b/board/ti/am335x/u-boot.lds
index a56cc8216bf..03c1d5f73b3 100644
--- a/board/ti/am335x/u-boot.lds
+++ b/board/ti/am335x/u-boot.lds
@@ -37,6 +37,25 @@ SECTIONS
*(.vectors)
CPUDIR/start.o (.text*)
board/ti/am335x/built-in.o (.text*)
+ }
+
+ /* This needs to come before *(.text*) */
+ .__efi_runtime_start : {
+ *(.__efi_runtime_start)
+ }
+
+ .efi_runtime : {
+ *(.text.efi_runtime*)
+ *(.rodata.efi_runtime*)
+ *(.data.efi_runtime*)
+ }
+
+ .__efi_runtime_stop : {
+ *(.__efi_runtime_stop)
+ }
+
+ .text_rest :
+ {
*(.text*)
}
@@ -59,27 +78,14 @@ SECTIONS
. = ALIGN(4);
- .__efi_runtime_start : {
- *(.__efi_runtime_start)
- }
-
- .efi_runtime : {
- *(efi_runtime_text)
- *(efi_runtime_data)
- }
-
- .__efi_runtime_stop : {
- *(.__efi_runtime_stop)
- }
-
.efi_runtime_rel_start :
{
*(.__efi_runtime_rel_start)
}
.efi_runtime_rel : {
- *(.relefi_runtime_text)
- *(.relefi_runtime_data)
+ *(.rel*.efi_runtime)
+ *(.rel*.efi_runtime.*)
}
.efi_runtime_rel_stop :
diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index cd755b6bf44..b60c151fb4a 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -14,12 +14,18 @@
#include <errno.h>
#include <linux/libfdt.h>
#include <linux/libfdt_env.h>
+#include <mapmem.h>
#include <memalign.h>
#include <asm/global_data.h>
#include <asm-generic/sections.h>
#include <asm-generic/unaligned.h>
#include <linux/linkage.h>
+#ifdef CONFIG_ARMV7_NONSEC
+#include <asm/armv7.h>
+#include <asm/secure.h>
+#endif
+
DECLARE_GLOBAL_DATA_PTR;
#define OBJ_LIST_NOT_INITIALIZED 1
@@ -38,6 +44,11 @@ efi_status_t efi_init_obj_list(void)
if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
return efi_obj_list_initialized;
+ /* Initialize system table */
+ ret = efi_initialize_system_table();
+ if (ret != EFI_SUCCESS)
+ goto out;
+
/* Initialize EFI driver uclass */
ret = efi_driver_init();
if (ret != EFI_SUCCESS)
@@ -79,9 +90,6 @@ efi_status_t efi_init_obj_list(void)
ret = efi_reset_system_init();
if (ret != EFI_SUCCESS)
goto out;
- ret = efi_get_time_init();
- if (ret != EFI_SUCCESS)
- goto out;
out:
efi_obj_list_initialized = ret;
@@ -142,8 +150,12 @@ static void *copy_fdt(void *fdt)
fdt_ram_start = ram_start;
}
- /* Give us at least 4kb breathing room */
- fdt_size = ALIGN(fdt_size + 4096, EFI_PAGE_SIZE);
+ /*
+ * Give us at least 4KB of breathing room in case the device tree needs
+ * to be expanded later. Round up to the nearest EFI page boundary.
+ */
+ fdt_size += 4096;
+ fdt_size = ALIGN(fdt_size + EFI_PAGE_SIZE - 1, EFI_PAGE_SIZE);
fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
/* Safe fdt location is at 128MB */
@@ -194,8 +206,32 @@ static efi_status_t efi_run_in_el2(EFIAPI efi_status_t (*entry)(
}
#endif
-/* Carve out DT reserved memory ranges */
-static efi_status_t efi_carve_out_dt_rsv(void *fdt)
+#ifdef CONFIG_ARMV7_NONSEC
+static bool is_nonsec;
+
+static efi_status_t efi_run_in_hyp(EFIAPI efi_status_t (*entry)(
+ efi_handle_t image_handle, struct efi_system_table *st),
+ efi_handle_t image_handle, struct efi_system_table *st)
+{
+ /* Enable caches again */
+ dcache_enable();
+
+ is_nonsec = true;
+
+ return efi_do_enter(image_handle, st, entry);
+}
+#endif
+
+/*
+ * efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges
+ *
+ * The mem_rsv entries of the FDT are added to the memory map. Any failures are
+ * ignored because this is not critical and we would rather continue to try to
+ * boot.
+ *
+ * @fdt: Pointer to device tree
+ */
+static void efi_carve_out_dt_rsv(void *fdt)
{
int nr_rsv, i;
uint64_t addr, size, pages;
@@ -208,11 +244,10 @@ static efi_status_t efi_carve_out_dt_rsv(void *fdt)
continue;
pages = ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT;
- efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE,
- false);
+ if (!efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE,
+ false))
+ printf("FDT memrsv map %d: Failed to add to map\n", i);
}
-
- return EFI_SUCCESS;
}
static efi_status_t efi_install_fdt(void *fdt)
@@ -236,10 +271,7 @@ static efi_status_t efi_install_fdt(void *fdt)
return EFI_LOAD_ERROR;
}
- if (efi_carve_out_dt_rsv(fdt) != EFI_SUCCESS) {
- printf("ERROR: failed to carve out memory\n");
- return EFI_LOAD_ERROR;
- }
+ efi_carve_out_dt_rsv(fdt);
/* Link to it in the efi tables */
ret = efi_install_configuration_table(&efi_guid_fdt, fdt);
@@ -350,6 +382,22 @@ static efi_status_t do_bootefi_exec(void *efi,
}
#endif
+#ifdef CONFIG_ARMV7_NONSEC
+ if (armv7_boot_nonsec() && !is_nonsec) {
+ dcache_disable(); /* flush cache before switch to HYP */
+
+ armv7_init_nonsec();
+ secure_ram_addr(_do_nonsec_entry)(
+ efi_run_in_hyp,
+ (uintptr_t)entry,
+ (uintptr_t)loaded_image_info_obj.handle,
+ (uintptr_t)&systab);
+
+ /* Should never reach here, efi exits with longjmp */
+ while (1) { }
+ }
+#endif
+
ret = efi_do_enter(loaded_image_info_obj.handle, &systab, entry);
exit:
@@ -394,7 +442,8 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
unsigned long addr;
char *saddr;
efi_status_t r;
- void *fdt_addr;
+ unsigned long fdt_addr;
+ void *fdt;
/* Allow unaligned memory access */
allow_unaligned();
@@ -411,11 +460,12 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return CMD_RET_USAGE;
if (argc > 2) {
- fdt_addr = (void *)simple_strtoul(argv[2], NULL, 16);
+ fdt_addr = simple_strtoul(argv[2], NULL, 16);
if (!fdt_addr && *argv[2] != '0')
return CMD_RET_USAGE;
/* Install device tree */
- r = efi_install_fdt(fdt_addr);
+ fdt = map_sysmem(fdt_addr, 0);
+ r = efi_install_fdt(fdt);
if (r != EFI_SUCCESS) {
printf("ERROR: failed to install device tree\n");
return CMD_RET_FAILURE;
@@ -434,7 +484,7 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
addr = simple_strtoul(saddr, NULL, 16);
else
addr = CONFIG_SYS_LOAD_ADDR;
- memcpy((char *)addr, __efi_helloworld_begin, size);
+ memcpy(map_sysmem(addr, size), __efi_helloworld_begin, size);
} else
#endif
#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
@@ -480,7 +530,7 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
printf("## Starting EFI application at %08lx ...\n", addr);
- r = do_bootefi_exec((void *)addr, bootefi_device_path,
+ r = do_bootefi_exec(map_sysmem(addr, 0), bootefi_device_path,
bootefi_image_path);
printf("## Application terminated, r = %lu\n",
r & ~EFI_ERROR_MASK);
diff --git a/doc/README.uefi b/doc/README.uefi
index d4031ef8e86..6b9759cfede 100644
--- a/doc/README.uefi
+++ b/doc/README.uefi
@@ -329,8 +329,6 @@ This driver is only available if U-Boot is configured with
* persistence
* runtime support
-* support bootefi booting ARMv7 in non-secure mode (CONFIG_ARMV7_NONSEC=y)
-
## Links
* [1](http://uefi.org/specifications)
diff --git a/drivers/rtc/at91sam9_rtt.c b/drivers/rtc/at91sam9_rtt.c
index da5bb3e2f78..6f92660ef1d 100644
--- a/drivers/rtc/at91sam9_rtt.c
+++ b/drivers/rtc/at91sam9_rtt.c
@@ -27,8 +27,6 @@
#include <asm/arch/at91_rtt.h>
#include <asm/arch/at91_gpbr.h>
-#if defined(CONFIG_CMD_DATE)
-
int rtc_get (struct rtc_time *tmp)
{
at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
@@ -78,5 +76,3 @@ void rtc_reset (void)
while (readl(&rtt->vr) != 0)
;
}
-
-#endif
diff --git a/drivers/rtc/davinci.c b/drivers/rtc/davinci.c
index f03dc56069f..b6930bd8394 100644
--- a/drivers/rtc/davinci.c
+++ b/drivers/rtc/davinci.c
@@ -9,7 +9,6 @@
#include <asm/io.h>
#include <asm/davinci_rtc.h>
-#if defined(CONFIG_CMD_DATE)
int rtc_get(struct rtc_time *tmp)
{
struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE;
@@ -79,4 +78,3 @@ void rtc_reset(void)
/* run RTC counter */
writel(0x01, &rtc->ctrl);
}
-#endif
diff --git a/drivers/rtc/ds1302.c b/drivers/rtc/ds1302.c
index 87ddd019168..b94163f7486 100644
--- a/drivers/rtc/ds1302.c
+++ b/drivers/rtc/ds1302.c
@@ -9,8 +9,6 @@
#include <command.h>
#include <rtc.h>
-#if defined(CONFIG_CMD_DATE)
-
/* GPP Pins */
#define DATA 0x200
#define SCLK 0x400
@@ -328,5 +326,3 @@ int rtc_set(struct rtc_time *tmp)
return 0;
}
-
-#endif
diff --git a/drivers/rtc/ds1306.c b/drivers/rtc/ds1306.c
index bd1e0845aab..02d617e09c9 100644
--- a/drivers/rtc/ds1306.c
+++ b/drivers/rtc/ds1306.c
@@ -19,8 +19,6 @@
#include <rtc.h>
#include <spi.h>
-#if defined(CONFIG_CMD_DATE)
-
#define RTC_SECONDS 0x00
#define RTC_MINUTES 0x01
#define RTC_HOURS 0x02
@@ -437,5 +435,3 @@ static void rtc_write (unsigned char reg, unsigned char val)
}
#endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */
-
-#endif
diff --git a/drivers/rtc/ds1307.c b/drivers/rtc/ds1307.c
index cdb088c9b15..48220b45db1 100644
--- a/drivers/rtc/ds1307.c
+++ b/drivers/rtc/ds1307.c
@@ -51,8 +51,6 @@ enum ds_type {
#ifndef CONFIG_DM_RTC
-#if defined(CONFIG_CMD_DATE)
-
/*---------------------------------------------------------------------*/
#undef DEBUG_RTC
@@ -204,8 +202,6 @@ static void rtc_write (uchar reg, uchar val)
i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
}
-#endif /* CONFIG_CMD_DATE*/
-
#endif /* !CONFIG_DM_RTC */
#ifdef CONFIG_DM_RTC
diff --git a/drivers/rtc/ds1337.c b/drivers/rtc/ds1337.c
index 9a0a214386a..9b31048e972 100644
--- a/drivers/rtc/ds1337.c
+++ b/drivers/rtc/ds1337.c
@@ -15,8 +15,6 @@
#include <rtc.h>
#include <i2c.h>
-#if defined(CONFIG_CMD_DATE)
-
/*
* RTC register addresses
*/
@@ -190,5 +188,3 @@ static void rtc_write (uchar reg, uchar val)
{
i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
}
-
-#endif
diff --git a/drivers/rtc/ds1374.c b/drivers/rtc/ds1374.c
index bc27f61c72b..5a2060fe753 100644
--- a/drivers/rtc/ds1374.c
+++ b/drivers/rtc/ds1374.c
@@ -18,8 +18,6 @@
#include <rtc.h>
#include <i2c.h>
-#if defined(CONFIG_CMD_DATE)
-
/*---------------------------------------------------------------------*/
#undef DEBUG_RTC
#define DEBUG_RTC
@@ -214,4 +212,3 @@ static void rtc_write_raw (uchar reg, uchar val)
{
i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
}
-#endif
diff --git a/drivers/rtc/ds164x.c b/drivers/rtc/ds164x.c
index 7ee6214b2b5..f8707892e71 100644
--- a/drivers/rtc/ds164x.c
+++ b/drivers/rtc/ds164x.c
@@ -20,8 +20,6 @@
#include <rtc.h>
-#if defined(CONFIG_CMD_DATE)
-
static uchar rtc_read(unsigned int addr );
static void rtc_write(unsigned int addr, uchar val);
@@ -171,5 +169,3 @@ static void rtc_write( unsigned int addr, uchar val )
#endif
*(volatile unsigned char*)(addr) = val;
}
-
-#endif
diff --git a/drivers/rtc/ds174x.c b/drivers/rtc/ds174x.c
index b6daf59e808..94f943d97a5 100644
--- a/drivers/rtc/ds174x.c
+++ b/drivers/rtc/ds174x.c
@@ -16,8 +16,6 @@
#include <command.h>
#include <rtc.h>
-#if defined(CONFIG_CMD_DATE)
-
static uchar rtc_read( unsigned int addr );
static void rtc_write( unsigned int addr, uchar val);
@@ -172,5 +170,3 @@ static void rtc_write( unsigned int addr, uchar val )
#endif
out8( addr, val );
}
-
-#endif
diff --git a/drivers/rtc/ds3231.c b/drivers/rtc/ds3231.c
index 0e66f6ea0fb..9352ff87a29 100644
--- a/drivers/rtc/ds3231.c
+++ b/drivers/rtc/ds3231.c
@@ -16,8 +16,6 @@
#include <rtc.h>
#include <i2c.h>
-#if defined(CONFIG_CMD_DATE)
-
/*
* RTC register addresses
*/
@@ -166,5 +164,3 @@ static void rtc_write (uchar reg, uchar val)
{
i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
}
-
-#endif
diff --git a/drivers/rtc/imxdi.c b/drivers/rtc/imxdi.c
index 3c4797f4c57..39920f1a7a9 100644
--- a/drivers/rtc/imxdi.c
+++ b/drivers/rtc/imxdi.c
@@ -17,8 +17,6 @@
#include <linux/compat.h>
#include <rtc.h>
-#if defined(CONFIG_CMD_DATE)
-
#include <asm/io.h>
#include <asm/arch/imx-regs.h>
@@ -222,5 +220,3 @@ void rtc_reset(void)
{
di_init();
}
-
-#endif
diff --git a/drivers/rtc/m41t11.c b/drivers/rtc/m41t11.c
index e9971520984..960348bb3ea 100644
--- a/drivers/rtc/m41t11.c
+++ b/drivers/rtc/m41t11.c
@@ -29,8 +29,6 @@
#endif
*/
-#if defined(CONFIG_SYS_I2C_RTC_ADDR) && defined(CONFIG_CMD_DATE)
-
/* ------------------------------------------------------------------------- */
/*
these are simple defines for the chip local to here so they aren't too
@@ -167,4 +165,3 @@ void rtc_reset (void)
val = val & 0x3F;/*turn off freq test keep calibration*/
i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
}
-#endif
diff --git a/drivers/rtc/m41t60.c b/drivers/rtc/m41t60.c
index 7846193e260..c84c8e11b3b 100644
--- a/drivers/rtc/m41t60.c
+++ b/drivers/rtc/m41t60.c
@@ -20,8 +20,6 @@
#include <rtc.h>
#include <i2c.h>
-#if defined(CONFIG_SYS_I2C_RTC_ADDR) && defined(CONFIG_CMD_DATE)
-
/*
* Convert between century and "century bits" (CB1 and CB0). These routines
* assume years are in the range 1900 - 2299.
@@ -237,4 +235,3 @@ void rtc_reset(void)
}
rtc_dump("end reset");
}
-#endif /* CONFIG_RTC_M41T60 && CONFIG_SYS_I2C_RTC_ADDR && CONFIG_CMD_DATE */
diff --git a/drivers/rtc/m41t62.c b/drivers/rtc/m41t62.c
index d53ef7d8628..137438389db 100644
--- a/drivers/rtc/m41t62.c
+++ b/drivers/rtc/m41t62.c
@@ -18,8 +18,6 @@
#include <rtc.h>
#include <i2c.h>
-#if defined(CONFIG_CMD_DATE)
-
#define M41T62_REG_SSEC 0
#define M41T62_REG_SEC 1
#define M41T62_REG_MIN 2
@@ -130,5 +128,3 @@ void rtc_reset(void)
val &= ~M41T80_ALHOUR_HT;
i2c_write(CONFIG_SYS_I2C_RTC_ADDR, M41T62_REG_ALARM_HOUR, 1, &val, 1);
}
-
-#endif
diff --git a/drivers/rtc/m48t35ax.c b/drivers/rtc/m48t35ax.c
index 0b035ced268..1cc24cccae7 100644
--- a/drivers/rtc/m48t35ax.c
+++ b/drivers/rtc/m48t35ax.c
@@ -16,8 +16,6 @@
#include <rtc.h>
#include <config.h>
-#if defined(CONFIG_CMD_DATE)
-
static uchar rtc_read (uchar reg);
static void rtc_write (uchar reg, uchar val);
@@ -135,5 +133,3 @@ static void rtc_write (uchar reg, uchar val)
*(unsigned char *)
((CONFIG_SYS_NVRAM_BASE_ADDR + CONFIG_SYS_NVRAM_SIZE - 8) + reg) = val;
}
-
-#endif
diff --git a/drivers/rtc/max6900.c b/drivers/rtc/max6900.c
index f5c651bad0d..b35186579a5 100644
--- a/drivers/rtc/max6900.c
+++ b/drivers/rtc/max6900.c
@@ -15,8 +15,6 @@
#include <rtc.h>
#include <i2c.h>
-#if defined(CONFIG_CMD_DATE)
-
#ifndef CONFIG_SYS_I2C_RTC_ADDR
#define CONFIG_SYS_I2C_RTC_ADDR 0x50
#endif
@@ -104,5 +102,3 @@ int rtc_set (struct rtc_time *tmp)
void rtc_reset (void)
{
}
-
-#endif
diff --git a/drivers/rtc/mc146818.c b/drivers/rtc/mc146818.c
index 4df443d84aa..b98c39d8219 100644
--- a/drivers/rtc/mc146818.c
+++ b/drivers/rtc/mc146818.c
@@ -19,8 +19,6 @@
#define out8(p, v) outb(v, p)
#endif
-#if defined(CONFIG_CMD_DATE)
-
/* Set this to 1 to clear the CMOS RAM */
#define CLEAR_CMOS 0
@@ -196,7 +194,6 @@ static void mc146818_init(void)
/* Clear any pending interrupts */
mc146818_read8(RTC_CONFIG_C);
}
-#endif /* CONFIG_CMD_DATE */
#ifdef CONFIG_DM_RTC
diff --git a/drivers/rtc/mcfrtc.c b/drivers/rtc/mcfrtc.c
index 0ac8e4dbc52..e10638ec7dd 100644
--- a/drivers/rtc/mcfrtc.c
+++ b/drivers/rtc/mcfrtc.c
@@ -6,8 +6,6 @@
#include <common.h>
-#if defined(CONFIG_CMD_DATE)
-
#include <command.h>
#include <rtc.h>
#include <asm/immap.h>
@@ -104,5 +102,3 @@ void rtc_reset(void)
rtc->cr |= RTC_CR_SWR;
}
-
-#endif /* CONFIG_MCFRTC && CONFIG_CMD_DATE */
diff --git a/drivers/rtc/mk48t59.c b/drivers/rtc/mk48t59.c
index d29d5ce600b..8c90a704076 100644
--- a/drivers/rtc/mk48t59.c
+++ b/drivers/rtc/mk48t59.c
@@ -70,8 +70,6 @@ void nvram_write(short dest, const void *src, size_t count)
rtc_write(d++, *s++);
}
-#if defined(CONFIG_CMD_DATE)
-
/* ------------------------------------------------------------------------- */
int rtc_get (struct rtc_time *tmp)
@@ -175,5 +173,3 @@ void rtc_set_watchdog(short multi, short res)
wd_value = RTC_WDS | ((multi & 0x1F) << 2) | (res & 0x3);
rtc_write(RTC_WATCHDOG, wd_value);
}
-
-#endif
diff --git a/drivers/rtc/pcf8563.c b/drivers/rtc/pcf8563.c
index e2fa6b6aab6..a839d6cc98b 100644
--- a/drivers/rtc/pcf8563.c
+++ b/drivers/rtc/pcf8563.c
@@ -15,8 +15,6 @@
#include <rtc.h>
#include <i2c.h>
-#if defined(CONFIG_CMD_DATE)
-
static uchar rtc_read (uchar reg);
static void rtc_write (uchar reg, uchar val);
@@ -117,5 +115,3 @@ static void rtc_write (uchar reg, uchar val)
{
i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
}
-
-#endif
diff --git a/drivers/rtc/rs5c372.c b/drivers/rtc/rs5c372.c
index c815c915d5c..97ec001aef5 100644
--- a/drivers/rtc/rs5c372.c
+++ b/drivers/rtc/rs5c372.c
@@ -24,7 +24,6 @@
#include <rtc.h>
#include <i2c.h>
-#if defined(CONFIG_CMD_DATE)
/*
* Reads are always done starting with register 15, which requires some
* jumping-through-hoops to access the data correctly.
@@ -255,5 +254,3 @@ rtc_reset (void)
if (!setup_done)
rs5c372_enable();
}
-
-#endif
diff --git a/drivers/rtc/rx8025.c b/drivers/rtc/rx8025.c
index 1c2b92fe000..7bd9f8b42af 100644
--- a/drivers/rtc/rx8025.c
+++ b/drivers/rtc/rx8025.c
@@ -13,8 +13,6 @@
#include <rtc.h>
#include <i2c.h>
-#if defined(CONFIG_CMD_DATE)
-
/*---------------------------------------------------------------------*/
#undef DEBUG_RTC
@@ -190,5 +188,3 @@ static void rtc_write (uchar reg, uchar val)
printf("Error writing to RTC\n");
}
-
-#endif /* CONFIG_RTC_RX8025 && CONFIG_CMD_DATE */
diff --git a/drivers/rtc/s3c24x0_rtc.c b/drivers/rtc/s3c24x0_rtc.c
index 1253085f535..96ea3cf878e 100644
--- a/drivers/rtc/s3c24x0_rtc.c
+++ b/drivers/rtc/s3c24x0_rtc.c
@@ -11,8 +11,6 @@
#include <common.h>
#include <command.h>
-#if (defined(CONFIG_CMD_DATE))
-
#include <asm/arch/s3c24x0_cpu.h>
#include <rtc.h>
@@ -149,5 +147,3 @@ void rtc_reset(void)
writeb((readb(&rtc->rtccon) & ~0x06) | 0x08, &rtc->rtccon);
writeb(readb(&rtc->rtccon) & ~(0x08 | 0x01), &rtc->rtccon);
}
-
-#endif
diff --git a/drivers/rtc/x1205.c b/drivers/rtc/x1205.c
index e9d8390f396..ed6aaa52377 100644
--- a/drivers/rtc/x1205.c
+++ b/drivers/rtc/x1205.c
@@ -22,8 +22,6 @@
#include <rtc.h>
#include <i2c.h>
-#if defined(CONFIG_CMD_DATE)
-
#define CCR_SEC 0
#define CCR_MIN 1
#define CCR_HOUR 2
@@ -160,5 +158,3 @@ void rtc_reset(void)
* Nothing to do
*/
}
-
-#endif
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c
index 3b77557b3ed..27e0ff66966 100644
--- a/fs/fat/fat_write.c
+++ b/fs/fat/fat_write.c
@@ -909,9 +909,11 @@ static int do_fat_write(const char *filename, void *buffer, loff_t size,
volume_info volinfo;
fsdata datablock;
fsdata *mydata = &datablock;
- int cursect;
+ int cursect, i;
int ret = -1, name_len;
char l_filename[VFAT_MAXLEN_BYTES];
+ char bad[2] = " ";
+ const char illegal[] = "<>:\"/\\|?*";
*actwrite = size;
dir_curclust = 0;
@@ -971,6 +973,18 @@ static int do_fat_write(const char *filename, void *buffer, loff_t size,
}
dentptr = (dir_entry *) do_fat_read_at_block;
+ /* Strip leading (back-)slashes */
+ while ISDIRDELIM(*filename)
+ ++filename;
+ /* Check that the filename is valid */
+ for (i = 0; i < strlen(illegal); ++i) {
+ *bad = illegal[i];
+ if (strstr(filename, bad)) {
+ printf("FAT: illegal filename (%s)\n", filename);
+ return -1;
+ }
+ }
+
name_len = strlen(filename);
if (name_len >= VFAT_MAXLEN_BYTES)
name_len = VFAT_MAXLEN_BYTES - 1;
diff --git a/include/efi.h b/include/efi.h
index 0fe15e65c06..41530a7537d 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -29,8 +29,16 @@
*/
#ifdef __x86_64__
#define EFIAPI __attribute__((ms_abi))
+#define efi_va_list __builtin_ms_va_list
+#define efi_va_start __builtin_ms_va_start
+#define efi_va_arg __builtin_va_arg
+#define efi_va_end __builtin_ms_va_end
#else
#define EFIAPI asmlinkage
+#define efi_va_list va_list
+#define efi_va_start va_start
+#define efi_va_arg va_arg
+#define efi_va_end va_end
#endif /* __x86_64__ */
struct efi_device_path;
diff --git a/include/efi_api.h b/include/efi_api.h
index 0c3dd3cdd49..ebf2a3bc18c 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -21,6 +21,9 @@
#include <asm/setjmp.h>
#endif
+/* UEFI spec version 2.7 */
+#define EFI_SPECIFICATION_VERSION (2 << 16 | 70)
+
/* Types and defines for EFI CreateEvent */
enum efi_timer_delay {
EFI_TIMER_STOP = 0,
@@ -46,6 +49,7 @@ typedef uint16_t *efi_string_t;
struct efi_event;
/* EFI Boot Services table */
+#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42
struct efi_boot_services {
struct efi_table_hdr hdr;
efi_status_t (EFIAPI *raise_tpl)(efi_uintn_t new_tpl);
@@ -161,8 +165,9 @@ struct efi_boot_services {
void **handle, ...);
efi_status_t (EFIAPI *uninstall_multiple_protocol_interfaces)(
void *handle, ...);
- efi_status_t (EFIAPI *calculate_crc32)(void *data,
- unsigned long data_size, uint32_t *crc32);
+ efi_status_t (EFIAPI *calculate_crc32)(const void *data,
+ efi_uintn_t data_size,
+ u32 *crc32);
void (EFIAPI *copy_mem)(void *destination, const void *source,
size_t length);
void (EFIAPI *set_mem)(void *buffer, size_t size, uint8_t value);
@@ -185,8 +190,7 @@ enum efi_reset_type {
};
/* EFI Runtime Services table */
-#define EFI_RUNTIME_SERVICES_SIGNATURE 0x5652453544e5552ULL
-#define EFI_RUNTIME_SERVICES_REVISION 0x00010000
+#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552ULL
#define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000
#define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000
@@ -300,7 +304,7 @@ struct efi_configuration_table
struct efi_system_table {
struct efi_table_hdr hdr;
- unsigned long fw_vendor; /* physical addr of wchar_t vendor string */
+ u16 *fw_vendor; /* physical addr of wchar_t vendor string */
u32 fw_revision;
efi_handle_t con_in_handle;
struct efi_simple_input_interface *con_in;
@@ -318,6 +322,8 @@ struct efi_system_table {
EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, \
0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
+#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000
+
struct efi_loaded_image {
u32 revision;
void *parent_handle;
diff --git a/include/efi_loader.h b/include/efi_loader.h
index d837e7b157f..57ca5502726 100644
--- a/include/efi_loader.h
+++ b/include/efi_loader.h
@@ -17,6 +17,9 @@
#include <linux/list.h>
+/* Maximum number of configuration tables */
+#define EFI_MAX_CONFIGURATION_TABLES 16
+
int __efi_entry_check(void);
int __efi_exit_check(void);
const char *__efi_nesting(void);
@@ -82,6 +85,9 @@ const char *__efi_nesting_dec(void);
#define EFI_CACHELINE_SIZE 128
#endif
+/* Key identifying current memory map */
+extern efi_uintn_t efi_memory_map_key;
+
extern struct efi_runtime_services efi_runtime_services;
extern struct efi_system_table systab;
@@ -199,6 +205,8 @@ extern struct list_head efi_obj_list;
/* List of all events */
extern struct list_head efi_events;
+/* Called by bootefi to initialize runtime */
+efi_status_t efi_initialize_system_table(void);
/* Called by bootefi to make console interface available */
int efi_console_register(void);
/* Called by bootefi to make all disk storage accessible as EFI objects */
@@ -406,8 +414,8 @@ static inline int guidcmp(const efi_guid_t *g1, const efi_guid_t *g2)
* Use these to indicate that your code / data should go into the EFI runtime
* section and thus still be available when the OS is running
*/
-#define __efi_runtime_data __attribute__ ((section ("efi_runtime_data")))
-#define __efi_runtime __attribute__ ((section ("efi_runtime_text")))
+#define __efi_runtime_data __attribute__ ((section (".data.efi_runtime")))
+#define __efi_runtime __attribute__ ((section (".text.efi_runtime")))
/* Call this with mmio_ptr as the _pointer_ to a pointer to an MMIO region
* to make it available at runtime */
@@ -426,7 +434,6 @@ efi_status_t efi_reset_system_init(void);
efi_status_t __efi_runtime EFIAPI efi_get_time(
struct efi_time *time,
struct efi_time_cap *capabilities);
-efi_status_t efi_get_time_init(void);
#ifdef CONFIG_CMD_BOOTEFI_SELFTEST
/*
diff --git a/include/elf.h b/include/elf.h
index 0d3845e0632..6802428ac42 100644
--- a/include/elf.h
+++ b/include/elf.h
@@ -550,6 +550,41 @@ unsigned long elf_hash(const unsigned char *name);
#endif /* __ASSEMBLER */
+/* ELF register definitions */
+#define R_386_NONE 0
+#define R_386_32 1
+#define R_386_PC32 2
+#define R_386_GOT32 3
+#define R_386_PLT32 4
+#define R_386_COPY 5
+#define R_386_GLOB_DAT 6
+#define R_386_JMP_SLOT 7
+#define R_386_RELATIVE 8
+#define R_386_GOTOFF 9
+#define R_386_GOTPC 10
+#define R_386_NUM 11
+
+/* x86-64 relocation types */
+#define R_X86_64_NONE 0 /* No reloc */
+#define R_X86_64_64 1 /* Direct 64 bit */
+#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
+#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
+#define R_X86_64_PLT32 4 /* 32 bit PLT address */
+#define R_X86_64_COPY 5 /* Copy symbol at runtime */
+#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
+#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
+#define R_X86_64_RELATIVE 8 /* Adjust by program base */
+/* 32 bit signed pc relative offset to GOT */
+#define R_X86_64_GOTPCREL 9
+#define R_X86_64_32 10 /* Direct 32 bit zero extended */
+#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
+#define R_X86_64_16 12 /* Direct 16 bit zero extended */
+#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
+#define R_X86_64_8 14 /* Direct 8 bit sign extended */
+#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
+
+#define R_X86_64_NUM 16
+
/*
* XXX - PowerPC defines really don't belong in here,
* but we'll put them in for simplicity.
diff --git a/lib/efi_driver/efi_block_device.c b/lib/efi_driver/efi_block_device.c
index 9c807ff71df..5b9c139f389 100644
--- a/lib/efi_driver/efi_block_device.c
+++ b/lib/efi_driver/efi_block_device.c
@@ -161,6 +161,8 @@ static int efi_bl_bind(efi_handle_t handle, void *interface)
return ret;
if (!bdev)
return -ENOENT;
+ /* Set the DM_FLAG_NAME_ALLOCED flag to avoid a memory leak */
+ device_set_name_alloced(bdev);
/* Allocate priv */
ret = device_probe(bdev);
if (ret)
diff --git a/lib/efi_loader/Kconfig b/lib/efi_loader/Kconfig
index df58e633d1c..ce6a09f0b43 100644
--- a/lib/efi_loader/Kconfig
+++ b/lib/efi_loader/Kconfig
@@ -1,8 +1,6 @@
config EFI_LOADER
bool "Support running EFI Applications in U-Boot"
depends on (ARM || X86 || RISCV) && OF_LIBFDT
- # We do not support bootefi booting ARMv7 in non-secure mode
- depends on !ARMV7_NONSEC
# We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB
depends on !EFI_STUB || !X86_64 || EFI_STUB_64BIT
# We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB
diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile
index d6402c4615f..1ffbf52a898 100644
--- a/lib/efi_loader/Makefile
+++ b/lib/efi_loader/Makefile
@@ -6,6 +6,9 @@
# This file only gets included with CONFIG_EFI_LOADER set, so all
# object inclusion implicitly depends on it
+CFLAGS_efi_boottime.o += \
+ -DFW_VERSION="0x$(VERSION)" \
+ -DFW_PATCHLEVEL="0x$(PATCHLEVEL)"
CFLAGS_helloworld.o := $(CFLAGS_EFI) -Os -ffreestanding
CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI) -Os
diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c
index eeefe0bdfe3..b9e54f551a4 100644
--- a/lib/efi_loader/efi_boottime.c
+++ b/lib/efi_loader/efi_boottime.c
@@ -35,16 +35,6 @@ LIST_HEAD(efi_events);
*/
static bool efi_is_direct_boot = true;
-/*
- * EFI can pass arbitrary additional "tables" containing vendor specific
- * information to the payload. One such table is the FDT table which contains
- * a pointer to a flattened device tree blob.
- *
- * In most cases we want to pass an FDT to the payload, so reserve one slot of
- * config table space for it. The pointer gets populated by do_bootefi_exec().
- */
-static struct efi_configuration_table __efi_runtime_data efi_conf_table[16];
-
#ifdef CONFIG_ARM
/*
* The "gd" pointer lives in a register on ARM and AArch64 that we declare
@@ -164,6 +154,18 @@ const char *__efi_nesting_dec(void)
}
/**
+ * efi_update_table_header_crc32() - Update CRC32 in table header
+ *
+ * @table: EFI table
+ */
+static void efi_update_table_header_crc32(struct efi_table_hdr *table)
+{
+ table->crc32 = 0;
+ table->crc32 = crc32(0, (const unsigned char *)table,
+ table->headersize);
+}
+
+/**
* efi_queue_event() - queue an EFI event
* @event: event to signal
* @check_tpl: check the TPL level
@@ -191,6 +193,25 @@ static void efi_queue_event(struct efi_event *event, bool check_tpl)
}
/**
+ * is_valid_tpl() - check if the task priority level is valid
+ *
+ * @tpl: TPL level to check
+ * ReturnValue: status code
+ */
+efi_status_t is_valid_tpl(efi_uintn_t tpl)
+{
+ switch (tpl) {
+ case TPL_APPLICATION:
+ case TPL_CALLBACK:
+ case TPL_NOTIFY:
+ case TPL_HIGH_LEVEL:
+ return EFI_SUCCESS;
+ default:
+ return EFI_INVALID_PARAMETER;
+ }
+}
+
+/**
* efi_signal_event() - signal an EFI event
* @event: event to signal
* @check_tpl: check the TPL level
@@ -592,11 +613,21 @@ efi_status_t efi_create_event(uint32_t type, efi_uintn_t notify_tpl,
if (event == NULL)
return EFI_INVALID_PARAMETER;
- if ((type & EVT_NOTIFY_SIGNAL) && (type & EVT_NOTIFY_WAIT))
+ switch (type) {
+ case 0:
+ case EVT_TIMER:
+ case EVT_NOTIFY_SIGNAL:
+ case EVT_TIMER | EVT_NOTIFY_SIGNAL:
+ case EVT_NOTIFY_WAIT:
+ case EVT_TIMER | EVT_NOTIFY_WAIT:
+ case EVT_SIGNAL_EXIT_BOOT_SERVICES:
+ case EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE:
+ break;
+ default:
return EFI_INVALID_PARAMETER;
+ }
- if ((type & (EVT_NOTIFY_SIGNAL | EVT_NOTIFY_WAIT)) &&
- notify_function == NULL)
+ if (is_valid_tpl(notify_tpl) != EFI_SUCCESS)
return EFI_INVALID_PARAMETER;
evt = calloc(1, sizeof(struct efi_event));
@@ -1361,9 +1392,9 @@ static efi_status_t EFIAPI efi_locate_handle_ext(
*/
static void efi_remove_configuration_table(int i)
{
- struct efi_configuration_table *this = &efi_conf_table[i];
- struct efi_configuration_table *next = &efi_conf_table[i + 1];
- struct efi_configuration_table *end = &efi_conf_table[systab.nr_tables];
+ struct efi_configuration_table *this = &systab.tables[i];
+ struct efi_configuration_table *next = &systab.tables[i + 1];
+ struct efi_configuration_table *end = &systab.tables[systab.nr_tables];
memmove(this, next, (ulong)end - (ulong)next);
systab.nr_tables--;
@@ -1391,9 +1422,9 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid,
/* Check for guid override */
for (i = 0; i < systab.nr_tables; i++) {
- if (!guidcmp(guid, &efi_conf_table[i].guid)) {
+ if (!guidcmp(guid, &systab.tables[i].guid)) {
if (table)
- efi_conf_table[i].table = table;
+ systab.tables[i].table = table;
else
efi_remove_configuration_table(i);
goto out;
@@ -1404,15 +1435,18 @@ efi_status_t efi_install_configuration_table(const efi_guid_t *guid,
return EFI_NOT_FOUND;
/* No override, check for overflow */
- if (i >= ARRAY_SIZE(efi_conf_table))
+ if (i >= EFI_MAX_CONFIGURATION_TABLES)
return EFI_OUT_OF_RESOURCES;
/* Add a new entry */
- memcpy(&efi_conf_table[i].guid, guid, sizeof(*guid));
- efi_conf_table[i].table = table;
+ memcpy(&systab.tables[i].guid, guid, sizeof(*guid));
+ systab.tables[i].table = table;
systab.nr_tables = i + 1;
out:
+ /* systab.nr_tables may have changed. So we need to update the crc32 */
+ efi_update_table_header_crc32(&systab.hdr);
+
/* Notify that the configuration table was changed */
list_for_each_entry(evt, &efi_events, link) {
if (evt->group && !guidcmp(evt->group, guid)) {
@@ -1468,6 +1502,7 @@ efi_status_t efi_setup_loaded_image(
/* efi_exit() assumes that the handle points to the info */
obj->handle = info;
+ info->revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
info->file_path = file_path;
if (device_path) {
@@ -1825,6 +1860,10 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
EFI_ENTRY("%p, %ld", image_handle, map_key);
+ /* Check that the caller has read the current memory map */
+ if (map_key != efi_memory_map_key)
+ return EFI_INVALID_PARAMETER;
+
/* Make sure that notification functions are not called anymore */
efi_tpl = TPL_HIGH_LEVEL;
@@ -1867,9 +1906,7 @@ static efi_status_t EFIAPI efi_exit_boot_services(efi_handle_t image_handle,
systab.boottime = NULL;
/* Recalculate CRC32 */
- systab.hdr.crc32 = 0;
- systab.hdr.crc32 = crc32(0, (const unsigned char *)&systab,
- sizeof(struct efi_system_table));
+ efi_update_table_header_crc32(&systab.hdr);
/* Give the payload some time to boot */
efi_set_watchdog(0);
@@ -2302,7 +2339,7 @@ static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
{
EFI_ENTRY("%p", handle);
- va_list argptr;
+ efi_va_list argptr;
const efi_guid_t *protocol;
void *protocol_interface;
efi_status_t r = EFI_SUCCESS;
@@ -2311,12 +2348,12 @@ static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
if (!handle)
return EFI_EXIT(EFI_INVALID_PARAMETER);
- va_start(argptr, handle);
+ efi_va_start(argptr, handle);
for (;;) {
- protocol = va_arg(argptr, efi_guid_t*);
+ protocol = efi_va_arg(argptr, efi_guid_t*);
if (!protocol)
break;
- protocol_interface = va_arg(argptr, void*);
+ protocol_interface = efi_va_arg(argptr, void*);
r = EFI_CALL(efi_install_protocol_interface(
handle, protocol,
EFI_NATIVE_INTERFACE,
@@ -2325,19 +2362,19 @@ static efi_status_t EFIAPI efi_install_multiple_protocol_interfaces(
break;
i++;
}
- va_end(argptr);
+ efi_va_end(argptr);
if (r == EFI_SUCCESS)
return EFI_EXIT(r);
/* If an error occurred undo all changes. */
- va_start(argptr, handle);
+ efi_va_start(argptr, handle);
for (; i; --i) {
- protocol = va_arg(argptr, efi_guid_t*);
- protocol_interface = va_arg(argptr, void*);
+ protocol = efi_va_arg(argptr, efi_guid_t*);
+ protocol_interface = efi_va_arg(argptr, void*);
EFI_CALL(efi_uninstall_protocol_interface(handle, protocol,
protocol_interface));
}
- va_end(argptr);
+ efi_va_end(argptr);
return EFI_EXIT(r);
}
@@ -2361,7 +2398,7 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
{
EFI_ENTRY("%p", handle);
- va_list argptr;
+ efi_va_list argptr;
const efi_guid_t *protocol;
void *protocol_interface;
efi_status_t r = EFI_SUCCESS;
@@ -2370,12 +2407,12 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
if (!handle)
return EFI_EXIT(EFI_INVALID_PARAMETER);
- va_start(argptr, handle);
+ efi_va_start(argptr, handle);
for (;;) {
- protocol = va_arg(argptr, efi_guid_t*);
+ protocol = efi_va_arg(argptr, efi_guid_t*);
if (!protocol)
break;
- protocol_interface = va_arg(argptr, void*);
+ protocol_interface = efi_va_arg(argptr, void*);
r = EFI_CALL(efi_uninstall_protocol_interface(
handle, protocol,
protocol_interface));
@@ -2383,20 +2420,20 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
break;
i++;
}
- va_end(argptr);
+ efi_va_end(argptr);
if (r == EFI_SUCCESS)
return EFI_EXIT(r);
/* If an error occurred undo all changes. */
- va_start(argptr, handle);
+ efi_va_start(argptr, handle);
for (; i; --i) {
- protocol = va_arg(argptr, efi_guid_t*);
- protocol_interface = va_arg(argptr, void*);
+ protocol = efi_va_arg(argptr, efi_guid_t*);
+ protocol_interface = efi_va_arg(argptr, void*);
EFI_CALL(efi_install_protocol_interface(&handle, protocol,
EFI_NATIVE_INTERFACE,
protocol_interface));
}
- va_end(argptr);
+ efi_va_end(argptr);
return EFI_EXIT(r);
}
@@ -2414,11 +2451,11 @@ static efi_status_t EFIAPI efi_uninstall_multiple_protocol_interfaces(
*
* Return: status code
*/
-static efi_status_t EFIAPI efi_calculate_crc32(void *data,
- unsigned long data_size,
- uint32_t *crc32_p)
+static efi_status_t EFIAPI efi_calculate_crc32(const void *data,
+ efi_uintn_t data_size,
+ u32 *crc32_p)
{
- EFI_ENTRY("%p, %ld", data, data_size);
+ EFI_ENTRY("%p, %zu", data, data_size);
*crc32_p = crc32(0, data, data_size);
return EFI_EXIT(EFI_SUCCESS);
}
@@ -3022,9 +3059,11 @@ out:
return EFI_EXIT(r);
}
-static const struct efi_boot_services efi_boot_services = {
+static struct efi_boot_services efi_boot_services = {
.hdr = {
- .headersize = sizeof(struct efi_table_hdr),
+ .signature = EFI_BOOT_SERVICES_SIGNATURE,
+ .revision = EFI_SPECIFICATION_VERSION,
+ .headersize = sizeof(struct efi_boot_services),
},
.raise_tpl = efi_raise_tpl,
.restore_tpl = efi_restore_tpl,
@@ -3074,20 +3113,44 @@ static const struct efi_boot_services efi_boot_services = {
.create_event_ex = efi_create_event_ex,
};
-static uint16_t __efi_runtime_data firmware_vendor[] = L"Das U-Boot";
+static u16 __efi_runtime_data firmware_vendor[] = L"Das U-Boot";
struct efi_system_table __efi_runtime_data systab = {
.hdr = {
.signature = EFI_SYSTEM_TABLE_SIGNATURE,
- .revision = 2 << 16 | 70, /* 2.7 */
- .headersize = sizeof(struct efi_table_hdr),
+ .revision = EFI_SPECIFICATION_VERSION,
+ .headersize = sizeof(struct efi_system_table),
},
- .fw_vendor = (long)firmware_vendor,
+ .fw_vendor = firmware_vendor,
+ .fw_revision = FW_VERSION << 16 | FW_PATCHLEVEL << 8,
.con_in = (void *)&efi_con_in,
.con_out = (void *)&efi_con_out,
.std_err = (void *)&efi_con_out,
.runtime = (void *)&efi_runtime_services,
.boottime = (void *)&efi_boot_services,
.nr_tables = 0,
- .tables = (void *)efi_conf_table,
+ .tables = NULL,
};
+
+/**
+ * efi_initialize_system_table() - Initialize system table
+ *
+ * Return Value: status code
+ */
+efi_status_t efi_initialize_system_table(void)
+{
+ efi_status_t ret;
+
+ /* Allocate configuration table array */
+ ret = efi_allocate_pool(EFI_RUNTIME_SERVICES_DATA,
+ EFI_MAX_CONFIGURATION_TABLES *
+ sizeof(struct efi_configuration_table),
+ (void **)&systab.tables);
+
+ /* Set crc32 field in table headers */
+ efi_update_table_header_crc32(&systab.hdr);
+ efi_update_table_header_crc32(&efi_runtime_services.hdr);
+ efi_update_table_header_crc32(&efi_boot_services.hdr);
+
+ return ret;
+}
diff --git a/lib/efi_loader/efi_console.c b/lib/efi_loader/efi_console.c
index ce66c935ecb..3fd0d2fd516 100644
--- a/lib/efi_loader/efi_console.c
+++ b/lib/efi_loader/efi_console.c
@@ -335,6 +335,8 @@ static efi_status_t EFIAPI efi_cout_clear_screen(
EFI_ENTRY("%p", this);
printf(ESC"[2J");
+ efi_con_mode.cursor_column = 0;
+ efi_con_mode.cursor_row = 0;
return EFI_EXIT(EFI_SUCCESS);
}
@@ -381,7 +383,12 @@ static efi_status_t EFIAPI efi_cin_reset(
bool extended_verification)
{
EFI_ENTRY("%p, %d", this, extended_verification);
- return EFI_EXIT(EFI_UNSUPPORTED);
+
+ /* Empty input buffer */
+ while (tstc())
+ getc();
+
+ return EFI_EXIT(EFI_SUCCESS);
}
/*
diff --git a/lib/efi_loader/efi_image_loader.c b/lib/efi_loader/efi_image_loader.c
index ecdb77e5b6b..fdf40a62c8e 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -19,25 +19,25 @@ const efi_guid_t efi_simple_file_system_protocol_guid =
const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID;
static int machines[] = {
-#if defined(CONFIG_ARM64)
+#if defined(__aarch64__)
IMAGE_FILE_MACHINE_ARM64,
-#elif defined(CONFIG_ARM)
+#elif defined(__arm__)
IMAGE_FILE_MACHINE_ARM,
IMAGE_FILE_MACHINE_THUMB,
IMAGE_FILE_MACHINE_ARMNT,
#endif
-#if defined(CONFIG_X86_64)
+#if defined(__x86_64__)
IMAGE_FILE_MACHINE_AMD64,
-#elif defined(CONFIG_X86)
+#elif defined(__i386__)
IMAGE_FILE_MACHINE_I386,
#endif
-#if defined(CONFIG_CPU_RISCV_32)
+#if defined(__riscv) && (__riscv_xlen == 32)
IMAGE_FILE_MACHINE_RISCV32,
#endif
-#if defined(CONFIG_CPU_RISCV_64)
+#if defined(__riscv) && (__riscv_xlen == 64)
IMAGE_FILE_MACHINE_RISCV64,
#endif
0 };
diff --git a/lib/efi_loader/efi_memory.c b/lib/efi_loader/efi_memory.c
index ec66af98ea8..967c3f733e4 100644
--- a/lib/efi_loader/efi_memory.c
+++ b/lib/efi_loader/efi_memory.c
@@ -9,11 +9,14 @@
#include <efi_loader.h>
#include <inttypes.h>
#include <malloc.h>
+#include <mapmem.h>
#include <watchdog.h>
#include <linux/list_sort.h>
DECLARE_GLOBAL_DATA_PTR;
+efi_uintn_t efi_memory_map_key;
+
struct efi_mem_list {
struct list_head link;
struct efi_mem_desc desc;
@@ -159,9 +162,13 @@ uint64_t efi_add_memory_map(uint64_t start, uint64_t pages, int memory_type,
debug("%s: 0x%" PRIx64 " 0x%" PRIx64 " %d %s\n", __func__,
start, pages, memory_type, overlap_only_ram ? "yes" : "no");
+ if (memory_type >= EFI_MAX_MEMORY_TYPE)
+ return EFI_INVALID_PARAMETER;
+
if (!pages)
return start;
+ ++efi_memory_map_key;
newlist = calloc(1, sizeof(*newlist));
newlist->desc.type = memory_type;
newlist->desc.physical_start = start;
@@ -292,10 +299,13 @@ efi_status_t efi_allocate_pages(int type, int memory_type,
efi_status_t r = EFI_SUCCESS;
uint64_t addr;
+ if (!memory)
+ return EFI_INVALID_PARAMETER;
+
switch (type) {
case EFI_ALLOCATE_ANY_PAGES:
/* Any page */
- addr = efi_find_free_memory(len, gd->start_addr_sp);
+ addr = efi_find_free_memory(len, -1ULL);
if (!addr) {
r = EFI_NOT_FOUND;
break;
@@ -325,7 +335,7 @@ efi_status_t efi_allocate_pages(int type, int memory_type,
/* Reserve that map in our memory maps */
ret = efi_add_memory_map(addr, pages, memory_type, true);
if (ret == addr) {
- *memory = addr;
+ *memory = (uintptr_t)map_sysmem(addr, len);
} else {
/* Map would overlap, bail out */
r = EFI_OUT_OF_RESOURCES;
@@ -359,11 +369,12 @@ void *efi_alloc(uint64_t len, int memory_type)
efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
{
uint64_t r = 0;
+ uint64_t addr = map_to_sysmem((void *)(uintptr_t)memory);
- r = efi_add_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, false);
+ r = efi_add_memory_map(addr, pages, EFI_CONVENTIONAL_MEMORY, false);
/* Merging of adjacent free regions is missing */
- if (r == memory)
+ if (r == addr)
return EFI_SUCCESS;
return EFI_NOT_FOUND;
@@ -380,20 +391,22 @@ efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
{
efi_status_t r;
- efi_physical_addr_t t;
+ struct efi_pool_allocation *alloc;
u64 num_pages = (size + sizeof(struct efi_pool_allocation) +
EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
+ if (!buffer)
+ return EFI_INVALID_PARAMETER;
+
if (size == 0) {
*buffer = NULL;
return EFI_SUCCESS;
}
r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, pool_type, num_pages,
- &t);
+ (uint64_t *)&alloc);
if (r == EFI_SUCCESS) {
- struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
alloc->num_pages = num_pages;
*buffer = alloc->data;
}
@@ -446,6 +459,9 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
struct list_head *lhandle;
efi_uintn_t provided_map_size = *memory_map_size;
+ if (!memory_map_size)
+ return EFI_INVALID_PARAMETER;
+
list_for_each(lhandle, &efi_mem)
map_entries++;
@@ -456,6 +472,9 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
if (provided_map_size < map_size)
return EFI_BUFFER_TOO_SMALL;
+ if (!memory_map)
+ return EFI_INVALID_PARAMETER;
+
if (descriptor_size)
*descriptor_size = sizeof(struct efi_mem_desc);
@@ -463,19 +482,18 @@ efi_status_t efi_get_memory_map(efi_uintn_t *memory_map_size,
*descriptor_version = EFI_MEMORY_DESCRIPTOR_VERSION;
/* Copy list into array */
- if (memory_map) {
- /* Return the list in ascending order */
- memory_map = &memory_map[map_entries - 1];
- list_for_each(lhandle, &efi_mem) {
- struct efi_mem_list *lmem;
+ /* Return the list in ascending order */
+ memory_map = &memory_map[map_entries - 1];
+ list_for_each(lhandle, &efi_mem) {
+ struct efi_mem_list *lmem;
- lmem = list_entry(lhandle, struct efi_mem_list, link);
- *memory_map = lmem->desc;
- memory_map--;
- }
+ lmem = list_entry(lhandle, struct efi_mem_list, link);
+ *memory_map = lmem->desc;
+ memory_map--;
}
- *map_key = 0;
+ if (map_key)
+ *map_key = efi_memory_map_key;
return EFI_SUCCESS;
}
@@ -496,14 +514,13 @@ __weak void efi_add_known_memory(void)
}
}
-int efi_memory_init(void)
+/* Add memory regions for U-Boot's memory and for the runtime services code */
+static void add_u_boot_and_runtime(void)
{
unsigned long runtime_start, runtime_end, runtime_pages;
unsigned long uboot_start, uboot_pages;
unsigned long uboot_stack_size = 16 * 1024 * 1024;
- efi_add_known_memory();
-
/* Add U-Boot */
uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK;
uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT;
@@ -516,6 +533,14 @@ int efi_memory_init(void)
runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
efi_add_memory_map(runtime_start, runtime_pages,
EFI_RUNTIME_SERVICES_CODE, false);
+}
+
+int efi_memory_init(void)
+{
+ efi_add_known_memory();
+
+ if (!IS_ENABLED(CONFIG_SANDBOX))
+ add_u_boot_and_runtime();
#ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
/* Request a 32bit 64MB bounce buffer region */
diff --git a/lib/efi_loader/efi_runtime.c b/lib/efi_loader/efi_runtime.c
index 4874eb602f7..06958f23fa1 100644
--- a/lib/efi_loader/efi_runtime.c
+++ b/lib/efi_loader/efi_runtime.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <command.h>
#include <dm.h>
+#include <elf.h>
#include <efi_loader.h>
#include <rtc.h>
@@ -32,19 +33,17 @@ static efi_status_t __efi_runtime EFIAPI efi_invalid_parameter(void);
* TODO(sjg@chromium.org): These defines and structs should come from the elf
* header for each arch (or a generic header) rather than being repeated here.
*/
-#if defined(CONFIG_ARM64)
-#define R_RELATIVE 1027
+#if defined(__aarch64__)
+#define R_RELATIVE R_AARCH64_RELATIVE
#define R_MASK 0xffffffffULL
#define IS_RELA 1
-#elif defined(CONFIG_ARM)
-#define R_RELATIVE 23
+#elif defined(__arm__)
+#define R_RELATIVE R_ARM_RELATIVE
#define R_MASK 0xffULL
-#elif defined(CONFIG_X86)
-#include <asm/elf.h>
+#elif defined(__x86_64__) || defined(__i386__)
#define R_RELATIVE R_386_RELATIVE
#define R_MASK 0xffULL
-#elif defined(CONFIG_RISCV)
-#include <elf.h>
+#elif defined(__riscv)
#define R_RELATIVE R_RISCV_RELATIVE
#define R_MASK 0xffULL
#define IS_RELA 1
@@ -55,12 +54,14 @@ struct dyn_sym {
u32 foo2;
u32 foo3;
};
-#ifdef CONFIG_CPU_RISCV_32
+#if (__riscv_xlen == 32)
#define R_ABSOLUTE R_RISCV_32
#define SYM_INDEX 8
-#else
+#elif (__riscv_xlen == 64)
#define R_ABSOLUTE R_RISCV_64
#define SYM_INDEX 32
+#else
+#error unknown riscv target
#endif
#else
#error Need to add relocation awareness
@@ -116,24 +117,41 @@ static void EFIAPI efi_reset_system_boottime(
while (1) { }
}
+/**
+ * efi_get_time_boottime - get current time
+ *
+ * This function implements the GetTime runtime service.
+ * See the Unified Extensible Firmware Interface (UEFI) specification
+ * for details.
+ *
+ * @time: pointer to structure to receive current time
+ * @capabilities: pointer to structure to receive RTC properties
+ * Return Value: status code
+ */
static efi_status_t EFIAPI efi_get_time_boottime(
struct efi_time *time,
struct efi_time_cap *capabilities)
{
-#if defined(CONFIG_CMD_DATE) && defined(CONFIG_DM_RTC)
- struct rtc_time tm;
+#ifdef CONFIG_DM_RTC
+ efi_status_t ret = EFI_SUCCESS;
int r;
+ struct rtc_time tm;
struct udevice *dev;
EFI_ENTRY("%p %p", time, capabilities);
- r = uclass_get_device(UCLASS_RTC, 0, &dev);
- if (r)
- return EFI_EXIT(EFI_DEVICE_ERROR);
+ if (!time) {
+ ret = EFI_INVALID_PARAMETER;
+ goto out;
+ }
- r = dm_rtc_get(dev, &tm);
- if (r)
- return EFI_EXIT(EFI_DEVICE_ERROR);
+ r = uclass_get_device(UCLASS_RTC, 0, &dev);
+ if (!r)
+ r = dm_rtc_get(dev, &tm);
+ if (r) {
+ ret = EFI_DEVICE_ERROR;
+ goto out;
+ }
memset(time, 0, sizeof(*time));
time->year = tm.tm_year;
@@ -141,11 +159,23 @@ static efi_status_t EFIAPI efi_get_time_boottime(
time->day = tm.tm_mday;
time->hour = tm.tm_hour;
time->minute = tm.tm_min;
- time->daylight = tm.tm_isdst;
-
- return EFI_EXIT(EFI_SUCCESS);
+ time->second = tm.tm_sec;
+ time->daylight = EFI_TIME_ADJUST_DAYLIGHT;
+ if (tm.tm_isdst > 0)
+ time->daylight |= EFI_TIME_IN_DAYLIGHT;
+ time->timezone = EFI_UNSPECIFIED_TIMEZONE;
+
+ if (capabilities) {
+ /* Set reasonable dummy values */
+ capabilities->resolution = 1; /* 1 Hz */
+ capabilities->accuracy = 100000000; /* 100 ppm */
+ capabilities->sets_to_zero = false;
+ }
+out:
+ return EFI_EXIT(ret);
#else
- return EFI_DEVICE_ERROR;
+ EFI_ENTRY("%p %p", time, capabilities);
+ return EFI_EXIT(EFI_DEVICE_ERROR);
#endif
}
@@ -173,11 +203,6 @@ efi_status_t __weak __efi_runtime EFIAPI efi_get_time(
return EFI_DEVICE_ERROR;
}
-efi_status_t __weak efi_get_time_init(void)
-{
- return EFI_SUCCESS;
-}
-
struct efi_runtime_detach_list_struct {
void *ptr;
void *patchto;
@@ -458,8 +483,8 @@ efi_status_t __efi_runtime EFIAPI efi_query_variable_info(
struct efi_runtime_services __efi_runtime_data efi_runtime_services = {
.hdr = {
.signature = EFI_RUNTIME_SERVICES_SIGNATURE,
- .revision = EFI_RUNTIME_SERVICES_REVISION,
- .headersize = sizeof(struct efi_table_hdr),
+ .revision = EFI_SPECIFICATION_VERSION,
+ .headersize = sizeof(struct efi_runtime_services),
},
.get_time = &efi_get_time_boottime,
.set_time = (void *)&efi_device_error,
diff --git a/lib/efi_loader/efi_smbios.c b/lib/efi_loader/efi_smbios.c
index 7c3fc8af0b2..932f7582ec6 100644
--- a/lib/efi_loader/efi_smbios.c
+++ b/lib/efi_loader/efi_smbios.c
@@ -26,8 +26,15 @@ efi_status_t efi_smbios_register(void)
/* Reserve 4kiB page for SMBIOS */
ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
- if (ret != EFI_SUCCESS)
- return ret;
+
+ if (ret != EFI_SUCCESS) {
+ /* Could not find space in lowmem, use highmem instead */
+ ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
+ EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
+
+ if (ret != EFI_SUCCESS)
+ return ret;
+ }
/*
* Generate SMBIOS tables - we know that efi_allocate_pages() returns
diff --git a/lib/efi_selftest/.gitignore b/lib/efi_selftest/.gitignore
index c527e464e53..293a17b818c 100644
--- a/lib/efi_selftest/.gitignore
+++ b/lib/efi_selftest/.gitignore
@@ -1,2 +1,4 @@
-efi_miniapp_file_image.h
+efi_miniapp_file_image_exit.h
+efi_miniapp_file_image_return.h
*.efi
+*.so
diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile
index 4fe404d88d8..590f90b16d3 100644
--- a/lib/efi_selftest/Makefile
+++ b/lib/efi_selftest/Makefile
@@ -13,8 +13,10 @@ CFLAGS_REMOVE_efi_selftest_miniapp_return.o := $(CFLAGS_NON_EFI) -Os
obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += \
efi_selftest.o \
efi_selftest_bitblt.o \
+efi_selftest_config_table.o \
efi_selftest_controllers.o \
efi_selftest_console.o \
+efi_selftest_crc32.o \
efi_selftest_devicepath.o \
efi_selftest_devicepath_util.o \
efi_selftest_events.o \
@@ -23,6 +25,7 @@ efi_selftest_exitbootservices.o \
efi_selftest_fdt.o \
efi_selftest_gop.o \
efi_selftest_manageprotocols.o \
+efi_selftest_rtc.o \
efi_selftest_snp.o \
efi_selftest_textinput.o \
efi_selftest_textoutput.o \
@@ -41,7 +44,7 @@ endif
# TODO: As of v2018.01 the relocation code for the EFI application cannot
# be built on x86_64.
-ifeq ($(CONFIG_X86_64),)
+ifeq ($(CONFIG_X86_64)$(CONFIG_SANDBOX),)
ifneq ($(CONFIG_CMD_BOOTEFI_SELFTEST),)
diff --git a/lib/efi_selftest/efi_selftest.c b/lib/efi_selftest/efi_selftest.c
index 13eb2cd6048..dd338db687e 100644
--- a/lib/efi_selftest/efi_selftest.c
+++ b/lib/efi_selftest/efi_selftest.c
@@ -8,9 +8,7 @@
#include <efi_selftest.h>
#include <vsprintf.h>
-/*
- * Constants for test step bitmap
- */
+/* Constants for test step bitmap */
#define EFI_ST_SETUP 1
#define EFI_ST_EXECUTE 2
#define EFI_ST_TEARDOWN 4
@@ -26,7 +24,7 @@ static u16 reset_message[] = L"Selftest completed";
*
* The size of the memory map is determined.
* Pool memory is allocated to copy the memory map.
- * The memory amp is copied and the map key is obtained.
+ * The memory map is copied and the map key is obtained.
* The map key is used to exit the boot services.
*/
void efi_st_exit_boot_services(void)
@@ -146,7 +144,7 @@ static int teardown(struct efi_unit_test *test, unsigned int *failures)
* Check that a test exists.
*
* @testname: name of the test
- * @return: test
+ * @return: test, or NULL if not found
*/
static struct efi_unit_test *find_test(const u16 *testname)
{
@@ -182,7 +180,7 @@ static void list_all_tests(void)
*
* @testname name of a single selected test or NULL
* @phase test phase
- * @steps steps to execute
+ * @steps steps to execute (mask with bits from EFI_ST_...)
* failures returns EFI_ST_SUCCESS if all test steps succeeded
*/
void efi_st_do_tests(const u16 *testname, unsigned int phase,
@@ -296,12 +294,12 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
efi_st_printc(EFI_WHITE, "\nSummary: %u failures\n\n", failures);
/* Reset system */
- efi_st_printf("Preparing for reset. Press any key.\n");
+ efi_st_printf("Preparing for reset. Press any key...\n");
efi_st_get_key();
runtime->reset_system(EFI_RESET_WARM, EFI_NOT_READY,
sizeof(reset_message), reset_message);
efi_st_printf("\n");
- efi_st_error("Reset failed.\n");
+ efi_st_error("Reset failed\n");
return EFI_UNSUPPORTED;
}
diff --git a/lib/efi_selftest/efi_selftest_block_device.c b/lib/efi_selftest/efi_selftest_block_device.c
index 4af8bd8cb28..b82e4050302 100644
--- a/lib/efi_selftest/efi_selftest_block_device.c
+++ b/lib/efi_selftest/efi_selftest_block_device.c
@@ -309,11 +309,14 @@ static int execute(void)
efi_uintn_t buf_size;
char buf[16] __aligned(ARCH_DMA_MINALIGN);
+ /* Connect controller to virtual disk */
ret = boottime->connect_controller(disk_handle, NULL, NULL, 1);
if (ret != EFI_SUCCESS) {
efi_st_error("Failed to connect controller\n");
return EFI_ST_FAILURE;
}
+
+ /* Get the handle for the partition */
ret = boottime->locate_handle_buffer(
BY_PROTOCOL, &guid_device_path, NULL,
&no_handles, &handles);
@@ -347,6 +350,8 @@ static int execute(void)
efi_st_error("Partition handle not found\n");
return EFI_ST_FAILURE;
}
+
+ /* Open the simple file system protocol */
ret = boottime->open_protocol(handle_partition,
&guid_simple_file_system_protocol,
(void **)&file_system, NULL, NULL,
@@ -355,6 +360,8 @@ static int execute(void)
efi_st_error("Failed to open simple file system protocol\n");
return EFI_ST_FAILURE;
}
+
+ /* Open volume */
ret = file_system->open_volume(file_system, &root);
if (ret != EFI_SUCCESS) {
efi_st_error("Failed to open volume\n");
@@ -377,6 +384,8 @@ static int execute(void)
"Wrong volume label '%ps', expected 'U-BOOT TEST'\n",
system_info.info.volume_label);
}
+
+ /* Read file */
ret = root->open(root, &file, (s16 *)L"hello.txt", EFI_FILE_MODE_READ,
0);
if (ret != EFI_SUCCESS) {
@@ -389,6 +398,11 @@ static int execute(void)
efi_st_error("Failed to read file\n");
return EFI_ST_FAILURE;
}
+ if (buf_size != 13) {
+ efi_st_error("Wrong number of bytes read: %u\n",
+ (unsigned int)buf_size);
+ return EFI_ST_FAILURE;
+ }
if (efi_st_memcmp(buf, "Hello world!", 12)) {
efi_st_error("Unexpected file content\n");
return EFI_ST_FAILURE;
@@ -398,6 +412,62 @@ static int execute(void)
efi_st_error("Failed to close file\n");
return EFI_ST_FAILURE;
}
+
+#ifdef CONFIG_FAT_WRITE
+ /* Write file */
+ ret = root->open(root, &file, (s16 *)L"u-boot.txt",
+ EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to open file\n");
+ return EFI_ST_FAILURE;
+ }
+ buf_size = 7;
+ boottime->set_mem(buf, sizeof(buf), 0);
+ boottime->copy_mem(buf, "U-Boot", buf_size);
+ ret = file->write(file, &buf_size, buf);
+ if (ret != EFI_SUCCESS || buf_size != 7) {
+ efi_st_error("Failed to write file\n");
+ return EFI_ST_FAILURE;
+ }
+ ret = file->close(file);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to close file\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Verify file */
+ boottime->set_mem(buf, sizeof(buf), 0);
+ ret = root->open(root, &file, (s16 *)L"u-boot.txt", EFI_FILE_MODE_READ,
+ 0);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to open file\n");
+ return EFI_ST_FAILURE;
+ }
+ buf_size = sizeof(buf) - 1;
+ ret = file->read(file, &buf_size, buf);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to read file\n");
+ return EFI_ST_FAILURE;
+ }
+ if (buf_size != 7) {
+ efi_st_error("Wrong number of bytes read: %u\n",
+ (unsigned int)buf_size);
+ return EFI_ST_FAILURE;
+ }
+ if (efi_st_memcmp(buf, "U-Boot", 7)) {
+ efi_st_error("Unexpected file content %s\n", buf);
+ return EFI_ST_FAILURE;
+ }
+ ret = file->close(file);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to close file\n");
+ return EFI_ST_FAILURE;
+ }
+#else
+ efi_st_todo("CONFIG_FAT_WRITE is not set\n");
+#endif /* CONFIG_FAT_WRITE */
+
+ /* Close volume */
ret = root->close(root);
if (ret != EFI_SUCCESS) {
efi_st_error("Failed to close volume\n");
diff --git a/lib/efi_selftest/efi_selftest_config_table.c b/lib/efi_selftest/efi_selftest_config_table.c
new file mode 100644
index 00000000000..2aa3fc72847
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_config_table.c
@@ -0,0 +1,266 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_config_tables
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * This test checks the following service:
+ * InstallConfigurationTable.
+ */
+
+#include <efi_selftest.h>
+
+static const struct efi_system_table *sys_table;
+static struct efi_boot_services *boottime;
+
+static efi_guid_t table_guid =
+ EFI_GUID(0xff1c3f9e, 0x795b, 0x1529, 0xf1, 0x55,
+ 0x17, 0x2e, 0x51, 0x6b, 0x49, 0x75);
+
+/*
+ * Notification function, increments the notfication count if parameter
+ * context is provided.
+ *
+ * @event notified event
+ * @context pointer to the notification count
+ */
+static void EFIAPI notify(struct efi_event *event, void *context)
+{
+ unsigned int *count = context;
+
+ if (count)
+ ++*count;
+}
+
+/*
+ * Check crc32 of a table.
+ */
+static int check_table(const void *table)
+{
+ efi_status_t ret;
+ u32 crc32, res;
+ /* Casting from const to not const */
+ struct efi_table_hdr *hdr = (struct efi_table_hdr *)table;
+
+ crc32 = hdr->crc32;
+ /*
+ * Setting the crc32 of the 'const' table to zero is easier than
+ * copying
+ */
+ hdr->crc32 = 0;
+ ret = boottime->calculate_crc32(table, hdr->headersize, &res);
+ /* Reset table crc32 so it stays constant */
+ hdr->crc32 = crc32;
+ if (ret != EFI_ST_SUCCESS) {
+ efi_st_error("CalculateCrc32 failed\n");
+ return EFI_ST_FAILURE;
+ }
+ if (res != crc32) {
+ efi_st_error("Incorrect CRC32\n");
+ return EFI_ST_FAILURE;
+ }
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Setup unit test.
+ *
+ * @handle: handle of the loaded image
+ * @systable: system table
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+ const struct efi_system_table *systable)
+{
+ sys_table = systable;
+ boottime = systable->boottime;
+
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ *
+ * A table is installed, updated, removed. The table entry and the
+ * triggering of events is checked.
+ *
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+ efi_status_t ret;
+ unsigned int counter = 0;
+ struct efi_event *event;
+ void *table;
+ const unsigned int tables[2];
+ efi_uintn_t i;
+ efi_uintn_t tabcnt;
+ efi_uintn_t table_count = sys_table->nr_tables;
+
+ ret = boottime->create_event_ex(0, TPL_NOTIFY,
+ notify, (void *)&counter,
+ &table_guid, &event);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to create event\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Try to delete non-existent table */
+ ret = boottime->install_configuration_table(&table_guid, NULL);
+ if (ret != EFI_NOT_FOUND) {
+ efi_st_error("Failed to detect missing table\n");
+ return EFI_ST_FAILURE;
+ }
+ if (counter) {
+ efi_st_error("Notification function was called.\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check if the event was signaled */
+ ret = boottime->check_event(event);
+ if (ret == EFI_SUCCESS) {
+ efi_st_error("Event was signaled on EFI_NOT_FOUND\n");
+ return EFI_ST_FAILURE;
+ }
+ if (counter != 1) {
+ efi_st_error("Notification function was not called.\n");
+ return EFI_ST_FAILURE;
+ }
+ if (table_count != sys_table->nr_tables) {
+ efi_st_error("Incorrect table count %u, expected %u\n",
+ (unsigned int)sys_table->nr_tables,
+ (unsigned int)table_count);
+ return EFI_ST_FAILURE;
+ }
+
+ /* Install table */
+ ret = boottime->install_configuration_table(&table_guid,
+ (void *)&tables[0]);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to install table\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check signaled state */
+ ret = boottime->check_event(event);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Event was not signaled on insert\n");
+ return EFI_ST_FAILURE;
+ }
+ if (++table_count != sys_table->nr_tables) {
+ efi_st_error("Incorrect table count %u, expected %u\n",
+ (unsigned int)sys_table->nr_tables,
+ (unsigned int)table_count);
+ return EFI_ST_FAILURE;
+ }
+ table = NULL;
+ for (i = 0; i < sys_table->nr_tables; ++i) {
+ if (!efi_st_memcmp(&sys_table->tables[i].guid, &table_guid,
+ sizeof(efi_guid_t)))
+ table = sys_table->tables[i].table;
+ }
+ if (!table) {
+ efi_st_error("Installed table not found\n");
+ return EFI_ST_FAILURE;
+ }
+ if (table != &tables[0]) {
+ efi_st_error("Incorrect table address\n");
+ return EFI_ST_FAILURE;
+ }
+ if (check_table(sys_table) != EFI_ST_SUCCESS) {
+ efi_st_error("Checking system table\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Update table */
+ ret = boottime->install_configuration_table(&table_guid,
+ (void *)&tables[1]);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to update table\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check signaled state */
+ ret = boottime->check_event(event);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Event was not signaled on update\n");
+ return EFI_ST_FAILURE;
+ }
+ if (table_count != sys_table->nr_tables) {
+ efi_st_error("Incorrect table count %u, expected %u\n",
+ (unsigned int)sys_table->nr_tables,
+ (unsigned int)table_count);
+ return EFI_ST_FAILURE;
+ }
+ table = NULL;
+ tabcnt = 0;
+ for (i = 0; i < sys_table->nr_tables; ++i) {
+ if (!efi_st_memcmp(&sys_table->tables[i].guid, &table_guid,
+ sizeof(efi_guid_t))) {
+ table = sys_table->tables[i].table;
+ ++tabcnt;
+ }
+ }
+ if (!table) {
+ efi_st_error("Installed table not found\n");
+ return EFI_ST_FAILURE;
+ }
+ if (tabcnt > 1) {
+ efi_st_error("Duplicate table guid\n");
+ return EFI_ST_FAILURE;
+ }
+ if (table != &tables[1]) {
+ efi_st_error("Incorrect table address\n");
+ return EFI_ST_FAILURE;
+ }
+ if (check_table(sys_table) != EFI_ST_SUCCESS) {
+ efi_st_error("Checking system table\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Delete table */
+ ret = boottime->install_configuration_table(&table_guid, NULL);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to delete table\n");
+ return EFI_ST_FAILURE;
+ }
+ /* Check signaled state */
+ ret = boottime->check_event(event);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Event was not signaled on delete\n");
+ return EFI_ST_FAILURE;
+ }
+ if (--table_count != sys_table->nr_tables) {
+ efi_st_error("Incorrect table count %u, expected %u\n",
+ (unsigned int)sys_table->nr_tables,
+ (unsigned int)table_count);
+ return EFI_ST_FAILURE;
+ }
+ table = NULL;
+ for (i = 0; i < sys_table->nr_tables; ++i) {
+ if (!efi_st_memcmp(&sys_table->tables[i].guid, &table_guid,
+ sizeof(efi_guid_t))) {
+ table = sys_table->tables[i].table;
+ }
+ }
+ if (table) {
+ efi_st_error("Wrong table deleted\n");
+ return EFI_ST_FAILURE;
+ }
+
+ ret = boottime->close_event(event);
+ if (ret != EFI_SUCCESS) {
+ efi_st_error("Failed to close event\n");
+ return EFI_ST_FAILURE;
+ }
+ if (check_table(sys_table) != EFI_ST_SUCCESS) {
+ efi_st_error("Checking system table\n");
+ return EFI_ST_FAILURE;
+ }
+
+ return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(configtables) = {
+ .name = "configuration tables",
+ .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+ .setup = setup,
+ .execute = execute,
+};
diff --git a/lib/efi_selftest/efi_selftest_console.c b/lib/efi_selftest/efi_selftest_console.c
index c3655a1fcc0..eb139c127cb 100644
--- a/lib/efi_selftest/efi_selftest_console.c
+++ b/lib/efi_selftest/efi_selftest_console.c
@@ -70,11 +70,12 @@ static void pointer(void *pointer, u16 **buf)
/*
* Print an unsigned 32bit value as decimal number to an u16 string
*
- * @value: value to be printed
- * @buf: pointer to buffer address
- * on return position of terminating zero word
+ * @value: value to be printed
+ * @prec: minimum number of digits to display
+ * @buf: pointer to buffer address
+ * on return position of terminating zero word
*/
-static void uint2dec(u32 value, u16 **buf)
+static void uint2dec(u32 value, int prec, u16 **buf)
{
u16 *pos = *buf;
int i;
@@ -93,7 +94,7 @@ static void uint2dec(u32 value, u16 **buf)
for (i = 0; i < 10; ++i) {
/* Write current digit */
c = f >> 60;
- if (c || pos != *buf)
+ if (c || pos != *buf || 10 - i <= prec)
*pos++ = c + '0';
/* Eliminate current digit */
f &= 0xfffffffffffffff;
@@ -109,11 +110,12 @@ static void uint2dec(u32 value, u16 **buf)
/*
* Print a signed 32bit value as decimal number to an u16 string
*
- * @value: value to be printed
- * @buf: pointer to buffer address
+ * @value: value to be printed
+ * @prec: minimum number of digits to display
+ * @buf: pointer to buffer address
* on return position of terminating zero word
*/
-static void int2dec(s32 value, u16 **buf)
+static void int2dec(s32 value, int prec, u16 **buf)
{
u32 u;
u16 *pos = *buf;
@@ -124,7 +126,7 @@ static void int2dec(s32 value, u16 **buf)
} else {
u = value;
}
- uint2dec(u, &pos);
+ uint2dec(u, prec, &pos);
*buf = pos;
}
@@ -143,6 +145,7 @@ void efi_st_printc(int color, const char *fmt, ...)
u16 *pos = buf;
const char *s;
u16 *u;
+ int prec;
va_start(args, fmt);
@@ -172,12 +175,20 @@ void efi_st_printc(int color, const char *fmt, ...)
break;
case '%':
++c;
+ /* Parse precision */
+ if (*c == '.') {
+ ++c;
+ prec = *c - '0';
+ ++c;
+ } else {
+ prec = 0;
+ }
switch (*c) {
case '\0':
--c;
break;
case 'd':
- int2dec(va_arg(args, s32), &pos);
+ int2dec(va_arg(args, s32), prec, &pos);
break;
case 'p':
++c;
@@ -209,7 +220,7 @@ void efi_st_printc(int color, const char *fmt, ...)
*pos++ = *s;
break;
case 'u':
- uint2dec(va_arg(args, u32), &pos);
+ uint2dec(va_arg(args, u32), prec, &pos);
break;
default:
break;
diff --git a/lib/efi_selftest/efi_selftest_crc32.c b/lib/efi_selftest/efi_selftest_crc32.c
new file mode 100644
index 00000000000..8555b8f1140
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_crc32.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_crc32
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * This unit test checks the CalculateCrc32 bootservice and checks the
+ * headers of the system table, the boot services tablle, and the runtime
+ * services table before and after ExitBootServices().
+ */
+
+#include <efi_selftest.h>
+
+const struct efi_system_table *st;
+efi_status_t (EFIAPI *bs_crc32)(const void *data, efi_uintn_t data_size,
+ u32 *crc32);
+
+static int check_table(const void *table)
+{
+ efi_status_t ret;
+ u32 crc32, res;
+ /* Casting from const to not const */
+ struct efi_table_hdr *hdr = (struct efi_table_hdr *)table;
+
+ if (!hdr->signature) {
+ efi_st_error("Missing header signature\n");
+ return EFI_ST_FAILURE;
+ }
+ if (!hdr->revision) {
+ efi_st_error("Missing header revision\n");
+ return EFI_ST_FAILURE;
+ }
+ if (hdr->headersize <= sizeof(struct efi_table_hdr)) {
+ efi_st_error("Incorrect headersize value\n");
+ return EFI_ST_FAILURE;
+ }
+ if (hdr->reserved) {
+ efi_st_error("Reserved header field is not zero\n");
+ return EFI_ST_FAILURE;
+ }
+
+ crc32 = hdr->crc32;
+ /*
+ * Setting the crc32 of the 'const' table to zero is easier than
+ * copying
+ */
+ hdr->crc32 = 0;
+ ret = bs_crc32(table, hdr->headersize, &res);
+ /* Reset table crc32 so it stays constant */
+ hdr->crc32 = crc32;
+ if (ret != EFI_ST_SUCCESS) {
+ efi_st_error("CalculateCrc32 failed\n");
+ return EFI_ST_FAILURE;
+ }
+ if (res != crc32) {
+ efi_st_error("Incorrect CRC32\n");
+ // return EFI_ST_FAILURE;
+ }
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Setup unit test.
+ *
+ * Check that CalculateCrc32 is working correctly.
+ * Check tables before ExitBootServices().
+ *
+ * @handle: handle of the loaded image
+ * @systable: system table
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+ const struct efi_system_table *systable)
+{
+ efi_status_t ret;
+ u32 res;
+
+ st = systable;
+ bs_crc32 = systable->boottime->calculate_crc32;
+
+ /* Check that CalculateCrc32 is working */
+ ret = bs_crc32("U-Boot", 6, &res);
+ if (ret != EFI_ST_SUCCESS) {
+ efi_st_error("CalculateCrc32 failed\n");
+ return EFI_ST_FAILURE;
+ }
+ if (res != 0x134b0db4) {
+ efi_st_error("Incorrect CRC32\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /* Check tables before ExitBootServices() */
+ if (check_table(st) != EFI_ST_SUCCESS) {
+ efi_st_error("Checking system table\n");
+ return EFI_ST_FAILURE;
+ }
+ if (check_table(st->boottime) != EFI_ST_SUCCESS) {
+ efi_st_error("Checking boottime table\n");
+ return EFI_ST_FAILURE;
+ }
+ if (check_table(st->runtime) != EFI_ST_SUCCESS) {
+ efi_st_error("Checking runtime table\n");
+ return EFI_ST_FAILURE;
+ }
+
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test
+ *
+ * Check tables after ExitBootServices()
+ *
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+ if (check_table(st) != EFI_ST_SUCCESS) {
+ efi_st_error("Checking system table\n");
+ return EFI_ST_FAILURE;
+ }
+ if (check_table(st->runtime) != EFI_ST_SUCCESS) {
+ efi_st_error("Checking runtime table\n");
+ return EFI_ST_FAILURE;
+ }
+
+ /*
+ * We cannot call SetVirtualAddressMap() and recheck the runtime
+ * table afterwards because this would invalidate the addresses of the
+ * unit tests.
+ */
+
+ return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(crc32) = {
+ .name = "crc32",
+ .phase = EFI_SETUP_BEFORE_BOOTTIME_EXIT,
+ .setup = setup,
+ .execute = execute,
+};
diff --git a/lib/efi_selftest/efi_selftest_rtc.c b/lib/efi_selftest/efi_selftest_rtc.c
new file mode 100644
index 00000000000..8d440dc0b3c
--- /dev/null
+++ b/lib/efi_selftest/efi_selftest_rtc.c
@@ -0,0 +1,67 @@
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * efi_selftest_rtc
+ *
+ * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
+ *
+ * Test the real time clock runtime services.
+ */
+
+#include <efi_selftest.h>
+
+#define EFI_ST_NO_RTC "Could not read real time clock\n"
+
+static struct efi_runtime_services *runtime;
+
+/*
+ * Setup unit test.
+ *
+ * @handle: handle of the loaded image
+ * @systable: system table
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int setup(const efi_handle_t handle,
+ const struct efi_system_table *systable)
+{
+ runtime = systable->runtime;
+ return EFI_ST_SUCCESS;
+}
+
+/*
+ * Execute unit test.
+ *
+ * Display current time.
+ *
+ * @return: EFI_ST_SUCCESS for success
+ */
+static int execute(void)
+{
+ efi_status_t ret;
+ struct efi_time tm;
+
+ /* Display current time */
+ ret = runtime->get_time(&tm, NULL);
+ if (ret != EFI_SUCCESS) {
+#ifdef CONFIG_CMD_DATE
+ efi_st_error(EFI_ST_NO_RTC);
+ return EFI_ST_FAILURE;
+#else
+ efi_st_todo(EFI_ST_NO_RTC);
+ return EFI_ST_SUCCESS;
+#endif
+ } else {
+ efi_st_printf("Time according to real time clock: "
+ "%.4u-%.2u-%.2u %.2u:%.2u:%.2u\n",
+ tm.year, tm.month, tm.day,
+ tm.hour, tm.minute, tm.second);
+ }
+
+ return EFI_ST_SUCCESS;
+}
+
+EFI_UNIT_TEST(rtc) = {
+ .name = "real time clock",
+ .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
+ .setup = setup,
+ .execute = execute,
+};
diff --git a/lib/vsprintf.c b/lib/vsprintf.c
index 8b1b29fb5aa..914fbd30cbc 100644
--- a/lib/vsprintf.c
+++ b/lib/vsprintf.c
@@ -407,7 +407,10 @@ static char *uuid_string(char *buf, char *end, u8 *addr, int field_width,
break;
}
- uuid_bin_to_str(addr, uuid, str_format);
+ if (addr)
+ uuid_bin_to_str(addr, uuid, str_format);
+ else
+ strcpy(uuid, "<NULL>");
return string(buf, end, uuid, field_width, precision, flags);
}