// SPDX-License-Identifier: GPL-2.0+ /* * Bootmethod for distro boot via EFI * * Copyright 2021 Google LLC * Written by Simon Glass */ #define LOG_CATEGORY LOGC_EFI #include #include #include #include #include #include /** * efi_load_distro_fdt() - load distro device-tree * * @handle: handle of loaded image * @fdt: on return device-tree, must be freed via efi_free_pages() * @fdt_size: buffer size */ void efi_load_distro_fdt(efi_handle_t handle, void **fdt, efi_uintn_t *fdt_size) { struct efi_device_path *dp; efi_status_t ret; struct efi_handler *handler; struct efi_loaded_image *loaded_image; efi_handle_t device; *fdt = NULL; /* Get boot device from loaded image protocol */ ret = efi_search_protocol(handle, &efi_guid_loaded_image, &handler); if (ret != EFI_SUCCESS) return; loaded_image = handler->protocol_interface; device = loaded_image->device_handle; /* Get device path of boot device */ ret = efi_search_protocol(device, &efi_guid_device_path, &handler); if (ret != EFI_SUCCESS) return; dp = handler->protocol_interface; /* Try the various available names */ for (int seq = 0; ; ++seq) { struct efi_device_path *file; char buf[255]; if (efi_get_distro_fdt_name(buf, sizeof(buf), seq)) break; file = efi_dp_from_file(dp, buf); if (!file) break; ret = efi_load_image_from_path(true, file, fdt, fdt_size); efi_free_pool(file); if (ret == EFI_SUCCESS) { log_debug("Fdt %pD loaded\n", file); break; } } }