Commit 406fd7e207d3593f150079514a371dccdc651ce7

Authored by Tom Rini

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

Patch queue for efi - 2018-07-25

Highlights this time:

  - Many small fixes to improve spec compatibility (found by SCT)
  - Almost enough to run with sandbox target
  - GetTime() improvements
  - Enable EFI_LOADER and HYP entry on ARMv7 with NONSEC=y

Showing 70 changed files Side-by-side Diff

... ... @@ -368,6 +368,7 @@
368 368 F: include/efi*
369 369 F: include/pe.h
370 370 F: include/asm-generic/pe.h
  371 +F: lib/charset.c
371 372 F: lib/efi*/
372 373 F: test/py/tests/test_efi*
373 374 F: cmd/bootefi.c
... ... @@ -134,11 +134,11 @@
134 134 ifdef CONFIG_ARM64
135 135 OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .data \
136 136 -j .u_boot_list -j .rela.dyn -j .got -j .got.plt \
137   - -j .binman_sym_table
  137 + -j .binman_sym_table -j .text_rest
138 138 else
139 139 OBJCOPYFLAGS += -j .text -j .secure_text -j .secure_data -j .rodata -j .hash \
140 140 -j .data -j .got -j .got.plt -j .u_boot_list -j .rel.dyn \
141   - -j .binman_sym_table
  141 + -j .binman_sym_table -j .text_rest
142 142 endif
143 143  
144 144 # if a dtb section exists we always have to include it
arch/arm/cpu/armv7/Kconfig
... ... @@ -53,7 +53,7 @@
53 53 config ARMV7_LPAE
54 54 bool "Use LPAE page table format" if EXPERT
55 55 depends on CPU_V7A
56   - default n
  56 + default y if ARMV7_VIRT
57 57 ---help---
58 58 Say Y here to use the long descriptor page table format. This is
59 59 required if U-Boot runs in HYP mode.
arch/arm/cpu/armv7/nonsec_virt.S
... ... @@ -80,6 +80,8 @@
80 80 #ifdef CONFIG_ARMV7_VIRT
81 81 orreq r5, r5, #0x100 @ allow HVC instruction
82 82 moveq r6, #HYP_MODE @ Enter the kernel as HYP
  83 + mrseq r3, sp_svc
  84 + msreq sp_hyp, r3 @ migrate SP
83 85 #endif
84 86  
85 87 mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set)
arch/arm/cpu/armv8/u-boot.lds
... ... @@ -25,6 +25,19 @@
25 25 {
26 26 *(.__image_copy_start)
27 27 CPUDIR/start.o (.text*)
  28 + }
  29 +
  30 + /* This needs to come before *(.text*) */
  31 + .efi_runtime : {
  32 + __efi_runtime_start = .;
  33 + *(.text.efi_runtime*)
  34 + *(.rodata.efi_runtime*)
  35 + *(.data.efi_runtime*)
  36 + __efi_runtime_stop = .;
  37 + }
  38 +
  39 + .text_rest :
  40 + {
28 41 *(.text*)
29 42 }
30 43  
31 44  
... ... @@ -98,17 +111,10 @@
98 111  
99 112 . = ALIGN(8);
100 113  
101   - .efi_runtime : {
102   - __efi_runtime_start = .;
103   - *(efi_runtime_text)
104   - *(efi_runtime_data)
105   - __efi_runtime_stop = .;
106   - }
107   -
108 114 .efi_runtime_rel : {
109 115 __efi_runtime_rel_start = .;
110   - *(.relaefi_runtime_text)
111   - *(.relaefi_runtime_data)
  116 + *(.rel*.efi_runtime)
  117 + *(.rel*.efi_runtime.*)
112 118 __efi_runtime_rel_stop = .;
113 119 }
114 120  
arch/arm/cpu/u-boot.lds
... ... @@ -43,6 +43,25 @@
43 43 *(.__image_copy_start)
44 44 *(.vectors)
45 45 CPUDIR/start.o (.text*)
  46 + }
  47 +
  48 + /* This needs to come before *(.text*) */
  49 + .__efi_runtime_start : {
  50 + *(.__efi_runtime_start)
  51 + }
  52 +
  53 + .efi_runtime : {
  54 + *(.text.efi_runtime*)
  55 + *(.rodata.efi_runtime*)
  56 + *(.data.efi_runtime*)
  57 + }
  58 +
  59 + .__efi_runtime_stop : {
  60 + *(.__efi_runtime_stop)
  61 + }
  62 +
  63 + .text_rest :
  64 + {
46 65 *(.text*)
47 66 }
48 67  
49 68  
... ... @@ -136,27 +155,14 @@
136 155  
137 156 . = ALIGN(4);
138 157  
139   - .__efi_runtime_start : {
140   - *(.__efi_runtime_start)
141   - }
142   -
143   - .efi_runtime : {
144   - *(efi_runtime_text)
145   - *(efi_runtime_data)
146   - }
147   -
148   - .__efi_runtime_stop : {
149   - *(.__efi_runtime_stop)
150   - }
151   -
152 158 .efi_runtime_rel_start :
153 159 {
154 160 *(.__efi_runtime_rel_start)
155 161 }
156 162  
157 163 .efi_runtime_rel : {
158   - *(.relefi_runtime_text)
159   - *(.relefi_runtime_data)
  164 + *(.rel*.efi_runtime)
  165 + *(.rel*.efi_runtime.*)
160 166 }
161 167  
162 168 .efi_runtime_rel_stop :
arch/arm/mach-zynq/u-boot.lds
... ... @@ -19,6 +19,25 @@
19 19 *(.__image_copy_start)
20 20 *(.vectors)
21 21 CPUDIR/start.o (.text*)
  22 + }
  23 +
  24 + /* This needs to come before *(.text*) */
  25 + .__efi_runtime_start : {
  26 + *(.__efi_runtime_start)
  27 + }
  28 +
  29 + .efi_runtime : {
  30 + *(.text.efi_runtime*)
  31 + *(.rodata.efi_runtime*)
  32 + *(.data.efi_runtime*)
  33 + }
  34 +
  35 + .__efi_runtime_stop : {
  36 + *(.__efi_runtime_stop)
  37 + }
  38 +
  39 + .text_rest :
  40 + {
22 41 *(.text*)
23 42 }
24 43  
25 44  
... ... @@ -41,27 +60,14 @@
41 60  
42 61 . = ALIGN(4);
43 62  
44   - .__efi_runtime_start : {
45   - *(.__efi_runtime_start)
46   - }
47   -
48   - .efi_runtime : {
49   - *(efi_runtime_text)
50   - *(efi_runtime_data)
51   - }
52   -
53   - .__efi_runtime_stop : {
54   - *(.__efi_runtime_stop)
55   - }
56   -
57 63 .efi_runtime_rel_start :
58 64 {
59 65 *(.__efi_runtime_rel_start)
60 66 }
61 67  
62 68 .efi_runtime_rel : {
63   - *(.relefi_runtime_text)
64   - *(.relefi_runtime_data)
  69 + *(.rel*.efi_runtime)
  70 + *(.rel*.efi_runtime.*)
65 71 }
66 72  
67 73 .efi_runtime_rel_stop :
arch/riscv/cpu/ax25/u-boot.lds
... ... @@ -12,9 +12,22 @@
12 12 .text :
13 13 {
14 14 arch/riscv/cpu/ax25/start.o (.text)
15   - *(.text)
16 15 }
17 16  
  17 + /* This needs to come before *(.text*) */
  18 + .efi_runtime : {
  19 + __efi_runtime_start = .;
  20 + *(.text.efi_runtime*)
  21 + *(.rodata.efi_runtime*)
  22 + *(.data.efi_runtime*)
  23 + __efi_runtime_stop = .;
  24 + }
  25 +
  26 + .text_rest :
  27 + {
  28 + *(.text*)
  29 + }
  30 +
18 31 . = ALIGN(4);
19 32 .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
20 33  
21 34  
... ... @@ -39,17 +52,10 @@
39 52  
40 53 . = ALIGN(4);
41 54  
42   - .efi_runtime : {
43   - __efi_runtime_start = .;
44   - *(efi_runtime_text)
45   - *(efi_runtime_data)
46   - __efi_runtime_stop = .;
47   - }
48   -
49 55 .efi_runtime_rel : {
50 56 __efi_runtime_rel_start = .;
51   - *(.relaefi_runtime_text)
52   - *(.relaefi_runtime_data)
  57 + *(.rel*.efi_runtime)
  58 + *(.rel*.efi_runtime.*)
53 59 __efi_runtime_rel_stop = .;
54 60 }
55 61  
arch/sandbox/config.mk
... ... @@ -5,6 +5,9 @@
5 5 PLATFORM_CPPFLAGS += -DCONFIG_ARCH_MAP_SYSMEM
6 6 PLATFORM_LIBS += -lrt
7 7  
  8 +LDFLAGS_FINAL += --gc-sections
  9 +PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections
  10 +
8 11 # Define this to avoid linking with SDL, which requires SDL libraries
9 12 # This can solve 'sdl-config: Command not found' errors
10 13 ifneq ($(NO_SDL),)
arch/sandbox/cpu/u-boot.lds
... ... @@ -24,8 +24,9 @@
24 24 }
25 25  
26 26 .efi_runtime : {
27   - *(efi_runtime_text)
28   - *(efi_runtime_data)
  27 + *(.text.efi_runtime*)
  28 + *(.rodata.efi_runtime*)
  29 + *(.data.efi_runtime*)
29 30 }
30 31  
31 32 .__efi_runtime_stop : {
... ... @@ -38,8 +39,8 @@
38 39 }
39 40  
40 41 .efi_runtime_rel : {
41   - *(.relefi_runtime_text)
42   - *(.relefi_runtime_data)
  42 + *(.rel*.efi_runtime)
  43 + *(.rel*.efi_runtime.*)
43 44 }
44 45  
45 46 .efi_runtime_rel_stop :
... ... @@ -23,6 +23,8 @@
23 23  
24 24 ifeq ($(IS_32BIT),y)
25 25 PLATFORM_CPPFLAGS += -march=i386 -m32
  26 +# TODO: These break on x86_64; need to debug further
  27 +PLATFORM_RELFLAGS += -fdata-sections
26 28 else
27 29 PLATFORM_CPPFLAGS += $(if $(CONFIG_SPL_BUILD),,-fpic) -fno-common -m64
28 30 endif
arch/x86/cpu/start.S
... ... @@ -17,7 +17,7 @@
17 17 #include <generated/generic-asm-offsets.h>
18 18 #include <generated/asm-offsets.h>
19 19  
20   -.section .text
  20 +.section .text.start
21 21 .code32
22 22 .globl _start
23 23 .type _start, @function
arch/x86/cpu/start64.S
... ... @@ -8,7 +8,7 @@
8 8  
9 9 #include <config.h>
10 10  
11   -.section .text
  11 +.section .text.start
12 12 .code64
13 13 .globl _start
14 14 .type _start, @function
arch/x86/cpu/u-boot-64.lds
... ... @@ -17,6 +17,23 @@
17 17  
18 18 . = CONFIG_SYS_TEXT_BASE; /* Location of bootcode in flash */
19 19 __text_start = .;
  20 +
  21 + .text.start : { *(.text.start); }
  22 +
  23 + .__efi_runtime_start : {
  24 + *(.__efi_runtime_start)
  25 + }
  26 +
  27 + .efi_runtime : {
  28 + *(.text.efi_runtime*)
  29 + *(.rodata.efi_runtime*)
  30 + *(.data.efi_runtime*)
  31 + }
  32 +
  33 + .__efi_runtime_stop : {
  34 + *(.__efi_runtime_stop)
  35 + }
  36 +
20 37 .text : { *(.text*); }
21 38  
22 39 . = ALIGN(4);
... ... @@ -27,7 +44,10 @@
27 44 }
28 45  
29 46 . = ALIGN(4);
30   - .rodata : { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }
  47 + .rodata : {
  48 + *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*)))
  49 + KEEP(*(.rodata.efi.init));
  50 + }
31 51  
32 52 . = ALIGN(4);
33 53 .data : { *(.data*) }
... ... @@ -37,6 +57,21 @@
37 57  
38 58 . = ALIGN(4);
39 59 .got : { *(.got*) }
  60 +
  61 + .efi_runtime_rel_start :
  62 + {
  63 + *(.__efi_runtime_rel_start)
  64 + }
  65 +
  66 + .efi_runtime_rel : {
  67 + *(.rel*.efi_runtime)
  68 + *(.rel*.efi_runtime.*)
  69 + }
  70 +
  71 + .efi_runtime_rel_stop :
  72 + {
  73 + *(.__efi_runtime_rel_stop)
  74 + }
40 75  
41 76 . = ALIGN(4);
42 77 __data_end = .;
arch/x86/cpu/u-boot.lds
... ... @@ -17,6 +17,23 @@
17 17  
18 18 . = CONFIG_SYS_TEXT_BASE; /* Location of bootcode in flash */
19 19 __text_start = .;
  20 +
  21 + .text.start : { *(.text.start); }
  22 +
  23 + .__efi_runtime_start : {
  24 + *(.__efi_runtime_start)
  25 + }
  26 +
  27 + .efi_runtime : {
  28 + *(.text.efi_runtime*)
  29 + *(.rodata.efi_runtime*)
  30 + *(.data.efi_runtime*)
  31 + }
  32 +
  33 + .__efi_runtime_stop : {
  34 + *(.__efi_runtime_stop)
  35 + }
  36 +
