diff --git a/cmd/bootefi.c b/cmd/bootefi.c index c8812b0..5fc054c 100644 --- a/cmd/bootefi.c +++ b/cmd/bootefi.c @@ -49,6 +49,11 @@ efi_status_t efi_init_obj_list(void) 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) diff --git a/include/efi_loader.h b/include/efi_loader.h index 3bf059b..2855c01 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -20,6 +20,11 @@ /* Maximum number of configuration tables */ #define EFI_MAX_CONFIGURATION_TABLES 16 +/* GUID used by the root node */ +#define U_BOOT_GUID \ + EFI_GUID(0xe61d73b9, 0xa384, 0x4acc, \ + 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, 0x62, 0x8b) + int __efi_entry_check(void); int __efi_exit_check(void); const char *__efi_nesting(void); @@ -104,6 +109,8 @@ extern const struct efi_unicode_collation_protocol uint16_t *efi_dp_str(struct efi_device_path *dp); +/* GUID of the U-Boot root node */ +extern const efi_guid_t efi_u_boot_guid; /* GUID of the EFI_BLOCK_IO_PROTOCOL */ extern const efi_guid_t efi_block_io_guid; extern const efi_guid_t efi_global_variable_guid; @@ -210,6 +217,8 @@ extern struct list_head efi_obj_list; /* List of all events */ extern struct list_head efi_events; +/* Called by bootefi to initialize root node */ +efi_status_t efi_root_node_register(void); /* Called by bootefi to initialize runtime */ efi_status_t efi_initialize_system_table(void); /* Called by bootefi to make console interface available */ diff --git a/lib/efi_loader/Makefile b/lib/efi_loader/Makefile index 7eebbc5..6703435 100644 --- a/lib/efi_loader/Makefile +++ b/lib/efi_loader/Makefile @@ -26,6 +26,7 @@ obj-y += efi_device_path_utilities.o obj-y += efi_file.o obj-y += efi_image_loader.o obj-y += efi_memory.o +obj-y += efi_root_node.o obj-y += efi_runtime.o obj-y += efi_unicode_collation.o obj-y += efi_variable.o diff --git a/lib/efi_loader/efi_boottime.c b/lib/efi_loader/efi_boottime.c index 5d93db8..b4de996 100644 --- a/lib/efi_loader/efi_boottime.c +++ b/lib/efi_loader/efi_boottime.c @@ -1514,24 +1514,6 @@ efi_status_t efi_setup_loaded_image( if (ret != EFI_SUCCESS) goto failure; - ret = efi_add_protocol(obj->handle, - &efi_guid_device_path_to_text_protocol, - (void *)&efi_device_path_to_text); - if (ret != EFI_SUCCESS) - goto failure; - - ret = efi_add_protocol(obj->handle, - &efi_guid_device_path_utilities_protocol, - (void *)&efi_device_path_utilities); - if (ret != EFI_SUCCESS) - goto failure; - - ret = efi_add_protocol(obj->handle, - &efi_guid_unicode_collation_protocol, - (void *)&efi_unicode_collation_protocol); - if (ret != EFI_SUCCESS) - goto failure; - return ret; failure: printf("ERROR: Failure to install protocols for loaded image\n"); diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index 9d776a6..5a61a1c 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -22,10 +22,6 @@ static const struct efi_device_path END = { .length = sizeof(END), }; -#define U_BOOT_GUID \ - EFI_GUID(0xe61d73b9, 0xa384, 0x4acc, \ - 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, 0x62, 0x8b) - /* template ROOT node: */ static const struct efi_device_path_vendor ROOT = { .dp = { diff --git a/lib/efi_loader/efi_root_node.c b/lib/efi_loader/efi_root_node.c new file mode 100644 index 0000000..b056ba3 --- /dev/null +++ b/lib/efi_loader/efi_root_node.c @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Root node for system services + * + * Copyright (c) 2018 Heinrich Schuchardt + */ + +#include +#include +#include + +const efi_guid_t efi_u_boot_guid = U_BOOT_GUID; + +struct efi_root_dp { + struct efi_device_path_vendor vendor; + struct efi_device_path end; +} __packed; + +/** + * efi_root_node_register() - create root node + * + * Create the root node on which we install all protocols that are + * not related to a loaded image or a driver. + * + * Return: status code + */ +efi_status_t efi_root_node_register(void) +{ + efi_handle_t root; + efi_status_t ret; + struct efi_root_dp *dp; + + /* Create handle */ + ret = efi_create_handle(&root); + if (ret != EFI_SUCCESS) + return ret; + + /* Install device path protocol */ + dp = calloc(1, sizeof(*dp)); + if (!dp) + return EFI_OUT_OF_RESOURCES; + + /* Fill vendor node */ + dp->vendor.dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE; + dp->vendor.dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR; + dp->vendor.dp.length = sizeof(struct efi_device_path_vendor); + dp->vendor.guid = efi_u_boot_guid; + + /* Fill end node */ + dp->end.type = DEVICE_PATH_TYPE_END; + dp->end.sub_type = DEVICE_PATH_SUB_TYPE_END; + dp->end.length = sizeof(struct efi_device_path); + + /* Install device path protocol */ + ret = efi_add_protocol(root, &efi_guid_device_path, dp); + if (ret != EFI_SUCCESS) + goto failure; + + /* Install device path to text protocol */ + ret = efi_add_protocol(root, &efi_guid_device_path_to_text_protocol, + (void *)&efi_device_path_to_text); + if (ret != EFI_SUCCESS) + goto failure; + + /* Install device path utilities protocol */ + ret = efi_add_protocol(root, &efi_guid_device_path_utilities_protocol, + (void *)&efi_device_path_utilities); + if (ret != EFI_SUCCESS) + goto failure; + + /* Install Unicode collation protocol */ + ret = efi_add_protocol(root, &efi_guid_unicode_collation_protocol, + (void *)&efi_unicode_collation_protocol); + if (ret != EFI_SUCCESS) + goto failure; + +failure: + return ret; +}