Patch queue for efi - 2019-02-13

Goodness this time around:
 
   - HII protocol, finally allows us to run the UEFI Shell!
     (experimantal, disabled by default)
   - efi selftest now available on Cortex-M
   - NVMe support for distro boot
   - Lots of code cleanup
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iQIcBAABAgAGBQJcY9m6AAoJECszeR4D/txgTikP/3J6vXriBjXh13AtsGQpCeaC
 9HCRHV/iR4MNki1EaexoGkF5Mnb6ARufuG4ru+6X9lrrQWbgIyzr0NWH6ZQEz31u
 MENZG5iO9fo5IZJrfc/pkBk0++dB/N/3/h0PgN6/Y3rVkUVXbkYieX7D8J62T4kn
 mkpZJTRqOZD16RAk4tENOOpVclrU8HkUccg8+MgxSN0TqX18oxF4Wgbgn2GGoU8R
 ANF/6Ke6mOAxUedA58Y9KflZ02q0bThoMtBYeWxI+WYCsGVgH9a4Q/TVwhZMbjH0
 dAj3aAIRf6TmAOcQAlHhT8muruYlO6ri8ztq/PB/3ThDvagc4dnrXNxDFWlo6Y4q
 WPJBw9TAGDpnpDplx4WW6CJdP9HlXH/NIFWEYokqyeLcnjcvvH34zfrgWTcD8epJ
 gtDzLO2YsblA+q5SsbzAk/BsNjLpkzA1St7S/vZFCVNbazBAZgGUD2NoChI3MfM7
 n0KQr5rlvrdckYRhln6IEZBXvs0drsb9Ki4g7jw1N9PDMmUW8uwArGINT2Zi2HW0
 lPkf+jlw30ds2zcHoUH0EA8cfYgdTzvCLIKjmodN4nd/taKN292NbTmaQeZQ9wqG
 TclMiyY9VoqIeKV4l44q9lxdowS82cb0G203eHyTIOAFJlNtuthNdISJIFIrqljA
 na3RDAFYC8Ibfo+zIgLb
 =g6l7
 -----END PGP SIGNATURE-----

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

Patch queue for efi - 2019-02-13

Goodness this time around:

  - HII protocol, finally allows us to run the UEFI Shell!
    (experimantal, disabled by default)
  - efi selftest now available on Cortex-M
  - NVMe support for distro boot
  - Lots of code cleanup
This commit is contained in:
Tom Rini 2019-02-13 07:12:29 -05:00
commit 63f7e3fca3
50 changed files with 3984 additions and 340 deletions

View file

@ -14,6 +14,7 @@ obj-$(CONFIG_SYS_ARM_MPU) += mpu_v7r.o
ifneq ($(CONFIG_SPL_BUILD),y) ifneq ($(CONFIG_SPL_BUILD),y)
obj-$(CONFIG_EFI_LOADER) += sctlr.o obj-$(CONFIG_EFI_LOADER) += sctlr.o
obj-$(CONFIG_ARMV7_NONSEC) += exception_level.o
endif endif
ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y) ifneq ($(CONFIG_SKIP_LOWLEVEL_INIT),y)

View file

@ -0,0 +1,56 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Switch to non-secure mode
*
* Copyright (c) 2018 Heinrich Schuchardt
*
* This module contains the ARMv7 specific code required for leaving the
* secure mode before booting an operating system.
*/
#include <common.h>
#include <bootm.h>
#include <asm/armv7.h>
#include <asm/secure.h>
#include <asm/setjmp.h>
/**
* entry_non_secure() - entry point when switching to non-secure mode
*
* When switching to non-secure mode switch_to_non_secure_mode() calls this
* function passing a jump buffer. We use this jump buffer to restore the
* original stack and register state.
*
* @non_secure_jmp: jump buffer for restoring stack and registers
*/
static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
{
dcache_enable();
debug("Reached non-secure mode\n");
/* Restore stack and registers saved in switch_to_non_secure_mode() */
longjmp(non_secure_jmp, 1);
}
/**
* switch_to_non_secure_mode() - switch to non-secure mode
*
* Operating systems may expect to run in non-secure mode. Here we check if
* we are running in secure mode and switch to non-secure mode if necessary.
*/
void switch_to_non_secure_mode(void)
{
static bool is_nonsec;
struct jmp_buf_data non_secure_jmp;
if (armv7_boot_nonsec() && !is_nonsec) {
if (setjmp(&non_secure_jmp))
return;
dcache_disable(); /* flush cache before switch to HYP */
armv7_init_nonsec();
is_nonsec = true;
secure_ram_addr(_do_nonsec_entry)(entry_non_secure,
(uintptr_t)&non_secure_jmp,
0, 0);
}
}

View file

@ -7,7 +7,9 @@
#include <asm/opcodes-sec.h> #include <asm/opcodes-sec.h>
#include <asm/opcodes-virt.h> #include <asm/opcodes-virt.h>
#ifdef CONFIG_EFI_LOADER
.section .text.efi_runtime .section .text.efi_runtime
#endif
#define UNWIND(x...) #define UNWIND(x...)
/* /*

View file

@ -14,6 +14,7 @@ ifdef CONFIG_SPL_BUILD
obj-$(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) += exceptions.o obj-$(CONFIG_ARMV8_SPL_EXCEPTION_VECTORS) += exceptions.o
else else
obj-y += exceptions.o obj-y += exceptions.o
obj-y += exception_level.o
endif endif
obj-y += cache.o obj-y += cache.o
obj-y += tlb.o obj-y += tlb.o

View file

@ -0,0 +1,55 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Switch to non-secure mode
*
* Copyright (c) 2018 Heinrich Schuchardt
*
* This module contains the ARMv8 specific code required to adjust the exception
* level before booting an operating system.
*/
#include <common.h>
#include <bootm.h>
#include <asm/setjmp.h>
/**
* entry_non_secure() - entry point when switching to non-secure mode
*
* When switching to non-secure mode switch_to_non_secure_mode() calls this
* function passing a jump buffer. We use this jump buffer to restore the
* original stack and register state.
*
* @non_secure_jmp: jump buffer for restoring stack and registers
*/
static void entry_non_secure(struct jmp_buf_data *non_secure_jmp)
{
dcache_enable();
debug("Reached non-secure mode\n");
/* Restore stack and registers saved in switch_to_non_secure_mode() */
longjmp(non_secure_jmp, 1);
}
/**
* switch_to_non_secure_mode() - switch to non-secure mode
*
* Exception level EL3 is meant to be used by the secure monitor only (ARM
* trusted firmware being one embodiment). The operating system shall be
* started at exception level EL2. So here we check the exception level
* and switch it if necessary.
*/
void switch_to_non_secure_mode(void)
{
struct jmp_buf_data non_secure_jmp;
/* On AArch64 we need to make sure we call our payload in < EL3 */
if (current_el() == 3) {
if (setjmp(&non_secure_jmp))
return;
dcache_disable(); /* flush cache before switch to EL2 */
/* Move into EL2 and keep running there */
armv8_switch_to_el2((uintptr_t)&non_secure_jmp, 0, 0, 0,
(uintptr_t)entry_non_secure, ES_TO_AARCH64);
}
}

View file

@ -6,7 +6,9 @@
#include <linux/arm-smccc.h> #include <linux/arm-smccc.h>
#include <generated/asm-offsets.h> #include <generated/asm-offsets.h>
#ifdef CONFIG_EFI_LOADER
.section .text.efi_runtime .section .text.efi_runtime
#endif
.macro SMCCC instr .macro SMCCC instr
.cfi_startproc .cfi_startproc

View file

@ -106,5 +106,9 @@ CFLAGS_$(EFI_RELOC) := $(CFLAGS_EFI)
CFLAGS_REMOVE_$(EFI_RELOC) := $(CFLAGS_NON_EFI) CFLAGS_REMOVE_$(EFI_RELOC) := $(CFLAGS_NON_EFI)
extra-$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE) += $(EFI_CRT0) $(EFI_RELOC) extra-$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE) += $(EFI_CRT0) $(EFI_RELOC)
extra-$(CONFIG_CMD_BOOTEFI_SELFTEST) += $(EFI_CRT0) $(EFI_RELOC) # TODO: As of v2019.01 the relocation code for the EFI application cannot
# be built on ARMv7-M.
ifndef CONFIG_CPU_V7M
#extra-$(CONFIG_CMD_BOOTEFI_SELFTEST) += $(EFI_CRT0) $(EFI_RELOC)
endif
extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC) extra-$(CONFIG_EFI) += $(EFI_CRT0) $(EFI_RELOC)

View file

@ -9,22 +9,37 @@
extern char *strncpy(char *__dest, __const__ char *__src, __kernel_size_t __n); extern char *strncpy(char *__dest, __const__ char *__src, __kernel_size_t __n);
#undef __HAVE_ARCH_STRRCHR #undef __HAVE_ARCH_STRRCHR
extern char * strrchr(const char * s, int c); extern char *strrchr(const char *s, int c);
#undef __HAVE_ARCH_STRCHR #undef __HAVE_ARCH_STRCHR
extern char * strchr(const char * s, int c); extern char *strchr(const char *s, int c);
#ifdef CONFIG_X86_64
#undef __HAVE_ARCH_MEMCPY
extern void *memcpy(void *, const void *, __kernel_size_t);
#undef __HAVE_ARCH_MEMMOVE
extern void *memmove(void *, const void *, __kernel_size_t);
#undef __HAVE_ARCH_MEMSET
extern void *memset(void *, int, __kernel_size_t);
#else
#define __HAVE_ARCH_MEMCPY #define __HAVE_ARCH_MEMCPY
extern void * memcpy(void *, const void *, __kernel_size_t); extern void *memcpy(void *, const void *, __kernel_size_t);
#define __HAVE_ARCH_MEMMOVE #define __HAVE_ARCH_MEMMOVE
extern void * memmove(void *, const void *, __kernel_size_t); extern void *memmove(void *, const void *, __kernel_size_t);
#undef __HAVE_ARCH_MEMCHR
extern void * memchr(const void *, int, __kernel_size_t);
#define __HAVE_ARCH_MEMSET #define __HAVE_ARCH_MEMSET
extern void * memset(void *, int, __kernel_size_t); extern void *memset(void *, int, __kernel_size_t);
#endif /* CONFIG_X86_64 */
#undef __HAVE_ARCH_MEMCHR
extern void *memchr(const void *, int, __kernel_size_t);
#undef __HAVE_ARCH_MEMZERO #undef __HAVE_ARCH_MEMZERO
extern void memzero(void *ptr, __kernel_size_t n); extern void memzero(void *ptr, __kernel_size_t n);

View file

@ -7,6 +7,7 @@ ifndef CONFIG_X86_64
obj-y += bios.o obj-y += bios.o
obj-y += bios_asm.o obj-y += bios_asm.o
obj-y += bios_interrupts.o obj-y += bios_interrupts.o
obj-y += string.o
endif endif
ifndef CONFIG_SPL_BUILD ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTM) += bootm.o
@ -32,7 +33,6 @@ obj-$(CONFIG_X86_RAMTEST) += ramtest.o
obj-$(CONFIG_INTEL_MID) += scu.o obj-$(CONFIG_INTEL_MID) += scu.o
obj-y += sections.o obj-y += sections.o
obj-y += sfi.o obj-y += sfi.o
obj-y += string.o
obj-y += acpi.o obj-y += acpi.o
obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o obj-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.o
ifndef CONFIG_QEMU ifndef CONFIG_QEMU

View file

@ -226,7 +226,7 @@ config CMD_BOOTEFI
config CMD_BOOTEFI_HELLO_COMPILE config CMD_BOOTEFI_HELLO_COMPILE
bool "Compile a standard EFI hello world binary for testing" bool "Compile a standard EFI hello world binary for testing"
depends on CMD_BOOTEFI && (ARM || X86 || RISCV) depends on CMD_BOOTEFI && !CPU_V7M && !SANDBOX
default y default y
help help
This compiles a standard EFI hello world application with U-Boot so This compiles a standard EFI hello world application with U-Boot so

View file

