summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/efi_loader/efi_bootbin.c42
-rw-r--r--lib/efi_loader/efi_device_path.c5
-rw-r--r--lib/efi_loader/efi_net.c55
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