Pull request for UEFI sub-system for efi-2021-01-rc1
The following bugs in the UEFI system are resolved: * illegal free in EFI_LOAD_FILE2_PROTOCOL implementation * incorrect documentation of EFI_LOAD_FILE2_PROTOCOL implementation * output of CRC32 as decimal instead hexadecimal in unit test * use EfiReservedMemoryType for no-map reserved memory * avoid unnecessary resets in UEFI unit tests * call EFI bootmgr even without having /EFI/boot -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEEbcT5xx8ppvoGt20zxIHbvCwFGsQFAl98KaIACgkQxIHbvCwF GsSeEQ/9E8i1GyZp/rGcL6/Ui84z6ZBglUs73MfJkPJ+uI1WqY7pBVvoybciHBfX ZgAfoVLZnMmgZhPAN9kao9HtqmqeMqAjxYAKGBvjJTH+xhvAPgUA81+H0cLw7UBs XcNcchEinI6EMqGBlzrdRoLSrFyQT0ZdhEWeGoQ+clMPMZHjOqJ40DA+sUnDfdLP Ab0MxrfT7XZ4naufM2HiA9bD+qNnYMjpr/y3tX5Y4vcHYfka7Dk5/97ILcpXCwmr sBWEZISBuUHzWZydPW8nWm1P7SmT8YLfVORVetPC4Gv1ZOiNdF9s7bgPoab9lCMV sqQyoNgRDYBCvppr3xStCVbSQ+KkotyX2gHDpuG4Xq//n23QWo6qWKQc0iN5g943 aaJTn7qw9KB4HESRZPgABY/cyJIziWupLGbKdf1DnoLPxvZaOF/NR8zHiO3rLd4t F4Rg3RHI8PkQf8Yv9GSwBGP2QVFQKIQbPjaFBsGiJm2KBEC+ZAaQ0W459Bnn/pwT fGqhlzpblbFLApIoH2EXDNHxRuI/My/Wr39uN7oX3f+dfhSDxO0mbzfXBlttZYNp LgF4NnPuAPAcNXZc/O6nG2IDDTv1NqKuK5bd9nUe5PIPV/9iS9XNulrdHqsZQS9H efJHphuJ0zSvRQF5jSvzuVsxe6zWff4i4xBJCeJcaIg9Toz/lkM= =laLr -----END PGP SIGNATURE----- Merge tag 'efi-2021-01-rc1' of https://gitlab.denx.de/u-boot/custodians/u-boot-efi Pull request for UEFI sub-system for efi-2021-01-rc1 The following bugs in the UEFI system are resolved: * illegal free in EFI_LOAD_FILE2_PROTOCOL implementation * incorrect documentation of EFI_LOAD_FILE2_PROTOCOL implementation * output of CRC32 as decimal instead hexadecimal in unit test * use EfiReservedMemoryType for no-map reserved memory * avoid unnecessary resets in UEFI unit tests * call EFI bootmgr even without having /EFI/boot
This commit is contained in:
commit
5dcf7cc590
@ -135,12 +135,29 @@ done:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void efi_reserve_memory(u64 addr, u64 size)
|
||||
/**
|
||||
* efi_reserve_memory() - add reserved memory to memory map
|
||||
*
|
||||
* @addr: start address of the reserved memory range
|
||||
* @size: size of the reserved memory range
|
||||
* @nomap: indicates that the memory range shall not be accessed by the
|
||||
* UEFI payload
|
||||
*/
|
||||
static void efi_reserve_memory(u64 addr, u64 size, bool nomap)
|
||||
{
|
||||
int type;
|
||||
efi_uintn_t ret;
|
||||
|
||||
/* Convert from sandbox address space. */
|
||||
addr = (uintptr_t)map_sysmem(addr, 0);
|
||||
if (efi_add_memory_map(addr, size,
|
||||
EFI_RESERVED_MEMORY_TYPE) != EFI_SUCCESS)
|
||||
|
||||
if (nomap)
|
||||
type = EFI_RESERVED_MEMORY_TYPE;
|
||||
else
|
||||
type = EFI_BOOT_SERVICES_DATA;
|
||||
|
||||
ret = efi_add_memory_map(addr, size, type);
|
||||
if (ret != EFI_SUCCESS)
|
||||
log_err("Reserved memory mapping failed addr %llx size %llx\n",
|
||||
addr, size);
|
||||
}
|
||||
@ -166,7 +183,7 @@ static void efi_carve_out_dt_rsv(void *fdt)
|
||||
for (i = 0; i < nr_rsv; i++) {
|
||||
if (fdt_get_mem_rsv(fdt, i, &addr, &size) != 0)
|
||||
continue;
|
||||
efi_reserve_memory(addr, size);
|
||||
efi_reserve_memory(addr, size, false);
|
||||
}
|
||||
|
||||
/* process reserved-memory */
|
||||
@ -186,8 +203,13 @@ static void efi_carve_out_dt_rsv(void *fdt)
|
||||
* a size instead of a reg property.
|
||||
*/
|
||||
if (fdt_addr != FDT_ADDR_T_NONE &&
|
||||
fdtdec_get_is_enabled(fdt, subnode))
|
||||
efi_reserve_memory(fdt_addr, fdt_size);
|
||||
fdtdec_get_is_enabled(fdt, subnode)) {
|
||||
bool nomap;
|
||||
|
||||
nomap = !!fdt_getprop(fdt, subnode, "no-map",
|
||||
NULL);
|
||||
efi_reserve_memory(fdt_addr, fdt_size, nomap);
|
||||
}
|
||||
subnode = fdt_next_subnode(fdt, subnode);
|
||||
}
|
||||
}
|
||||
|
@ -56,4 +56,3 @@ CONFIG_USB=y
|
||||
CONFIG_DM_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_PCI=y
|
||||
# CONFIG_EFI_GRUB_ARM32_WORKAROUND is not set
|
||||
|
@ -123,12 +123,14 @@
|
||||
|
||||
|
||||
#define BOOTENV_SHARED_EFI \
|
||||
"boot_efi_binary=" \
|
||||
"boot_efi_bootmgr=" \
|
||||
"if fdt addr ${fdt_addr_r}; then " \
|
||||
"bootefi bootmgr ${fdt_addr_r};" \
|
||||
"else " \
|
||||
"bootefi bootmgr ${fdtcontroladdr};" \
|
||||
"fi;" \
|
||||
"bootefi bootmgr;" \
|
||||
"fi\0" \
|
||||
\
|
||||
"boot_efi_binary=" \
|
||||
"load ${devtype} ${devnum}:${distro_bootpart} " \
|
||||
"${kernel_addr_r} efi/boot/"BOOTEFI_NAME"; " \
|
||||
"if fdt addr ${fdt_addr_r}; then " \
|
||||
@ -152,6 +154,7 @@
|
||||
"run load_efi_dtb; " \
|
||||
"fi;" \
|
||||
"done;" \
|
||||
"run boot_efi_bootmgr;" \
|
||||
"if test -e ${devtype} ${devnum}:${distro_bootpart} " \
|
||||
"efi/boot/"BOOTEFI_NAME"; then " \
|
||||
"echo Found EFI removable media binary " \
|
||||
|
@ -164,6 +164,7 @@ config EFI_HAVE_RUNTIME_RESET
|
||||
|
||||
config EFI_GRUB_ARM32_WORKAROUND
|
||||
bool "Workaround for GRUB on 32bit ARM"
|
||||
default n if ARCH_QEMU
|
||||
default y
|
||||
depends on ARM && !ARM64
|
||||
help
|
||||
|
@ -47,9 +47,9 @@ static const struct efi_initrd_dp dp = {
|
||||
/**
|
||||
* get_file_size() - retrieve the size of initramfs, set efi status on error
|
||||
*
|
||||
* @dev: device to read from. i.e "mmc"
|
||||
* @part: device partition. i.e "0:1"
|
||||
* @file: name fo file
|
||||
* @dev: device to read from, e.g. "mmc"
|
||||
* @part: device partition, e.g. "0:1"
|
||||
* @file: name of file
|
||||
* @status: EFI exit code in case of failure
|
||||
*
|
||||
* Return: size of file
|
||||
@ -78,15 +78,16 @@ out:
|
||||
}
|
||||
|
||||
/**
|
||||
* load_file2() - get information about random number generation
|
||||
* efi_load_file2initrd() - load initial RAM disk
|
||||
*
|
||||
* This function implements the LoadFile service of the EFI_LOAD_FILE2_PROTOCOL
|
||||
* in order to load an initial RAM disk requested by the Linux kernel stub.
|
||||
*
|
||||
* This function implement the LoadFile2() service in order to load an initram
|
||||
* disk requested by the Linux kernel stub.
|
||||
* See the UEFI spec for details.
|
||||
*
|
||||
* @this: loadfile2 protocol instance
|
||||
* @file_path: relative path of the file. "" in this case
|
||||
* @boot_policy: must be false for Loadfile2
|
||||
* @this: EFI_LOAD_FILE2_PROTOCOL instance
|
||||
* @file_path: media device path of the file, "" in this case
|
||||
* @boot_policy: must be false
|
||||
* @buffer_size: size of allocated buffer
|
||||
* @buffer: buffer to load the file
|
||||
*
|
||||
@ -97,19 +98,20 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this,
|
||||
struct efi_device_path *file_path, bool boot_policy,
|
||||
efi_uintn_t *buffer_size, void *buffer)
|
||||
{
|
||||
const char *filespec = CONFIG_EFI_INITRD_FILESPEC;
|
||||
char *filespec;
|
||||
efi_status_t status = EFI_NOT_FOUND;
|
||||
loff_t file_sz = 0, read_sz = 0;
|
||||
char *dev, *part, *file;
|
||||
char *s;
|
||||
char *pos;
|
||||
int ret;
|
||||
|
||||
EFI_ENTRY("%p, %p, %d, %p, %p", this, file_path, boot_policy,
|
||||
buffer_size, buffer);
|
||||
|
||||
s = strdup(filespec);
|
||||
if (!s)
|
||||
filespec = strdup(CONFIG_EFI_INITRD_FILESPEC);
|
||||
if (!filespec)
|
||||
goto out;
|
||||
pos = filespec;
|
||||
|
||||
if (!this || this != &efi_lf2_protocol ||
|
||||
!buffer_size) {
|
||||
@ -128,14 +130,20 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* expect something like 'mmc 0:1 initrd.cpio.gz' */
|
||||
dev = strsep(&s, " ");
|
||||
/*
|
||||
* expect a string with three space separated parts:
|
||||
*
|
||||
* * a block device type, e.g. "mmc"
|
||||
* * a device and partition identifier, e.g. "0:1"
|
||||
* * a file path on the block device, e.g. "/boot/initrd.cpio.gz"
|
||||
*/
|
||||
dev = strsep(&pos, " ");
|
||||
if (!dev)
|
||||
goto out;
|
||||
part = strsep(&s, " ");
|
||||
part = strsep(&pos, " ");
|
||||
if (!part)
|
||||
goto out;
|
||||
file = strsep(&s, " ");
|
||||
file = strsep(&pos, " ");
|
||||
if (!file)
|
||||
goto out;
|
||||
|
||||
@ -163,28 +171,25 @@ efi_load_file2_initrd(struct efi_load_file_protocol *this,
|
||||
}
|
||||
|
||||
out:
|
||||
free(s);
|
||||
free(filespec);
|
||||
return EFI_EXIT(status);
|
||||
}
|
||||
|
||||
/**
|
||||
* efi_initrd_register() - Register a handle and loadfile2 protocol
|
||||
* efi_initrd_register() - create handle for loading initial RAM disk
|
||||
*
|
||||
* This function creates a new handle and installs a linux specific GUID
|
||||
* to handle initram disk loading during boot.
|
||||
* See the UEFI spec for details.
|
||||
* This function creates a new handle and installs a Linux specific vendor
|
||||
* device path and an EFI_LOAD_FILE_2_PROTOCOL. Linux uses the device path
|
||||
* to identify the handle and then calls the LoadFile service of the
|
||||
* EFI_LOAD_FILE_2_PROTOCOL to read the initial RAM disk.
|
||||
*
|
||||
* Return: status code
|
||||
* Return: status code
|
||||
*/
|
||||
efi_status_t efi_initrd_register(void)
|
||||
{
|
||||
efi_handle_t efi_initrd_handle = NULL;
|
||||
efi_status_t ret;
|
||||
|
||||
/*
|
||||
* Set up the handle with the EFI_LOAD_FILE2_PROTOCOL which Linux may
|
||||
* use to load the initial ramdisk.
|
||||
*/
|
||||
ret = EFI_CALL(efi_install_multiple_protocol_interfaces
|
||||
(&efi_initrd_handle,
|
||||
/* initramfs */
|
||||
|
@ -142,6 +142,27 @@ static int teardown(struct efi_unit_test *test, unsigned int *failures)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that a test requiring reset exists.
|
||||
*
|
||||
* @testname: name of the test
|
||||
* @return: test, or NULL if not found
|
||||
*/
|
||||
static bool need_reset(const u16 *testname)
|
||||
{
|
||||
struct efi_unit_test *test;
|
||||
|
||||
for (test = ll_entry_start(struct efi_unit_test, efi_unit_test);
|
||||
test < ll_entry_end(struct efi_unit_test, efi_unit_test); ++test) {
|
||||
if (testname && efi_st_strcmp_16_8(testname, test->name))
|
||||
continue;
|
||||
if (test->phase == EFI_SETUP_BEFORE_BOOTTIME_EXIT ||
|
||||
test->phase == EFI_SETUP_AFTER_BOOTTIME_EXIT)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that a test exists.
|
||||
*
|
||||
@ -290,6 +311,16 @@ efi_status_t EFIAPI efi_selftest(efi_handle_t image_handle,
|
||||
EFI_ST_SETUP | EFI_ST_EXECUTE | EFI_ST_TEARDOWN,
|
||||
&failures);
|
||||
|
||||
if (!need_reset(testname)) {
|
||||
if (failures)
|
||||
ret = EFI_PROTOCOL_ERROR;
|
||||
|
||||
/* Give feedback */
|
||||
efi_st_printc(EFI_WHITE, "\nSummary: %u failures\n\n",
|
||||
failures);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Execute mixed tests */
|
||||
efi_st_do_tests(testname, EFI_SETUP_BEFORE_BOOTTIME_EXIT,
|
||||
EFI_ST_SETUP, &failures);
|
||||
|
@ -44,25 +44,28 @@ static void mac(void *pointer, u16 **buf)
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a pointer to an u16 string
|
||||
* printx() - print hexadecimal number to an u16 string
|
||||
*
|
||||
* @pointer: pointer
|
||||
* @buf: pointer to buffer address
|
||||
* on return position of terminating zero word
|
||||
* @pointer: pointer
|
||||
* @prec: minimum number of digits to print
|
||||
* @buf: pointer to buffer address,
|
||||
* on return position of terminating zero word
|
||||
* @size: size of value to be printed in bytes
|
||||
*/
|
||||
static void pointer(void *pointer, u16 **buf)
|
||||
static void printx(u64 p, int prec, u16 **buf)
|
||||
{
|
||||
int i;
|
||||
u16 c;
|
||||
uintptr_t p = (uintptr_t)pointer;
|
||||
u16 *pos = *buf;
|
||||
|
||||
for (i = 8 * sizeof(p) - 4; i >= 0; i -= 4) {
|
||||
c = (p >> i) & 0x0f;
|
||||
c += '0';
|
||||
if (c > '9')
|
||||
c += 'a' - '9' - 1;
|
||||
*pos++ = c;
|
||||
for (i = 2 * sizeof(p) - 1; i >= 0; --i) {
|
||||
c = (p >> (4 * i)) & 0x0f;
|
||||
if (c || pos != *buf || !i || i < prec) {
|
||||
c += '0';
|
||||
if (c > '9')
|
||||
c += 'a' - '9' - 1;
|
||||
*pos++ = c;
|
||||
}
|
||||
}
|
||||
*pos = 0;
|
||||
*buf = pos;
|
||||
@ -212,7 +215,9 @@ void efi_st_printc(int color, const char *fmt, ...)
|
||||
break;
|
||||
default:
|
||||
--c;
|
||||
pointer(va_arg(args, void*), &pos);
|
||||
printx((uintptr_t)va_arg(args, void *),
|
||||
2 * sizeof(void *), &pos);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
@ -223,6 +228,10 @@ void efi_st_printc(int color, const char *fmt, ...)
|
||||
case 'u':
|
||||
uint2dec(va_arg(args, u32), prec, &pos);
|
||||
break;
|
||||
case 'x':
|
||||
printx((u64)va_arg(args, unsigned int),
|
||||
prec, &pos);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -200,7 +200,7 @@ static int execute(void)
|
||||
efi_st_error("Could not determine CRC32\n");
|
||||
return EFI_ST_FAILURE;
|
||||
}
|
||||
efi_st_printf("CRC32 %u\n", (unsigned int)crc32);
|
||||
efi_st_printf("CRC32 %.8x\n", (unsigned int)crc32);
|
||||
|
||||
status = boottime->free_pool(buf);
|
||||
if (status != EFI_SUCCESS) {
|
||||
|
@ -23,7 +23,7 @@ static u32 notify_call_count;
|
||||
static bool convert_pointer_failed;
|
||||
|
||||
/**
|
||||
* notify () - notification function
|
||||
* notify() - notification function
|
||||
*
|
||||
* This function is called when the EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE event
|
||||
* occurs. The correct output of ConvertPointer() is checked.
|
||||
|
Loading…
Reference in New Issue
Block a user