diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/efi_loader/efi_bootbin.c | 42 | ||||
-rw-r--r-- | lib/efi_loader/efi_device_path.c | 5 | ||||
-rw-r--r-- | lib/efi_loader/efi_net.c | 55 |
3 files changed, 83 insertions, 19 deletions
diff --git a/lib/efi_loader/efi_bootbin.c b/lib/efi_loader/efi_bootbin.c index a87006b3c0e..b677bbc3124 100644 --- a/lib/efi_loader/efi_bootbin.c +++ b/lib/efi_loader/efi_bootbin.c @@ -93,24 +93,34 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path, image_addr = buffer; image_size = buffer_size; +#if IS_ENABLED(CONFIG_NETDEVICES) + if (!strcmp(dev, "Net") || !strcmp(dev, "Http")) { + ret = efi_net_set_dp(dev, devnr); + if (ret != EFI_SUCCESS) + goto error; + } +#endif + ret = efi_dp_from_name(dev, devnr, path, &device, &image); - if (ret == EFI_SUCCESS) { - bootefi_device_path = device; - if (image) { - /* FIXME: image should not contain device */ - struct efi_device_path *image_tmp = image; - - efi_dp_split_file_path(image, &device, &image); - efi_free_pool(image_tmp); - } - bootefi_image_path = image; - log_debug("- boot device %pD\n", device); - if (image) - log_debug("- image %pD\n", image); - } else { - log_debug("- efi_dp_from_name() failed, err=%lx\n", ret); - efi_clear_bootdev(); + if (ret != EFI_SUCCESS) + goto error; + + bootefi_device_path = device; + if (image) { + /* FIXME: image should not contain device */ + struct efi_device_path *image_tmp = image; + + efi_dp_split_file_path(image, &device, &image); + efi_free_pool(image_tmp); } + bootefi_image_path = image; + log_debug("- boot device %pD\n", device); + if (image) + log_debug("- image %pD\n", image); + return; +error: + log_debug("- efi_dp_from_name() failed, err=%lx\n", ret); + efi_clear_bootdev(); } /** diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index a6d43006869..5eae6fd39cc 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -1185,8 +1185,9 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE, (uintptr_t)image_addr, image_size); - } else if (IS_ENABLED(CONFIG_NETDEVICES) && !strcmp(dev, "Net")) { - dp = efi_dp_from_eth(); + } else if (IS_ENABLED(CONFIG_NETDEVICES) && + (!strcmp(dev, "Net") || !strcmp(dev, "Http"))) { + efi_net_get_dp(&dp); } else if (!strcmp(dev, "Uart")) { dp = efi_dp_from_uart(); } else { diff --git a/lib/efi_loader/efi_net.c b/lib/efi_loader/efi_net.c index 3491d4c4818..e8af2e3d95e 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -16,6 +16,7 @@ */ #include <efi_loader.h> +#include <dm.h> #include <malloc.h> #include <vsprintf.h> #include <net.h> @@ -33,6 +34,13 @@ static int rx_packet_num; static struct efi_net_obj *netobj; /* + * The current network device path. This device path is updated when a new + * bootfile is downloaded from the network. If then the bootfile is loaded + * as an efi image, net_dp is passed as the device path of the loaded image. + */ +static struct efi_device_path *net_dp; + +/* * The notification function of this event is called in every timer cycle * to check if a new network packet has been received. */ @@ -902,8 +910,10 @@ efi_status_t efi_net_register(void) &netobj->net); if (r != EFI_SUCCESS) goto failure_to_add_protocol; + if (!net_dp) + efi_net_set_dp("Net", NULL); r = efi_add_protocol(&netobj->header, &efi_guid_device_path, - efi_dp_from_eth()); + net_dp); if (r != EFI_SUCCESS) goto failure_to_add_protocol; r = efi_add_protocol(&netobj->header, &efi_pxe_base_code_protocol_guid, @@ -1000,6 +1010,49 @@ out_of_resources: } /** + * efi_net_set_dp() - set device path of efi net device + * + * This gets called to update the device path when a new boot + * file is downloaded + * + * @dev: dev to set the device path from + * @server: remote server address + * Return: status code + */ +efi_status_t efi_net_set_dp(const char *dev, const char *server) +{ + efi_free_pool(net_dp); + + net_dp = NULL; + if (!strcmp(dev, "Net")) + net_dp = efi_dp_from_eth(); + else if (!strcmp(dev, "Http")) + net_dp = efi_dp_from_http(server); + + if (!net_dp) + return EFI_OUT_OF_RESOURCES; + + return EFI_SUCCESS; +} + +/** + * efi_net_get_dp() - get device path of efi net device + * + * Produce a copy of the current device path + * + * @dp: copy of the current device path, or NULL on error + */ +void efi_net_get_dp(struct efi_device_path **dp) +{ + if (!dp) + return; + if (!net_dp) + efi_net_set_dp("Net", NULL); + if (net_dp) + *dp = efi_dp_dup(net_dp); +} + +/** * efi_net_get_addr() - get IP address information * * Copy the current IP address, mask, and gateway into the |