Support setting the device path with efi_dp_from_eth, efi_dp_from_ipv4, and efi_dp_from_http to an ethernet device other than the current ethernet udevice. Calling eth_dp_from_eth with eth_get_dev() as the argument recovers the pevious functionality.
Signed-off-by: Adriano Cordova <adriano.cord...@canonical.com> --- include/efi_loader.h | 10 +++++----- lib/efi_loader/efi_bootbin.c | 3 ++- lib/efi_loader/efi_device_path.c | 21 ++++++++++++--------- lib/efi_loader/efi_net.c | 24 ++++++++++++++---------- 4 files changed, 33 insertions(+), 25 deletions(-) diff --git a/include/efi_loader.h b/include/efi_loader.h index 97152bbb6a..8be52e2766 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -128,9 +128,9 @@ static inline void efi_set_bootdev(const char *dev, const char *devnr, #if CONFIG_IS_ENABLED(NETDEVICES) && CONFIG_IS_ENABLED(EFI_LOADER) /* Call this to update the current device path of the efi net device */ -efi_status_t efi_net_set_dp(const char *dev, const char *server); +efi_status_t efi_net_set_dp(const char *dev, const char *server, struct udevice *udev); /* Call this to get the current device path of the efi net device */ -void efi_net_get_dp(struct efi_device_path **dp); +void efi_net_get_dp(struct efi_device_path **dp, struct udevice *udev); void efi_net_get_addr(struct efi_ipv4_address *ip, struct efi_ipv4_address *mask, struct efi_ipv4_address *gw); @@ -150,7 +150,7 @@ struct http_header { void efi_net_parse_headers(ulong *num_headers, struct http_header *headers); #else -static inline void efi_net_get_dp(struct efi_device_path **dp) { } +static inline void efi_net_get_dp(struct efi_device_path **dp, struct udevice *udev) { } static inline void efi_net_get_addr(struct efi_ipv4_address *ip, struct efi_ipv4_address *mask, struct efi_ipv4_address *gw) { } @@ -918,8 +918,8 @@ struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part); struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part); struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp, const char *path); -struct efi_device_path *efi_dp_from_eth(void); -struct efi_device_path *efi_dp_from_http(const char *server); +struct efi_device_path *efi_dp_from_eth(struct udevice *dev); +struct efi_device_path *efi_dp_from_http(const char *server, struct udevice *dev); struct efi_device_path *efi_dp_from_mem(uint32_t mem_type, uint64_t start_address, size_t size); diff --git a/lib/efi_loader/efi_bootbin.c b/lib/efi_loader/efi_bootbin.c index b677bbc312..b6b40c030f 100644 --- a/lib/efi_loader/efi_bootbin.c +++ b/lib/efi_loader/efi_bootbin.c @@ -13,6 +13,7 @@ #include <image.h> #include <log.h> #include <malloc.h> +#include <net.h> static struct efi_device_path *bootefi_image_path; static struct efi_device_path *bootefi_device_path; @@ -95,7 +96,7 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path, #if IS_ENABLED(CONFIG_NETDEVICES) if (!strcmp(dev, "Net") || !strcmp(dev, "Http")) { - ret = efi_net_set_dp(dev, devnr); + ret = efi_net_set_dp(dev, devnr, eth_get_dev()); if (ret != EFI_SUCCESS) goto error; } diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c index c0633a736b..4a5d50fdf5 100644 --- a/lib/efi_loader/efi_device_path.c +++ b/lib/efi_loader/efi_device_path.c @@ -954,20 +954,20 @@ struct efi_device_path *efi_dp_from_uart(void) return buf; } -struct efi_device_path __maybe_unused *efi_dp_from_eth(void) +struct efi_device_path __maybe_unused *efi_dp_from_eth(struct udevice *dev) { void *buf, *start; unsigned dpsize = 0; - assert(eth_get_dev()); + assert(dev); - dpsize += dp_size(eth_get_dev()); + dpsize += dp_size(dev); start = buf = efi_alloc(dpsize + sizeof(END)); if (!buf) return NULL; - buf = dp_fill(buf, eth_get_dev()); + buf = dp_fill(buf, dev); *((struct efi_device_path *)buf) = END; @@ -984,11 +984,13 @@ struct efi_device_path __maybe_unused *efi_dp_from_eth(void) * @ip: IPv4 local address * @mask: network mask * @srv: IPv4 remote/server address + * @dev: net udevice * Return: pointer to device path, NULL on error */ static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip, struct efi_ipv4_address *mask, - struct efi_ipv4_address *srv) + struct efi_ipv4_address *srv, + struct udevice *dev) { struct efi_device_path *dp1, *dp2, *pos; struct { @@ -1010,7 +1012,7 @@ static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip, pos = &dp.end; memcpy(pos, &END, sizeof(END)); - dp1 = efi_dp_from_eth(); + dp1 = efi_dp_from_eth(dev); if (!dp1) return NULL; @@ -1029,9 +1031,10 @@ static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip, * and an END node. * * @server: URI of remote server + * @dev: net udevice * Return: pointer to HTTP device path, NULL on error */ -struct efi_device_path *efi_dp_from_http(const char *server) +struct efi_device_path *efi_dp_from_http(const char *server, struct udevice *dev) { struct efi_device_path *dp1, *dp2; struct efi_device_path_uri *uridp; @@ -1047,7 +1050,7 @@ struct efi_device_path *efi_dp_from_http(const char *server) efi_net_get_addr(&ip, &mask, NULL); - dp1 = efi_dp_from_ipv4(&ip, &mask, NULL); + dp1 = efi_dp_from_ipv4(&ip, &mask, NULL, dev); if (!dp1) return NULL; @@ -1186,7 +1189,7 @@ efi_status_t efi_dp_from_name(const char *dev, const char *devnr, (uintptr_t)image_addr, image_size); } else if (IS_ENABLED(CONFIG_NETDEVICES) && (!strcmp(dev, "Net") || !strcmp(dev, "Http"))) { - efi_net_get_dp(&dp); + efi_net_get_dp(&dp, eth_get_dev()); } 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 f0cf317d4f..a399f6f593 100644 --- a/lib/efi_loader/efi_net.c +++ b/lib/efi_loader/efi_net.c @@ -949,10 +949,12 @@ 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, - net_dp); + + if (net_dp) + r = efi_add_protocol(&netobj->header, &efi_guid_device_path, + net_dp); + else + r = efi_net_set_dp("Net", NULL, eth_get_dev()); if (r != EFI_SUCCESS) goto failure_to_add_protocol; r = efi_add_protocol(&netobj->header, &efi_pxe_base_code_protocol_guid, @@ -1068,17 +1070,18 @@ out_of_resources: * * @dev: dev to set the device path from * @server: remote server address + * @udev: net udevice * Return: status code */ -efi_status_t efi_net_set_dp(const char *dev, const char *server) +efi_status_t efi_net_set_dp(const char *dev, const char *server, struct udevice *udev) { efi_free_pool(net_dp); net_dp = NULL; if (!strcmp(dev, "Net")) - net_dp = efi_dp_from_eth(); + net_dp = efi_dp_from_eth(udev); else if (!strcmp(dev, "Http")) - net_dp = efi_dp_from_http(server); + net_dp = efi_dp_from_http(server, udev); if (!net_dp) return EFI_OUT_OF_RESOURCES; @@ -1091,14 +1094,15 @@ efi_status_t efi_net_set_dp(const char *dev, const char *server) * * Produce a copy of the current device path * - * @dp: copy of the current device path, or NULL on error + * @dp: copy of the current device path + * @udev: net udevice */ -void efi_net_get_dp(struct efi_device_path **dp) +void efi_net_get_dp(struct efi_device_path **dp, struct udevice *udev) { if (!dp) return; if (!net_dp) - efi_net_set_dp("Net", NULL); + efi_net_set_dp("Net", NULL, udev); if (net_dp) *dp = efi_dp_dup(net_dp); } -- 2.43.0