20 37 .text : { *(.text*); }
21 38  
22 39 . = ALIGN(4);
23 40  
... ... @@ -43,27 +60,14 @@
43 60  
44 61 . = ALIGN(4);
45 62  
46   - .__efi_runtime_start : {
47   - *(.__efi_runtime_start)
48   - }
49   -
50   - .efi_runtime : {
51   - *(efi_runtime_text)
52   - *(efi_runtime_data)
53   - }
54   -
55   - .__efi_runtime_stop : {
56   - *(.__efi_runtime_stop)
57   - }
58   -
59 63 .efi_runtime_rel_start :
60 64 {
61 65 *(.__efi_runtime_rel_start)
62 66 }
63 67  
64 68 .efi_runtime_rel : {
65   - *(.relefi_runtime_text)
66   - *(.relefi_runtime_data)
  69 + *(.rel*.efi_runtime)
  70 + *(.rel*.efi_runtime.*)
67 71 }
68 72  
69 73 .efi_runtime_rel_stop :
arch/x86/include/asm/elf.h
1   -/* SPDX-License-Identifier: GPL-2.0+ */
2   -/*
3   - * Brought in from Linux 4.1, removed things not useful to U-Boot.
4   - * The definitions perhaps came from the GNU Library which is GPL.
5   - */
6   -
7   -#ifndef _ASM_X86_ELF_H
8   -#define _ASM_X86_ELF_H
9   -
10   -/* ELF register definitions */
11   -#define R_386_NONE 0
12   -#define R_386_32 1
13   -#define R_386_PC32 2
14   -#define R_386_GOT32 3
15   -#define R_386_PLT32 4
16   -#define R_386_COPY 5
17   -#define R_386_GLOB_DAT 6
18   -#define R_386_JMP_SLOT 7
19   -#define R_386_RELATIVE 8
20   -#define R_386_GOTOFF 9
21   -#define R_386_GOTPC 10
22   -#define R_386_NUM 11
23   -
24   -/* x86-64 relocation types */
25   -#define R_X86_64_NONE 0 /* No reloc */
26   -#define R_X86_64_64 1 /* Direct 64 bit */
27   -#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
28   -#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
29   -#define R_X86_64_PLT32 4 /* 32 bit PLT address */
30   -#define R_X86_64_COPY 5 /* Copy symbol at runtime */
31   -#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
32   -#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
33   -#define R_X86_64_RELATIVE 8 /* Adjust by program base */
34   -/* 32 bit signed pc relative offset to GOT */
35   -#define R_X86_64_GOTPCREL 9
36   -#define R_X86_64_32 10 /* Direct 32 bit zero extended */
37   -#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
38   -#define R_X86_64_16 12 /* Direct 16 bit zero extended */
39   -#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
40   -#define R_X86_64_8 14 /* Direct 8 bit sign extended */
41   -#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
42   -
43   -#define R_X86_64_NUM 16
44   -
45   -#endif
arch/x86/lib/reloc_ia32_efi.c
... ... @@ -10,7 +10,6 @@
10 10 #include <common.h>
11 11 #include <efi.h>
12 12 #include <elf.h>
13   -#include <asm/elf.h>
14 13  
15 14 efi_status_t EFIAPI _relocate(long ldbase, Elf32_Dyn *dyn)
16 15 {
arch/x86/lib/reloc_x86_64_efi.c
... ... @@ -12,7 +12,6 @@
12 12 #include <common.h>
13 13 #include <efi.h>
14 14 #include <elf.h>
15   -#include <asm/elf.h>
16 15  
17 16 efi_status_t EFIAPI _relocate(long ldbase, Elf64_Dyn *dyn)
18 17 {
board/qualcomm/dragonboard410c/u-boot.lds
... ... @@ -20,6 +20,19 @@
20 20 *(.__image_copy_start)
21 21 board/qualcomm/dragonboard410c/head.o (.text*)
22 22 CPUDIR/start.o (.text*)
  23 + }
  24 +
  25 + /* This needs to come before *(.text*) */
  26 + .efi_runtime : {
  27 + __efi_runtime_start = .;
  28 + *(.text.efi_runtime*)
  29 + *(.rodata.efi_runtime*)
  30 + *(.data.efi_runtime*)
  31 + __efi_runtime_stop = .;
  32 + }
  33 +
  34 + .text_rest :
  35 + {
23 36 *(.text*)
24 37 }
25 38  
... ... @@ -51,8 +64,8 @@
51 64  
52 65 .efi_runtime_rel : {
53 66 __efi_runtime_rel_start = .;
54   - *(.relaefi_runtime_text)
55   - *(.relaefi_runtime_data)
  67 + *(.rel*.efi_runtime)
  68 + *(.rel*.efi_runtime.*)
56 69 __efi_runtime_rel_stop = .;
57 70 }
58 71  
board/qualcomm/dragonboard820c/u-boot.lds
... ... @@ -20,6 +20,19 @@
20 20 *(.__image_copy_start)
21 21 board/qualcomm/dragonboard820c/head.o (.text*)
22 22 CPUDIR/start.o (.text*)
  23 + }
  24 +
  25 + /* This needs to come before *(.text*) */
  26 + .efi_runtime : {
  27 + __efi_runtime_start = .;
  28 + *(.text.efi_runtime*)
  29 + *(.rodata.efi_runtime*)
  30 + *(.data.efi_runtime*)
  31 + __efi_runtime_stop = .;
  32 + }
  33 +
  34 + .text_rest :
  35 + {
23 36 *(.text*)
24 37 }
25 38  
26 39  
... ... @@ -42,17 +55,10 @@
42 55  
43 56 . = ALIGN(8);
44 57  
45   - .efi_runtime : {
46   - __efi_runtime_start = .;
47   - *(efi_runtime_text)
48   - *(efi_runtime_data)
49   - __efi_runtime_stop = .;
50   - }
51   -
52 58 .efi_runtime_rel : {
53 59 __efi_runtime_rel_start = .;
54   - *(.relaefi_runtime_text)
55   - *(.relaefi_runtime_data)
  60 + *(.rel*.efi_runtime)
  61 + *(.rel*.efi_runtime.*)
56 62 __efi_runtime_rel_stop = .;
57 63 }
58 64  
board/ti/am335x/u-boot.lds
... ... @@ -37,6 +37,25 @@
37 37 *(.vectors)
38 38 CPUDIR/start.o (.text*)
39 39 board/ti/am335x/built-in.o (.text*)
  40 + }
  41 +
  42 + /* This needs to come before *(.text*) */
  43 + .__efi_runtime_start : {
  44 + *(.__efi_runtime_start)
  45 + }
  46 +
  47 + .efi_runtime : {
  48 + *(.text.efi_runtime*)
  49 + *(.rodata.efi_runtime*)
  50 + *(.data.efi_runtime*)
  51 + }
  52 +
  53 + .__efi_runtime_stop : {
  54 + *(.__efi_runtime_stop)
  55 + }
  56 +
  57 + .text_rest :
  58 + {
40 59 *(.text*)
41 60 }
42 61  
43 62  
... ... @@ -59,27 +78,14 @@
59 78  
60 79 . = ALIGN(4);
61 80  
62   - .__efi_runtime_start : {
63   - *(.__efi_runtime_start)
64   - }
65   -
66   - .efi_runtime : {
67   - *(efi_runtime_text)
68   - *(efi_runtime_data)
69   - }
70   -
71   - .__efi_runtime_stop : {
72   - *(.__efi_runtime_stop)
73   - }
74   -
75 81 .efi_runtime_rel_start :
76 82 {
77 83 *(.__efi_runtime_rel_start)
78 84 }
79 85  
80 86 .efi_runtime_rel : {
81   - *(.relefi_runtime_text)
82   - *(.relefi_runtime_data)
  87 + *(.rel*.efi_runtime)
  88 + *(.rel*.efi_runtime.*)
83 89 }
84 90  
85 91 .efi_runtime_rel_stop :
... ... @@ -14,12 +14,18 @@
14 14 #include <errno.h>
15 15 #include <linux/libfdt.h>
16 16 #include <linux/libfdt_env.h>
  17 +#include <mapmem.h>
17 18 #include <memalign.h>
18 19 #include <asm/global_data.h>
19 20 #include <asm-generic/sections.h>
20 21 #include <asm-generic/unaligned.h>
21 22 #include <linux/linkage.h>
22 23  
  24 +#ifdef CONFIG_ARMV7_NONSEC
  25 +#include <asm/armv7.h>
  26 +#include <asm/secure.h>
  27 +#endif
  28 +
23 29 DECLARE_GLOBAL_DATA_PTR;
24 30  
25 31 #define OBJ_LIST_NOT_INITIALIZED 1
... ... @@ -38,6 +44,11 @@
38 44 if (efi_obj_list_initialized != OBJ_LIST_NOT_INITIALIZED)
39 45 return efi_obj_list_initialized;
40 46  
  47 + /* Initialize system table */
  48 + ret = efi_initialize_system_table();
  49 + if (ret != EFI_SUCCESS)
  50 + goto out;
  51 +
41 52 /* Initialize EFI driver uclass */
42 53 ret = efi_driver_init();
43 54 if (ret != EFI_SUCCESS)
... ... @@ -79,9 +90,6 @@
79 90 ret = efi_reset_system_init();
80 91 if (ret != EFI_SUCCESS)
81 92 goto out;
82   - ret = efi_get_time_init();
83   - if (ret != EFI_SUCCESS)
84   - goto out;
85 93  
86 94 out:
87 95 efi_obj_list_initialized = ret;
... ... @@ -142,8 +150,12 @@
142 150 fdt_ram_start = ram_start;
143 151 }
144 152  
145   - /* Give us at least 4kb breathing room */
146   - fdt_size = ALIGN(fdt_size + 4096, EFI_PAGE_SIZE);
  153 + /*
  154 + * Give us at least 4KB of breathing room in case the device tree needs
  155 + * to be expanded later. Round up to the nearest EFI page boundary.
  156 + */
  157 + fdt_size += 4096;
  158 + fdt_size = ALIGN(fdt_size + EFI_PAGE_SIZE - 1, EFI_PAGE_SIZE);
147 159 fdt_pages = fdt_size >> EFI_PAGE_SHIFT;
148 160  
149 161 /* Safe fdt location is at 128MB */
150 162  
... ... @@ -194,9 +206,33 @@
194 206 }
195 207 #endif
196 208  
197   -/* Carve out DT reserved memory ranges */
198   -static efi_status_t efi_carve_out_dt_rsv(void *fdt)
  209 +#ifdef CONFIG_ARMV7_NONSEC
  210 +static bool is_nonsec;
  211 +
  212 +static efi_status_t efi_run_in_hyp(EFIAPI efi_status_t (*entry)(
  213 + efi_handle_t image_handle, struct efi_system_table *st),
  214 + efi_handle_t image_handle, struct efi_system_table *st)
199 215 {
  216 + /* Enable caches again */
  217 + dcache_enable();
  218 +
  219 + is_nonsec = true;
  220 +
  221 + return efi_do_enter(image_handle, st, entry);
  222 +}
  223 +#endif
  224 +
  225 +/*
  226 + * efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges
  227 + *
  228 + * The mem_rsv entries of the FDT are added to the memory map. Any failures are
  229 + * ignored because this is not critical and we would rather continue to try to
  230 + * boot.
  231 + *
  232 + * @fdt: Pointer to device tree
  233 + */
  234 +static void efi_carve_out_dt_rsv(void *fdt)
  235 +{
200 236 int nr_rsv, i;
201 237 uint64_t addr, size, pages;
202 238  
203 239  
... ... @@ -208,11 +244,10 @@
208 244 continue;
209 245  
210 246 pages = ALIGN(size, EFI_PAGE_SIZE) >> EFI_PAGE_SHIFT;
211   - efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE,
212   - false);
  247 + if (!efi_add_memory_map(addr, pages, EFI_RESERVED_MEMORY_TYPE,
  248 + false))
  249 + printf("FDT memrsv map %d: Failed to add to map\n", i);
213 250 }
214   -
215   - return EFI_SUCCESS;
216 251 }
217 252  
218 253 static efi_status_t efi_install_fdt(void *fdt)
... ... @@ -236,10 +271,7 @@
236 271 return EFI_LOAD_ERROR;
237 272 }
238 273  
239   - if (efi_carve_out_dt_rsv(fdt) != EFI_SUCCESS) {
240   - printf("ERROR: failed to carve out memory\n");
241   - return EFI_LOAD_ERROR;
242   - }
  274 + efi_carve_out_dt_rsv(fdt);
243 275  
244 276 /* Link to it in the efi tables */
245 277 ret = efi_install_configuration_table(&efi_guid_fdt, fdt);
... ... @@ -350,6 +382,22 @@
350 382 }
351 383 #endif
352 384  
  385 +#ifdef CONFIG_ARMV7_NONSEC
  386 + if (armv7_boot_nonsec() && !is_nonsec) {
  387 + dcache_disable(); /* flush cache before switch to HYP */
  388 +
  389 + armv7_init_nonsec();
  390 + secure_ram_addr(_do_nonsec_entry)(
  391 + efi_run_in_hyp,
  392 + (uintptr_t)entry,
  393 + (uintptr_t)loaded_image_info_obj.handle,
  394 + (uintptr_t)&systab);
  395 +
  396 + /* Should never reach here, efi exits with longjmp */
  397 + while (1) { }
  398 + }
  399 +#endif
  400 +
353 401 ret = efi_do_enter(loaded_image_info_obj.handle, &systab, entry);
354 402  
355 403 exit:
... ... @@ -394,7 +442,8 @@
394 442 unsigned long addr;
395 443 char *saddr;
396 444 efi_status_t r;
397   - void *fdt_addr;
  445 + unsigned long fdt_addr;
  446 + void *fdt;
