mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-14 08:57:58 +00:00
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:
commit
63f7e3fca3
50 changed files with 3984 additions and 340 deletions
|
@ -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)
|
||||||
|
|
56
arch/arm/cpu/armv7/exception_level.c
Normal file
56
arch/arm/cpu/armv7/exception_level.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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...)
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -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
|
||||||
|
|
55
arch/arm/cpu/armv8/exception_level.c
Normal file
55
arch/arm/cpu/armv8/exception_level.c
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
152
cmd/bootefi.c
152
cmd/bootefi.c
|
@ -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) {
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
*
|
*
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
90
lib/efi_loader/efi_freestanding.c
Normal file
90
lib/efi_loader/efi_freestanding.c
Normal 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
1095
lib/efi_loader/efi_hii.c
Normal file
File diff suppressed because it is too large
Load diff
146
lib/efi_loader/efi_hii_config.c
Normal file
146
lib/efi_loader/efi_hii_config.c
Normal 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
|
||||||
|
};
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
86
lib/efi_loader/efi_setup.c
Normal file
86
lib/efi_loader/efi_setup.c
Normal 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;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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 \
|
||||||
|
|
|
@ -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");
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
1035
lib/efi_selftest/efi_selftest_hii.c
Normal file
1035
lib/efi_selftest/efi_selftest_hii.c
Normal file
File diff suppressed because it is too large
Load diff
453
lib/efi_selftest/efi_selftest_hii_data.c
Normal file
453
lib/efi_selftest/efi_selftest_hii_data.c
Normal 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);
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in a new issue