
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.cordova@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); }