398 447  
399 448 /* Allow unaligned memory access */
400 449 allow_unaligned();
401 450  
... ... @@ -411,11 +460,12 @@
411 460 return CMD_RET_USAGE;
412 461  
413 462 if (argc > 2) {
414   - fdt_addr = (void *)simple_strtoul(argv[2], NULL, 16);
  463 + fdt_addr = simple_strtoul(argv[2], NULL, 16);
415 464 if (!fdt_addr && *argv[2] != '0')
416 465 return CMD_RET_USAGE;
417 466 /* Install device tree */
418   - r = efi_install_fdt(fdt_addr);
  467 + fdt = map_sysmem(fdt_addr, 0);
  468 + r = efi_install_fdt(fdt);
419 469 if (r != EFI_SUCCESS) {
420 470 printf("ERROR: failed to install device tree\n");
421 471 return CMD_RET_FAILURE;
... ... @@ -434,7 +484,7 @@
434 484 addr = simple_strtoul(saddr, NULL, 16);
435 485 else
436 486 addr = CONFIG_SYS_LOAD_ADDR;
437   - memcpy((char *)addr, __efi_helloworld_begin, size);
  487 + memcpy(map_sysmem(addr, size), __efi_helloworld_begin, size);
438 488 } else
439 489 #endif
440 490 #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
... ... @@ -480,7 +530,7 @@
480 530 }
481 531  
482 532 printf("## Starting EFI application at %08lx ...\n", addr);
483   - r = do_bootefi_exec((void *)addr, bootefi_device_path,
  533 + r = do_bootefi_exec(map_sysmem(addr, 0), bootefi_device_path,
484 534 bootefi_image_path);
485 535 printf("## Application terminated, r = %lu\n",
486 536 r & ~EFI_ERROR_MASK);
... ... @@ -329,8 +329,6 @@
329 329 * persistence
330 330 * runtime support
331 331  
332   -* support bootefi booting ARMv7 in non-secure mode (CONFIG_ARMV7_NONSEC=y)
333   -
334 332 ## Links
335 333  
336 334 * [1](http://uefi.org/specifications)
drivers/rtc/at91sam9_rtt.c
... ... @@ -27,8 +27,6 @@
27 27 #include <asm/arch/at91_rtt.h>
28 28 #include <asm/arch/at91_gpbr.h>
29 29  
30   -#if defined(CONFIG_CMD_DATE)
31   -
32 30 int rtc_get (struct rtc_time *tmp)
33 31 {
34 32 at91_rtt_t *rtt = (at91_rtt_t *) ATMEL_BASE_RTT;
... ... @@ -78,6 +76,4 @@
78 76 while (readl(&rtt->vr) != 0)
79 77 ;
80 78 }
81   -
82   -#endif
drivers/rtc/davinci.c
... ... @@ -9,7 +9,6 @@
9 9 #include <asm/io.h>
10 10 #include <asm/davinci_rtc.h>
11 11  
12   -#if defined(CONFIG_CMD_DATE)
13 12 int rtc_get(struct rtc_time *tmp)
14 13 {
15 14 struct davinci_rtc *rtc = (struct davinci_rtc *)DAVINCI_RTC_BASE;
... ... @@ -79,5 +78,4 @@
79 78 /* run RTC counter */
80 79 writel(0x01, &rtc->ctrl);
81 80 }
82   -#endif
drivers/rtc/ds1302.c
... ... @@ -9,8 +9,6 @@
9 9 #include <command.h>
10 10 #include <rtc.h>
11 11  
12   -#if defined(CONFIG_CMD_DATE)
13   -
14 12 /* GPP Pins */
15 13 #define DATA 0x200
16 14 #define SCLK 0x400
... ... @@ -328,6 +326,4 @@
328 326  
329 327 return 0;
330 328 }
331   -
332   -#endif
drivers/rtc/ds1306.c
... ... @@ -19,8 +19,6 @@
19 19 #include <rtc.h>
20 20 #include <spi.h>
21 21  
22   -#if defined(CONFIG_CMD_DATE)
23   -
24 22 #define RTC_SECONDS 0x00
25 23 #define RTC_MINUTES 0x01
26 24 #define RTC_HOURS 0x02
... ... @@ -437,6 +435,4 @@
437 435 }
438 436  
439 437 #endif /* end of code exclusion (see #ifdef CONFIG_SXNI855T above) */
440   -
441   -#endif
drivers/rtc/ds1307.c
... ... @@ -51,8 +51,6 @@
51 51  
52 52 #ifndef CONFIG_DM_RTC
53 53  
54   -#if defined(CONFIG_CMD_DATE)
55   -
56 54 /*---------------------------------------------------------------------*/
57 55 #undef DEBUG_RTC
58 56  
... ... @@ -203,8 +201,6 @@
203 201 {
204 202 i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
205 203 }
206   -
207   -#endif /* CONFIG_CMD_DATE*/
208 204  
209 205 #endif /* !CONFIG_DM_RTC */
210 206  
drivers/rtc/ds1337.c
... ... @@ -15,8 +15,6 @@
15 15 #include <rtc.h>
16 16 #include <i2c.h>
17 17  
18   -#if defined(CONFIG_CMD_DATE)
19   -
20 18 /*
21 19 * RTC register addresses
22 20 */
... ... @@ -190,6 +188,4 @@
190 188 {
191 189 i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
192 190 }
193   -
194   -#endif
drivers/rtc/ds1374.c
... ... @@ -18,8 +18,6 @@
18 18 #include <rtc.h>
19 19 #include <i2c.h>
20 20  
21   -#if defined(CONFIG_CMD_DATE)
22   -
23 21 /*---------------------------------------------------------------------*/
24 22 #undef DEBUG_RTC
25 23 #define DEBUG_RTC
... ... @@ -214,5 +212,4 @@
214 212 {
215 213 i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
216 214 }
217   -#endif
drivers/rtc/ds164x.c
... ... @@ -20,8 +20,6 @@
20 20 #include <rtc.h>
21 21  
22 22  
23   -#if defined(CONFIG_CMD_DATE)
24   -
25 23 static uchar rtc_read(unsigned int addr );
26 24 static void rtc_write(unsigned int addr, uchar val);
27 25  
... ... @@ -171,6 +169,4 @@
171 169 #endif
172 170 *(volatile unsigned char*)(addr) = val;
173 171 }
174   -
175   -#endif
drivers/rtc/ds174x.c
... ... @@ -16,8 +16,6 @@
16 16 #include <command.h>
17 17 #include <rtc.h>
18 18  
19   -#if defined(CONFIG_CMD_DATE)
20   -
21 19 static uchar rtc_read( unsigned int addr );
22 20 static void rtc_write( unsigned int addr, uchar val);
23 21  
... ... @@ -172,6 +170,4 @@
172 170 #endif
173 171 out8( addr, val );
174 172 }
175   -
176   -#endif
drivers/rtc/ds3231.c
... ... @@ -16,8 +16,6 @@
16 16 #include <rtc.h>
17 17 #include <i2c.h>
18 18  
19   -#if defined(CONFIG_CMD_DATE)
20   -
21 19 /*
22 20 * RTC register addresses
23 21 */
... ... @@ -166,6 +164,4 @@
166 164 {
167 165 i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
168 166 }
169   -
170   -#endif
... ... @@ -17,8 +17,6 @@
17 17 #include <linux/compat.h>
18 18 #include <rtc.h>
19 19  
20   -#if defined(CONFIG_CMD_DATE)
21   -
22 20 #include <asm/io.h>
23 21 #include <asm/arch/imx-regs.h>
24 22  
... ... @@ -222,6 +220,4 @@
222 220 {
223 221 di_init();
224 222 }
225   -
226   -#endif
drivers/rtc/m41t11.c
... ... @@ -29,8 +29,6 @@
29 29 #endif
30 30 */
31 31  
32   -#if defined(CONFIG_SYS_I2C_RTC_ADDR) && defined(CONFIG_CMD_DATE)
33   -
34 32 /* ------------------------------------------------------------------------- */
35 33 /*
36 34 these are simple defines for the chip local to here so they aren't too
... ... @@ -167,5 +165,4 @@
167 165 val = val & 0x3F;/*turn off freq test keep calibration*/
168 166 i2c_write(CONFIG_SYS_I2C_RTC_ADDR, RTC_CONTROL_ADDR, 1, &val, 1);
169 167 }
170   -#endif
drivers/rtc/m41t60.c
... ... @@ -20,8 +20,6 @@
20 20 #include <rtc.h>
21 21 #include <i2c.h>
22 22  
23   -#if defined(CONFIG_SYS_I2C_RTC_ADDR) && defined(CONFIG_CMD_DATE)
24   -
25 23 /*
26 24 * Convert between century and "century bits" (CB1 and CB0). These routines
27 25 * assume years are in the range 1900 - 2299.
... ... @@ -237,5 +235,4 @@
237 235 }
238 236 rtc_dump("end reset");
239 237 }
240   -#endif /* CONFIG_RTC_M41T60 && CONFIG_SYS_I2C_RTC_ADDR && CONFIG_CMD_DATE */
drivers/rtc/m41t62.c
... ... @@ -18,8 +18,6 @@
18 18 #include <rtc.h>
19 19 #include <i2c.h>
20 20  
21   -#if defined(CONFIG_CMD_DATE)
22   -
23 21 #define M41T62_REG_SSEC 0
24 22 #define M41T62_REG_SEC 1
25 23 #define M41T62_REG_MIN 2
... ... @@ -130,6 +128,4 @@
130 128 val &= ~M41T80_ALHOUR_HT;
131 129 i2c_write(CONFIG_SYS_I2C_RTC_ADDR, M41T62_REG_ALARM_HOUR, 1, &val, 1);
132 130 }
133   -
134   -#endif
drivers/rtc/m48t35ax.c
... ... @@ -16,8 +16,6 @@
16 16 #include <rtc.h>
17 17 #include <config.h>
18 18  
19   -#if defined(CONFIG_CMD_DATE)
20   -
21 19 static uchar rtc_read (uchar reg);
22 20 static void rtc_write (uchar reg, uchar val);
23 21  
... ... @@ -135,6 +133,4 @@
135 133 *(unsigned char *)
136 134 ((CONFIG_SYS_NVRAM_BASE_ADDR + CONFIG_SYS_NVRAM_SIZE - 8) + reg) = val;
137 135 }
138   -
139   -#endif
drivers/rtc/max6900.c
... ... @@ -15,8 +15,6 @@
15 15 #include <rtc.h>
16 16 #include <i2c.h>
17 17  
18   -#if defined(CONFIG_CMD_DATE)
19   -
20 18 #ifndef CONFIG_SYS_I2C_RTC_ADDR
21 19 #define CONFIG_SYS_I2C_RTC_ADDR 0x50
22 20 #endif
... ... @@ -104,6 +102,4 @@
104 102 void rtc_reset (void)
105 103 {
106 104 }
107   -
108   -#endif
drivers/rtc/mc146818.c
... ... @@ -19,8 +19,6 @@
19 19 #define out8(p, v) outb(v, p)
20 20 #endif
21 21  
22   -#if defined(CONFIG_CMD_DATE)
23   -
24 22 /* Set this to 1 to clear the CMOS RAM */
25 23 #define CLEAR_CMOS 0
26 24  
... ... @@ -196,7 +194,6 @@
196 194 /* Clear any pending interrupts */
197 195 mc146818_read8(RTC_CONFIG_C);
198 196 }
199   -#endif /* CONFIG_CMD_DATE */
200 197  
201 198 #ifdef CONFIG_DM_RTC
202 199  
drivers/rtc/mcfrtc.c
... ... @@ -6,8 +6,6 @@
6 6  
7 7 #include <common.h>
8 8  
9   -#if defined(CONFIG_CMD_DATE)
10   -
11 9 #include <command.h>
12 10 #include <rtc.h>
13 11 #include <asm/immap.h>
... ... @@ -104,6 +102,4 @@
104 102  
105 103 rtc->cr |= RTC_CR_SWR;
106 104 }
107   -
108   -#endif /* CONFIG_MCFRTC && CONFIG_CMD_DATE */
drivers/rtc/mk48t59.c
... ... @@ -70,8 +70,6 @@
70 70 rtc_write(d++, *s++);
71 71 }
72 72  
73   -#if defined(CONFIG_CMD_DATE)
74   -
75 73 /* ------------------------------------------------------------------------- */
76 74  
77 75 int rtc_get (struct rtc_time *tmp)
... ... @@ -175,6 +173,4 @@
175 173 wd_value = RTC_WDS | ((multi & 0x1F) << 2) | (res & 0x3);
176 174 rtc_write(RTC_WATCHDOG, wd_value);
177 175 }
178   -
179   -#endif
drivers/rtc/pcf8563.c
... ... @@ -15,8 +15,6 @@
15 15 #include <rtc.h>
16 16 #include <i2c.h>
17 17  
18   -#if defined(CONFIG_CMD_DATE)
19   -
20 18 static uchar rtc_read (uchar reg);
21 19 static void rtc_write (uchar reg, uchar val);
22 20  
... ... @@ -117,6 +115,4 @@
117 115 {
118 116 i2c_reg_write (CONFIG_SYS_I2C_RTC_ADDR, reg, val);
119 117 }
120   -
121   -#endif
drivers/rtc/rs5c372.c
... ... @@ -24,7 +24,6 @@
24 24 #include <rtc.h>
25 25 #include <i2c.h>
26 26  
27   -#if defined(CONFIG_CMD_DATE)
28 27 /*
29 28 * Reads are always done starting with register 15, which requires some
30 29 * jumping-through-hoops to access the data correctly.
... ... @@ -255,6 +254,4 @@
255 254 if (!setup_done)
256 255 rs5c372_enable();
257 256 }
258   -
259   -#endif
drivers/rtc/rx8025.c
... ... @@ -13,8 +13,6 @@
13 13 #include <rtc.h>
14 14 #include <i2c.h>
15 15  
16   -#if defined(CONFIG_CMD_DATE)
17   -
18 16 /*---------------------------------------------------------------------*/
19 17 #undef DEBUG_RTC
20 18  
... ... @@ -190,6 +188,4 @@
190 188 printf("Error writing to RTC\n");
191 189  
192 190 }
193   -
194   -#endif /* CONFIG_RTC_RX8025 && CONFIG_CMD_DATE */
drivers/rtc/s3c24x0_rtc.c
... ... @@ -11,8 +11,6 @@
11 11 #include <common.h>
12 12 #include <command.h>
13 13  
14   -#if (defined(CONFIG_CMD_DATE))
15   -
16 14 #include <asm/arch/s3c24x0_cpu.h>
17 15  
18 16 #include <rtc.h>
... ... @@ -149,6 +147,4 @@
149 147 writeb((readb(&rtc->rtccon) & ~0x06) | 0x08, &rtc->rtccon);
150 148 writeb(readb(&rtc->rtccon) & ~(0x08 | 0x01), &rtc->rtccon);
151 149 }
152   -
153   -#endif
... ... @@ -22,8 +22,6 @@
22 22 #include <rtc.h>
23 23 #include <i2c.h>
24 24  
25   -#if defined(CONFIG_CMD_DATE)
26   -
27 25 #define CCR_SEC 0
28 26 #define CCR_MIN 1
29 27 #define CCR_HOUR 2
... ... @@ -160,6 +158,4 @@
160 158 * Nothing to do
161 159 */
162 160 }
163   -
164   -#endif
... ... @@ -909,9 +909,11 @@
909 909 volume_info volinfo;
910 910 fsdata datablock;
911 911 fsdata *mydata = &datablock;
912   - int cursect;
  912 + int cursect, i;
913 913 int ret = -1, name_len;
914 914 char l_filename[VFAT_MAXLEN_BYTES];
  915 + char bad[2] = " ";
  916 + const char illegal[] = "<>:\"/\\|?*";
915 917  
916 918 *actwrite = size;
917 919 dir_curclust = 0;
... ... @@ -970,6 +972,18 @@
970 972 goto exit;
971 973 }
972 974 dentptr = (dir_entry *) do_fat_read_at_block;
  975 +
  976 + /* Strip leading (back-)slashes */
  977 + while ISDIRDELIM(*filename)
  978 + ++filename;
  979 + /* Check that the filename is valid */
  980 + for (i = 0; i < strlen(illegal); ++i) {
  981 + *bad = illegal[i];
  982 + if (strstr(filename, bad)) {
  983 + printf("FAT: illegal filename (%s)\n", filename);
  984 + return -1;
  985 + }
  986 + }
973 987  
974 988 name_len = strlen(filename);
975 989 if (name_len >= VFAT_MAXLEN_BYTES)
... ... @@ -29,8 +29,16 @@
29 29 */
30 30 #ifdef __x86_64__
31 31 #define EFIAPI __attribute__((ms_abi))
  32 +#define efi_va_list __builtin_ms_va_list
  33 +#define efi_va_start __builtin_ms_va_start
  34 +#define efi_va_arg __builtin_va_arg
  35 +#define efi_va_end __builtin_ms_va_end