@ -5,8 +5,9 @@
* Copyright (c) 2016 Alexander Graf * Copyright (c) 2016 Alexander Graf
*/ */
#include <charset.h>
#include <common.h> #include <common.h>
#include <bootm.h>
#include <charset.h>
#include <command.h> #include <command.h>
#include <dm.h> #include <dm.h>
#include <efi_loader.h> #include <efi_loader.h>
@ -21,93 +22,11 @@
#include <asm-generic/unaligned.h> #include <asm-generic/unaligned.h>
#include <linux/linkage.h> #include <linux/linkage.h>
#ifdef CONFIG_ARMV7_NONSEC
#include <asm/armv7.h>
#include <asm/secure.h>
#endif
DECLARE_GLOBAL_DATA_PTR; DECLARE_GLOBAL_DATA_PTR;
#define OBJ_LIST_NOT_INITIALIZED 1
static efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED;
static struct efi_device_path *bootefi_image_path; static struct efi_device_path *bootefi_image_path;
static struct efi_device_path *bootefi_device_path; static struct efi_device_path *bootefi_device_path;
/* Initialize and populate EFI object list */
efi_status_t efi_init_obj_list(void)
{
efi_status_t ret = EFI_SUCCESS;
/*
* On the ARM architecture gd is mapped to a fixed register (r9 or x18).
* As this register may be overwritten by an EFI payload we save it here
* and restore it on every callback entered.
*/
efi_save_gd();
/* Initialize once only */
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 root node */
ret = efi_root_node_register();
if (ret != EFI_SUCCESS)
goto out;
/* Initialize EFI driver uclass */
ret = efi_driver_init();
if (ret != EFI_SUCCESS)
goto out;
ret = efi_console_register();
if (ret != EFI_SUCCESS)
goto out;
#ifdef CONFIG_PARTITIONS
ret = efi_disk_register();
if (ret != EFI_SUCCESS)
goto out;
#endif
#if defined(CONFIG_LCD) || defined(CONFIG_DM_VIDEO)
ret = efi_gop_register();
if (ret != EFI_SUCCESS)
goto out;
#endif
#ifdef CONFIG_NET
ret = efi_net_register();
if (ret != EFI_SUCCESS)
goto out;
#endif
#ifdef CONFIG_GENERATE_ACPI_TABLE
ret = efi_acpi_register();
if (ret != EFI_SUCCESS)
goto out;
#endif
#ifdef CONFIG_GENERATE_SMBIOS_TABLE
ret = efi_smbios_register();
if (ret != EFI_SUCCESS)
goto out;
#endif
ret = efi_watchdog_register();
if (ret != EFI_SUCCESS)
goto out;
/* Initialize EFI runtime services */
ret = efi_reset_system_init();
if (ret != EFI_SUCCESS)
goto out;
out:
efi_obj_list_initialized = ret;
return ret;
}
/* /*
* Allow unaligned memory access. * Allow unaligned memory access.
* *
@ -228,34 +147,6 @@ static efi_status_t efi_do_enter(
return ret; return ret;
} }
#ifdef CONFIG_ARM64
static efi_status_t efi_run_in_el2(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();
return efi_do_enter(image_handle, st, entry);
}
#endif
#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 * efi_carve_out_dt_rsv() - Carve out DT reserved memory ranges
* *
@ -386,7 +277,7 @@ static efi_status_t do_bootefi_exec(void *efi,
if (!device_path && !image_path) { if (!device_path && !image_path) {
printf("WARNING: using memory device/image path, this may confuse some payloads!\n"); printf("WARNING: using memory device/image path, this may confuse some payloads!\n");
/* actual addresses filled in after efi_load_pe() */ /* actual addresses filled in after efi_load_pe() */
memdp = efi_dp_from_mem(0, 0, 0); memdp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, 0, 0);
device_path = image_path = memdp; device_path = image_path = memdp;
/* /*
* Grub expects that the device path of the loaded image is * Grub expects that the device path of the loaded image is
@ -428,46 +319,13 @@ static efi_status_t do_bootefi_exec(void *efi,
"{ro,boot}(blob)0000000000000000"); "{ro,boot}(blob)0000000000000000");
/* Call our payload! */ /* Call our payload! */
debug("%s:%d Jumping to 0x%lx\n", __func__, __LINE__, (long)entry); debug("%s: Jumping to 0x%p\n", __func__, entry);
if (setjmp(&image_obj->exit_jmp)) { if (setjmp(&image_obj->exit_jmp)) {
ret = image_obj->exit_status; ret = image_obj->exit_status;
goto err_prepare; goto err_prepare;
} }
#ifdef CONFIG_ARM64
/* On AArch64 we need to make sure we call our payload in < EL3 */
if (current_el() == 3) {
smp_kick_all_cpus();
dcache_disable(); /* flush cache before switch to EL2 */
/* Move into EL2 and keep running there */
armv8_switch_to_el2((ulong)entry,
(ulong)&image_obj->header,
(ulong)&systab, 0, (ulong)efi_run_in_el2,
ES_TO_AARCH64);
/* Should never reach here, efi exits with longjmp */
while (1) { }
}
#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)&image_obj->header,
(uintptr_t)&systab);
/* Should never reach here, efi exits with longjmp */
while (1) { }
}
#endif
ret = efi_do_enter(&image_obj->header, &systab, entry); ret = efi_do_enter(&image_obj->header, &systab, entry);
err_prepare: err_prepare:
@ -553,6 +411,8 @@ static int do_bootefi(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
/* Allow unaligned memory access */ /* Allow unaligned memory access */
allow_unaligned(); allow_unaligned();
switch_to_non_secure_mode();
/* Initialize EFI drivers */ /* Initialize EFI drivers */
r = efi_init_obj_list(); r = efi_init_obj_list();
if (r != EFI_SUCCESS) { if (r != EFI_SUCCESS) {

View file

@ -912,6 +912,16 @@ static const void *boot_get_kernel(cmd_tbl_t *cmdtp, int flag, int argc,
return buf; return buf;
} }
/**
* switch_to_non_secure_mode() - switch to non-secure mode
*
* This routine is overridden by architectures requiring this feature.
*/
void __weak switch_to_non_secure_mode(void)
{
}
#else /* USE_HOSTCC */ #else /* USE_HOSTCC */
void memmove_wd(void *to, void *from, size_t len, ulong chunksz) void memmove_wd(void *to, void *from, size_t len, ulong chunksz)

View file

@ -38,7 +38,6 @@ CONFIG_SPL_PCH_SUPPORT=y
CONFIG_SPL_RTC_SUPPORT=y CONFIG_SPL_RTC_SUPPORT=y
CONFIG_HUSH_PARSER=y CONFIG_HUSH_PARSER=y
CONFIG_CMD_CPU=y CONFIG_CMD_CPU=y
# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
# CONFIG_CMD_FLASH is not set # CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y CONFIG_CMD_GPIO=y
CONFIG_CMD_SF=y CONFIG_CMD_SF=y

View file

@ -21,7 +21,6 @@ CONFIG_SPL_RAW_IMAGE_SUPPORT=y
CONFIG_SPL_WATCHDOG_SUPPORT=y CONFIG_SPL_WATCHDOG_SUPPORT=y
CONFIG_AUTOBOOT_KEYED=y CONFIG_AUTOBOOT_KEYED=y
CONFIG_AUTOBOOT_STOP_STR="." CONFIG_AUTOBOOT_STOP_STR="."
# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
# CONFIG_CMD_ELF is not set # CONFIG_CMD_ELF is not set
# CONFIG_CMD_FLASH is not set # CONFIG_CMD_FLASH is not set
CONFIG_CMD_GPIO=y CONFIG_CMD_GPIO=y

View file

@ -36,7 +36,6 @@ CONFIG_SPL_PCH_SUPPORT=y
CONFIG_SPL_RTC_SUPPORT=y CONFIG_SPL_RTC_SUPPORT=y
CONFIG_HUSH_PARSER=y CONFIG_HUSH_PARSER=y
CONFIG_CMD_CPU=y CONFIG_CMD_CPU=y
# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
CONFIG_CMD_BOOTEFI_SELFTEST=y CONFIG_CMD_BOOTEFI_SELFTEST=y
# CONFIG_CMD_FLASH is not set # CONFIG_CMD_FLASH is not set
CONFIG_CMD_IDE=y CONFIG_CMD_IDE=y

View file

@ -15,7 +15,6 @@ CONFIG_MISC_INIT_R=y
CONFIG_BOARD_EARLY_INIT_F=y CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_HUSH_PARSER=y CONFIG_HUSH_PARSER=y
CONFIG_SYS_PROMPT="U-Boot > " CONFIG_SYS_PROMPT="U-Boot > "
# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
CONFIG_CMD_IMLS=y CONFIG_CMD_IMLS=y
# CONFIG_CMD_SETEXPR is not set # CONFIG_CMD_SETEXPR is not set
CONFIG_CMD_TIMER=y CONFIG_CMD_TIMER=y

View file

@ -12,7 +12,6 @@ CONFIG_MISC_INIT_R=y
# CONFIG_DISPLAY_CPUINFO is not set # CONFIG_DISPLAY_CPUINFO is not set
CONFIG_BOARD_EARLY_INIT_F=y CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SYS_PROMPT="U-Boot > " CONFIG_SYS_PROMPT="U-Boot > "
# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
CONFIG_CMD_IMLS=y CONFIG_CMD_IMLS=y
CONFIG_CMD_GPT=y CONFIG_CMD_GPT=y
# CONFIG_RANDOM_UUID is not set # CONFIG_RANDOM_UUID is not set

View file

@ -12,7 +12,6 @@ CONFIG_MISC_INIT_R=y
# CONFIG_DISPLAY_CPUINFO is not set # CONFIG_DISPLAY_CPUINFO is not set
CONFIG_BOARD_EARLY_INIT_F=y CONFIG_BOARD_EARLY_INIT_F=y
CONFIG_SYS_PROMPT="U-Boot > " CONFIG_SYS_PROMPT="U-Boot > "
# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set
CONFIG_CMD_IMLS=y CONFIG_CMD_IMLS=y
CONFIG_CMD_GPT=y CONFIG_CMD_GPT=y
# CONFIG_RANDOM_UUID is not set # CONFIG_RANDOM_UUID is not set

View file

@ -14,7 +14,7 @@ and boot loaders like GRUB or the FreeBSD loader can be executed.
## Building for UEFI ## Building for UEFI
The UEFI standard supports only little endian systems. The UEFI support can be The UEFI standard supports only little-endian systems. The UEFI support can be
activated for ARM and x86 by specifying activated for ARM and x86 by specifying
CONFIG_CMD_BOOTEFI=y CONFIG_CMD_BOOTEFI=y
@ -53,7 +53,7 @@ arguments.
### Executing the boot manager ### Executing the boot manager
The UEFI specfication foresees to define boot entries and boot sequence via UEFI The UEFI specification foresees to define boot entries and boot sequence via UEFI
variables. Booting according to these variables is possible via variables. Booting according to these variables is possible via
bootefi bootmgr [fdt address] bootefi bootmgr [fdt address]
@ -90,14 +90,14 @@ Below you find the output of an example session.
The environment variable fdtcontroladdr points to U-Boot's internal device tree The environment variable fdtcontroladdr points to U-Boot's internal device tree
(if available). (if available).
### Executing the built-in selftest ### Executing the built-in self-test
An UEFI selftest suite can be embedded in U-Boot by building with An UEFI self-test suite can be embedded in U-Boot by building with
CONFIG_CMD_BOOTEFI_SELFTEST=y CONFIG_CMD_BOOTEFI_SELFTEST=y
For testing the UEFI implementation the bootefi command can be used to start the For testing the UEFI implementation the bootefi command can be used to start the
selftest. self-test.
bootefi selftest [fdt address] bootefi selftest [fdt address]

View file

@ -82,4 +82,9 @@ int bootm_decomp_image(int comp, ulong load, ulong image_start, int type,
*/ */
void board_quiesce_devices(void); void board_quiesce_devices(void);
/**
* switch_to_non_secure_mode() - switch to non-secure mode
*/
void switch_to_non_secure_mode(void);
#endif #endif

View file

@ -191,6 +191,29 @@ size_t u16_strlen(const u16 *in);
*/ */
size_t u16_strnlen(const u16 *in, size_t count); size_t u16_strnlen(const u16 *in, size_t count);
/**
* u16_strcpy() - copy u16 string
*
* Copy u16 string pointed to by src, including terminating null word, to
* the buffer pointed to by dest.
*
* @dest: destination buffer
* @src: source buffer (null terminated)
* Return: 'dest' address
*/
u16 *u16_strcpy(u16 *dest, const u16 *src);
/**
* u16_strdup() - duplicate u16 string
*
* Copy u16 string pointed to by src, including terminating null word, to a
* newly allocated buffer.
*
* @src: source buffer (null terminated)
* Return: allocated new buffer on success, NULL on failure
*/
u16 *u16_strdup(const u16 *src);
/** /**
* utf16_to_utf8() - Convert an utf16 string to utf8 * utf16_to_utf8() - Convert an utf16 string to utf8
* *

View file

@ -27,7 +27,7 @@
#define BOOTENV_SHARED_BLKDEV_BODY(devtypel) \ #define BOOTENV_SHARED_BLKDEV_BODY(devtypel) \
"if " #devtypel " dev ${devnum}; then " \ "if " #devtypel " dev ${devnum}; then " \
"setenv devtype " #devtypel "; " \ "devtype=" #devtypel "; " \
"run scan_dev_for_boot_part; " \ "run scan_dev_for_boot_part; " \
"fi\0" "fi\0"
@ -37,7 +37,7 @@
#define BOOTENV_DEV_BLKDEV(devtypeu, devtypel, instance) \ #define BOOTENV_DEV_BLKDEV(devtypeu, devtypel, instance) \
"bootcmd_" #devtypel #instance "=" \ "bootcmd_" #devtypel #instance "=" \
"setenv devnum " #instance "; " \ "devnum=" #instance "; " \
"run " #devtypel "_boot\0" "run " #devtypel "_boot\0"
#define BOOTENV_DEV_NAME_BLKDEV(devtypeu, devtypel, instance) \ #define BOOTENV_DEV_NAME_BLKDEV(devtypeu, devtypel, instance) \
@ -77,7 +77,7 @@
"if ubi part ${bootubipart} && " \ "if ubi part ${bootubipart} && " \
"ubifsmount ubi${devnum}:${bootubivol}; " \ "ubifsmount ubi${devnum}:${bootubivol}; " \
"then " \ "then " \
"setenv devtype ubi; " \ "devtype=ubi; " \
"run scan_dev_for_boot; " \ "run scan_dev_for_boot; " \
"fi\0" "fi\0"
#define BOOTENV_DEV_UBIFS BOOTENV_DEV_BLKDEV #define BOOTENV_DEV_UBIFS BOOTENV_DEV_BLKDEV
@ -178,13 +178,38 @@
BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_SATA BOOT_TARGET_DEVICES_references_SATA_without_CONFIG_SATA
#endif #endif
#ifdef CONFIG_NVME
#define BOOTENV_RUN_NVME_INIT "run nvme_init; "
#define BOOTENV_SET_NVME_NEED_INIT "setenv nvme_need_init; "
#define BOOTENV_SHARED_NVME \
"nvme_init=" \
"if ${nvme_need_init}; then " \
"setenv nvme_need_init false; " \
"nvme scan; " \
"fi\0" \
\
"nvme_boot=" \
BOOTENV_RUN_NVME_INIT \
BOOTENV_SHARED_BLKDEV_BODY(nvme)
#define BOOTENV_DEV_NVME BOOTENV_DEV_BLKDEV
#define BOOTENV_DEV_NAME_NVME BOOTENV_DEV_NAME_BLKDEV
#else
#define BOOTENV_RUN_NVME_INIT
#define BOOTENV_SET_NVME_NEED_INIT
#define BOOTENV_SHARED_NVME
#define BOOTENV_DEV_NVME \
BOOT_TARGET_DEVICES_references_NVME_without_CONFIG_NVME
#define BOOTENV_DEV_NAME_NVME \
BOOT_TARGET_DEVICES_references_NVME_without_CONFIG_NVME
#endif
#ifdef CONFIG_SCSI #ifdef CONFIG_SCSI
#define BOOTENV_RUN_SCSI_INIT "run scsi_init; " #define BOOTENV_RUN_SCSI_INIT "run scsi_init; "
#define BOOTENV_SET_SCSI_NEED_INIT "setenv scsi_need_init; " #define BOOTENV_SET_SCSI_NEED_INIT "scsi_need_init=; "
#define BOOTENV_SHARED_SCSI \ #define BOOTENV_SHARED_SCSI \
"scsi_init=" \ "scsi_init=" \
"if ${scsi_need_init}; then " \ "if ${scsi_need_init}; then " \
"setenv scsi_need_init false; " \ "scsi_need_init=false; " \
"scsi scan; " \ "scsi scan; " \
"fi\0" \ "fi\0" \
\ \
@ -359,6 +384,7 @@
BOOTENV_SHARED_USB \ BOOTENV_SHARED_USB \
BOOTENV_SHARED_SATA \ BOOTENV_SHARED_SATA \
BOOTENV_SHARED_SCSI \ BOOTENV_SHARED_SCSI \
BOOTENV_SHARED_NVME \
BOOTENV_SHARED_IDE \ BOOTENV_SHARED_IDE \
BOOTENV_SHARED_UBIFS \ BOOTENV_SHARED_UBIFS \
BOOTENV_SHARED_EFI \ BOOTENV_SHARED_EFI \
@ -418,11 +444,13 @@
"bootfstype; then " \ "bootfstype; then " \
"run scan_dev_for_boot; " \ "run scan_dev_for_boot; " \
"fi; " \ "fi; " \
"done\0" \ "done; " \
"setenv devplist\0" \
\ \
BOOT_TARGET_DEVICES(BOOTENV_DEV) \ BOOT_TARGET_DEVICES(BOOTENV_DEV) \
\ \
"distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT \ "distro_bootcmd=" BOOTENV_SET_SCSI_NEED_INIT \
BOOTENV_SET_NVME_NEED_INIT \
"for target in ${boot_targets}; do " \ "for target in ${boot_targets}; do " \
"run bootcmd_${target}; " \ "run bootcmd_${target}; " \
"done\0" "done\0"

View file

@ -49,7 +49,7 @@ struct efi_device_path;
typedef struct { typedef struct {
u8 b[16]; u8 b[16];
} efi_guid_t; } efi_guid_t __attribute__((aligned(8)));
#define EFI_BITS_PER_LONG (sizeof(long) * 8) #define EFI_BITS_PER_LONG (sizeof(long) * 8)

View file

@ -17,6 +17,7 @@
#define _EFI_API_H #define _EFI_API_H
#include <efi.h> #include <efi.h>
#include <charset.h>
#ifdef CONFIG_EFI_LOADER #ifdef CONFIG_EFI_LOADER
#include <asm/setjmp.h> #include <asm/setjmp.h>
@ -34,7 +35,13 @@ enum efi_timer_delay {
#define efi_intn_t ssize_t #define efi_intn_t ssize_t
#define efi_uintn_t size_t #define efi_uintn_t size_t
typedef uint16_t *efi_string_t; typedef void *efi_hii_handle_t;
typedef u16 *efi_string_t;
typedef u16 efi_string_id_t;
typedef u32 efi_hii_font_style_t;
typedef u16 efi_question_id_t;
typedef u16 efi_image_id_t;
typedef u16 efi_form_id_t;
#define EVT_TIMER 0x80000000 #define EVT_TIMER 0x80000000
#define EVT_RUNTIME 0x40000000 #define EVT_RUNTIME 0x40000000
@ -115,11 +122,11 @@ struct efi_boot_services {
struct efi_device_path *file_path, void *source_buffer, struct efi_device_path *file_path, void *source_buffer,
efi_uintn_t source_size, efi_handle_t *image); efi_uintn_t source_size, efi_handle_t *image);
efi_status_t (EFIAPI *start_image)(efi_handle_t handle, efi_status_t (EFIAPI *start_image)(efi_handle_t handle,
unsigned long *exitdata_size, efi_uintn_t *exitdata_size,
s16 **exitdata); u16 **exitdata);
efi_status_t (EFIAPI *exit)(efi_handle_t handle, efi_status_t (EFIAPI *exit)(efi_handle_t handle,
efi_status_t exit_status, efi_status_t exit_status,
unsigned long exitdata_size, s16 *exitdata); efi_uintn_t exitdata_size, u16 *exitdata);
efi_status_t (EFIAPI *unload_image)(efi_handle_t image_handle); efi_status_t (EFIAPI *unload_image)(efi_handle_t image_handle);
efi_status_t (EFIAPI *exit_boot_services)(efi_handle_t, unsigned long); efi_status_t (EFIAPI *exit_boot_services)(efi_handle_t, unsigned long);
@ -221,14 +228,17 @@ struct efi_runtime_services {
struct efi_mem_desc *virtmap); struct efi_mem_desc *virtmap);
efi_status_t (*convert_pointer)(unsigned long dbg, void **address); efi_status_t (*convert_pointer)(unsigned long dbg, void **address);
efi_status_t (EFIAPI *get_variable)(u16 *variable_name, efi_status_t (EFIAPI *get_variable)(u16 *variable_name,
efi_guid_t *vendor, u32 *attributes, const efi_guid_t *vendor,
u32 *attributes,
efi_uintn_t *data_size, void *data); efi_uintn_t *data_size, void *data);
efi_status_t (EFIAPI *get_next_variable_name)( efi_status_t (EFIAPI *get_next_variable_name)(
efi_uintn_t *variable_name_size, efi_uintn_t *variable_name_size,
u16 *variable_name, efi_guid_t *vendor); u16 *variable_name, const efi_guid_t *vendor);
efi_status_t (EFIAPI *set_variable)(u16 *variable_name, efi_status_t (EFIAPI *set_variable)(u16 *variable_name,
efi_guid_t *vendor, u32 attributes, const efi_guid_t *vendor,
efi_uintn_t data_size, void *data); u32 attributes,
efi_uintn_t data_size,
const void *data);
efi_status_t (EFIAPI *get_next_high_mono_count)( efi_status_t (EFIAPI *get_next_high_mono_count)(
uint32_t *high_count); uint32_t *high_count);
void (EFIAPI *reset_system)(enum efi_reset_type reset_type, void (EFIAPI *reset_system)(enum efi_reset_type reset_type,
@ -299,7 +309,7 @@ struct efi_runtime_services {
struct efi_configuration_table { struct efi_configuration_table {
efi_guid_t guid; efi_guid_t guid;
void *table; void *table;
}; } __packed;
#define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL) #define EFI_SYSTEM_TABLE_SIGNATURE ((u64)0x5453595320494249ULL)
@ -697,6 +707,418 @@ struct efi_device_path_utilities_protocol {
uint16_t node_length); uint16_t node_length);
}; };
/*
* Human Interface Infrastructure (HII)
*/
struct efi_hii_package_list_header {
efi_guid_t package_list_guid;
u32 package_length;
} __packed;
/**
* struct efi_hii_package_header - EFI HII package header
*
* @fields: 'fields' replaces the bit-fields defined in the EFI
* specification to to avoid possible compiler incompatibilities::
*
* u32 length:24;
* u32 type:8;
*/
struct efi_hii_package_header {
u32 fields;
} __packed;
#define __EFI_HII_PACKAGE_LEN_SHIFT 0
#define __EFI_HII_PACKAGE_TYPE_SHIFT 24
#define __EFI_HII_PACKAGE_LEN_MASK 0xffffff
#define __EFI_HII_PACKAGE_TYPE_MASK 0xff
#define EFI_HII_PACKAGE_TYPE_ALL 0x00
#define EFI_HII_PACKAGE_TYPE_GUID 0x01
#define EFI_HII_PACKAGE_FORMS 0x02
#define EFI_HII_PACKAGE_STRINGS 0x04
#define EFI_HII_PACKAGE_FONTS 0x05
#define EFI_HII_PACKAGE_IMAGES 0x06
#define EFI_HII_PACKAGE_SIMPLE_FONTS 0x07
#define EFI_HII_PACKAGE_DEVICE_PATH 0x08
#define EFI_HII_PACKAGE_KEYBOARD_LAYOUT 0x09
#define EFI_HII_PACKAGE_ANIMATIONS 0x0A
#define EFI_HII_PACKAGE_END 0xDF
#define EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN 0xE0
#define EFI_HII_PACKAGE_TYPE_SYSTEM_END 0xFF
/*
* HII GUID package
*/
struct efi_hii_guid_package {
struct efi_hii_package_header header;
efi_guid_t guid;
char data[];
} __packed;
/*
* HII string package
*/
struct efi_hii_strings_package {
struct efi_hii_package_header header;
u32 header_size;
u32 string_info_offset;
u16 language_window[16];
efi_string_id_t language_name;
u8 language[];
} __packed;
struct efi_hii_string_block {
u8 block_type;
/* u8 block_body[]; */
} __packed;
#define EFI_HII_SIBT_END 0x00
#define EFI_HII_SIBT_STRING_SCSU 0x10
#define EFI_HII_SIBT_STRING_SCSU_FONT 0x11
#define EFI_HII_SIBT_STRINGS_SCSU 0x12
#define EFI_HII_SIBT_STRINGS_SCSU_FONT 0x13
#define EFI_HII_SIBT_STRING_UCS2 0x14
#define EFI_HII_SIBT_STRING_UCS2_FONT 0x15
#define EFI_HII_SIBT_STRINGS_UCS2 0x16
#define EFI_HII_SIBT_STRINGS_UCS2_FONT 0x17
#define EFI_HII_SIBT_DUPLICATE 0x20
#define EFI_HII_SIBT_SKIP2 0x21
#define EFI_HII_SIBT_SKIP1 0x22
#define EFI_HII_SIBT_EXT1 0x30
#define EFI_HII_SIBT_EXT2 0x31
#define EFI_HII_SIBT_EXT4 0x32
#define EFI_HII_SIBT_FONT 0x40
struct efi_hii_sibt_string_ucs2_block {
struct efi_hii_string_block header;
u16 string_text[];
} __packed;
static inline struct efi_hii_string_block *
efi_hii_sibt_string_ucs2_block_next(struct efi_hii_sibt_string_ucs2_block *blk)
{
return ((void *)blk) + sizeof(*blk) +
(u16_strlen(blk->string_text) + 1) * 2;
}
/*
* HII forms package
* TODO: full scope of definitions
*/
struct efi_hii_time {
u8 hour;
u8 minute;
u8 second;
};
struct efi_hii_date {
u16 year;
u8 month;
u8 day;
};
struct efi_hii_ref {
efi_question_id_t question_id;
efi_form_id_t form_id;
efi_guid_t form_set_guid;
efi_string_id_t device_path;
};
union efi_ifr_type_value {
u8 u8; // EFI_IFR_TYPE_NUM_SIZE_8
u16 u16; // EFI_IFR_TYPE_NUM_SIZE_16
u32 u32; // EFI_IFR_TYPE_NUM_SIZE_32
u64 u64; // EFI_IFR_TYPE_NUM_SIZE_64
bool b; // EFI_IFR_TYPE_BOOLEAN
struct efi_hii_time time; // EFI_IFR_TYPE_TIME
struct efi_hii_date date; // EFI_IFR_TYPE_DATE
efi_string_id_t string; // EFI_IFR_TYPE_STRING, EFI_IFR_TYPE_ACTION
struct efi_hii_ref ref; // EFI_IFR_TYPE_REF
// u8 buffer[]; // EFI_IFR_TYPE_BUFFER
};
#define EFI_IFR_TYPE_NUM_SIZE_8 0x00
#define EFI_IFR_TYPE_NUM_SIZE_16 0x01
#define EFI_IFR_TYPE_NUM_SIZE_32 0x02
#define EFI_IFR_TYPE_NUM_SIZE_64 0x03
#define EFI_IFR_TYPE_BOOLEAN 0x04
#define EFI_IFR_TYPE_TIME 0x05
#define EFI_IFR_TYPE_DATE 0x06
#define EFI_IFR_TYPE_STRING 0x07
#define EFI_IFR_TYPE_OTHER 0x08
#define EFI_IFR_TYPE_UNDEFINED 0x09
#define EFI_IFR_TYPE_ACTION 0x0A
#define EFI_IFR_TYPE_BUFFER 0x0B
#define EFI_IFR_TYPE_REF 0x0C
#define EFI_IFR_OPTION_DEFAULT 0x10
#define EFI_IFR_OPTION_DEFAULT_MFG 0x20
#define EFI_IFR_ONE_OF_OPTION_OP 0x09
struct efi_ifr_op_header {
u8 opCode;
u8 length:7;
u8 scope:1;
};
struct efi_ifr_one_of_option {
struct efi_ifr_op_header header;
efi_string_id_t option;
u8 flags;
u8 type;
union efi_ifr_type_value value;
};
typedef efi_uintn_t efi_browser_action_t;
#define EFI_BROWSER_ACTION_REQUEST_NONE 0
#define EFI_BROWSER_ACTION_REQUEST_RESET 1
#define EFI_BROWSER_ACTION_REQUEST_SUBMIT 2
#define EFI_BROWSER_ACTION_REQUEST_EXIT 3
#define EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT 4
#define EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT 5
#define EFI_BROWSER_ACTION_REQUEST_FORM_APPLY 6
#define EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD 7
#define EFI_BROWSER_ACTION_REQUEST_RECONNECT 8
typedef efi_uintn_t efi_browser_action_request_t;
#define EFI_BROWSER_ACTION_CHANGING 0
#define EFI_BROWSER_ACTION_CHANGED 1
#define EFI_BROWSER_ACTION_RETRIEVE 2
#define EFI_BROWSER_ACTION_FORM_OPEN 3
#define EFI_BROWSER_ACTION_FORM_CLOSE 4
#define EFI_BROWSER_ACTION_SUBMITTED 5
#define EFI_BROWSER_ACTION_DEFAULT_STANDARD 0x1000
#define EFI_BROWSER_ACTION_DEFAULT_MANUFACTURING 0x1001
#define EFI_BROWSER_ACTION_DEFAULT_SAFE 0x1002
#define EFI_BROWSER_ACTION_DEFAULT_PLATFORM 0x2000
#define EFI_BROWSER_ACTION_DEFAULT_HARDWARE 0x3000
#define EFI_BROWSER_ACTION_DEFAULT_FIRMWARE 0x4000
/*
* HII keyboard package
*/
typedef enum {
EFI_KEY_LCTRL, EFI_KEY_A0, EFI_KEY_LALT, EFI_KEY_SPACE_BAR,
EFI_KEY_A2, EFI_KEY_A3, EFI_KEY_A4, EFI_KEY_RCTRL, EFI_KEY_LEFT_ARROW,
EFI_KEY_DOWN_ARROW, EFI_KEY_RIGHT_ARROW, EFI_KEY_ZERO,
EFI_KEY_PERIOD, EFI_KEY_ENTER, EFI_KEY_LSHIFT, EFI_KEY_B0,
EFI_KEY_B1, EFI_KEY_B2, EFI_KEY_B3, EFI_KEY_B4, EFI_KEY_B5, EFI_KEY_B6,
EFI_KEY_B7, EFI_KEY_B8, EFI_KEY_B9, EFI_KEY_B10, EFI_KEY_RSHIFT,
EFI_KEY_UP_ARROW, EFI_KEY_ONE, EFI_KEY_TWO, EFI_KEY_THREE,
EFI_KEY_CAPS_LOCK, EFI_KEY_C1, EFI_KEY_C2, EFI_KEY_C3, EFI_KEY_C4,
EFI_KEY_C5, EFI_KEY_C6, EFI_KEY_C7, EFI_KEY_C8, EFI_KEY_C9,
EFI_KEY_C10, EFI_KEY_C11, EFI_KEY_C12, EFI_KEY_FOUR, EFI_KEY_FIVE,
EFI_KEY_SIX, EFI_KEY_PLUS, EFI_KEY_TAB, EFI_KEY_D1, EFI_KEY_D2,
EFI_KEY_D3, EFI_KEY_D4, EFI_KEY_D5, EFI_KEY_D6, EFI_KEY_D7, EFI_KEY_D8,
EFI_KEY_D9, EFI_KEY_D10, EFI_KEY_D11, EFI_KEY_D12, EFI_KEY_D13,
EFI_KEY_DEL, EFI_KEY_END, EFI_KEY_PG_DN, EFI_KEY_SEVEN, EFI_KEY_EIGHT,
EFI_KEY_NINE, EFI_KEY_E0, EFI_KEY_E1, EFI_KEY_E2, EFI_KEY_E3,
EFI_KEY_E4, EFI_KEY_E5, EFI_KEY_E6, EFI_KEY_E7, EFI_KEY_E8, EFI_KEY_E9,
EFI_KEY_E10, EFI_KEY_E11, EFI_KEY_E12, EFI_KEY_BACK_SPACE,
EFI_KEY_INS, EFI_KEY_HOME, EFI_KEY_PG_UP, EFI_KEY_NLCK, EFI_KEY_SLASH,
EFI_KEY_ASTERISK, EFI_KEY_MINUS, EFI_KEY_ESC, EFI_KEY_F1, EFI_KEY_F2,
EFI_KEY_F3, EFI_KEY_F4, EFI_KEY_F5, EFI_KEY_F6, EFI_KEY_F7, EFI_KEY_F8,
EFI_KEY_F9, EFI_KEY_F10, EFI_KEY_F11, EFI_KEY_F12, EFI_KEY_PRINT,
EFI_KEY_SLCK, EFI_KEY_PAUSE,
} efi_key;
struct efi_key_descriptor {
u32 key;
u16 unicode;
u16 shifted_unicode;
u16 alt_gr_unicode;
u16 shifted_alt_gr_unicode;
u16 modifier;
u16 affected_attribute;
} __packed;
struct efi_hii_keyboard_layout {
u16 layout_length;
efi_guid_t guid;
u32 layout_descriptor_string_offset;
u8 descriptor_count;
struct efi_key_descriptor descriptors[];
} __packed;
struct efi_hii_keyboard_package {
struct efi_hii_package_header header;
u16 layout_count;
struct efi_hii_keyboard_layout layout[];
} __packed;
/*
* HII protocols
*/
#define EFI_HII_STRING_PROTOCOL_GUID \
EFI_GUID(0x0fd96974, 0x23aa, 0x4cdc, \
0xb9, 0xcb, 0x98, 0xd1, 0x77, 0x50, 0x32, 0x2a)
struct efi_font_info {
efi_hii_font_style_t font_style;
u16 font_size;
u16 font_name[1];
};
struct efi_hii_string_protocol {
efi_status_t(EFIAPI *new_string)(
const struct efi_hii_string_protocol *this,
efi_hii_handle_t package_list,
efi_string_id_t *string_id,
const u8 *language,
const u16 *language_name,
const efi_string_t string,
const struct efi_font_info *string_font_info);
efi_status_t(EFIAPI *get_string)(
const struct efi_hii_string_protocol *this,
const u8 *language,
efi_hii_handle_t package_list,
efi_string_id_t string_id,
efi_string_t string,
efi_uintn_t *string_size,
struct efi_font_info **string_font_info);
efi_status_t(EFIAPI *set_string)(
const struct efi_hii_string_protocol *this,
efi_hii_handle_t package_list,
efi_string_id_t string_id,
const u8 *language,
const efi_string_t string,
const struct efi_font_info *string_font_info);
efi_status_t(EFIAPI *get_languages)(
const struct efi_hii_string_protocol *this,
efi_hii_handle_t package_list,
u8 *languages,
efi_uintn_t *languages_size);
efi_status_t(EFIAPI *get_secondary_languages)(
const struct efi_hii_string_protocol *this,
efi_hii_handle_t package_list,
const u8 *primary_language,
u8 *secondary_languages,
efi_uintn_t *secondary_languages_size);
};
#define EFI_HII_DATABASE_PROTOCOL_GUID \
EFI_GUID(0xef9fc172, 0xa1b2, 0x4693, \
0xb3, 0x27, 0x6d, 0x32, 0xfc, 0x41, 0x60, 0x42)
struct efi_hii_database_protocol {
efi_status_t(EFIAPI *new_package_list)(
const struct efi_hii_database_protocol *this,
const struct efi_hii_package_list_header *package_list,
const efi_handle_t driver_handle,
efi_hii_handle_t *handle);
efi_status_t(EFIAPI *remove_package_list)(
const struct efi_hii_database_protocol *this,
efi_hii_handle_t handle);
efi_status_t(EFIAPI *update_package_list)(
const struct efi_hii_database_protocol *this,
efi_hii_handle_t handle,
const struct efi_hii_package_list_header *package_list);
efi_status_t(EFIAPI *list_package_lists)(
const struct efi_hii_database_protocol *this,
u8 package_type,
const efi_guid_t *package_guid,
efi_uintn_t *handle_buffer_length,
efi_hii_handle_t *handle);
efi_status_t(EFIAPI *export_package_lists)(
const struct efi_hii_database_protocol *this,
efi_hii_handle_t handle,
efi_uintn_t *buffer_size,
struct efi_hii_package_list_header *buffer);
efi_status_t(EFIAPI *register_package_notify)(
const struct efi_hii_database_protocol *this,
u8 package_type,
const efi_guid_t *package_guid,
const void *package_notify_fn,
efi_uintn_t notify_type,
efi_handle_t *notify_handle);
efi_status_t(EFIAPI *unregister_package_notify)(
const struct efi_hii_database_protocol *this,
efi_handle_t notification_handle
);
efi_status_t(EFIAPI *find_keyboard_layouts)(
const struct efi_hii_database_protocol *this,
u16 *key_guid_buffer_length,
efi_guid_t *key_guid_buffer);
efi_status_t(EFIAPI *get_keyboard_layout)(
const struct efi_hii_database_protocol *this,
efi_guid_t *key_guid,
u16 *keyboard_layout_length,
struct efi_hii_keyboard_layout *keyboard_layout);
efi_status_t(EFIAPI *set_keyboard_layout)(
const struct efi_hii_database_protocol *this,
efi_guid_t *key_guid);
efi_status_t(EFIAPI *get_package_list_handle)(
const struct efi_hii_database_protocol *this,
efi_hii_handle_t package_list_handle,
efi_handle_t *driver_handle);
};
#define EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID \
EFI_GUID(0x587e72d7, 0xcc50, 0x4f79, \
0x82, 0x09, 0xca, 0x29, 0x1f, 0xc1, 0xa1, 0x0f)
struct efi_hii_config_routing_protocol {
efi_status_t(EFIAPI *extract_config)(
const struct efi_hii_config_routing_protocol *this,
const efi_string_t request,
efi_string_t *progress,
efi_string_t *results);
efi_status_t(EFIAPI *export_config)(
const struct efi_hii_config_routing_protocol *this,
efi_string_t *results);
efi_status_t(EFIAPI *route_config)(
const struct efi_hii_config_routing_protocol *this,
const efi_string_t configuration,
efi_string_t *progress);
efi_status_t(EFIAPI *block_to_config)(
const struct efi_hii_config_routing_protocol *this,
const efi_string_t config_request,
const uint8_t *block,
const efi_uintn_t block_size,
efi_string_t *config,
efi_string_t *progress);
efi_status_t(EFIAPI *config_to_block)(
const struct efi_hii_config_routing_protocol *this,
const efi_string_t config_resp,
const uint8_t *block,
const efi_uintn_t *block_size,
efi_string_t *progress);
efi_status_t(EFIAPI *get_alt_config)(
const struct efi_hii_config_routing_protocol *this,
const efi_string_t config_resp,
const efi_guid_t *guid,
const efi_string_t name,
const struct efi_device_path *device_path,
const efi_string_t alt_cfg_id,
efi_string_t *alt_cfg_resp);
};
#define EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID \
EFI_GUID(0x330d4706, 0xf2a0, 0x4e4f, \
0xa3, 0x69, 0xb6, 0x6f, 0xa8, 0xd5, 0x43, 0x85)
struct efi_hii_config_access_protocol {
efi_status_t(EFIAPI *extract_config_access)(
const struct efi_hii_config_access_protocol *this,
const efi_string_t request,
efi_string_t *progress,
efi_string_t *results);
efi_status_t(EFIAPI *route_config_access)(
const struct efi_hii_config_access_protocol *this,
const efi_string_t configuration,
efi_string_t *progress);
efi_status_t(EFIAPI *form_callback)(
const struct efi_hii_config_access_protocol *this,
efi_browser_action_t action,
efi_question_id_t question_id,
u8 type,
union efi_ifr_type_value *value,
efi_browser_action_request_t *action_request);
};
#define EFI_GOP_GUID \ #define EFI_GOP_GUID \
EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, \ EFI_GUID(0x9042a9de, 0x23dc, 0x4a38, \
0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a) 0x96, 0xfb, 0x7a, 0xde, 0xd0, 0x80, 0x51, 0x6a)
@ -906,7 +1328,7 @@ struct efi_file_handle {
u64 rev; u64 rev;
efi_status_t (EFIAPI *open)(struct efi_file_handle *file, efi_status_t (EFIAPI *open)(struct efi_file_handle *file,
struct efi_file_handle **new_handle, struct efi_file_handle **new_handle,
s16 *file_name, u64 open_mode, u64 attributes); u16 *file_name, u64 open_mode, u64 attributes);
efi_status_t (EFIAPI *close)(struct efi_file_handle *file); efi_status_t (EFIAPI *close)(struct efi_file_handle *file);
efi_status_t (EFIAPI *delete)(struct efi_file_handle *file); efi_status_t (EFIAPI *delete)(struct efi_file_handle *file);
efi_status_t (EFIAPI *read)(struct efi_file_handle *file, efi_status_t (EFIAPI *read)(struct efi_file_handle *file,
@ -926,9 +1348,6 @@ struct efi_file_handle {
efi_status_t (EFIAPI *flush)(struct efi_file_handle *file); efi_status_t (EFIAPI *flush)(struct efi_file_handle *file);
}; };
#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_GUID \
EFI_GUID(0x964e5b22, 0x6459, 0x11d2, \
0x8e, 0x39, 0x0, 0xa0, 0xc9, 0x69, 0x72, 0x3b)
#define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION 0x00010000 #define EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION 0x00010000
struct efi_simple_file_system_protocol { struct efi_simple_file_system_protocol {

View file

@ -106,6 +106,10 @@ extern const struct efi_device_path_utilities_protocol
/* Implementation of the EFI_UNICODE_COLLATION_PROTOCOL */ /* Implementation of the EFI_UNICODE_COLLATION_PROTOCOL */
extern const struct efi_unicode_collation_protocol extern const struct efi_unicode_collation_protocol
efi_unicode_collation_protocol; efi_unicode_collation_protocol;
extern const struct efi_hii_config_routing_protocol efi_hii_config_routing;
extern const struct efi_hii_config_access_protocol efi_hii_config_access;
extern const struct efi_hii_database_protocol efi_hii_database;
extern const struct efi_hii_string_protocol efi_hii_string;
uint16_t *efi_dp_str(struct efi_device_path *dp); uint16_t *efi_dp_str(struct efi_device_path *dp);
@ -139,6 +143,10 @@ extern const efi_guid_t efi_file_system_info_guid;
extern const efi_guid_t efi_guid_device_path_utilities_protocol; extern const efi_guid_t efi_guid_device_path_utilities_protocol;
/* GUID of the Unicode collation protocol */ /* GUID of the Unicode collation protocol */
extern const efi_guid_t efi_guid_unicode_collation_protocol; extern const efi_guid_t efi_guid_unicode_collation_protocol;
extern const efi_guid_t efi_guid_hii_config_routing_protocol;
extern const efi_guid_t efi_guid_hii_config_access_protocol;
extern const efi_guid_t efi_guid_hii_database_protocol;
extern const efi_guid_t efi_guid_hii_string_protocol;
extern unsigned int __efi_runtime_start, __efi_runtime_stop; extern unsigned int __efi_runtime_start, __efi_runtime_stop;
extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop;
@ -244,6 +252,8 @@ extern struct list_head efi_obj_list;
/* List of all events */ /* List of all events */
extern struct list_head efi_events; extern struct list_head efi_events;
/* Initialize efi execution environment */
efi_status_t efi_init_obj_list(void);
/* Called by bootefi to initialize root node */ /* Called by bootefi to initialize root node */
efi_status_t efi_root_node_register(void); efi_status_t efi_root_node_register(void);
/* Called by bootefi to initialize runtime */ /* Called by bootefi to initialize runtime */
@ -508,15 +518,15 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
struct efi_system_table *systab); struct efi_system_table *systab);
#endif #endif
efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, efi_status_t EFIAPI efi_get_variable(u16 *variable_name,
u32 *attributes, efi_uintn_t *data_size, const efi_guid_t *vendor, u32 *attributes,
void *data); efi_uintn_t *data_size, void *data);
efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
u16 *variable_name, u16 *variable_name,
efi_guid_t *vendor); const efi_guid_t *vendor);
efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor, efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
u32 attributes, efi_uintn_t data_size, const efi_guid_t *vendor, u32 attributes,
void *data); efi_uintn_t data_size, const void *data);
/* /*
* See section 3.1.3 in the v2.7 UEFI spec for more details on * See section 3.1.3 in the v2.7 UEFI spec for more details on

View file

@ -349,6 +349,35 @@ size_t u16_strnlen(const u16 *in, size_t count)
return i; return i;
} }
u16 *u16_strcpy(u16 *dest, const u16 *src)
{
u16 *tmp = dest;
for (;; dest++, src++) {
*dest = *src;
if (!*src)
break;
}
return tmp;
}
u16 *u16_strdup(const u16 *src)
{
u16 *new;
if (!src)
return NULL;
new = malloc((u16_strlen(src) + 1) * sizeof(u16));
if (!new)
return NULL;
u16_strcpy(new, src);
return new;
}
/* Convert UTF-16 to UTF-8. */ /* Convert UTF-16 to UTF-8. */
uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size) uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size)
{ {

View file

@ -233,8 +233,7 @@ static efi_status_t EFIAPI efi_uc_stop(
} }
ret = EFI_CALL(systab.boottime->free_pool(entry_buffer)); ret = EFI_CALL(systab.boottime->free_pool(entry_buffer));
if (ret != EFI_SUCCESS) if (ret != EFI_SUCCESS)
printf("%s(%u) %s: ERROR: Cannot free pool\n", printf("%s: ERROR: Cannot free pool\n", __func__);
__FILE__, __LINE__, __func__);
/* Detach driver from controller */ /* Detach driver from controller */
ret = EFI_CALL(systab.boottime->close_protocol( ret = EFI_CALL(systab.boottime->close_protocol(

View file

@ -8,6 +8,7 @@ config EFI_LOADER
default y default y
select LIB_UUID select LIB_UUID
select HAVE_BLOCK_DEVICE select HAVE_BLOCK_DEVICE
select REGEX
imply CFB_CONSOLE_ANSI imply CFB_CONSOLE_ANSI
help help
Select this option if you want to run EFI applications (like grub2) Select this option if you want to run EFI applications (like grub2)
@ -33,3 +34,18 @@ config EFI_LOADER_BOUNCE_BUFFER
Some hardware does not support DMA to full 64bit addresses. For this Some hardware does not support DMA to full 64bit addresses. For this
hardware we can create a bounce buffer so that payloads don't have to hardware we can create a bounce buffer so that payloads don't have to
worry about platform details. worry about platform details.
config EFI_LOADER_HII
bool "Expose HII protocols to EFI applications"
depends on EFI_LOADER
default n
help
The Human Interface Infrastructure is a complicated framework that
allows UEFI applications to draw fancy menus and hook strings using
a translation framework.
U-Boot implements enough of its features to be able to run the UEFI
Shell, but not more than that. The code is experimental still, so
beware that your system might break with HII enabled.
If unsure, say n.

View file

@ -10,7 +10,7 @@ CFLAGS_efi_boottime.o += \
-DFW_VERSION="0x$(VERSION)" \ -DFW_VERSION="0x$(VERSION)" \
-DFW_PATCHLEVEL="0x$(PATCHLEVEL)" -DFW_PATCHLEVEL="0x$(PATCHLEVEL)"
CFLAGS_helloworld.o := $(CFLAGS_EFI) -Os -ffreestanding CFLAGS_helloworld.o := $(CFLAGS_EFI) -Os -ffreestanding
CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI) -Os CFLAGS_REMOVE_helloworld.o := $(CFLAGS_NON_EFI)
ifneq ($(CONFIG_CMD_BOOTEFI_HELLO_COMPILE),) ifneq ($(CONFIG_CMD_BOOTEFI_HELLO_COMPILE),)
always += helloworld.efi always += helloworld.efi
@ -24,10 +24,12 @@ obj-y += efi_device_path.o
obj-y += efi_device_path_to_text.o obj-y += efi_device_path_to_text.o
obj-y += efi_device_path_utilities.o obj-y += efi_device_path_utilities.o
obj-y += efi_file.o obj-y += efi_file.o
obj-y += efi_hii.o efi_hii_config.o
obj-y += efi_image_loader.o obj-y += efi_image_loader.o
obj-y += efi_memory.o obj-y += efi_memory.o
obj-y += efi_root_node.o obj-y += efi_root_node.o
obj-y += efi_runtime.o obj-y += efi_runtime.o
obj-y += efi_setup.o
obj-y += efi_unicode_collation.o obj-y += efi_unicode_collation.o
obj-y += efi_variable.o obj-y += efi_variable.o
obj-y += efi_watchdog.o obj-y += efi_watchdog.o

View file

@ -1558,6 +1558,26 @@ efi_status_t efi_setup_loaded_image(struct efi_device_path *device_path,
if (ret != EFI_SUCCESS) if (ret != EFI_SUCCESS)
goto failure; goto failure;
#if CONFIG_IS_ENABLED(EFI_LOADER_HII)
ret = efi_add_protocol(&obj->header,
&efi_guid_hii_string_protocol,
(void *)&efi_hii_string);
if (ret != EFI_SUCCESS)
goto failure;
ret = efi_add_protocol(&obj->header,
&efi_guid_hii_database_protocol,
(void *)&efi_hii_database);
if (ret != EFI_SUCCESS)
goto failure;
ret = efi_add_protocol(&obj->header,
&efi_guid_hii_config_routing_protocol,
(void *)&efi_hii_config_routing);
if (ret != EFI_SUCCESS)
goto failure;
#endif
return ret; return ret;
failure: failure:
printf("ERROR: Failure to install protocols for loaded image\n"); printf("ERROR: Failure to install protocols for loaded image\n");
@ -1706,8 +1726,8 @@ error:
* Return: status code * Return: status code
*/ */
static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle, static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
unsigned long *exit_data_size, efi_uintn_t *exit_data_size,
s16 **exit_data) u16 **exit_data)
{ {
struct efi_loaded_image_obj *image_obj = struct efi_loaded_image_obj *image_obj =
(struct efi_loaded_image_obj *)image_handle; (struct efi_loaded_image_obj *)image_handle;
@ -1773,8 +1793,8 @@ static efi_status_t EFIAPI efi_start_image(efi_handle_t image_handle,
*/ */
static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle, static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
efi_status_t exit_status, efi_status_t exit_status,
unsigned long exit_data_size, efi_uintn_t exit_data_size,
int16_t *exit_data) u16 *exit_data)
{ {
/* /*
* TODO: We should call the unload procedure of the loaded * TODO: We should call the unload procedure of the loaded
@ -1783,7 +1803,7 @@ static efi_status_t EFIAPI efi_exit(efi_handle_t image_handle,
struct efi_loaded_image_obj *image_obj = struct efi_loaded_image_obj *image_obj =
(struct efi_loaded_image_obj *)image_handle; (struct efi_loaded_image_obj *)image_handle;
EFI_ENTRY("%p, %ld, %ld, %p", image_handle, exit_status, EFI_ENTRY("%p, %ld, %zu, %p", image_handle, exit_status,
exit_data_size, exit_data); exit_data_size, exit_data);
/* Make sure entry/exit counts for EFI world cross-overs match */ /* Make sure entry/exit counts for EFI world cross-overs match */
@ -2483,7 +2503,7 @@ static void EFIAPI efi_copy_mem(void *destination, const void *source,
size_t length) size_t length)
{ {
EFI_ENTRY("%p, %p, %ld", destination, source, (unsigned long)length); EFI_ENTRY("%p, %p, %ld", destination, source, (unsigned long)length);
memcpy(destination, source, length); memmove(destination, source, length);
EFI_EXIT(EFI_SUCCESS); EFI_EXIT(EFI_SUCCESS);
} }
@ -2825,7 +2845,7 @@ static efi_status_t EFIAPI efi_connect_controller(
efi_status_t ret = EFI_NOT_FOUND; efi_status_t ret = EFI_NOT_FOUND;
struct efi_object *efiobj; struct efi_object *efiobj;
EFI_ENTRY("%p, %p, %p, %d", controller_handle, driver_image_handle, EFI_ENTRY("%p, %p, %pD, %d", controller_handle, driver_image_handle,
remain_device_path, recursive); remain_device_path, recursive);
efiobj = efi_search_obj(controller_handle); efiobj = efi_search_obj(controller_handle);

View file

@ -148,7 +148,7 @@ static int sanitize_path(char *path)
* Returns: handle to the opened file or NULL * Returns: handle to the opened file or NULL
*/ */
static struct efi_file_handle *file_open(struct file_system *fs, static struct efi_file_handle *file_open(struct file_system *fs,
struct file_handle *parent, s16 *file_name, u64 mode, struct file_handle *parent, u16 *file_name, u64 mode,
u64 attributes) u64 attributes)
{ {
struct file_handle *fh; struct file_handle *fh;
@ -157,8 +157,8 @@ static struct efi_file_handle *file_open(struct file_system *fs,
int flen = 0; int flen = 0;
if (file_name) { if (file_name) {
utf16_to_utf8((u8 *)f0, (u16 *)file_name, 1); utf16_to_utf8((u8 *)f0, file_name, 1);
flen = u16_strlen((u16 *)file_name); flen = u16_strlen(file_name);
} }
/* we could have a parent, but also an absolute path: */ /* we could have a parent, but also an absolute path: */
@ -183,7 +183,7 @@ static struct efi_file_handle *file_open(struct file_system *fs,
*p++ = '/'; *p++ = '/';
} }
utf16_to_utf8((u8 *)p, (u16 *)file_name, flen); utf16_to_utf8((u8 *)p, file_name, flen);
if (sanitize_path(fh->path)) if (sanitize_path(fh->path))
goto error; goto error;
@ -200,6 +200,10 @@ static struct efi_file_handle *file_open(struct file_system *fs,
fs_exists(fh->path))) fs_exists(fh->path)))
goto error; goto error;
/* fs_exists() calls fs_close(), so open file system again */
if (set_blk_dev(fh))
goto error;
/* figure out if file is a directory: */ /* figure out if file is a directory: */
fh->isdir = is_dir(fh); fh->isdir = is_dir(fh);
} else { } else {
@ -216,7 +220,7 @@ error:
static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file, static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file,
struct efi_file_handle **new_handle, struct efi_file_handle **new_handle,
s16 *file_name, u64 open_mode, u64 attributes) u16 *file_name, u64 open_mode, u64 attributes)
{ {
struct file_handle *fh = to_fh(file); struct file_handle *fh = to_fh(file);
efi_status_t ret; efi_status_t ret;
@ -375,7 +379,7 @@ static efi_status_t dir_read(struct file_handle *fh, u64 *buffer_size,
if (dent->type == FS_DT_DIR) if (dent->type == FS_DT_DIR)
info->attribute |= EFI_FILE_DIRECTORY; info->attribute |= EFI_FILE_DIRECTORY;
ascii2unicode((u16 *)info->file_name, dent->name); ascii2unicode(info->file_name, dent->name);
fh->offset++; fh->offset++;
@ -666,7 +670,7 @@ struct efi_file_handle *efi_file_from_path(struct efi_device_path *fp)
return NULL; return NULL;
} }
EFI_CALL(ret = f->open(f, &f2, (s16 *)fdp->str, EFI_CALL(ret = f->open(f, &f2, fdp->str,
EFI_FILE_MODE_READ, 0)); EFI_FILE_MODE_READ, 0));
if (ret != EFI_SUCCESS) if (ret != EFI_SUCCESS)
return NULL; return NULL;

View file

@ -0,0 +1,90 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Library for freestanding binary
*
* Copyright 2019, Heinrich Schuchardt <xypron.glpk@gmx.de>
*
* GCC requires that freestanding programs provide memcpy(), memmove(),
* memset(), and memcmp().
*/
#include <common.h>
/**
* memcmp() - compare memory areas
*
* @s1: pointer to first area
* @s2: pointer to second area
* @n: number of bytes to compare
* Return: 0 if both memory areas are the same, otherwise the sign of the
* result value is the same as the sign of the difference between
* the first differing pair of bytes taken as u8.
*/
int memcmp(const void *s1, const void *s2, size_t n)
{
const u8 *pos1 = s1;
const u8 *pos2 = s2;
for (; n; --n) {
if (*pos1 != *pos2)
return *pos1 - *pos2;
++pos1;
++pos2;
}
return 0;
}
/**
* memcpy() - copy memory area
*
* @dest: destination buffer
* @src: source buffer
* @n: number of bytes to copy
* Return: pointer to destination buffer
*/
void *memmove(void *dest, const void *src, size_t n)
{
u8 *d = dest;
const u8 *s = src;
if (d >= s) {
for (; n; --n)
*d++ = *s++;
} else {
d += n;
s += n;
for (; n; --n)
*--d = *--s;
}
return dest;
}
/**
* memcpy() - copy memory area
*
* @dest: destination buffer
* @src: source buffer
* @n: number of bytes to copy
* Return: pointer to destination buffer
*/
void *memcpy(void *dest, const void *src, size_t n)
{
return memmove(dest, src, n);
}
/**
* memset() - fill memory with a constant byte
*
* @s: destination buffer
* @c: byte value
* @n: number of bytes to set
* Return: pointer to destination buffer
*/
void *memset(void *s, int c, size_t n)
{
u8 *d = s;
for (; n; --n)
*d++ = c;
return s;
}

1095
lib/efi_loader/efi_hii.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,146 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* EFI Human Interface Infrastructure ... Configuration
*
* Copyright (c) 2017 Leif Lindholm
* Copyright (c) 2018 AKASHI Takahiro, Linaro Limited
*/
#include <common.h>
#include <efi_loader.h>
const efi_guid_t efi_guid_hii_config_routing_protocol
= EFI_HII_CONFIG_ROUTING_PROTOCOL_GUID;
const efi_guid_t efi_guid_hii_config_access_protocol
= EFI_HII_CONFIG_ACCESS_PROTOCOL_GUID;
/*
* EFI_HII_CONFIG_ROUTING_PROTOCOL
*/
static efi_status_t EFIAPI
extract_config(const struct efi_hii_config_routing_protocol *this,
const efi_string_t request,
efi_string_t *progress,
efi_string_t *results)
{
EFI_ENTRY("%p, \"%ls\", %p, %p", this, request, progress, results);
return EFI_EXIT(EFI_OUT_OF_RESOURCES);
}
static efi_status_t EFIAPI
export_config(const struct efi_hii_config_routing_protocol *this,
efi_string_t *results)
{
EFI_ENTRY("%p, %p", this, results);
return EFI_EXIT(EFI_OUT_OF_RESOURCES);
}
static efi_status_t EFIAPI
route_config(const struct efi_hii_config_routing_protocol *this,
const efi_string_t configuration,
efi_string_t *progress)
{
EFI_ENTRY("%p, \"%ls\", %p", this, configuration, progress);
return EFI_EXIT(EFI_OUT_OF_RESOURCES);
}
static efi_status_t EFIAPI
block_to_config(const struct efi_hii_config_routing_protocol *this,
const efi_string_t config_request,
const u8 *block,
const efi_uintn_t block_size,
efi_string_t *config,
efi_string_t *progress)
{
EFI_ENTRY("%p, \"%ls\", %p, %zu, %p, %p", this, config_request,
block, block_size, config, progress);
return EFI_EXIT(EFI_OUT_OF_RESOURCES);
}
static efi_status_t EFIAPI
config_to_block(const struct efi_hii_config_routing_protocol *this,
const efi_string_t config_resp,
const u8 *block,
const efi_uintn_t *block_size,
efi_string_t *progress)
{
EFI_ENTRY("%p, \"%ls\", %p, %p, %p", this, config_resp,
block, block_size, progress);
return EFI_EXIT(EFI_OUT_OF_RESOURCES);
}
static efi_status_t EFIAPI
get_alt_config(const struct efi_hii_config_routing_protocol *this,
const efi_string_t config_resp,
const efi_guid_t *guid,
const efi_string_t name,
const struct efi_device_path *device_path,
const efi_string_t alt_cfg_id,
efi_string_t *alt_cfg_resp)
{
EFI_ENTRY("%p, \"%ls\", %pUl, \"%ls\", %p, \"%ls\", %p",
this, config_resp, guid, name, device_path,
alt_cfg_id, alt_cfg_resp);
return EFI_EXIT(EFI_OUT_OF_RESOURCES);
}
/*
* EFI_HII_ACCESS_PROTOCOL
*/
efi_status_t EFIAPI
extract_config_access(const struct efi_hii_config_access_protocol *this,
const efi_string_t request,
efi_string_t *progress,
efi_string_t *results)
{
EFI_ENTRY("%p, \"%ls\", %p, %p", this, request, progress, results);
return EFI_EXIT(EFI_OUT_OF_RESOURCES);
};
efi_status_t EFIAPI
route_config_access(const struct efi_hii_config_access_protocol *this,
const efi_string_t configuration,
efi_string_t *progress)
{
EFI_ENTRY("%p, \"%ls\", %p", this, configuration, progress);
return EFI_EXIT(EFI_OUT_OF_RESOURCES);
};
efi_status_t EFIAPI
form_callback(const struct efi_hii_config_access_protocol *this,
efi_browser_action_t action,
efi_question_id_t question_id,
u8 type,
union efi_ifr_type_value *value,
efi_browser_action_request_t *action_request)
{
EFI_ENTRY("%p, 0x%zx, 0x%x, 0x%x, %p, %p", this, action,
question_id, type, value, action_request);
return EFI_EXIT(EFI_DEVICE_ERROR);
};
const struct efi_hii_config_routing_protocol efi_hii_config_routing = {
.extract_config = extract_config,
.export_config = export_config,
.route_config = route_config,
.block_to_config = block_to_config,
.config_to_block = config_to_block,
.get_alt_config = get_alt_config
};
const struct efi_hii_config_access_protocol efi_hii_config_access = {
.extract_config_access = extract_config_access,
.route_config_access = route_config_access,
.form_callback = form_callback
};

View file

@ -554,6 +554,12 @@ __weak void efi_add_known_memory(void)
u64 ram_top = board_get_usable_ram_top(0) & ~EFI_PAGE_MASK; u64 ram_top = board_get_usable_ram_top(0) & ~EFI_PAGE_MASK;
int i; int i;
/*
* ram_top is just outside mapped memory. So use an offset of one for
* mapping the sandbox address.
*/
ram_top = (uintptr_t)map_sysmem(ram_top - 1, 0) + 1;
/* Fix for 32bit targets with ram_top at 4G */ /* Fix for 32bit targets with ram_top at 4G */
if (!ram_top) if (!ram_top)
ram_top = 0x100000000ULL; ram_top = 0x100000000ULL;

View file

@ -530,7 +530,8 @@ static efi_status_t EFIAPI efi_set_virtual_address_map(
* This function adds a memory-mapped IO region to the memory map to make it * This function adds a memory-mapped IO region to the memory map to make it
* available at runtime. * available at runtime.
* *
* @mmio_ptr: address of the memory-mapped IO region * @mmio_ptr: pointer to a pointer to the start of the memory-mapped
* IO region
* @len: size of the memory-mapped IO region * @len: size of the memory-mapped IO region
* Returns: status code * Returns: status code
*/ */

View file

@ -0,0 +1,86 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* EFI setup code
*
* Copyright (c) 2016-2018 Alexander Graf et al.
*/
#include <common.h>
#include <efi_loader.h>
#define OBJ_LIST_NOT_INITIALIZED 1
static efi_status_t efi_obj_list_initialized = OBJ_LIST_NOT_INITIALIZED;
/* Initialize and populate EFI object list */
efi_status_t efi_init_obj_list(void)
{
efi_status_t ret = EFI_SUCCESS;
/*
* On the ARM architecture gd is mapped to a fixed register (r9 or x18).
* As this register may be overwritten by an EFI payload we save it here
* and restore it on every callback entered.
*/
efi_save_gd();
/* Initialize once only */
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 root node */
ret = efi_root_node_register();
if (ret != EFI_SUCCESS)
goto out;
/* Initialize EFI driver uclass */
ret = efi_driver_init();
if (ret != EFI_SUCCESS)
goto out;
ret = efi_console_register();
if (ret != EFI_SUCCESS)
goto out;
#ifdef CONFIG_PARTITIONS
ret = efi_disk_register();
if (ret != EFI_SUCCESS)
goto out;
#endif
#if defined(CONFIG_LCD) || defined(CONFIG_DM_VIDEO)
ret = efi_gop_register();
if (ret != EFI_SUCCESS)
goto out;
#endif
#ifdef CONFIG_NET
ret = efi_net_register();
if (ret != EFI_SUCCESS)
goto out;
#endif
#ifdef CONFIG_GENERATE_ACPI_TABLE
ret = efi_acpi_register();
if (ret != EFI_SUCCESS)
goto out;
#endif
#ifdef CONFIG_GENERATE_SMBIOS_TABLE
ret = efi_smbios_register();
if (ret != EFI_SUCCESS)
goto out;
#endif
ret = efi_watchdog_register();
if (ret != EFI_SUCCESS)
goto out;
/* Initialize EFI runtime services */
ret = efi_reset_system_init();
if (ret != EFI_SUCCESS)
goto out;
out:
efi_obj_list_initialized = ret;
return ret;
}

View file

@ -8,6 +8,10 @@
#include <malloc.h> #include <malloc.h>
#include <charset.h> #include <charset.h>
#include <efi_loader.h> #include <efi_loader.h>
#include <hexdump.h>
#include <environment.h>
#include <search.h>
#include <uuid.h>
#define READ_ONLY BIT(31) #define READ_ONLY BIT(31)
@ -46,60 +50,21 @@
#define PREFIX_LEN (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_")) #define PREFIX_LEN (strlen("efi_xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx_"))
static int hex(int ch) /**
{ * efi_to_native() - convert the UEFI variable name and vendor GUID to U-Boot
if (ch >= 'a' && ch <= 'f') * variable name
return ch-'a'+10; *
if (ch >= '0' && ch <= '9') * The U-Boot variable name is a concatenation of prefix 'efi', the hexstring
return ch-'0'; * encoded vendor GUID, and the UTF-8 encoded UEFI variable name separated by
if (ch >= 'A' && ch <= 'F') * underscores, e.g. 'efi_8be4df61-93ca-11d2-aa0d-00e098032b8c_BootOrder'.
return ch-'A'+10; *
return -1; * @native: pointer to pointer to U-Boot variable name
} * @variable_name: UEFI variable name
* @vendor: vendor GUID
static int hex2mem(u8 *mem, const char *hexstr, int size) * Return: status code
{ */
int nibble;
int i;
for (i = 0; i < size; i++) {
if (*hexstr == '\0')
break;
nibble = hex(*hexstr);
if (nibble < 0)
return -1;
*mem = nibble;
hexstr++;
nibble = hex(*hexstr);
if (nibble < 0)
return -1;
*mem = (*mem << 4) | nibble;
hexstr++;
mem++;
}
return i;
}
static char *mem2hex(char *hexstr, const u8 *mem, int count)
{
static const char hexchars[] = "0123456789abcdef";
while (count-- > 0) {
u8 ch = *mem++;
*hexstr++ = hexchars[ch >> 4];
*hexstr++ = hexchars[ch & 0xf];
}
return hexstr;
}
static efi_status_t efi_to_native(char **native, const u16 *variable_name, static efi_status_t efi_to_native(char **native, const u16 *variable_name,
efi_guid_t *vendor) const efi_guid_t *vendor)
{ {
size_t len; size_t len;
char *pos; char *pos;
@ -116,6 +81,15 @@ static efi_status_t efi_to_native(char **native, const u16 *variable_name,
return EFI_SUCCESS; return EFI_SUCCESS;
} }
/**
* prefix() - skip over prefix
*
* Skip over a prefix string.
*
* @str: string with prefix
* @prefix: prefix string
* Return: string without prefix, or NULL if prefix not found
*/
static const char *prefix(const char *str, const char *prefix) static const char *prefix(const char *str, const char *prefix)
{ {
size_t n = strlen(prefix); size_t n = strlen(prefix);
@ -124,7 +98,16 @@ static const char *prefix(const char *str, const char *prefix)
return NULL; return NULL;
} }
/* parse attributes part of variable value, if present: */ /**
* parse_attr() - decode attributes part of variable value
*
* Convert the string encoded attributes of a UEFI variable to a bit mask.
* TODO: Several attributes are not supported.
*
* @str: value of U-Boot variable
* @attrp: pointer to UEFI attributes
* Return: pointer to remainder of U-Boot variable value
*/
static const char *parse_attr(const char *str, u32 *attrp) static const char *parse_attr(const char *str, u32 *attrp)
{ {
u32 attr = 0; u32 attr = 0;
@ -162,10 +145,24 @@ static const char *parse_attr(const char *str, u32 *attrp)
return str; return str;
} }
/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetVariable.28.29 */ /**
efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor, * efi_efi_get_variable() - retrieve value of a UEFI variable
u32 *attributes, efi_uintn_t *data_size, *
void *data) * This function implements the GetVariable runtime service.
*
* See the Unified Extensible Firmware Interface (UEFI) specification for
* details.
*
* @variable_name: name of the variable
* @vendor: vendor GUID
* @attributes: attributes of the variable
* @data_size: size of the buffer to which the variable value is copied
* @data: buffer to which the variable value is copied
* Return: status code
*/
efi_status_t EFIAPI efi_get_variable(u16 *variable_name,
const efi_guid_t *vendor, u32 *attributes,
efi_uintn_t *data_size, void *data)
{ {
char *native_name; char *native_name;
efi_status_t ret; efi_status_t ret;
@ -195,7 +192,7 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor,
in_size = *data_size; in_size = *data_size;
if ((s = prefix(val, "(blob)"))) { if ((s = prefix(val, "(blob)"))) {
unsigned len = strlen(s); size_t len = strlen(s);
/* number of hexadecimal digits must be even */ /* number of hexadecimal digits must be even */
if (len & 1) if (len & 1)
@ -211,7 +208,7 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor,
if (!data) if (!data)
return EFI_EXIT(EFI_INVALID_PARAMETER); return EFI_EXIT(EFI_INVALID_PARAMETER);
if (hex2mem(data, s, len) != len) if (hex2bin(data, s, len))
return EFI_EXIT(EFI_DEVICE_ERROR); return EFI_EXIT(EFI_DEVICE_ERROR);
debug("%s: got value: \"%s\"\n", __func__, s); debug("%s: got value: \"%s\"\n", __func__, s);
@ -241,20 +238,182 @@ efi_status_t EFIAPI efi_get_variable(u16 *variable_name, efi_guid_t *vendor,
return EFI_EXIT(EFI_SUCCESS); return EFI_EXIT(EFI_SUCCESS);
} }
/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#GetNextVariableName.28.29 */ static char *efi_variables_list;
efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size, static char *efi_cur_variable;
u16 *variable_name,
efi_guid_t *vendor)
{
EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor);
return EFI_EXIT(EFI_DEVICE_ERROR); /**
* parse_uboot_variable() - parse a u-boot variable and get uefi-related
* information
* @variable: whole data of u-boot variable (ie. name=value)
* @variable_name_size: size of variable_name buffer in byte
* @variable_name: name of uefi variable in u16, null-terminated
* @vendor: vendor's guid
* @attributes: attributes
*
* A uefi variable is encoded into a u-boot variable as described above.
* This function parses such a u-boot variable and retrieve uefi-related
* information into respective parameters. In return, variable_name_size
* is the size of variable name including NULL.
*
* Return: EFI_SUCCESS if parsing is OK, EFI_NOT_FOUND when
the entire variable list has been returned,
otherwise non-zero status code
*/
static efi_status_t parse_uboot_variable(char *variable,
efi_uintn_t *variable_name_size,
u16 *variable_name,
const efi_guid_t *vendor,
u32 *attributes)
{
char *guid, *name, *end, c;
unsigned long name_len;
u16 *p;
guid = strchr(variable, '_');
if (!guid)
return EFI_INVALID_PARAMETER;
guid++;
name = strchr(guid, '_');
if (!name)
return EFI_INVALID_PARAMETER;
name++;
end = strchr(name, '=');
if (!end)
return EFI_INVALID_PARAMETER;
name_len = end - name;
if (*variable_name_size < (name_len + 1)) {
*variable_name_size = name_len + 1;
return EFI_BUFFER_TOO_SMALL;
}
end++; /* point to value */
/* variable name */
p = variable_name;
utf8_utf16_strncpy(&p, name, name_len);
variable_name[name_len] = 0;
*variable_name_size = name_len + 1;
/* guid */
c = *(name - 1);
*(name - 1) = '\0'; /* guid need be null-terminated here */
uuid_str_to_bin(guid, (unsigned char *)vendor, UUID_STR_FORMAT_GUID);
*(name - 1) = c;
/* attributes */
parse_attr(end, attributes);
return EFI_SUCCESS;
} }
/* http://wiki.phoenix.com/wiki/index.php/EFI_RUNTIME_SERVICES#SetVariable.28.29 */ /**
efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor, * efi_get_next_variable_name() - enumerate the current variable names
u32 attributes, efi_uintn_t data_size, * @variable_name_size: size of variable_name buffer in byte
void *data) * @variable_name: name of uefi variable's name in u16
* @vendor: vendor's guid
*
* This function implements the GetNextVariableName service.
*
* See the Unified Extensible Firmware Interface (UEFI) specification for
* details: http://wiki.phoenix.com/wiki/index.php/
* EFI_RUNTIME_SERVICES#GetNextVariableName.28.29
*
* Return: status code
*/
efi_status_t EFIAPI efi_get_next_variable_name(efi_uintn_t *variable_name_size,
u16 *variable_name,
const efi_guid_t *vendor)
{
char *native_name, *variable;
ssize_t name_len, list_len;
char regex[256];
char * const regexlist[] = {regex};
u32 attributes;
int i;
efi_status_t ret;
EFI_ENTRY("%p \"%ls\" %pUl", variable_name_size, variable_name, vendor);
if (!variable_name_size || !variable_name || !vendor)
EFI_EXIT(EFI_INVALID_PARAMETER);
if (variable_name[0]) {
/* check null-terminated string */
for (i = 0; i < *variable_name_size; i++)
if (!variable_name[i])
break;
if (i >= *variable_name_size)
return EFI_EXIT(EFI_INVALID_PARAMETER);
/* search for the last-returned variable */
ret = efi_to_native(&native_name, variable_name, vendor);
if (ret)
return EFI_EXIT(ret);
name_len = strlen(native_name);
for (variable = efi_variables_list; variable && *variable;) {
if (!strncmp(variable, native_name, name_len) &&
variable[name_len] == '=')
break;
variable = strchr(variable, '\n');
if (variable)
variable++;
}
free(native_name);
if (!(variable && *variable))
return EFI_EXIT(EFI_INVALID_PARAMETER);
/* next variable */
variable = strchr(variable, '\n');
if (variable)
variable++;
if (!(variable && *variable))
return EFI_EXIT(EFI_NOT_FOUND);
} else {
/*
*new search: free a list used in the previous search
*/
free(efi_variables_list);
efi_variables_list = NULL;
efi_cur_variable = NULL;
snprintf(regex, 256, "efi_.*-.*-.*-.*-.*_.*");
list_len = hexport_r(&env_htab, '\n',
H_MATCH_REGEX | H_MATCH_KEY,
&efi_variables_list, 0, 1, regexlist);
/* 1 indicates that no match was found */
if (list_len <= 1)
return EFI_EXIT(EFI_NOT_FOUND);
variable = efi_variables_list;
}
ret = parse_uboot_variable(variable, variable_name_size, variable_name,
vendor, &attributes);
return EFI_EXIT(ret);
}
/**
* efi_efi_set_variable() - set value of a UEFI variable
*
* This function implements the SetVariable runtime service.
*
* See the Unified Extensible Firmware Interface (UEFI) specification for
* details.
*
* @variable_name: name of the variable
* @vendor: vendor GUID
* @attributes: attributes of the variable
* @data_size: size of the buffer with the variable value
* @data: buffer with the variable value
* Return: status code
*/
efi_status_t EFIAPI efi_set_variable(u16 *variable_name,
const efi_guid_t *vendor, u32 attributes,
efi_uintn_t data_size, const void *data)
{ {
char *native_name = NULL, *val = NULL, *s; char *native_name = NULL, *val = NULL, *s;
efi_status_t ret = EFI_SUCCESS; efi_status_t ret = EFI_SUCCESS;
@ -301,7 +460,10 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor,
s = val; s = val;
/* store attributes: */ /*
* store attributes
* TODO: several attributes are not supported
*/
attributes &= (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS); attributes &= (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS);
s += sprintf(s, "{"); s += sprintf(s, "{");
while (attributes) { while (attributes) {
@ -320,7 +482,7 @@ efi_status_t EFIAPI efi_set_variable(u16 *variable_name, efi_guid_t *vendor,
/* store payload: */ /* store payload: */
s += sprintf(s, "(blob)"); s += sprintf(s, "(blob)");
s = mem2hex(s, data, data_size); s = bin2hex(s, data, data_size);
*s = '\0'; *s = '\0';
debug("%s: setting: %s=%s\n", __func__, native_name, val); debug("%s: setting: %s=%s\n", __func__, native_name, val);

View file

@ -17,30 +17,6 @@ static const efi_guid_t fdt_guid = EFI_FDT_GUID;
static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID; static const efi_guid_t acpi_guid = EFI_ACPI_TABLE_GUID;
static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID; static const efi_guid_t smbios_guid = SMBIOS_TABLE_GUID;
/**
* hw_memcmp() - compare memory areas
*
* @buf1: pointer to first area
* @buf2: pointer to second area
* @length: number of bytes to compare
* Return: 0 if both memory areas are the same, otherwise the sign of the
* result value is the same as the sign of ghe difference between
* the first differing pair of bytes taken as u8.
*/
static int hw_memcmp(const void *buf1, const void *buf2, size_t length)
{
const u8 *pos1 = buf1;
const u8 *pos2 = buf2;
for (; length; --length) {
if (*pos1 != *pos2)
return *pos1 - *pos2;
++pos1;
++pos2;
}
return 0;
}
/** /**
* efi_main() - entry point of the EFI application. * efi_main() - entry point of the EFI application.
* *
@ -88,15 +64,15 @@ efi_status_t EFIAPI efi_main(efi_handle_t handle,
} }
/* Find configuration tables */ /* Find configuration tables */
for (i = 0; i < systable->nr_tables; ++i) { for (i = 0; i < systable->nr_tables; ++i) {
if (!hw_memcmp(&systable->tables[i].guid, &fdt_guid, if (!memcmp(&systable->tables[i].guid, &fdt_guid,
sizeof(efi_guid_t))) sizeof(efi_guid_t)))
con_out->output_string con_out->output_string
(con_out, L"Have device tree\r\n"); (con_out, L"Have device tree\r\n");
if (!hw_memcmp(&systable->tables[i].guid, &acpi_guid, if (!memcmp(&systable->tables[i].guid, &acpi_guid,
sizeof(efi_guid_t))) sizeof(efi_guid_t)))
con_out->output_string con_out->output_string
(con_out, L"Have ACPI 2.0 table\r\n"); (con_out, L"Have ACPI 2.0 table\r\n");
if (!hw_memcmp(&systable->tables[i].guid, &smbios_guid, if (!memcmp(&systable->tables[i].guid, &smbios_guid,
sizeof(efi_guid_t))) sizeof(efi_guid_t)))
con_out->output_string con_out->output_string
(con_out, L"Have SMBIOS table\r\n"); (con_out, L"Have SMBIOS table\r\n");

View file

@ -6,9 +6,9 @@
# object inclusion implicitly depends on it # object inclusion implicitly depends on it
CFLAGS_efi_selftest_miniapp_exit.o := $(CFLAGS_EFI) -Os -ffreestanding CFLAGS_efi_selftest_miniapp_exit.o := $(CFLAGS_EFI) -Os -ffreestanding
CFLAGS_REMOVE_efi_selftest_miniapp_exit.o := $(CFLAGS_NON_EFI) -Os CFLAGS_REMOVE_efi_selftest_miniapp_exit.o := $(CFLAGS_NON_EFI)
CFLAGS_efi_selftest_miniapp_return.o := $(CFLAGS_EFI) -Os -ffreestanding CFLAGS_efi_selftest_miniapp_return.o := $(CFLAGS_EFI) -Os -ffreestanding
CFLAGS_REMOVE_efi_selftest_miniapp_return.o := $(CFLAGS_NON_EFI) -Os CFLAGS_REMOVE_efi_selftest_miniapp_return.o := $(CFLAGS_NON_EFI)
obj-y += \ obj-y += \
efi_selftest.o \ efi_selftest.o \
@ -40,14 +40,15 @@ efi_selftest_variables.o \
efi_selftest_watchdog.o efi_selftest_watchdog.o
obj-$(CONFIG_CPU_V7) += efi_selftest_unaligned.o obj-$(CONFIG_CPU_V7) += efi_selftest_unaligned.o
obj-$(CONFIG_EFI_LOADER_HII) += efi_selftest_hii.o
ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy) ifeq ($(CONFIG_BLK)$(CONFIG_PARTITIONS),yy)
obj-y += efi_selftest_block_device.o obj-y += efi_selftest_block_device.o
endif endif
# TODO: As of v2018.01 the relocation code for the EFI application cannot # TODO: As of v2019.01 the relocation code for the EFI application cannot
# be built on x86_64. # be built on ARMv7-M, Sandbox, and x86_64.
ifeq ($(CONFIG_X86_64)$(CONFIG_SANDBOX),) ifeq ($(CONFIG_SANDBOX)$(CONFIG_CPU_V7M)$(CONFIG_X86_64),)
obj-y += \ obj-y += \
efi_selftest_startimage_exit.o \ efi_selftest_startimage_exit.o \

View file

@ -387,7 +387,7 @@ static int execute(void)
} }
/* Read file */ /* Read file */
ret = root->open(root, &file, (s16 *)L"hello.txt", EFI_FILE_MODE_READ, ret = root->open(root, &file, L"hello.txt", EFI_FILE_MODE_READ,
0); 0);
if (ret != EFI_SUCCESS) { if (ret != EFI_SUCCESS) {
efi_st_error("Failed to open file\n"); efi_st_error("Failed to open file\n");
@ -431,7 +431,7 @@ static int execute(void)
#ifdef CONFIG_FAT_WRITE #ifdef CONFIG_FAT_WRITE
/* Write file */ /* Write file */
ret = root->open(root, &file, (s16 *)L"u-boot.txt", EFI_FILE_MODE_READ | ret = root->open(root, &file, L"u-boot.txt", EFI_FILE_MODE_READ |
EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0); EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE, 0);
if (ret != EFI_SUCCESS) { if (ret != EFI_SUCCESS) {
efi_st_error("Failed to open file\n"); efi_st_error("Failed to open file\n");
@ -463,7 +463,7 @@ static int execute(void)
/* Verify file */ /* Verify file */
boottime->set_mem(buf, sizeof(buf), 0); boottime->set_mem(buf, sizeof(buf), 0);
ret = root->open(root, &file, (s16 *)L"u-boot.txt", EFI_FILE_MODE_READ, ret = root->open(root, &file, L"u-boot.txt", EFI_FILE_MODE_READ,
0); 0);
if (ret != EFI_SUCCESS) { if (ret != EFI_SUCCESS) {
efi_st_error("Failed to open file\n"); efi_st_error("Failed to open file\n");

View file

@ -147,20 +147,20 @@ static int execute(void)
return EFI_ST_FAILURE; return EFI_ST_FAILURE;
} }
ret = boottime->set_timer(event_notify, EFI_TIMER_STOP, 0); ret = boottime->set_timer(event_notify, EFI_TIMER_STOP, 0);
if (index != 0) { if (ret != EFI_SUCCESS) {
efi_st_error("Could not cancel timer\n"); efi_st_error("Could not cancel timer\n");
return EFI_ST_FAILURE; return EFI_ST_FAILURE;
} }
/* Set 10 ms timer */ /* Set 10 ms timer */
timer_ticks = 0; timer_ticks = 0;
ret = boottime->set_timer(event_notify, EFI_TIMER_RELATIVE, 100000); ret = boottime->set_timer(event_notify, EFI_TIMER_RELATIVE, 100000);
if (index != 0) { if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n"); efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE; return EFI_ST_FAILURE;
} }
/* Set 100 ms timer */ /* Set 100 ms timer */
ret = boottime->set_timer(event_wait, EFI_TIMER_PERIODIC, 1000000); ret = boottime->set_timer(event_wait, EFI_TIMER_PERIODIC, 1000000);
if (index != 0) { if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n"); efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE; return EFI_ST_FAILURE;
} }

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,453 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* This file's test data is derived from UEFI SCT.
* The original copyright is attached below.
*/
/*
* Copyright 2006 - 2016 Unified EFI, Inc.<BR>
* Copyright (c) 2010 - 2016, Intel Corporation. All rights reserved.<BR>
*
* This program and the accompanying materials
* are licensed and made available under the terms and conditions of the BSD
* License which accompanies this distribution. The full text of the license
* may be found at
* http://opensource.org/licenses/bsd-license.php
*
* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
*/
#include <efi.h>
#ifdef NOT_USED
/*
* TODO: These macro's are not used as they appear only in
* "#ifdef NOT_USED" clauses. In the future, define them elsewhere.
*/
/* HII form */
#define EFI_IFR_AND_OP 0x15
#define EFI_IFR_END_OP 0x29
#define EFI_IFR_BITWISE_AND_OP 0x35
/* HII image */
#define EFI_HII_IIBT_END 0x00
#define EFI_HII_IIBT_IMAGE_1BIT 0x10
#endif
/* HII keyboard layout */
#define EFI_NULL_MODIFIER 0x0000
u8 packagelist1[] = {
// EFI_HII_PACKAGE_LIST_HEADER, length = 20
// SimpleFont, Font, GUID, Form, String, Image, DevicePath,
// (74) (110) 20 (8) 78 (67) (8)
// KeyboardLayout, End
// 192 4
0x89, 0xcd, 0xab, 0x03, 0xf4, 0x03, 0x44, 0x70,
0x81, 0xde, 0x99, 0xb1, 0x81, 0x20, 0xf7, 0x68, //16: guid
0x3a, 0x01, 0x00, 0x00, // 4: total 314(0x13a)
#ifdef NOT_USED /* TODO: simple font package not implemented yet */
//
// Simple Font Package 1, length = 74
//
0x4A, 0x00, 0x00,
EFI_HII_PACKAGE_SIMPLE_FONTS,
1, 0,
1, 0,
0x55, 0x0, 0x1,
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
0x77, 0x0, 0x2,
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 0, 0, 0,
//
// Font Package 1, length = 110
//
0x6e, 0x00, 0x00, // 3
EFI_HII_PACKAGE_FONTS, // 1
0x5c, 0x00, 0x00, 0x00, // 4: size of header
0x5c, 0x00, 0x00, 0x00, // 4: offset
0xf1, 0x00, 0xf2, 0x00, 0xf3, 0x00, 0xf4, 0x00,
0xf5, 0x00, 0xec, 0xec, //10+2(pads)
0xff, 0x33, 0xff, 0x44, // 4: font style
0x77, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, //64
//
// Glyph block 1, length = 18
//
EFI_HII_GIBT_GLYPH_DEFAULT, // 1
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x99,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, //16: BitMapData
EFI_HII_GIBT_END, // 1
#endif
//
// Guid Package 1, length = 20
//
0x14, 0x00, 0x00, // 3
EFI_HII_PACKAGE_TYPE_GUID, // 1
0x5a, 0xc9, 0x87, 0x03, 0x3, 0xd7, 0x46, 0x23,
0xb2, 0xab, 0xd0, 0xc7, 0xdd, 0x90, 0x44, 0xf8, //16: guid
#ifdef NOT_USED /* TODO: form package not implemented yet */
//
// EFI_HII_PACKAGE_FORMS, length = 8
//
0x08, 0x00, 0x00, // 3
EFI_HII_PACKAGE_FORMS, // 1
//
// Opcode 1, length = 4
//
EFI_IFR_AND_OP,
0x82,
EFI_IFR_END_OP,
0x02,
//
#endif
// EFI_HII_PACKAGE_STRINGS, length = 78
//
0x4e, 0x00, 0x00, // 3: length(header)
EFI_HII_PACKAGE_STRINGS, // 1: type(header)
0x3c, 0x00, 0x00, 0x00, // 4: header_size
0x3c, 0x00, 0x00, 0x00, // 4: string_offset
0x00, 0x00, 0x11, 0x22, 0x44, 0x55, 0x77, 0x89, //32: language_window
0x11, 0x00, 0x11, 0x22, 0x44, 0x55, 0x87, 0x89,
0x22, 0x00, 0x11, 0x22, 0x44, 0x55, 0x77, 0x89,
0x33, 0x00, 0x11, 0x22, 0x44, 0x55, 0x77, 0x89,
0x01, 0x00, // 2: language name
0x65, 0x6e, 0x2d, 0x55, 0x53, 0x3b, 0x7a, 0x68, //14: language
0x2d, 0x48, 0x61, 0x6e, 0x74, 0x00, // "en-US;zh-Hant"
EFI_HII_SIBT_STRING_UCS2, // 1
0x45, 0x00, 0x6E, 0x00, 0x67, 0x00, 0x6C, 0x00,
0x69, 0x00, 0x73, 0x00, 0x68, 0x00, 0x00, 0x00, //16: "English"
EFI_HII_SIBT_END, // 1
#ifdef NOT_USED /* TODO: image package not implemented yet */
//
// EFI_HII_PACKAGE_IMAGES, length = 67
//
0x43, 0x00, 0x00, // 3
EFI_HII_PACKAGE_IMAGES, // 1
0x0c, 0x00, 0x00, 0x00, // 4: image info offset
0x39, 0x00, 0x00, 0x00, // 4: palette info offset
EFI_HII_IIBT_IMAGE_1BIT, // 1
0x01,
0x0b, 0x00,
0x13, 0x00,
0x80, 0x00,
0xc0, 0x00,
0xe0, 0x00,
0xf0, 0x00,
0xf8, 0x00,
0xfc, 0x00,
0xfe, 0x00,
0xff, 0x00,
0xff, 0x80,
0xff, 0xc0,
0xff, 0xe0,
0xfe, 0x00,
0xef, 0x00,
0xcf, 0x00,
0x87, 0x80,
0x07, 0x80,
0x03, 0xc0,
0x03, 0xc0,
0x01, 0x80, //43
EFI_HII_IIBT_END, // 1
0x01, 0x00,
0x06, 0x00,
0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, //10
//
// EFI_HII_PACKAGE_DEVICE_PATH, length = 8
//
0x08, 0x00, 0x00, // 3
EFI_HII_PACKAGE_DEVICE_PATH, // 1
0x01, 0x23, 0x45, 0x66, // 4: dummy device path protocol
// instance address
#endif
//
// Keyboard layout package 1, length = 192
0xc0, 0x00, 0x00, // 3: length(header)
EFI_HII_PACKAGE_KEYBOARD_LAYOUT, // 1: type(header)
0x02, 0x00, // 2: LayoutCount
//
// Layout 1, length = 93
//
0x5d, 0x00, // 2: layout_length
0x95, 0xe4, 0x40, 0x8d, 0xaa, 0xe2, 0x6f, 0x4c,
0x89, 0x70, 0x68, 0x85, 0x09, 0xee, 0xc7, 0xd2, //16: guid
0x37, 0x00, 0x00, 0x00, // 4: layout_descriptor_
// string_offset
0x02, // 1: descriptor_count
//
// Descriptor 1, length = 16
//
49, 0x00, 0x00, 0x00, // 4: key (EfiKeyD1)
'q', 0x00, // 2: unicode
'Q', 0x00, // 2: shifted_unicode
0x00, 0x00, // 2: alt_gr_unicode
0x00, 0x00, // 2: shifted_alt_gr_unicode
EFI_NULL_MODIFIER, 0x00, // 2: modifier
0x03, 0x00, // 2: affected_attribute
//
// Descriptor 2, length = 16
//
50, 0x00, 0x00, 0x00, // 4: key (EfiKeyD2)
'w', 0x00, // 2: unicode
'W', 0x00, // 2: shifted_unicode
0x00, 0x00, // 2: alt_gr_unicode
0x00, 0x00, // 2: shifted_alt_gr_unicode
EFI_NULL_MODIFIER, 0x00, // 2: modifier
0x3, 0x0, // 2: affected_attribute
//
// EFI_DESCRIPTOR_STRING_BUNDLE, length = 38
//
0x01, 0x00, // 2: DescriptionCount
'e', 0x0, 'n', 0x0, '-', 0x0, 'U', 0x0, 'S', 0x0,
//10: RFC3066 language code
' ', 0x0, // 2: Space
'S', 0x0, 'i', 0x0, 'm', 0x0, 'p', 0x0, 'l', 0x0, 'e', 0x0,
'1', 0x0, 'o', 0x0, 'n', 0x0, 'l', 0x0, 'y', 0x0, '\0', 0x0,
//24: DescriptionString
//
// Layout 2, length = 93
//
0x5d, 0x00, // 2: layout_length
0x3e, 0x0b, 0xe6, 0x2a, 0xd6, 0xb9, 0xd8, 0x49,
0x9a, 0x16, 0xc2, 0x48, 0xf1, 0xeb, 0xa8, 0xdb, //16: guid
0x37, 0x00, 0x00, 0x00, // 4: layout_descriptor_
// string_offset
0x02, // 1 Descriptor count
//
// Descriptor 1, length = 16
//
51, 0x0, 0x0, 0x0, // 4: key (EfiKeyD3)
'e', 0x00, // 2: unicode
'E', 0x00, // 2: shifted_unicode
0x00, 0x00, // 2: alt_gr_unicode
0x00, 0x00, // 2: shifted_alt_gr_unicode
EFI_NULL_MODIFIER, 0x0, // 2: modifier
0x3, 0x0, // 2: affected_attribute
//
// Descriptor 2, length = 16
//
52, 0x0, 0x0, 0x0, // 4: key (EfiKeyD4)
'r', 0x00, // 2: unicode
'R', 0x00, // 2: shifted_unicode
0x00, 0x00, // 2: alt_gr_unicode
0x00, 0x00, // 2: shifted_alt_gr_unicode
EFI_NULL_MODIFIER, 0x0, // 2: modifier
0x3, 0x0, // 2: affected_attribute
//
// EFI_DESCRIPTOR_STRING_BUNDLE, length = 38
//
0x01, 0x00, // 2: DescriptionCount
'e', 0x0, 'n', 0x0, '-', 0x0, 'U', 0x0, 'S', 0x0,
//10: RFC3066 language code
' ', 0x0, // 2: Space
'S', 0x0, 'i', 0x0, 'm', 0x0, 'p', 0x0, 'l', 0x0, 'e', 0x0,
'2', 0x0, 'o', 0x0, 'n', 0x0, 'l', 0x0, 'y', 0x0, '\0', 0x0,
//24: DescriptionString
//
// End of package list, length = 4
//
0x4, 0x00, 0x00,
EFI_HII_PACKAGE_END
};
u8 packagelist2[] = {
// EFI_HII_PACKAGE_LIST_HEADER, length = 20
// SimpleFont, Font, GUID, KeyboardLayout, Form, End
// (74) (122) 20 192 (8) 4
0xd3, 0xde, 0x85, 0x86, 0xce, 0x1b, 0xf3, 0x43,
0xa2, 0x0c, 0xa3, 0x06, 0xec, 0x69, 0x72, 0xdd, //16
0xec, 0x00, 0x00, 0x00, // 4: total 236(0xec)
#ifdef NOT_USED /* TODO: simple font package not implemented yet */
//
// Simple Font Package 2, length = 74
//
0x4A, 0x00, 0x00, // 3
EFI_HII_PACKAGE_SIMPLE_FONTS, // 1
1, 0, // 2
1, 0, // 2
0x33, 0x0, 0, 1, 2, 3, 4, 5, 0, 7, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, //22
0x44, 0x0, 0x2, 2, 3, 4, 5, 6, 0, 8, 9,
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, //22
3, 4, 5, 6, 7, 8, 9, 10, 11, 9, 13,
14, 15, 16, 17, 18, 19, 20, 21, 0, 0, 0, //22
//
// Font Package 2, length = 122
//
0x7A, 0x00, 0x00, // 3
EFI_HII_PACKAGE_FONTS, // 1
0x5C, 0x00, 0x00, 0x00, // 4: size of header
0x5C, 0x00, 0x00, 0x00, // 4: dummy offset
0xf1, 0x00, 0xf2, 0x00, 0xf3, 0x00, 0xf4, 0x00,
0xf5, 0x00, 0xec, 0xec, //10+2(pads)
0xff, 0x11, 0xff, 0x22, // 4: font style
0x99, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, //64
//
// Glyph block 1, length = 30
//
EFI_HII_GIBT_GLYPH, // 1
0xf1, 0x00, 0xf2, 0x00, 0xf3, 0x00, 0xf4, 0x00,
0xf5, 0x00, //10
0xff, 0x01, // 2
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, //16: BitMapData
EFI_HII_GIBT_END, // 1
#endif
//
// Guid Package 1, length = 20
//
0x14, 0x00, 0x00, // 3
EFI_HII_PACKAGE_TYPE_GUID, // 1
0x5a, 0xc9, 0x87, 0x03, 0x3, 0xd7, 0x46, 0x23,
0xb2, 0xab, 0xd0, 0xc7, 0xdd, 0x90, 0x44, 0xf8, //16: guid
//
// Keyboard layout package 2, length = 192
0xc0, 0x00, 0x00, // 3
EFI_HII_PACKAGE_KEYBOARD_LAYOUT, // 1
0x02, 0x00, //0xec, 0xec, // 2: LayoutCount
//
// Layout 1, length = 93
//
0x5d, 0x00, // 2: layout_length
0x1f, 0x6a, 0xf5, 0xe0, 0x6b, 0xdf, 0x7e, 0x4a,
0xa3, 0x9a, 0xe7, 0xa5, 0x19, 0x15, 0x45, 0xd6,//16: guid
0x37, 0x00, 0x00, 0x00, // 4: layout_descriptor
// string offset
0x02, // 1: descriptor_count
//
// Descriptor 1, length = 16
//
32, 0x00, 0x00, 0x00, // 4: key (EfiKeyC1)
'a', 0x00, // 2: unicode
'A', 0x00, // 2: shifted_unicode
0x00, 0x00, // 2: alt_gr_unicode
0x00, 0x00, // 2: shifted_alt_gr_unic
EFI_NULL_MODIFIER, 0x00, // 2: modifier
0x03, 0x00, // 2: affected_attribute
//
// Descriptor 2, length = 16
//
33 /*EfiKeyC2*/, 0x00, 0x00, 0x00,
's', 0x00,
'S', 0x00,
0x00, 0x00,
0x00, 0x00,
EFI_NULL_MODIFIER, 0x00,
0x3, 0x0,
//
// EFI_DESCRIPTOR_STRING_BUNDLE, length = 38
//
0x01, 0x00, // 2: DescriptionCount
'e', 0x0, 'n', 0x0, '-', 0x0, 'U', 0x0, 'S', 0x0,
//10: RFC3066 language code
' ', 0x0, // 2: Space
'S', 0x0, 'i', 0x0, 'm', 0x0, 'p', 0x0, 'l', 0x0, 'e', 0x0,
'3', 0x0, 'o', 0x0, 'n', 0x0, 'l', 0x0, 'y', 0x0, '\0', 0x0,
//24: DescriptionString
//
// Layout 2, length = 93
//
0x5d, 0x00, // 2: layout_length
0xc9, 0x6a, 0xbe, 0x47, 0xcc, 0x54, 0xf9, 0x46,
0xa2, 0x62, 0xd5, 0x3b, 0x25, 0x6a, 0xc, 0x34, //16: guid
0x37, 0x00, 0x00, 0x00, // 4: layout_descriptor
// string_offset
0x02, // 1: descriptor_count
//
// Descriptor 1, length = 16
//
34 /*EfiKeyC3*/, 0x0, 0x0, 0x0,
'd', 0x00,
'D', 0x00,
0x00, 0x00,
0x00, 0x00,
EFI_NULL_MODIFIER, 0x0,
0x3, 0x0,
//
// Descriptor 2, length = 16
//
35 /*EfiKeyC4*/, 0x0, 0x0, 0x0,
'e', 0x00,
'E', 0x00,
0x00, 0x00,
0x00, 0x00,
EFI_NULL_MODIFIER, 0x0,
0x3, 0x0,
//
// EFI_DESCRIPTOR_STRING_BUNDLE, length = 38
//
0x01, 0x00, // 2: DescriptionCount
'e', 0x0, 'n', 0x0, '-', 0x0, 'U', 0x0, 'S', 0x0,
//10: RFC3066 language code
' ', 0x0, // 2: Space
'S', 0x0, 'i', 0x0, 'm', 0x0, 'p', 0x0, 'l', 0x0, 'e', 0x0,
'4', 0x0, 'o', 0x0, 'n', 0x0, 'l', 0x0, 'y', 0x0, '\0', 0x0,
//24: DescriptionString
#ifdef NOT_USED /* TODO: form package not implemented yet */
//
// EFI_HII_PACKAGE_FORMS, length = 8
//
0x08, 0x00, 0x00, // 3
EFI_HII_PACKAGE_FORMS, // 1
//
// Opcode 1
//
EFI_IFR_BITWISE_AND_OP, // 1
0x02, // 1
EFI_IFR_END_OP, // 1
0x02, // 1
#endif
//
// End of package list, length = 4
//
0x4, 0x00, 0x00, // 3
EFI_HII_PACKAGE_END // 1
};
efi_guid_t packagelist_guid1 =
EFI_GUID(0x03abcd89, 0x03f4, 0x7044,
0x81, 0xde, 0x99, 0xb1, 0x81, 0x20, 0xf7, 0x68);
efi_guid_t packagelist_guid2 =
EFI_GUID(0x8685ded3, 0x1bce, 0x43f3,
0xa2, 0x0c, 0xa3, 0x06, 0xec, 0x69, 0x72, 0xdd);
efi_guid_t kb_layout_guid11 =
EFI_GUID(0x8d40e495, 0xe2aa, 0x4c6f,
0x89, 0x70, 0x68, 0x85, 0x09, 0xee, 0xc7, 0xd2);
efi_guid_t kb_layout_guid12 =
EFI_GUID(0x2ae60b3e, 0xb9d6, 0x49d8,
0x9a, 0x16, 0xc2, 0x48, 0xf1, 0xeb, 0xa8, 0xdb);
efi_guid_t kb_layout_guid21 =
EFI_GUID(0xe0f56a1f, 0xdf6b, 0x4a7e,
0xa3, 0x9a, 0xe7, 0xa5, 0x19, 0x15, 0x45, 0xd6);
efi_guid_t kb_layout_guid22 =
EFI_GUID(0x47be6ac9, 0x54cc, 0x46f9,
0xa2, 0x62, 0xd5, 0x3b, 0x25, 0x6a, 0x0c, 0x34);
efi_guid_t package_guid =
EFI_GUID(0x0387c95a, 0xd703, 0x2346,
0xb2, 0xab, 0xd0, 0xc7, 0xdd, 0x90, 0x44, 0xf8);

View file

@ -427,4 +427,12 @@ EFI_UNIT_TEST(snp) = {
.setup = setup, .setup = setup,
.execute = execute, .execute = execute,
.teardown = teardown, .teardown = teardown,
#ifdef CONFIG_SANDBOX
/*
* Running this test on the sandbox requires setting environment
* variable ethact to a network interface connected to a DHCP server and
* ethrotate to 'no'.
*/
.on_request = true,
#endif
}; };

View file

@ -151,7 +151,7 @@ static int execute(void)
return EFI_ST_FAILURE; return EFI_ST_FAILURE;
} }
ret = boottime->set_timer(event_notify, EFI_TIMER_STOP, 0); ret = boottime->set_timer(event_notify, EFI_TIMER_STOP, 0);
if (index != 0) { if (ret != EFI_SUCCESS) {
efi_st_error("Could not cancel timer\n"); efi_st_error("Could not cancel timer\n");
return EFI_ST_FAILURE; return EFI_ST_FAILURE;
} }
@ -164,7 +164,7 @@ static int execute(void)
/* Set 10 ms timer */ /* Set 10 ms timer */
notification_count = 0; notification_count = 0;
ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC, 100000); ret = boottime->set_timer(event_notify, EFI_TIMER_PERIODIC, 100000);
if (index != 0) { if (ret != EFI_SUCCESS) {
efi_st_error("Could not set timer\n"); efi_st_error("Could not set timer\n");
return EFI_ST_FAILURE; return EFI_ST_FAILURE;
} }

View file

@ -15,10 +15,10 @@
static struct efi_boot_services *boottime; static struct efi_boot_services *boottime;
static struct efi_runtime_services *runtime; static struct efi_runtime_services *runtime;
static efi_guid_t guid_vendor0 = static const efi_guid_t guid_vendor0 =
EFI_GUID(0x67029eb5, 0x0af2, 0xf6b1, EFI_GUID(0x67029eb5, 0x0af2, 0xf6b1,
0xda, 0x53, 0xfc, 0xb5, 0x66, 0xdd, 0x1c, 0xe6); 0xda, 0x53, 0xfc, 0xb5, 0x66, 0xdd, 0x1c, 0xe6);
static efi_guid_t guid_vendor1 = static const efi_guid_t guid_vendor1 =
EFI_GUID(0xff629290, 0x1fc1, 0xd73f, EFI_GUID(0xff629290, 0x1fc1, 0xd73f,
0x8f, 0xb1, 0x32, 0xf9, 0x0c, 0xa0, 0x42, 0xea); 0x8f, 0xb1, 0x32, 0xf9, 0x0c, 0xa0, 0x42, 0xea);
@ -141,19 +141,22 @@ static int execute(void)
if (ret == EFI_NOT_FOUND) if (ret == EFI_NOT_FOUND)
break; break;
if (ret != EFI_SUCCESS) { if (ret != EFI_SUCCESS) {
efi_st_todo("GetNextVariableName failed\n"); efi_st_error("GetNextVariableName failed (%u)\n",
break; (unsigned int)ret);
return EFI_ST_FAILURE;
} }
if (!efi_st_memcmp(&guid, &guid_vendor0, sizeof(efi_guid_t)) && if (!efi_st_memcmp(&guid, &guid_vendor0, sizeof(efi_guid_t)) &&
!efi_st_strcmp_16_8(varname, "efi_st_var0")) !efi_st_strcmp_16_8(varname, "efi_st_var0"))
flag |= 2; flag |= 1;
if (!efi_st_memcmp(&guid, &guid_vendor1, sizeof(efi_guid_t)) && if (!efi_st_memcmp(&guid, &guid_vendor1, sizeof(efi_guid_t)) &&
!efi_st_strcmp_16_8(varname, "efi_st_var1")) !efi_st_strcmp_16_8(varname, "efi_st_var1"))
flag |= 2; flag |= 2;
} }
if (flag != 3) if (flag != 3) {
efi_st_todo( efi_st_error(
"GetNextVariableName did not return all variables\n"); "GetNextVariableName did not return all variables\n");
return EFI_ST_FAILURE;
}
/* Delete variable 1 */ /* Delete variable 1 */
ret = runtime->set_variable(L"efi_st_var1", &guid_vendor1, ret = runtime->set_variable(L"efi_st_var1", &guid_vendor1,
0, 0, NULL); 0, 0, NULL);

View file

@ -279,13 +279,17 @@ static char *string(char *buf, char *end, char *s, int field_width,
static char *string16(char *buf, char *end, u16 *s, int field_width, static char *string16(char *buf, char *end, u16 *s, int field_width,
int precision, int flags) int precision, int flags)
{ {
u16 *str = s ? s : L"<NULL>"; const u16 *str = s ? s : L"<NULL>";
ssize_t len = utf16_strnlen(str, precision); ssize_t i, len = utf16_strnlen(str, precision);
if (!(flags & LEFT)) if (!(flags & LEFT))
for (; len < field_width; --field_width) for (; len < field_width; --field_width)
ADDCH(buf, ' '); ADDCH(buf, ' ');
utf16_utf8_strncpy(&buf, str, len); for (i = 0; i < len && buf + utf16_utf8_strnlen(str, 1) <= end; ++i) {
s32 s = utf16_get(&str);
utf8_put(s, &buf);
}
for (; len < field_width; --field_width) for (; len < field_width; --field_width)
ADDCH(buf, ' '); ADDCH(buf, ' ');
return buf; return buf;

View file

@ -389,7 +389,7 @@ $(obj)/efi_reloc.o: $(srctree)/arch/$(ARCH)/lib/$(EFI_RELOC:.o=.c) $(recordmcoun
$(call cmd,force_checksrc) $(call cmd,force_checksrc)
$(call if_changed_rule,cc_o_c) $(call if_changed_rule,cc_o_c)
$(obj)/%_efi.so: $(obj)/%.o $(obj)/efi_crt0.o $(obj)/efi_reloc.o $(obj)/%_efi.so: $(obj)/%.o $(obj)/efi_crt0.o $(obj)/efi_reloc.o $(obj)/../efi_loader/efi_freestanding.o
$(call cmd,efi_ld) $(call cmd,efi_ld)
# ACPI # ACPI

View file

@ -50,6 +50,29 @@ static const char j1[] = {0x6a, 0x31, 0xa1, 0x6c, 0x00};
static const char j2[] = {0x6a, 0x32, 0xc3, 0xc3, 0x6c, 0x00}; static const char j2[] = {0x6a, 0x32, 0xc3, 0xc3, 0x6c, 0x00};
static const char j3[] = {0x6a, 0x33, 0xf0, 0x90, 0xf0, 0x00}; static const char j3[] = {0x6a, 0x33, 0xf0, 0x90, 0xf0, 0x00};
static int ut_u16_strdup(struct unit_test_state *uts)
{
u16 *copy = u16_strdup(c4);
ut_assert(copy != c4);
ut_assert(!memcmp(copy, c4, sizeof(c4)));
free(copy);
return 0;
}
UNICODE_TEST(ut_u16_strdup);
static int ut_u16_strcpy(struct unit_test_state *uts)
{
u16 *r;
u16 copy[10];
r = u16_strcpy(copy, c1);
ut_assert(r == copy);
ut_assert(!memcmp(copy, c1, sizeof(c1)));
return 0;
}
UNICODE_TEST(ut_u16_strcpy);
/* U-Boot uses UTF-16 strings in the EFI context only. */ /* U-Boot uses UTF-16 strings in the EFI context only. */
#if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD) #if CONFIG_IS_ENABLED(EFI_LOADER) && !defined(API_BUILD)
static int ut_string16(struct unit_test_state *uts) static int ut_string16(struct unit_test_state *uts)