32 36 #else
33 37 #define EFIAPI asmlinkage
  38 +#define efi_va_list va_list
  39 +#define efi_va_start va_start
  40 +#define efi_va_arg va_arg
  41 +#define efi_va_end va_end
34 42 #endif /* __x86_64__ */
35 43  
36 44 struct efi_device_path;
... ... @@ -21,6 +21,9 @@
21 21 #include <asm/setjmp.h>
22 22 #endif
23 23  
  24 +/* UEFI spec version 2.7 */
  25 +#define EFI_SPECIFICATION_VERSION (2 << 16 | 70)
  26 +
24 27 /* Types and defines for EFI CreateEvent */
25 28 enum efi_timer_delay {
26 29 EFI_TIMER_STOP = 0,
... ... @@ -46,6 +49,7 @@
46 49 struct efi_event;
47 50  
48 51 /* EFI Boot Services table */
  52 +#define EFI_BOOT_SERVICES_SIGNATURE 0x56524553544f4f42
49 53 struct efi_boot_services {
50 54 struct efi_table_hdr hdr;
51 55 efi_status_t (EFIAPI *raise_tpl)(efi_uintn_t new_tpl);
... ... @@ -161,8 +165,9 @@
161 165 void **handle, ...);
162 166 efi_status_t (EFIAPI *uninstall_multiple_protocol_interfaces)(
163 167 void *handle, ...);
164   - efi_status_t (EFIAPI *calculate_crc32)(void *data,
165   - unsigned long data_size, uint32_t *crc32);
  168 + efi_status_t (EFIAPI *calculate_crc32)(const void *data,
  169 + efi_uintn_t data_size,
  170 + u32 *crc32);
166 171 void (EFIAPI *copy_mem)(void *destination, const void *source,
167 172 size_t length);
168 173 void (EFIAPI *set_mem)(void *buffer, size_t size, uint8_t value);
... ... @@ -185,8 +190,7 @@
185 190 };
186 191  
187 192 /* EFI Runtime Services table */
188   -#define EFI_RUNTIME_SERVICES_SIGNATURE 0x5652453544e5552ULL
189   -#define EFI_RUNTIME_SERVICES_REVISION 0x00010000
  193 +#define EFI_RUNTIME_SERVICES_SIGNATURE 0x56524553544e5552ULL
190 194  
191 195 #define CAPSULE_FLAGS_PERSIST_ACROSS_RESET 0x00010000
192 196 #define CAPSULE_FLAGS_POPULATE_SYSTEM_TABLE 0x00020000
... ... @@ -300,7 +304,7 @@
300 304  
301 305 struct efi_system_table {
302 306 struct efi_table_hdr hdr;
303   - unsigned long fw_vendor; /* physical addr of wchar_t vendor string */
  307 + u16 *fw_vendor; /* physical addr of wchar_t vendor string */
304 308 u32 fw_revision;
305 309 efi_handle_t con_in_handle;
306 310 struct efi_simple_input_interface *con_in;
... ... @@ -317,6 +321,8 @@
317 321 #define LOADED_IMAGE_GUID \
318 322 EFI_GUID(0x5b1b31a1, 0x9562, 0x11d2, \
319 323 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
  324 +
  325 +#define EFI_LOADED_IMAGE_PROTOCOL_REVISION 0x1000
320 326  
321 327 struct efi_loaded_image {
322 328 u32 revision;
include/efi_loader.h
... ... @@ -17,6 +17,9 @@
17 17  
18 18 #include <linux/list.h>
19 19  
  20 +/* Maximum number of configuration tables */
  21 +#define EFI_MAX_CONFIGURATION_TABLES 16
  22 +
20 23 int __efi_entry_check(void);
21 24 int __efi_exit_check(void);
22 25 const char *__efi_nesting(void);
... ... @@ -82,6 +85,9 @@
82 85 #define EFI_CACHELINE_SIZE 128
83 86 #endif
84 87  
  88 +/* Key identifying current memory map */
  89 +extern efi_uintn_t efi_memory_map_key;
  90 +
85 91 extern struct efi_runtime_services efi_runtime_services;
86 92 extern struct efi_system_table systab;
87 93  
... ... @@ -199,6 +205,8 @@
199 205 /* List of all events */
200 206 extern struct list_head efi_events;
201 207  
  208 +/* Called by bootefi to initialize runtime */
  209 +efi_status_t efi_initialize_system_table(void);
202 210 /* Called by bootefi to make console interface available */
203 211 int efi_console_register(void);
204 212 /* Called by bootefi to make all disk storage accessible as EFI objects */
... ... @@ -406,8 +414,8 @@
406 414 * Use these to indicate that your code / data should go into the EFI runtime
407 415 * section and thus still be available when the OS is running
408 416 */
409   -#define __efi_runtime_data __attribute__ ((section ("efi_runtime_data")))
410   -#define __efi_runtime __attribute__ ((section ("efi_runtime_text")))
  417 +#define __efi_runtime_data __attribute__ ((section (".data.efi_runtime")))
  418 +#define __efi_runtime __attribute__ ((section (".text.efi_runtime")))
411 419  
412 420 /* Call this with mmio_ptr as the _pointer_ to a pointer to an MMIO region
413 421 * to make it available at runtime */
... ... @@ -426,7 +434,6 @@
426 434 efi_status_t __efi_runtime EFIAPI efi_get_time(
427 435 struct efi_time *time,
428 436 struct efi_time_cap *capabilities);
429   -efi_status_t efi_get_time_init(void);
430 437  
431 438 #ifdef CONFIG_CMD_BOOTEFI_SELFTEST
432 439 /*
... ... @@ -550,6 +550,41 @@
550 550  
551 551 #endif /* __ASSEMBLER */
552 552  
  553 +/* ELF register definitions */
  554 +#define R_386_NONE 0
  555 +#define R_386_32 1
  556 +#define R_386_PC32 2
  557 +#define R_386_GOT32 3
  558 +#define R_386_PLT32 4
  559 +#define R_386_COPY 5
  560 +#define R_386_GLOB_DAT 6
  561 +#define R_386_JMP_SLOT 7
  562 +#define R_386_RELATIVE 8
  563 +#define R_386_GOTOFF 9
  564 +#define R_386_GOTPC 10
  565 +#define R_386_NUM 11
  566 +
  567 +/* x86-64 relocation types */
  568 +#define R_X86_64_NONE 0 /* No reloc */
  569 +#define R_X86_64_64 1 /* Direct 64 bit */
  570 +#define R_X86_64_PC32 2 /* PC relative 32 bit signed */
  571 +#define R_X86_64_GOT32 3 /* 32 bit GOT entry */
  572 +#define R_X86_64_PLT32 4 /* 32 bit PLT address */
  573 +#define R_X86_64_COPY 5 /* Copy symbol at runtime */
  574 +#define R_X86_64_GLOB_DAT 6 /* Create GOT entry */
  575 +#define R_X86_64_JUMP_SLOT 7 /* Create PLT entry */
  576 +#define R_X86_64_RELATIVE 8 /* Adjust by program base */
  577 +/* 32 bit signed pc relative offset to GOT */
  578 +#define R_X86_64_GOTPCREL 9
  579 +#define R_X86_64_32 10 /* Direct 32 bit zero extended */
  580 +#define R_X86_64_32S 11 /* Direct 32 bit sign extended */
  581 +#define R_X86_64_16 12 /* Direct 16 bit zero extended */
  582 +#define R_X86_64_PC16 13 /* 16 bit sign extended pc relative */
  583 +#define R_X86_64_8 14 /* Direct 8 bit sign extended */
  584 +#define R_X86_64_PC8 15 /* 8 bit sign extended pc relative */
  585 +
  586 +#define R_X86_64_NUM 16
  587 +
553 588 /*
554 589 * XXX - PowerPC defines really don't belong in here,
555 590 * but we'll put them in for simplicity.
lib/efi_driver/efi_block_device.c
... ... @@ -161,6 +161,8 @@
161 161 return ret;
162 162 if (!bdev)
163 163 return -ENOENT;
  164 + /* Set the DM_FLAG_NAME_ALLOCED flag to avoid a memory leak */
  165 + device_set_name_alloced(bdev);
164 166 /* Allocate priv */
165 167 ret = device_probe(bdev);
166 168 if (ret)
lib/efi_loader/Kconfig
1 1 config EFI_LOADER
2 2 bool "Support running EFI Applications in U-Boot"
3 3 depends on (ARM || X86 || RISCV) && OF_LIBFDT
4   - # We do not support bootefi booting ARMv7 in non-secure mode
5   - depends on !ARMV7_NONSEC
6 4 # We need EFI_STUB_64BIT to be set on x86_64 with EFI_STUB
7 5 depends on !EFI_STUB || !X86_64 || EFI_STUB_64BIT
8 6 # We need EFI_STUB_32BIT to be set on x86_32 with EFI_STUB
lib/efi_loader/Makefile
... ... @@ -6,6 +6,9 @@
6 6 # This file only gets included with CONFIG_EFI_LOADER set, so all
7 7 # object inclusion implicitly depends on it
8 8  
  9 +CFLAGS_efi_boottime.o += \
  10 + -DFW_VERSION="0x$(VERSION)" \
  11 + -DFW_PATCHLEVEL="0x$(PATCHLEVEL)"
9 12 CFLAGS_helloworld.o := $(CFLAGS_EFI) -Os -ffreestanding
10 13 CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI) -Os
11 14  
lib/efi_loader/efi_boottime.c
... ... @@ -35,16 +35,6 @@
35 35 */
36 36 static bool efi_is_direct_boot = true;
37 37  
38   -/*
39   - * EFI can pass arbitrary additional "tables" containing vendor specific
40   - * information to the payload. One such table is the FDT table which contains
41   - * a pointer to a flattened device tree blob.
42   - *
43   - * In most cases we want to pass an FDT to the payload, so reserve one slot of
44   - * config table space for it. The pointer gets populated by do_bootefi_exec().
45   - */
46   -static struct efi_configuration_table __efi_runtime_data efi_conf_table[16];
47   -
48 38 #ifdef CONFIG_ARM
49 39 /*
50 40 * The "gd" pointer lives in a register on ARM and AArch64 that we declare
... ... @@ -164,6 +154,18 @@
164 154 }
165 155  
166 156 /**
  157 + * efi_update_table_header_crc32() - Update CRC32 in table header
  158 + *
  159 + * @table: EFI table
  160 + */
  161 +static void efi_update_table_header_crc32(struct efi_table_hdr *table)
  162 +{
  163 + table->crc32 = 0;
  164 + table->crc32 = crc32(0, (const unsigned char *)table,
  165 + table->headersize);
  166 +}
  167 +
  168 +/**
167 169 * efi_queue_event() - queue an EFI event
168 170 * @event: event to signal
169 171 * @check_tpl: check the TPL level
... ... @@ -191,6 +193,25 @@
191 193 }
192 194  
193 195 /**
  196 + * is_valid_tpl() - check if the task priority level is valid
  197 + *
  198 + * @tpl: TPL level to check
  199 + * ReturnValue: status code
  200 + */
  201 +efi_status_t is_valid_tpl(efi_uintn_t tpl)
  202 +{
  203 + switch (tpl) {
  204 + case TPL_APPLICATION:
  205 + case TPL_CALLBACK:
  206 + case TPL_NOTIFY:
  207 + case TPL_HIGH_LEVEL:
  208 + return EFI_SUCCESS;
  209 + default:
  210 + return EFI_INVALID_PARAMETER;
  211 + }
  212 +}
  213 +
  214 +/**
194 215 * efi_signal_event() - signal an EFI event
195 216 * @event: event to signal
196 217 * @check_tpl: check the TPL level
197 218  
198 219  
... ... @@ -592,11 +613,21 @@
592 613 if (event == NULL)
593 614 return EFI_INVALID_PARAMETER;
594 615  
595   - if ((type & EVT_NOTIFY_SIGNAL) && (type & EVT_NOTIFY_WAIT))
  616 + switch (type) {
  617 + case 0:
  618 + case EVT_TIMER:
  619 + case EVT_NOTIFY_SIGNAL:
  620 + case EVT_TIMER | EVT_NOTIFY_SIGNAL:
  621 + case EVT_NOTIFY_WAIT:
  622 + case EVT_TIMER | EVT_NOTIFY_WAIT:
  623 + case EVT_SIGNAL_EXIT_BOOT_SERVICES:
  624 + case EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE:
  625 + break;
  626 + default:
596 627 return EFI_INVALID_PARAMETER;
  628 + }
597 629  
598   - if ((type & (EVT_NOTIFY_SIGNAL | EVT_NOTIFY_WAIT)) &&
599   - notify_function == NULL)
  630 + if (is_valid_tpl(notify_tpl) != EFI_SUCCESS)
600 631 return EFI_INVALID_PARAMETER;
601 632  
602 633 evt = calloc(1, sizeof(struct efi_event));
... ... @@ -1361,9 +1392,9 @@
1361 1392 */
1362 1393 static void efi_remove_configuration_table(int i)
1363 1394 {
1364   - struct efi_configuration_table *this = &efi_conf_table[i];
1365   - struct efi_configuration_table *next = &efi_conf_table[i + 1];
1366   - struct efi_configuration_table *end = &efi_conf_table[systab.nr_tables];
  1395 + struct efi_configuration_table *this = &systab.tables[i];
  1396 + struct efi_configuration_table *next = &systab.tables[i + 1];
  1397 + struct efi_configuration_table *end = &systab.tables[systab.nr_tables];
1367 1398  
1368 1399 memmove(this, next, (ulong)end - (ulong)next);
1369 1400 systab.nr_tables--;
1370 1401  
... ... @@ -1391,9 +1422,9 @@
1391 1422  
1392 1423 /* Check for guid override */
1393 1424 for (i = 0; i < systab.nr_tables; i++) {
1394   - if (!guidcmp(guid, &efi_conf_table[i].guid)) {
  1425 + if (!guidcmp(guid, &systab.tables[i].guid)) {
1395 1426 if (table)
1396   - efi_conf_table[i].table = table;
  1427 + systab.tables[i].table = table;
1397 1428 else
1398 1429 efi_remove_configuration_table(i);
1399 1430 goto out;
1400 1431  
1401 1432  
... ... @@ -1404,15 +1435,18 @@
1404 1435 return EFI_NOT_FOUND;
1405 1436  
1406 1437 /* No override, check for overflow */
1407   - if (i >= ARRAY_SIZE(efi_conf_table))
  1438 + if (i >= EFI_MAX_CONFIGURATION_TABLES)
1408 1439 return EFI_OUT_OF_RESOURCES;
1409 1440  
1410 1441 /* Add a new entry */
1411   - memcpy(&efi_conf_table[i].guid, guid, sizeof(*guid));
1412   - efi_conf_table[i].table = table;
  1442 + memcpy(&systab.tables[i].guid, guid, sizeof(*guid));
  1443 + systab.tables[i].table = table;
1413 1444 systab.nr_tables = i + 1;
1414 1445  
1415 1446 out:
  1447 + /* systab.nr_tables may have changed. So we need to update the crc32 */
  1448 + efi_update_table_header_crc32(&systab.hdr);
  1449 +
1416 1450 /* Notify that the configuration table was changed */
1417 1451 list_for_each_entry(evt, &efi_events, link) {
1418 1452 if (evt->group && !guidcmp(evt->group, guid)) {
... ... @@ -1468,6 +1502,7 @@
1468 1502 /* efi_exit() assumes that the handle points to the info */
1469 1503 obj->handle = info;
1470 1504  
  1505 + info->revision = EFI_LOADED_IMAGE_PROTOCOL_REVISION;
1471 1506 info->file_path = file_path;
1472 1507  
1473 1508 if (device_path) {
... ... @@ -1825,6 +1860,10 @@
1825 1860  
1826 1861 EFI_ENTRY("%p, %ld", image_handle, map_key);
1827 1862  
  1863 + /* Check that the caller has read the current memory map */
  1864 + if (map_key != efi_memory_map_key)
  1865 + return EFI_INVALID_PARAMETER;
  1866 +
1828 1867 /* Make sure that notification functions are not called anymore */
1829 1868 efi_tpl = TPL_HIGH_LEVEL;
1830 1869  
... ... @@ -1867,9 +1906,7 @@
1867 1906 systab.boottime = NULL;
1868 1907  
1869 1908 /* Recalculate CRC32 */
1870   - systab.hdr.crc32 = 0;
1871   - systab.hdr.crc32 = crc32(0, (const unsigned char *)&systab,
1872   - sizeof(struct efi_system_table));
  1909 + efi_update_table_header_crc32(&systab.hdr);
1873 1910  
1874 1911 /* Give the payload some time to boot */
1875 1912 efi_set_watchdog(0);
... ... @@ -2302,7 +2339,7 @@
2302 2339 {
2303 2340 EFI_ENTRY("%p", handle);
2304 2341  
2305   - va_list argptr;
  2342 + efi_va_list argptr;
2306 2343 const efi_guid_t *protocol;
2307 2344 void *protocol_interface;
2308 2345 efi_status_t r = EFI_SUCCESS;
2309 2346  
2310 2347  
... ... @@ -2311,12 +2348,12 @@
2311 2348 if (!handle)
2312 2349 return EFI_EXIT(EFI_INVALID_PARAMETER);
2313 2350  
2314   - va_start(argptr, handle);
  2351 + efi_va_start(argptr, handle);
2315 2352 for (;;) {
2316   - protocol = va_arg(argptr, efi_guid_t*);
  2353 + protocol = efi_va_arg(argptr, efi_guid_t*);
2317 2354 if (!protocol)
2318 2355 break;
2319   - protocol_interface = va_arg(argptr, void*);
  2356 + protocol_interface = efi_va_arg(argptr, void*);
2320 2357 r = EFI_CALL(efi_install_protocol_interface(
2321 2358 handle, protocol,
2322 2359 EFI_NATIVE_INTERFACE,
2323 2360  
2324 2361  
2325 2362  
... ... @@ -2325,19 +2362,19 @@
2325 2362 break;
2326 2363 i++;
2327 2364 }
2328   - va_end(argptr);
  2365 + efi_va_end(argptr);
2329 2366 if (r == EFI_SUCCESS)
2330 2367 return EFI_EXIT(r);
2331 2368  
2332 2369 /* If an error occurred undo all changes. */
2333   - va_start(argptr, handle);
  2370 + efi_va_start(argptr, handle);
2334 2371 for (; i; --i) {
2335   - protocol = va_arg(argptr, efi_guid_t*);
2336   - protocol_interface = va_arg(argptr, void*);
  2372 + protocol = efi_va_arg(argptr, efi_guid_t*);
  2373 + protocol_interface = efi_va_arg(argptr, void*);
2337 2374 EFI_CALL(efi_uninstall_protocol_interface(handle, protocol,
2338 2375 protocol_interface));
2339 2376 }
2340   - va_end(argptr);
  2377 + efi_va_end(argptr);
2341 2378  
2342 2379 return EFI_EXIT(r);
2343 2380 }
... ... @@ -2361,7 +2398,7 @@
2361 2398 {
2362 2399 EFI_ENTRY("%p", handle);
2363 2400  
2364   - va_list argptr;
  2401 + efi_va_list argptr;
2365 2402 const efi_guid_t *protocol;
2366 2403 void *protocol_interface;
2367 2404 efi_status_t r = EFI_SUCCESS;
2368 2405  
2369 2406  
... ... @@ -2370,12 +2407,12 @@
2370 2407 if (!handle)
2371 2408 return EFI_EXIT(EFI_INVALID_PARAMETER);
2372 2409  
2373   - va_start(argptr, handle);
  2410 + efi_va_start(argptr, handle);
2374 2411 for (;;) {
2375   - protocol = va_arg(argptr, efi_guid_t*);
  2412 + protocol = efi_va_arg(argptr, efi_guid_t*);
2376 2413 if (!protocol)
2377 2414 break;
2378   - protocol_interface = va_arg(argptr, void*);
  2415 + protocol_interface = efi_va_arg(argptr, void*);
2379 2416 r = EFI_CALL(efi_uninstall_protocol_interface(
2380 2417 handle, protocol,
2381 2418 protocol_interface));
2382 2419  
2383 2420  
2384 2421  
... ... @@ -2383,20 +2420,20 @@
2383 2420 break;
2384 2421 i++;
2385 2422 }
2386   - va_end(argptr);
  2423 + efi_va_end(argptr);
2387 2424 if (r == EFI_SUCCESS)
2388 2425 return EFI_EXIT(r);
2389 2426  
2390 2427 /* If an error occurred undo all changes. */
2391   - va_start(argptr, handle);
  2428 + efi_va_start(argptr, handle);
2392 2429 for (; i; --i) {
2393   - protocol = va_arg(argptr, efi_guid_t*);
2394   - protocol_interface = va_arg(argptr, void*);
  2430 + protocol = efi_va_arg(argptr, efi_guid_t*);
  2431 + protocol_interface = efi_va_arg(argptr, void*);
2395 2432 EFI_CALL(efi_install_protocol_interface(&handle, protocol,
2396 2433 EFI_NATIVE_INTERFACE,
2397 2434 protocol_interface));
2398 2435 }
2399   - va_end(argptr);
  2436 + efi_va_end(argptr);
2400 2437  
2401 2438 return EFI_EXIT(r);
2402 2439 }
2403 2440  
... ... @@ -2414,11 +2451,11 @@
2414 2451 *
2415 2452 * Return: status code
2416 2453 */
2417   -static efi_status_t EFIAPI efi_calculate_crc32(void *data,
2418   - unsigned long data_size,
2419   - uint32_t *crc32_p)
  2454 +static efi_status_t EFIAPI efi_calculate_crc32(const void *data,
  2455 + efi_uintn_t data_size,
  2456 + u32 *crc32_p)
2420 2457 {
2421   - EFI_ENTRY("%p, %ld", data, data_size);
  2458 + EFI_ENTRY("%p, %zu", data, data_size);
2422 2459 *crc32_p = crc32(0, data, data_size);
2423 2460 return EFI_EXIT(EFI_SUCCESS);
2424 2461 }
2425 2462  
... ... @@ -3022,9 +3059,11 @@
3022 3059 return EFI_EXIT(r);
3023 3060 }
3024 3061  
3025   -static const struct efi_boot_services efi_boot_services = {
  3062 +static struct efi_boot_services efi_boot_services = {
3026 3063 .hdr = {
3027   - .headersize = sizeof(struct efi_table_hdr),
  3064 + .signature = EFI_BOOT_SERVICES_SIGNATURE,
  3065 + .revision = EFI_SPECIFICATION_VERSION,
  3066 + .headersize = sizeof(struct efi_boot_services),
3028 3067 },
3029 3068 .raise_tpl = efi_raise_tpl,
3030 3069 .restore_tpl = efi_restore_tpl,
3031 3070  
3032 3071  
3033 3072  
3034 3073  
... ... @@ -3074,21 +3113,45 @@
3074 3113 .create_event_ex = efi_create_event_ex,
3075 3114 };
3076 3115  
3077   -static uint16_t __efi_runtime_data firmware_vendor[] = L"Das U-Boot";
  3116 +static u16 __efi_runtime_data firmware_vendor[] = L"Das U-Boot";
3078 3117  
3079 3118 struct efi_system_table __efi_runtime_data systab = {
3080 3119 .hdr = {
3081 3120 .signature = EFI_SYSTEM_TABLE_SIGNATURE,
3082   - .revision = 2 << 16 | 70, /* 2.7 */
3083   - .headersize = sizeof(struct efi_table_hdr),
  3121 + .revision = EFI_SPECIFICATION_VERSION,
  3122 + .headersize = sizeof(struct efi_system_table),
3084 3123 },
3085   - .fw_vendor = (long)firmware_vendor,
  3124 + .fw_vendor = firmware_vendor,
  3125 + .fw_revision = FW_VERSION << 16 | FW_PATCHLEVEL << 8,
3086 3126 .con_in = (void *)&efi_con_in,
3087 3127 .con_out = (void *)&efi_con_out,
3088 3128 .std_err = (void *)&efi_con_out,
3089 3129 .runtime = (void *)&efi_runtime_services,
3090 3130 .boottime = (void *)&efi_boot_services,
3091 3131 .nr_tables = 0,
3092   - .tables = (void *)efi_conf_table,
  3132 + .tables = NULL,
3093 3133 };
  3134 +
  3135 +/**
  3136 + * efi_initialize_system_table() - Initialize system table
  3137 + *
  3138 + * Return Value: status code
  3139 + */
  3140 +efi_status_t efi_initialize_system_table(void)
  3141 +{
  3142 + efi_status_t ret;
  3143 +
  3144 + /* Allocate configuration table array */
  3145 + ret = efi_allocate_pool(EFI_RUNTIME_SERVICES_DATA,
  3146 + EFI_MAX_CONFIGURATION_TABLES *
  3147 + sizeof(struct efi_configuration_table),
  3148 + (void **)&systab.tables);
  3149 +
  3150 + /* Set crc32 field in table headers */
  3151 + efi_update_table_header_crc32(&systab.hdr);
  3152 + efi_update_table_header_crc32(&efi_runtime_services.hdr);
  3153 + efi_update_table_header_crc32(&efi_boot_services.hdr);
  3154 +
  3155 + return ret;
  3156 +}
lib/efi_loader/efi_console.c
... ... @@ -335,6 +335,8 @@
335 335 EFI_ENTRY("%p", this);
336 336  
337 337 printf(ESC"[2J");
  338 + efi_con_mode.cursor_column = 0;
  339 + efi_con_mode.cursor_row = 0;
338 340  
339 341 return EFI_EXIT(EFI_SUCCESS);
340 342 }
... ... @@ -381,7 +383,12 @@
381 383 bool extended_verification)
382 384 {
383 385 EFI_ENTRY("%p, %d", this, extended_verification);
384   - return EFI_EXIT(EFI_UNSUPPORTED);
  386 +
  387 + /* Empty input buffer */
  388 + while (tstc())
  389 + getc();
  390 +
  391 + return EFI_EXIT(EFI_SUCCESS);
385 392 }
386 393  
387 394 /*
lib/efi_loader/efi_image_loader.c
... ... @@ -19,25 +19,25 @@
19 19 const efi_guid_t efi_file_info_guid = EFI_FILE_INFO_GUID;
20 20  
21 21 static int machines[] = {
22   -#if defined(CONFIG_ARM64)
  22 +#if defined(__aarch64__)
23 23 IMAGE_FILE_MACHINE_ARM64,
24   -#elif defined(CONFIG_ARM)
  24 +#elif defined(__arm__)
25 25 IMAGE_FILE_MACHINE_ARM,
26 26 IMAGE_FILE_MACHINE_THUMB,
27 27 IMAGE_FILE_MACHINE_ARMNT,
28 28 #endif
29 29  
30   -#if defined(CONFIG_X86_64)
  30 +#if defined(__x86_64__)
31 31 IMAGE_FILE_MACHINE_AMD64,
32   -#elif defined(CONFIG_X86)
  32 +#elif defined(__i386__)
33 33 IMAGE_FILE_MACHINE_I386,
34 34 #endif
35 35  
36   -#if defined(CONFIG_CPU_RISCV_32)
  36 +#if defined(__riscv) && (__riscv_xlen == 32)
37 37 IMAGE_FILE_MACHINE_RISCV32,
38 38 #endif
39 39  
40   -#if defined(CONFIG_CPU_RISCV_64)
  40 +#if defined(__riscv) && (__riscv_xlen == 64)
41 41 IMAGE_FILE_MACHINE_RISCV64,
42 42 #endif
43 43 0 };
lib/efi_loader/efi_memory.c
... ... @@ -9,11 +9,14 @@
9 9 #include <efi_loader.h>
10 10 #include <inttypes.h>
11 11 #include <malloc.h>
  12 +#include <mapmem.h>
12 13 #include <watchdog.h>
13 14 #include <linux/list_sort.h>
14 15  
15 16 DECLARE_GLOBAL_DATA_PTR;
16 17  
  18 +efi_uintn_t efi_memory_map_key;
  19 +
17 20 struct efi_mem_list {
18 21 struct list_head link;
19 22 struct efi_mem_desc desc;
20 23  
... ... @@ -159,9 +162,13 @@
159 162 debug("%s: 0x%" PRIx64 " 0x%" PRIx64 " %d %s\n", __func__,
160 163 start, pages, memory_type, overlap_only_ram ? "yes" : "no");
161 164  
  165 + if (memory_type >= EFI_MAX_MEMORY_TYPE)
  166 + return EFI_INVALID_PARAMETER;
  167 +
162 168 if (!pages)
163 169 return start;
164 170  
  171 + ++efi_memory_map_key;
165 172 newlist = calloc(1, sizeof(*newlist));
166 173 newlist->desc.type = memory_type;
167 174 newlist->desc.physical_start = start;
168 175  
... ... @@ -292,10 +299,13 @@
292 299 efi_status_t r = EFI_SUCCESS;
293 300 uint64_t addr;
294 301  
  302 + if (!memory)
  303 + return EFI_INVALID_PARAMETER;
  304 +
295 305 switch (type) {
296 306 case EFI_ALLOCATE_ANY_PAGES:
297 307 /* Any page */
298   - addr = efi_find_free_memory(len, gd->start_addr_sp);
  308 + addr = efi_find_free_memory(len, -1ULL);
299 309 if (!addr) {
300 310 r = EFI_NOT_FOUND;
301 311 break;
... ... @@ -325,7 +335,7 @@
325 335 /* Reserve that map in our memory maps */
326 336 ret = efi_add_memory_map(addr, pages, memory_type, true);
327 337 if (ret == addr) {
328   - *memory = addr;
  338 + *memory = (uintptr_t)map_sysmem(addr, len);
329 339 } else {
330 340 /* Map would overlap, bail out */
331 341 r = EFI_OUT_OF_RESOURCES;
332 342  
333 343  
... ... @@ -359,11 +369,12 @@
359 369 efi_status_t efi_free_pages(uint64_t memory, efi_uintn_t pages)
360 370 {
361 371 uint64_t r = 0;
  372 + uint64_t addr = map_to_sysmem((void *)(uintptr_t)memory);
362 373  
363   - r = efi_add_memory_map(memory, pages, EFI_CONVENTIONAL_MEMORY, false);
  374 + r = efi_add_memory_map(addr, pages, EFI_CONVENTIONAL_MEMORY, false);
364 375 /* Merging of adjacent free regions is missing */
365 376  
366   - if (r == memory)
  377 + if (r == addr)
367 378 return EFI_SUCCESS;
368 379  
369 380 return EFI_NOT_FOUND;
370 381  
371 382  
372 383  
... ... @@ -380,20 +391,22 @@
380 391 efi_status_t efi_allocate_pool(int pool_type, efi_uintn_t size, void **buffer)
381 392 {
382 393 efi_status_t r;
383   - efi_physical_addr_t t;
  394 + struct efi_pool_allocation *alloc;
384 395 u64 num_pages = (size + sizeof(struct efi_pool_allocation) +
385 396 EFI_PAGE_MASK) >> EFI_PAGE_SHIFT;
386 397  
  398 + if (!buffer)
  399 + return EFI_INVALID_PARAMETER;
  400 +
387 401 if (size == 0) {
388 402 *buffer = NULL;
389 403 return EFI_SUCCESS;
390 404 }
391 405  
392 406 r = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES, pool_type, num_pages,
393   - &t);
  407 + (uint64_t *)&alloc);
394 408  
395 409 if (r == EFI_SUCCESS) {
396   - struct efi_pool_allocation *alloc = (void *)(uintptr_t)t;
397 410 alloc->num_pages = num_pages;
398 411 *buffer = alloc->data;
399 412 }
... ... @@ -446,6 +459,9 @@
446 459 struct list_head *lhandle;
447 460 efi_uintn_t provided_map_size = *memory_map_size;
448 461  
  462 + if (!memory_map_size)
  463 + return EFI_INVALID_PARAMETER;
  464 +
449 465 list_for_each(lhandle, &efi_mem)
450 466 map_entries++;
451 467  
... ... @@ -456,6 +472,9 @@
456 472 if (provided_map_size < map_size)
457 473 return EFI_BUFFER_TOO_SMALL;
458 474  
  475 + if (!memory_map)
  476 + return EFI_INVALID_PARAMETER;
  477 +
459 478 if (descriptor_size)
460 479 *descriptor_size = sizeof(struct efi_mem_desc);
461 480  
462 481  
463 482  
... ... @@ -463,19 +482,18 @@
463 482 *descriptor_version = EFI_MEMORY_DESCRIPTOR_VERSION;
464 483  
465 484 /* Copy list into array */
466   - if (memory_map) {
467   - /* Return the list in ascending order */
468   - memory_map = &memory_map[map_entries - 1];
469   - list_for_each(lhandle, &efi_mem) {
470   - struct efi_mem_list *lmem;
  485 + /* Return the list in ascending order */
  486 + memory_map = &memory_map[map_entries - 1];
  487 + list_for_each(lhandle, &efi_mem) {
  488 + struct efi_mem_list *lmem;
471 489  
472   - lmem = list_entry(lhandle, struct efi_mem_list, link);
473   - *memory_map = lmem->desc;
474   - memory_map--;
475   - }
  490 + lmem = list_entry(lhandle, struct efi_mem_list, link);
  491 + *memory_map = lmem->desc;
  492 + memory_map--;
476 493 }
477 494  
478   - *map_key = 0;
  495 + if (map_key)
  496 + *map_key = efi_memory_map_key;
479 497  
480 498 return EFI_SUCCESS;
481 499 }
482 500  
... ... @@ -496,14 +514,13 @@
496 514 }
497 515 }
498 516  
499   -int efi_memory_init(void)
  517 +/* Add memory regions for U-Boot's memory and for the runtime services code */
  518 +static void add_u_boot_and_runtime(void)
500 519 {
501 520 unsigned long runtime_start, runtime_end, runtime_pages;
502 521 unsigned long uboot_start, uboot_pages;
503 522 unsigned long uboot_stack_size = 16 * 1024 * 1024;
504 523  
505   - efi_add_known_memory();
506   -
507 524 /* Add U-Boot */
508 525 uboot_start = (gd->start_addr_sp - uboot_stack_size) & ~EFI_PAGE_MASK;
509 526 uboot_pages = (gd->ram_top - uboot_start) >> EFI_PAGE_SHIFT;
... ... @@ -516,6 +533,14 @@
516 533 runtime_pages = (runtime_end - runtime_start) >> EFI_PAGE_SHIFT;
517 534 efi_add_memory_map(runtime_start, runtime_pages,
518 535 EFI_RUNTIME_SERVICES_CODE, false);
  536 +}
  537 +
  538 +int efi_memory_init(void)
  539 +{
  540 + efi_add_known_memory();
  541 +
  542 + if (!IS_ENABLED(CONFIG_SANDBOX))
  543 + add_u_boot_and_runtime();
519 544  
520 545 #ifdef CONFIG_EFI_LOADER_BOUNCE_BUFFER
521 546 /* Request a 32bit 64MB bounce buffer region */
lib/efi_loader/efi_runtime.c
... ... @@ -8,6 +8,7 @@
8 8 #include <common.h>
9 9 #include <command.h>
10 10 #include <dm.h>
  11 +#include <elf.h>
11 12 #include <efi_loader.h>
12 13 #include <rtc.h>
13 14  
14 15  
15 16  
16 17  
... ... @@ -32,19 +33,17 @@
32 33 * TODO(sjg@chromium.org): These defines and structs should come from the elf
33 34 * header for each arch (or a generic header) rather than being repeated here.
34 35 */
35   -#if defined(CONFIG_ARM64)
36   -#define R_RELATIVE 1027
  36 +#if defined(__aarch64__)
  37 +#define R_RELATIVE R_AARCH64_RELATIVE
37 38 #define R_MASK 0xffffffffULL
38 39 #define IS_RELA 1
39   -#elif defined(CONFIG_ARM)
40   -#define R_RELATIVE 23
  40 +#elif defined(__arm__)
  41 +#define R_RELATIVE R_ARM_RELATIVE
41 42 #define R_MASK 0xffULL
42   -#elif defined(CONFIG_X86)
43   -#include <asm/elf.h>
  43 +#elif defined(__x86_64__) || defined(__i386__)
44 44 #define R_RELATIVE R_386_RELATIVE
45 45 #define R_MASK 0xffULL
46   -#elif defined(CONFIG_RISCV)
47   -#include <elf.h>
  46 +#elif defined(__riscv)
48 47 #define R_RELATIVE R_RISCV_RELATIVE
49 48 #define R_MASK 0xffULL
50 49 #define IS_RELA 1
51 50  
52 51  
... ... @@ -55,12 +54,14 @@
55 54 u32 foo2;
56 55 u32 foo3;
57 56 };
58   -#ifdef CONFIG_CPU_RISCV_32
  57 +#if (__riscv_xlen == 32)
59 58 #define R_ABSOLUTE R_RISCV_32
60 59 #define SYM_INDEX 8
61   -#else
  60 +#elif (__riscv_xlen == 64)
62 61 #define R_ABSOLUTE R_RISCV_64
63 62 #define SYM_INDEX 32
  63 +#else
  64 +#error unknown riscv target
64 65 #endif
65 66 #else
66 67 #error Need to add relocation awareness
67 68  
68 69  
69 70  
70 71  
71 72  
72 73  
73 74  
74 75  
... ... @@ -116,36 +117,65 @@
116 117 while (1) { }
117 118 }
118 119  
  120 +/**
  121 + * efi_get_time_boottime - get current time
  122 + *
  123 + * This function implements the GetTime runtime service.
  124 + * See the Unified Extensible Firmware Interface (UEFI) specification
  125 + * for details.
  126 + *
  127 + * @time: pointer to structure to receive current time
  128 + * @capabilities: pointer to structure to receive RTC properties
  129 + * Return Value: status code
  130 + */
119 131 static efi_status_t EFIAPI efi_get_time_boottime(
120 132 struct efi_time *time,
121 133 struct efi_time_cap *capabilities)
122 134 {
123   -#if defined(CONFIG_CMD_DATE) && defined(CONFIG_DM_RTC)
124   - struct rtc_time tm;
  135 +#ifdef CONFIG_DM_RTC
  136 + efi_status_t ret = EFI_SUCCESS;
125 137 int r;
  138 + struct rtc_time tm;
126 139 struct udevice *dev;
127 140  
128 141 EFI_ENTRY("%p %p", time, capabilities);
129 142  
  143 + if (!time) {
  144 + ret = EFI_INVALID_PARAMETER;
  145 + goto out;
  146 + }
  147 +
130 148 r = uclass_get_device(UCLASS_RTC, 0, &dev);
131   - if (r)
132   - return EFI_EXIT(EFI_DEVICE_ERROR);
  149 + if (!r)
  150 + r = dm_rtc_get(dev, &tm);
  151 + if (r) {
  152 + ret = EFI_DEVICE_ERROR;
  153 + goto out;
  154 + }
133 155  
134   - r = dm_rtc_get(dev, &tm);
135   - if (r)
136   - return EFI_EXIT(EFI_DEVICE_ERROR);
137   -
138 156 memset(time, 0, sizeof(*time));
139 157 time->year = tm.tm_year;
140 158 time->month = tm.tm_mon;
141 159 time->day = tm.tm_mday;
142 160 time->hour = tm.tm_hour;
143 161 time->minute = tm.tm_min;
144   - time->daylight = tm.tm_isdst;
  162 + time->second = tm.tm_sec;
  163 + time->daylight = EFI_TIME_ADJUST_DAYLIGHT;
  164 + if (tm.tm_isdst > 0)
  165 + time->daylight |= EFI_TIME_IN_DAYLIGHT;
  166 + time->timezone = EFI_UNSPECIFIED_TIMEZONE;
145 167  
146   - return EFI_EXIT(EFI_SUCCESS);
  168 + if (capabilities) {
  169 + /* Set reasonable dummy values */
  170 + capabilities->resolution = 1; /* 1 Hz */
  171 + capabilities->accuracy = 100000000; /* 100 ppm */
  172 + capabilities->sets_to_zero = false;
  173 + }
  174 +out:
  175 + return EFI_EXIT(ret);
147 176 #else
148   - return EFI_DEVICE_ERROR;
  177 + EFI_ENTRY("%p %p", time, capabilities);
  178 + return EFI_EXIT(EFI_DEVICE_ERROR);
149 179 #endif
150 180 }
151 181  
... ... @@ -173,11 +203,6 @@
173 203 return EFI_DEVICE_ERROR;
174 204 }
175 205  
176   -efi_status_t __weak efi_get_time_init(void)
177   -{
178   - return EFI_SUCCESS;
179   -}
180   -
181 206 struct efi_runtime_detach_list_struct {
182 207 void *ptr;
183 208 void *patchto;
... ... @@ -458,8 +483,8 @@
458 483 struct efi_runtime_services __efi_runtime_data efi_runtime_services = {
459 484 .hdr = {
460 485 .signature = EFI_RUNTIME_SERVICES_SIGNATURE,
461   - .revision = EFI_RUNTIME_SERVICES_REVISION,
462   - .headersize = sizeof(struct efi_table_hdr),
  486 + .revision = EFI_SPECIFICATION_VERSION,
  487 + .headersize = sizeof(struct efi_runtime_services),
463 488 },
464 489 .get_time = &efi_get_time_boottime,
465 490 .set_time = (void *)&efi_device_error,
lib/efi_loader/efi_smbios.c
... ... @@ -26,8 +26,15 @@
26 26 /* Reserve 4kiB page for SMBIOS */
27 27 ret = efi_allocate_pages(EFI_ALLOCATE_MAX_ADDRESS,
28 28 EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
29   - if (ret != EFI_SUCCESS)
30   - return ret;
  29 +
  30 + if (ret != EFI_SUCCESS) {
  31 + /* Could not find space in lowmem, use highmem instead */
  32 + ret = efi_allocate_pages(EFI_ALLOCATE_ANY_PAGES,
  33 + EFI_RUNTIME_SERVICES_DATA, 1, &dmi);
  34 +
  35 + if (ret != EFI_SUCCESS)
  36 + return ret;
  37 + }
31 38  
32 39 /*
33 40 * Generate SMBIOS tables - we know that efi_allocate_pages() returns
lib/efi_selftest/.gitignore
1   -efi_miniapp_file_image.h
  1 +efi_miniapp_file_image_exit.h
  2 +efi_miniapp_file_image_return.h
2 3 *.efi
  4 +*.so
lib/efi_selftest/Makefile
... ... @@ -13,8 +13,10 @@
13 13 obj-$(CONFIG_CMD_BOOTEFI_SELFTEST) += \
14 14 efi_selftest.o \
15 15 efi_selftest_bitblt.o \
  16 +efi_selftest_config_table.o \
16 17 efi_selftest_controllers.o \
17 18 efi_selftest_console.o \
  19 +efi_selftest_crc32.o \
18 20 efi_selftest_devicepath.o \
19 21 efi_selftest_devicepath_util.o \
20 22 efi_selftest_events.o \
... ... @@ -23,6 +25,7 @@
23 25 efi_selftest_fdt.o \
24 26 efi_selftest_gop.o \
25 27 efi_selftest_manageprotocols.o \
  28 +efi_selftest_rtc.o \
26 29 efi_selftest_snp.o \
27 30 efi_selftest_textinput.o \
28 31 efi_selftest_textoutput.o \
... ... @@ -41,7 +44,7 @@
41 44  
42 45 # TODO: As of v2018.01 the relocation code for the EFI application cannot
43 46 # be built on x86_64.
44   -ifeq ($(CONFIG_X86_64),)
  47 +ifeq ($(CONFIG_X86_64)$(CONFIG_SANDBOX),)
45 48  
46 49 ifneq ($(CONFIG_CMD_BOOTEFI_SELFTEST),)
47 50  
lib/efi_selftest/efi_selftest.c
... ... @@ -8,9 +8,7 @@
8 8 #include <efi_selftest.h>
9 9 #include <vsprintf.h>
10 10  
11   -/*
12   - * Constants for test step bitmap
13   - */
  11 +/* Constants for test step bitmap */
14 12 #define EFI_ST_SETUP 1
15 13 #define EFI_ST_EXECUTE 2
16 14 #define EFI_ST_TEARDOWN 4
... ... @@ -26,7 +24,7 @@
26 24 *
27 25 * The size of the memory map is determined.
28 26 * Pool memory is allocated to copy the memory map.
29   - * The memory amp is copied and the map key is obtained.
  27 + * The memory map is copied and the map key is obtained.
30 28 * The map key is used to exit the boot services.
31 29 */
32 30 void efi_st_exit_boot_services(void)
... ... @@ -146,7 +144,7 @@
146 144 * Check that a test exists.
147 145 *
148 146 * @testname: name of the test
149   - * @return: test
  147 + * @return: test, or NULL if not found
150 148 */
151 149 static struct efi_unit_test *find_test(const u16 *testname)
152 150 {
... ... @@ -182,7 +180,7 @@
182 180 *
183 181 * @testname name of a single selected test or NULL
184 182 * @phase test phase
185   - * @steps steps to execute
  183 + * @steps steps to execute (mask with bits from EFI_ST_...)
186 184 * failures returns EFI_ST_SUCCESS if all test steps succeeded
187 185 */
188 186 void efi_st_do_tests(const u16 *testname, unsigned int phase,
189 187  
... ... @@ -296,12 +294,12 @@
296 294 efi_st_printc(EFI_WHITE, "\nSummary: %u failures\n\n", failures);
297 295  
298 296 /* Reset system */
299   - efi_st_printf("Preparing for reset. Press any key.\n");
  297 + efi_st_printf("Preparing for reset. Press any key...\n");
300 298 efi_st_get_key();
301 299 runtime->reset_system(EFI_RESET_WARM, EFI_NOT_READY,
302 300 sizeof(reset_message), reset_message);
303 301 efi_st_printf("\n");
304   - efi_st_error("Reset failed.\n");
  302 + efi_st_error("Reset failed\n");
305 303  
306 304 return EFI_UNSUPPORTED;
307 305 }
lib/efi_selftest/efi_selftest_block_device.c
... ... @@ -309,11 +309,14 @@
309 309 efi_uintn_t buf_size;
310 310 char buf[16] __aligned(ARCH_DMA_MINALIGN);
311 311  
  312 + /* Connect controller to virtual disk */
312 313 ret = boottime->connect_controller(disk_handle, NULL, NULL, 1);
313 314 if (ret != EFI_SUCCESS) {
314 315 efi_st_error("Failed to connect controller\n");
315 316 return EFI_ST_FAILURE;
316 317 }
  318 +
  319 + /* Get the handle for the partition */
317 320 ret = boottime->locate_handle_buffer(
318 321 BY_PROTOCOL, &guid_device_path, NULL,
319 322 &no_handles, &handles);
... ... @@ -347,6 +350,8 @@
347 350 efi_st_error("Partition handle not found\n");
348 351 return EFI_ST_FAILURE;
349 352 }
  353 +
  354 + /* Open the simple file system protocol */
350 355 ret = boottime->open_protocol(handle_partition,
351 356 &guid_simple_file_system_protocol,
352 357 (void **)&file_system, NULL, NULL,
... ... @@ -355,6 +360,8 @@
355 360 efi_st_error("Failed to open simple file system protocol\n");
356 361 return EFI_ST_FAILURE;
357 362 }
  363 +
  364 + /* Open volume */
358 365 ret = file_system->open_volume(file_system, &root);
359 366 if (ret != EFI_SUCCESS) {
360 367 efi_st_error("Failed to open volume\n");
... ... @@ -377,6 +384,8 @@
377 384 "Wrong volume label '%ps', expected 'U-BOOT TEST'\n",
378 385 system_info.info.volume_label);
379 386 }
  387 +
  388 + /* Read file */
380 389 ret = root->open(root, &file, (s16 *)L"hello.txt", EFI_FILE_MODE_READ,
381 390 0);
382 391 if (ret != EFI_SUCCESS) {
... ... @@ -389,6 +398,11 @@
389 398 efi_st_error("Failed to read file\n");
390 399 return EFI_ST_FAILURE;
391 400 }
  401 + if (buf_size != 13) {
  402 + efi_st_error("Wrong number of bytes read: %u\n",
  403 + (unsigned int)buf_size);
  404 + return EFI_ST_FAILURE;
  405 + }
392 406 if (efi_st_memcmp(buf, "Hello world!", 12)) {
393 407 efi_st_error("Unexpected file content\n");
394 408 return EFI_ST_FAILURE;
... ... @@ -398,6 +412,62 @@
398 412 efi_st_error("Failed to close file\n");
399 413 return EFI_ST_FAILURE;
400 414 }
  415 +
  416 +#ifdef CONFIG_FAT_WRITE
  417 + /* Write file */
  418 + ret = root->open(root, &file, (s16 *)L"u-boot.txt",
  419 + EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
  420 + if (ret != EFI_SUCCESS) {
  421 + efi_st_error("Failed to open file\n");
  422 + return EFI_ST_FAILURE;
  423 + }
  424 + buf_size = 7;
  425 + boottime->set_mem(buf, sizeof(buf), 0);
  426 + boottime->copy_mem(buf, "U-Boot", buf_size);
  427 + ret = file->write(file, &buf_size, buf);
  428 + if (ret != EFI_SUCCESS || buf_size != 7) {
  429 + efi_st_error("Failed to write file\n");
  430 + return EFI_ST_FAILURE;
  431 + }
  432 + ret = file->close(file);
  433 + if (ret != EFI_SUCCESS) {
  434 + efi_st_error("Failed to close file\n");
  435 + return EFI_ST_FAILURE;
  436 + }
  437 +
  438 + /* Verify file */
  439 + boottime->set_mem(buf, sizeof(buf), 0);
  440 + ret = root->open(root, &file, (s16 *)L"u-boot.txt", EFI_FILE_MODE_READ,
  441 + 0);
  442 + if (ret != EFI_SUCCESS) {
  443 + efi_st_error("Failed to open file\n");
  444 + return EFI_ST_FAILURE;
  445 + }
  446 + buf_size = sizeof(buf) - 1;
  447 + ret = file->read(file, &buf_size, buf);
  448 + if (ret != EFI_SUCCESS) {
  449 + efi_st_error("Failed to read file\n");
  450 + return EFI_ST_FAILURE;
  451 + }
  452 + if (buf_size != 7) {
  453 + efi_st_error("Wrong number of bytes read: %u\n",
  454 + (unsigned int)buf_size);
  455 + return EFI_ST_FAILURE;
  456 + }
  457 + if (efi_st_memcmp(buf, "U-Boot", 7)) {
  458 + efi_st_error("Unexpected file content %s\n", buf);
  459 + return EFI_ST_FAILURE;
  460 + }
  461 + ret = file->close(file);
  462 + if (ret != EFI_SUCCESS) {
  463 + efi_st_error("Failed to close file\n");
  464 + return EFI_ST_FAILURE;
  465 + }
  466 +#else
  467 + efi_st_todo("CONFIG_FAT_WRITE is not set\n");
  468 +#endif /* CONFIG_FAT_WRITE */
  469 +
  470 + /* Close volume */
401 471 ret = root->close(root);
402 472 if (ret != EFI_SUCCESS) {
403 473 efi_st_error("Failed to close volume\n");
lib/efi_selftest/efi_selftest_config_table.c
  1 +// SPDX-License-Identifier: GPL-2.0+
  2 +/*
  3 + * efi_selftest_config_tables
  4 + *
  5 + * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  6 + *
  7 + * This test checks the following service:
  8 + * InstallConfigurationTable.
  9 + */
  10 +
  11 +#include <efi_selftest.h>
  12 +
  13 +static const struct efi_system_table *sys_table;
  14 +static struct efi_boot_services *boottime;
  15 +
  16 +static efi_guid_t table_guid =
  17 + EFI_GUID(0xff1c3f9e, 0x795b, 0x1529, 0xf1, 0x55,
  18 + 0x17, 0x2e, 0x51, 0x6b, 0x49, 0x75);
  19 +
  20 +/*
  21 + * Notification function, increments the notfication count if parameter
  22 + * context is provided.
  23 + *
  24 + * @event notified event
  25 + * @context pointer to the notification count
  26 + */
  27 +static void EFIAPI notify(struct efi_event *event, void *context)
  28 +{
  29 + unsigned int *count = context;
  30 +
  31 + if (count)
  32 + ++*count;
  33 +}
  34 +
  35 +/*
  36 + * Check crc32 of a table.
  37 + */
  38 +static int check_table(const void *table)
  39 +{
  40 + efi_status_t ret;
  41 + u32 crc32, res;
  42 + /* Casting from const to not const */
  43 + struct efi_table_hdr *hdr = (struct efi_table_hdr *)table;
  44 +
  45 + crc32 = hdr->crc32;
  46 + /*
  47 + * Setting the crc32 of the 'const' table to zero is easier than
  48 + * copying
  49 + */
  50 + hdr->crc32 = 0;
  51 + ret = boottime->calculate_crc32(table, hdr->headersize, &res);
  52 + /* Reset table crc32 so it stays constant */
  53 + hdr->crc32 = crc32;
  54 + if (ret != EFI_ST_SUCCESS) {
  55 + efi_st_error("CalculateCrc32 failed\n");
  56 + return EFI_ST_FAILURE;
  57 + }
  58 + if (res != crc32) {
  59 + efi_st_error("Incorrect CRC32\n");
  60 + return EFI_ST_FAILURE;
  61 + }
  62 + return EFI_ST_SUCCESS;
  63 +}
  64 +
  65 +/*
  66 + * Setup unit test.
  67 + *
  68 + * @handle: handle of the loaded image
  69 + * @systable: system table
  70 + * @return: EFI_ST_SUCCESS for success
  71 + */
  72 +static int setup(const efi_handle_t handle,
  73 + const struct efi_system_table *systable)
  74 +{
  75 + sys_table = systable;
  76 + boottime = systable->boottime;
  77 +
  78 + return EFI_ST_SUCCESS;
  79 +}
  80 +
  81 +/*
  82 + * Execute unit test.
  83 + *
  84 + * A table is installed, updated, removed. The table entry and the
  85 + * triggering of events is checked.
  86 + *
  87 + * @return: EFI_ST_SUCCESS for success
  88 + */
  89 +static int execute(void)
  90 +{
  91 + efi_status_t ret;
  92 + unsigned int counter = 0;
  93 + struct efi_event *event;
  94 + void *table;
  95 + const unsigned int tables[2];
  96 + efi_uintn_t i;
  97 + efi_uintn_t tabcnt;
  98 + efi_uintn_t table_count = sys_table->nr_tables;
  99 +
  100 + ret = boottime->create_event_ex(0, TPL_NOTIFY,
  101 + notify, (void *)&counter,
  102 + &table_guid, &event);
  103 + if (ret != EFI_SUCCESS) {
  104 + efi_st_error("Failed to create event\n");
  105 + return EFI_ST_FAILURE;
  106 + }
  107 +
  108 + /* Try to delete non-existent table */
  109 + ret = boottime->install_configuration_table(&table_guid, NULL);
  110 + if (ret != EFI_NOT_FOUND) {
  111 + efi_st_error("Failed to detect missing table\n");
  112 + return EFI_ST_FAILURE;
  113 + }
  114 + if (counter) {
  115 + efi_st_error("Notification function was called.\n");
  116 + return EFI_ST_FAILURE;
  117 + }
  118 + /* Check if the event was signaled */
  119 + ret = boottime->check_event(event);
  120 + if (ret == EFI_SUCCESS) {
  121 + efi_st_error("Event was signaled on EFI_NOT_FOUND\n");
  122 + return EFI_ST_FAILURE;
  123 + }
  124 + if (counter != 1) {
  125 + efi_st_error("Notification function was not called.\n");
  126 + return EFI_ST_FAILURE;
  127 + }
  128 + if (table_count != sys_table->nr_tables) {
  129 + efi_st_error("Incorrect table count %u, expected %u\n",
  130 + (unsigned int)sys_table->nr_tables,
  131 + (unsigned int)table_count);
  132 + return EFI_ST_FAILURE;
  133 + }
  134 +
  135 + /* Install table */
  136 + ret = boottime->install_configuration_table(&table_guid,
  137 + (void *)&tables[0]);
  138 + if (ret != EFI_SUCCESS) {
  139 + efi_st_error("Failed to install table\n");
  140 + return EFI_ST_FAILURE;
  141 + }
  142 + /* Check signaled state */
  143 + ret = boottime->check_event(event);
  144 + if (ret != EFI_SUCCESS) {
  145 + efi_st_error("Event was not signaled on insert\n");
  146 + return EFI_ST_FAILURE;
  147 + }
  148 + if (++table_count != sys_table->nr_tables) {
  149 + efi_st_error("Incorrect table count %u, expected %u\n",
  150 + (unsigned int)sys_table->nr_tables,
  151 + (unsigned int)table_count);
  152 + return EFI_ST_FAILURE;
  153 + }
  154 + table = NULL;
  155 + for (i = 0; i < sys_table->nr_tables; ++i) {
  156 + if (!efi_st_memcmp(&sys_table->tables[i].guid, &table_guid,
  157 + sizeof(efi_guid_t)))
  158 + table = sys_table->tables[i].table;
  159 + }
  160 + if (!table) {
  161 + efi_st_error("Installed table not found\n");
  162 + return EFI_ST_FAILURE;
  163 + }
  164 + if (table != &tables[0]) {
  165 + efi_st_error("Incorrect table address\n");
  166 + return EFI_ST_FAILURE;
  167 + }
  168 + if (check_table(sys_table) != EFI_ST_SUCCESS) {
  169 + efi_st_error("Checking system table\n");
  170 + return EFI_ST_FAILURE;
  171 + }
  172 +
  173 + /* Update table */
  174 + ret = boottime->install_configuration_table(&table_guid,
  175 + (void *)&tables[1]);
  176 + if (ret != EFI_SUCCESS) {
  177 + efi_st_error("Failed to update table\n");
  178 + return EFI_ST_FAILURE;
  179 + }
  180 + /* Check signaled state */
  181 + ret = boottime->check_event(event);
  182 + if (ret != EFI_SUCCESS) {
  183 + efi_st_error("Event was not signaled on update\n");
  184 + return EFI_ST_FAILURE;
  185 + }
  186 + if (table_count != sys_table->nr_tables) {
  187 + efi_st_error("Incorrect table count %u, expected %u\n",
  188 + (unsigned int)sys_table->nr_tables,
  189 + (unsigned int)table_count);
  190 + return EFI_ST_FAILURE;
  191 + }
  192 + table = NULL;
  193 + tabcnt = 0;
  194 + for (i = 0; i < sys_table->nr_tables; ++i) {
  195 + if (!efi_st_memcmp(&sys_table->tables[i].guid, &table_guid,
  196 + sizeof(efi_guid_t))) {
  197 + table = sys_table->tables[i].table;
  198 + ++tabcnt;
  199 + }
  200 + }
  201 + if (!table) {
  202 + efi_st_error("Installed table not found\n");
  203 + return EFI_ST_FAILURE;
  204 + }
  205 + if (tabcnt > 1) {
  206 + efi_st_error("Duplicate table guid\n");
  207 + return EFI_ST_FAILURE;
  208 + }
  209 + if (table != &tables[1]) {
  210 + efi_st_error("Incorrect table address\n");
  211 + return EFI_ST_FAILURE;
  212 + }
  213 + if (check_table(sys_table) != EFI_ST_SUCCESS) {
  214 + efi_st_error("Checking system table\n");
  215 + return EFI_ST_FAILURE;
  216 + }
  217 +
  218 + /* Delete table */
  219 + ret = boottime->install_configuration_table(&table_guid, NULL);
  220 + if (ret != EFI_SUCCESS) {
  221 + efi_st_error("Failed to delete table\n");
  222 + return EFI_ST_FAILURE;
  223 + }
  224 + /* Check signaled state */
  225 + ret = boottime->check_event(event);
  226 + if (ret != EFI_SUCCESS) {
  227 + efi_st_error("Event was not signaled on delete\n");
  228 + return EFI_ST_FAILURE;
  229 + }
  230 + if (--table_count != sys_table->nr_tables) {
  231 + efi_st_error("Incorrect table count %u, expected %u\n",
  232 + (unsigned int)sys_table->nr_tables,
  233 + (unsigned int)table_count);
  234 + return EFI_ST_FAILURE;
  235 + }
  236 + table = NULL;
  237 + for (i = 0; i < sys_table->nr_tables; ++i) {
  238 + if (!efi_st_memcmp(&sys_table->tables[i].guid, &table_guid,
  239 + sizeof(efi_guid_t))) {
  240 + table = sys_table->tables[i].table;
  241 + }
  242 + }
  243 + if (table) {
  244 + efi_st_error("Wrong table deleted\n");
  245 + return EFI_ST_FAILURE;
  246 + }
  247 +
  248 + ret = boottime->close_event(event);
  249 + if (ret != EFI_SUCCESS) {
  250 + efi_st_error("Failed to close event\n");
  251 + return EFI_ST_FAILURE;
  252 + }
  253 + if (check_table(sys_table) != EFI_ST_SUCCESS) {
  254 + efi_st_error("Checking system table\n");
  255 + return EFI_ST_FAILURE;
  256 + }
  257 +
  258 + return EFI_ST_SUCCESS;
  259 +}
  260 +
  261 +EFI_UNIT_TEST(configtables) = {
  262 + .name = "configuration tables",
  263 + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
  264 + .setup = setup,
  265 + .execute = execute,
  266 +};
lib/efi_selftest/efi_selftest_console.c
... ... @@ -70,11 +70,12 @@
70 70 /*
71 71 * Print an unsigned 32bit value as decimal number to an u16 string
72 72 *
73   - * @value: value to be printed
74   - * @buf: pointer to buffer address
75   - * on return position of terminating zero word
  73 + * @value: value to be printed
  74 + * @prec: minimum number of digits to display
  75 + * @buf: pointer to buffer address
  76 + * on return position of terminating zero word
76 77 */
77   -static void uint2dec(u32 value, u16 **buf)
  78 +static void uint2dec(u32 value, int prec, u16 **buf)
78 79 {
79 80 u16 *pos = *buf;
80 81 int i;
... ... @@ -93,7 +94,7 @@
93 94 for (i = 0; i < 10; ++i) {
94 95 /* Write current digit */
95 96 c = f >> 60;
96   - if (c || pos != *buf)
  97 + if (c || pos != *buf || 10 - i <= prec)
97 98 *pos++ = c + '0';
98 99 /* Eliminate current digit */
99 100 f &= 0xfffffffffffffff;
100 101  
... ... @@ -109,11 +110,12 @@
109 110 /*
110 111 * Print a signed 32bit value as decimal number to an u16 string
111 112 *
112   - * @value: value to be printed
113   - * @buf: pointer to buffer address
  113 + * @value: value to be printed
  114 + * @prec: minimum number of digits to display
  115 + * @buf: pointer to buffer address
114 116 * on return position of terminating zero word
115 117 */
116   -static void int2dec(s32 value, u16 **buf)
  118 +static void int2dec(s32 value, int prec, u16 **buf)
117 119 {
118 120 u32 u;
119 121 u16 *pos = *buf;
... ... @@ -124,7 +126,7 @@
124 126 } else {
125 127 u = value;
126 128 }
127   - uint2dec(u, &pos);
  129 + uint2dec(u, prec, &pos);
128 130 *buf = pos;
129 131 }
130 132  
... ... @@ -143,6 +145,7 @@
143 145 u16 *pos = buf;
144 146 const char *s;
145 147 u16 *u;
  148 + int prec;
146 149  
147 150 va_start(args, fmt);
148 151  
149 152  
... ... @@ -172,12 +175,20 @@
172 175 break;
173 176 case '%':
174 177 ++c;
  178 + /* Parse precision */
  179 + if (*c == '.') {
  180 + ++c;
  181 + prec = *c - '0';
  182 + ++c;
  183 + } else {
  184 + prec = 0;
  185 + }
175 186 switch (*c) {
176 187 case '\0':
177 188 --c;
178 189 break;
179 190 case 'd':
180   - int2dec(va_arg(args, s32), &pos);
  191 + int2dec(va_arg(args, s32), prec, &pos);
181 192 break;
182 193 case 'p':
183 194 ++c;
... ... @@ -209,7 +220,7 @@
209 220 *pos++ = *s;
210 221 break;
211 222 case 'u':
212   - uint2dec(va_arg(args, u32), &pos);
  223 + uint2dec(va_arg(args, u32), prec, &pos);
213 224 break;
214 225 default:
215 226 break;
lib/efi_selftest/efi_selftest_crc32.c
  1 +// SPDX-License-Identifier: GPL-2.0+
  2 +/*
  3 + * efi_selftest_crc32
  4 + *
  5 + * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  6 + *
  7 + * This unit test checks the CalculateCrc32 bootservice and checks the
  8 + * headers of the system table, the boot services tablle, and the runtime
  9 + * services table before and after ExitBootServices().
  10 + */
  11 +
  12 +#include <efi_selftest.h>
  13 +
  14 +const struct efi_system_table *st;
  15 +efi_status_t (EFIAPI *bs_crc32)(const void *data, efi_uintn_t data_size,
  16 + u32 *crc32);
  17 +
  18 +static int check_table(const void *table)
  19 +{
  20 + efi_status_t ret;
  21 + u32 crc32, res;
  22 + /* Casting from const to not const */
  23 + struct efi_table_hdr *hdr = (struct efi_table_hdr *)table;
  24 +
  25 + if (!hdr->signature) {
  26 + efi_st_error("Missing header signature\n");
  27 + return EFI_ST_FAILURE;
  28 + }
  29 + if (!hdr->revision) {
  30 + efi_st_error("Missing header revision\n");
  31 + return EFI_ST_FAILURE;
  32 + }
  33 + if (hdr->headersize <= sizeof(struct efi_table_hdr)) {
  34 + efi_st_error("Incorrect headersize value\n");
  35 + return EFI_ST_FAILURE;
  36 + }
  37 + if (hdr->reserved) {
  38 + efi_st_error("Reserved header field is not zero\n");
  39 + return EFI_ST_FAILURE;
  40 + }
  41 +
  42 + crc32 = hdr->crc32;
  43 + /*
  44 + * Setting the crc32 of the 'const' table to zero is easier than
  45 + * copying
  46 + */
  47 + hdr->crc32 = 0;
  48 + ret = bs_crc32(table, hdr->headersize, &res);
  49 + /* Reset table crc32 so it stays constant */
  50 + hdr->crc32 = crc32;
  51 + if (ret != EFI_ST_SUCCESS) {
  52 + efi_st_error("CalculateCrc32 failed\n");
  53 + return EFI_ST_FAILURE;
  54 + }
  55 + if (res != crc32) {
  56 + efi_st_error("Incorrect CRC32\n");
  57 + // return EFI_ST_FAILURE;
  58 + }
  59 + return EFI_ST_SUCCESS;
  60 +}
  61 +
  62 +/*
  63 + * Setup unit test.
  64 + *
  65 + * Check that CalculateCrc32 is working correctly.
  66 + * Check tables before ExitBootServices().
  67 + *
  68 + * @handle: handle of the loaded image
  69 + * @systable: system table
  70 + * @return: EFI_ST_SUCCESS for success
  71 + */
  72 +static int setup(const efi_handle_t handle,
  73 + const struct efi_system_table *systable)
  74 +{
  75 + efi_status_t ret;
  76 + u32 res;
  77 +
  78 + st = systable;
  79 + bs_crc32 = systable->boottime->calculate_crc32;
  80 +
  81 + /* Check that CalculateCrc32 is working */
  82 + ret = bs_crc32("U-Boot", 6, &res);
  83 + if (ret != EFI_ST_SUCCESS) {
  84 + efi_st_error("CalculateCrc32 failed\n");
  85 + return EFI_ST_FAILURE;
  86 + }
  87 + if (res != 0x134b0db4) {
  88 + efi_st_error("Incorrect CRC32\n");
  89 + return EFI_ST_FAILURE;
  90 + }
  91 +
  92 + /* Check tables before ExitBootServices() */
  93 + if (check_table(st) != EFI_ST_SUCCESS) {
  94 + efi_st_error("Checking system table\n");
  95 + return EFI_ST_FAILURE;
  96 + }
  97 + if (check_table(st->boottime) != EFI_ST_SUCCESS) {
  98 + efi_st_error("Checking boottime table\n");
  99 + return EFI_ST_FAILURE;
  100 + }
  101 + if (check_table(st->runtime) != EFI_ST_SUCCESS) {
  102 + efi_st_error("Checking runtime table\n");
  103 + return EFI_ST_FAILURE;
  104 + }
  105 +
  106 + return EFI_ST_SUCCESS;
  107 +}
  108 +
  109 +/*
  110 + * Execute unit test
  111 + *
  112 + * Check tables after ExitBootServices()
  113 + *
  114 + * @return: EFI_ST_SUCCESS for success
  115 + */
  116 +static int execute(void)
  117 +{
  118 + if (check_table(st) != EFI_ST_SUCCESS) {
  119 + efi_st_error("Checking system table\n");
  120 + return EFI_ST_FAILURE;
  121 + }
  122 + if (check_table(st->runtime) != EFI_ST_SUCCESS) {
  123 + efi_st_error("Checking runtime table\n");
  124 + return EFI_ST_FAILURE;
  125 + }
  126 +
  127 + /*
  128 + * We cannot call SetVirtualAddressMap() and recheck the runtime
  129 + * table afterwards because this would invalidate the addresses of the
  130 + * unit tests.
  131 + */
  132 +
  133 + return EFI_ST_SUCCESS;
  134 +}
  135 +
  136 +EFI_UNIT_TEST(crc32) = {
  137 + .name = "crc32",
  138 + .phase = EFI_SETUP_BEFORE_BOOTTIME_EXIT,
  139 + .setup = setup,
  140 + .execute = execute,
  141 +};
lib/efi_selftest/efi_selftest_rtc.c
  1 +// SPDX-License-Identifier: GPL-2.0+
  2 +/*
  3 + * efi_selftest_rtc
  4 + *
  5 + * Copyright (c) 2018 Heinrich Schuchardt <xypron.glpk@gmx.de>
  6 + *
  7 + * Test the real time clock runtime services.
  8 + */
  9 +
  10 +#include <efi_selftest.h>
  11 +
  12 +#define EFI_ST_NO_RTC "Could not read real time clock\n"
  13 +
  14 +static struct efi_runtime_services *runtime;
  15 +
  16 +/*
  17 + * Setup unit test.
  18 + *
  19 + * @handle: handle of the loaded image
  20 + * @systable: system table
  21 + * @return: EFI_ST_SUCCESS for success
  22 + */
  23 +static int setup(const efi_handle_t handle,
  24 + const struct efi_system_table *systable)
  25 +{
  26 + runtime = systable->runtime;
  27 + return EFI_ST_SUCCESS;
  28 +}
  29 +
  30 +/*
  31 + * Execute unit test.
  32 + *
  33 + * Display current time.
  34 + *
  35 + * @return: EFI_ST_SUCCESS for success
  36 + */
  37 +static int execute(void)
  38 +{
  39 + efi_status_t ret;
  40 + struct efi_time tm;
  41 +
  42 + /* Display current time */
  43 + ret = runtime->get_time(&tm, NULL);
  44 + if (ret != EFI_SUCCESS) {
  45 +#ifdef CONFIG_CMD_DATE
  46 + efi_st_error(EFI_ST_NO_RTC);
  47 + return EFI_ST_FAILURE;
  48 +#else
  49 + efi_st_todo(EFI_ST_NO_RTC);
  50 + return EFI_ST_SUCCESS;
  51 +#endif
  52 + } else {
  53 + efi_st_printf("Time according to real time clock: "
  54 + "%.4u-%.2u-%.2u %.2u:%.2u:%.2u\n",
  55 + tm.year, tm.month, tm.day,
  56 + tm.hour, tm.minute, tm.second);
  57 + }
  58 +
  59 + return EFI_ST_SUCCESS;
  60 +}
  61 +
  62 +EFI_UNIT_TEST(rtc) = {
  63 + .name = "real time clock",
  64 + .phase = EFI_EXECUTE_BEFORE_BOOTTIME_EXIT,
  65 + .setup = setup,
  66 + .execute = execute,
  67 +};
... ... @@ -407,7 +407,10 @@
407 407 break;
408 408 }
409 409  
410   - uuid_bin_to_str(addr, uuid, str_format);
  410 + if (addr)
  411 + uuid_bin_to_str(addr, uuid, str_format);
  412 + else
  413 + strcpy(uuid, "<NULL>");
411 414  
412 415 return string(buf, end, uuid, field_width, precision, flags);
413 416 }