summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_device_path.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/efi_loader/efi_device_path.c')
-rw-r--r--lib/efi_loader/efi_device_path.c175
1 files changed, 44 insertions, 131 deletions
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index 66a951a8c1b..b3fb20b2501 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -10,6 +10,7 @@
#include <blk.h>
#include <dm.h>
#include <dm/root.h>
+#include <efi_device_path.h>
#include <ide.h>
#include <log.h>
#include <net.h>
@@ -22,11 +23,11 @@
#include <asm-generic/unaligned.h>
#include <linux/compat.h> /* U16_MAX */
-/* template END node: */
-const struct efi_device_path END = {
+/* template EFI_DP_END node: */
+const struct efi_device_path EFI_DP_END = {
.type = DEVICE_PATH_TYPE_END,
.sub_type = DEVICE_PATH_SUB_TYPE_END,
- .length = sizeof(END),
+ .length = sizeof(EFI_DP_END),
};
#if defined(CONFIG_MMC)
@@ -47,10 +48,6 @@ static bool is_sd(struct blk_desc *desc)
}
#endif
-/*
- * Iterate to next block in device-path, terminating (returning NULL)
- * at /End* node.
- */
struct efi_device_path *efi_dp_next(const struct efi_device_path *dp)
{
if (dp == NULL)
@@ -63,12 +60,6 @@ struct efi_device_path *efi_dp_next(const struct efi_device_path *dp)
return (struct efi_device_path *)dp;
}
-/*
- * Compare two device-paths, stopping when the shorter of the two hits
- * an End* node. This is useful to, for example, compare a device-path
- * representing a device with one representing a file on the device, or
- * a device with a parent device.
- */
int efi_dp_match(const struct efi_device_path *a,
const struct efi_device_path *b)
{
@@ -91,20 +82,6 @@ int efi_dp_match(const struct efi_device_path *a,
}
}
-/**
- * efi_dp_shorten() - shorten device-path
- *
- * When creating a short boot option we want to use a device-path that is
- * independent of the location where the block device is plugged in.
- *
- * UsbWwi() nodes contain a serial number, hard drive paths a partition
- * UUID. Both should be unique.
- *
- * See UEFI spec, section 3.1.2 for "short-form device path".
- *
- * @dp: original device-path
- * Return: shortened device-path or NULL
- */
struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp)
{
while (dp) {
@@ -181,16 +158,6 @@ static efi_handle_t find_handle(struct efi_device_path *dp,
return best_handle;
}
-/**
- * efi_dp_find_obj() - find handle by device path
- *
- * If @rem is provided, the handle with the longest partial match is returned.
- *
- * @dp: device path to search
- * @guid: GUID of protocol that must be installed on path or NULL
- * @rem: pointer to receive remaining device path
- * Return: matching handle
- */
efi_handle_t efi_dp_find_obj(struct efi_device_path *dp,
const efi_guid_t *guid,
struct efi_device_path **rem)
@@ -205,13 +172,6 @@ efi_handle_t efi_dp_find_obj(struct efi_device_path *dp,
return handle;
}
-/*
- * Determine the last device path node that is not the end node.
- *
- * @dp device path
- * Return: last node before the end node if it exists
- * otherwise NULL
- */
const struct efi_device_path *efi_dp_last_node(const struct efi_device_path *dp)
{
struct efi_device_path *ret;
@@ -225,7 +185,6 @@ const struct efi_device_path *efi_dp_last_node(const struct efi_device_path *dp)
return ret;
}
-/* get size of the first device path instance excluding end node */
efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp)
{
efi_uintn_t sz = 0;
@@ -240,7 +199,6 @@ efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp)
return sz;
}
-/* get size of multi-instance device path excluding end node */
efi_uintn_t efi_dp_size(const struct efi_device_path *dp)
{
const struct efi_device_path *p = dp;
@@ -254,11 +212,10 @@ efi_uintn_t efi_dp_size(const struct efi_device_path *dp)
return (void *)p - (void *)dp;
}
-/* copy multi-instance device path */
struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp)
{
struct efi_device_path *ndp;
- size_t sz = efi_dp_size(dp) + sizeof(END);
+ size_t sz = efi_dp_size(dp) + sizeof(EFI_DP_END);
if (!dp)
return NULL;
@@ -271,21 +228,6 @@ struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp)
return ndp;
}
-/**
- * efi_dp_concat() - Concatenate two device paths and add and terminate them
- * with an end node.
- *
- * @dp1: First device path
- * @dp2: Second device path
- * @split_end_node:
- * * 0 to concatenate
- * * 1 to concatenate with end node added as separator
- * * size of dp1 excluding last end node to concatenate with end node as
- * separator in case dp1 contains an end node
- *
- * Return:
- * concatenated device path or NULL. Caller must free the returned value
- */
struct
efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
const struct efi_device_path *dp2,
@@ -296,7 +238,7 @@ efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
if (!dp1 && !dp2) {
/* return an end node */
- ret = efi_dp_dup(&END);
+ ret = efi_dp_dup(&EFI_DP_END);
} else if (!dp1) {
ret = efi_dp_dup(dp2);
} else if (!dp2) {
@@ -313,9 +255,9 @@ efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
sz1 = split_end_node;
if (split_end_node)
- end_size = 2 * sizeof(END);
+ end_size = 2 * sizeof(EFI_DP_END);
else
- end_size = sizeof(END);
+ end_size = sizeof(EFI_DP_END);
p = efi_alloc(sz1 + sz2 + end_size);
if (!p)
return NULL;
@@ -324,14 +266,14 @@ efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
p += sz1;
if (split_end_node) {
- memcpy(p, &END, sizeof(END));
- p += sizeof(END);
+ memcpy(p, &EFI_DP_END, sizeof(EFI_DP_END));
+ p += sizeof(EFI_DP_END);
}
/* the end node of the second device path has to be retained */
memcpy(p, dp2, sz2);
p += sz2;
- memcpy(p, &END, sizeof(END));
+ memcpy(p, &EFI_DP_END, sizeof(EFI_DP_END));
}
return ret;
@@ -343,26 +285,26 @@ struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
struct efi_device_path *ret;
if (!node && !dp) {
- ret = efi_dp_dup(&END);
+ ret = efi_dp_dup(&EFI_DP_END);
} else if (!node) {
ret = efi_dp_dup(dp);
} else if (!dp) {
size_t sz = node->length;
- void *p = efi_alloc(sz + sizeof(END));
+ void *p = efi_alloc(sz + sizeof(EFI_DP_END));
if (!p)
return NULL;
memcpy(p, node, sz);
- memcpy(p + sz, &END, sizeof(END));
+ memcpy(p + sz, &EFI_DP_END, sizeof(EFI_DP_END));
ret = p;
} else {
/* both dp and node are non-null */
size_t sz = efi_dp_size(dp);
- void *p = efi_alloc(sz + node->length + sizeof(END));
+ void *p = efi_alloc(sz + node->length + sizeof(EFI_DP_END));
if (!p)
return NULL;
memcpy(p, dp, sz);
memcpy(p + sz, node, node->length);
- memcpy(p + sz + node->length, &END, sizeof(END));
+ memcpy(p + sz + node->length, &EFI_DP_END, sizeof(EFI_DP_END));
ret = p;
}
@@ -400,17 +342,17 @@ struct efi_device_path *efi_dp_append_instance(
return efi_dp_dup(dpi);
sz = efi_dp_size(dp);
szi = efi_dp_instance_size(dpi);
- p = efi_alloc(sz + szi + 2 * sizeof(END));
+ p = efi_alloc(sz + szi + 2 * sizeof(EFI_DP_END));
if (!p)
return NULL;
ret = p;
- memcpy(p, dp, sz + sizeof(END));
+ memcpy(p, dp, sz + sizeof(EFI_DP_END));
p = (void *)p + sz;
p->sub_type = DEVICE_PATH_SUB_TYPE_INSTANCE_END;
- p = (void *)p + sizeof(END);
+ p = (void *)p + sizeof(EFI_DP_END);
memcpy(p, dpi, szi);
p = (void *)p + szi;
- memcpy(p, &END, sizeof(END));
+ memcpy(p, &EFI_DP_END, sizeof(EFI_DP_END));
return ret;
}
@@ -425,17 +367,17 @@ struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp,
if (!dp || !*dp)
return NULL;
sz = efi_dp_instance_size(*dp);
- p = efi_alloc(sz + sizeof(END));
+ p = efi_alloc(sz + sizeof(EFI_DP_END));
if (!p)
return NULL;
- memcpy(p, *dp, sz + sizeof(END));
+ memcpy(p, *dp, sz + sizeof(EFI_DP_END));
*dp = (void *)*dp + sz;
if ((*dp)->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END)
- *dp = (void *)*dp + sizeof(END);
+ *dp = (void *)*dp + sizeof(EFI_DP_END);
else
*dp = NULL;
if (size)
- *size = sz + sizeof(END);
+ *size = sz + sizeof(EFI_DP_END);
return p;
}
@@ -450,9 +392,6 @@ bool efi_dp_is_multi_instance(const struct efi_device_path *dp)
return p->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END;
}
-/* size of device-path not including END node for device and all parents
- * up to the root device.
- */
__maybe_unused static unsigned int dp_size(struct udevice *dev)
{
if (!dev || !dev->driver)
@@ -821,29 +760,21 @@ static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
return dp_part_node(buf, desc, part);
}
-/* Construct a device-path from a partition on a block device: */
struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part)
{
void *buf, *start;
- start = buf = efi_alloc(dp_part_size(desc, part) + sizeof(END));
- if (!buf)
+ start = efi_alloc(dp_part_size(desc, part) + sizeof(EFI_DP_END));
+ if (!start)
return NULL;
- buf = dp_part_fill(buf, desc, part);
+ buf = dp_part_fill(start, desc, part);
- *((struct efi_device_path *)buf) = END;
+ *((struct efi_device_path *)buf) = EFI_DP_END;
return start;
}
-/*
- * Create a device node for a block device partition.
- *
- * @buf buffer to which the device path is written
- * @desc block device descriptor
- * @part partition number, 0 identifies a block device
- */
struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part)
{
efi_uintn_t dpsize;
@@ -893,13 +824,6 @@ static void path_to_uefi(void *uefi, const char *src)
*pos = 0;
}
-/**
- * efi_dp_from_file() - append file path node to device path.
- *
- * @dp: device path or NULL
- * @path: file path or NULL
- * Return: device path or NULL in case of an error
- */
struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
const char *path)
{
@@ -913,7 +837,7 @@ struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
if (fpsize > U16_MAX)
return NULL;
- buf = efi_alloc(dpsize + fpsize + sizeof(END));
+ buf = efi_alloc(dpsize + fpsize + sizeof(EFI_DP_END));
if (!buf)
return NULL;
@@ -930,7 +854,7 @@ struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
pos += fpsize;
}
- memcpy(pos, &END, sizeof(END));
+ memcpy(pos, &EFI_DP_END, sizeof(EFI_DP_END));
return buf;
}
@@ -939,7 +863,7 @@ struct efi_device_path *efi_dp_from_uart(void)
{
void *buf, *pos;
struct efi_device_path_uart *uart;
- size_t dpsize = dp_size(dm_root()) + sizeof(*uart) + sizeof(END);
+ size_t dpsize = dp_size(dm_root()) + sizeof(*uart) + sizeof(EFI_DP_END);
buf = efi_alloc(dpsize);
if (!buf)
@@ -950,7 +874,7 @@ struct efi_device_path *efi_dp_from_uart(void)
uart->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_UART;
uart->dp.length = sizeof(*uart);
pos += sizeof(*uart);
- memcpy(pos, &END, sizeof(END));
+ memcpy(pos, &EFI_DP_END, sizeof(EFI_DP_END));
return buf;
}
@@ -964,13 +888,13 @@ struct efi_device_path __maybe_unused *efi_dp_from_eth(struct udevice *dev)
dpsize += dp_size(dev);
- start = buf = efi_alloc(dpsize + sizeof(END));
- if (!buf)
+ start = efi_alloc(dpsize + sizeof(EFI_DP_END));
+ if (!start)
return NULL;
- buf = dp_fill(buf, dev);
+ buf = dp_fill(start, dev);
- *((struct efi_device_path *)buf) = END;
+ *((struct efi_device_path *)buf) = EFI_DP_END;
return start;
}
@@ -980,7 +904,7 @@ struct efi_device_path __maybe_unused *efi_dp_from_eth(struct udevice *dev)
*
* Set the device path to an ethernet device path as provided by
* efi_dp_from_eth() concatenated with a device path of subtype
- * DEVICE_PATH_SUB_TYPE_MSG_IPV4, and an END node.
+ * DEVICE_PATH_SUB_TYPE_MSG_IPV4, and an EFI_DP_END node.
*
* @ip: IPv4 local address
* @mask: network mask
@@ -1011,7 +935,7 @@ static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip,
if (srv)
memcpy(&dp.ipv4dp.remote_ip_address, srv, sizeof(*srv));
pos = &dp.end;
- memcpy(pos, &END, sizeof(END));
+ memcpy(pos, &EFI_DP_END, sizeof(EFI_DP_END));
dp1 = efi_dp_from_eth(dev);
if (!dp1)
@@ -1024,17 +948,6 @@ static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip,
return dp2;
}
-/**
- * efi_dp_from_http() - set device path from http
- *
- * Set the device path to an IPv4 path as provided by efi_dp_from_ipv4
- * concatenated with a device path of subtype DEVICE_PATH_SUB_TYPE_MSG_URI,
- * 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 udevice *dev)
{
struct efi_device_path *dp1, *dp2;
@@ -1067,7 +980,7 @@ struct efi_device_path *efi_dp_from_http(const char *server, struct udevice *dev
}
uridp_len = sizeof(struct efi_device_path) + strlen(tmp) + 1;
- uridp = efi_alloc(uridp_len + sizeof(END));
+ uridp = efi_alloc(uridp_len + sizeof(EFI_DP_END));
if (!uridp) {
log_err("Out of memory\n");
return NULL;
@@ -1079,7 +992,7 @@ struct efi_device_path *efi_dp_from_http(const char *server, struct udevice *dev
memcpy(uridp->uri, tmp, strlen(tmp) + 1);
pos = (char *)uridp + uridp_len;
- memcpy(pos, &END, sizeof(END));
+ memcpy(pos, &EFI_DP_END, sizeof(EFI_DP_END));
dp2 = efi_dp_concat(dp1, (const struct efi_device_path *)uridp, 0);
@@ -1097,11 +1010,11 @@ struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
struct efi_device_path_memory *mdp;
void *buf, *start;
- start = buf = efi_alloc(sizeof(*mdp) + sizeof(END));
- if (!buf)
+ start = efi_alloc(sizeof(*mdp) + sizeof(EFI_DP_END));
+ if (!start)
return NULL;
- mdp = buf;
+ mdp = start;
mdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
mdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MEMORY;
mdp->dp.length = sizeof(*mdp);
@@ -1110,7 +1023,7 @@ struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
mdp->end_address = start_address + size;
buf = &mdp[1];
- *((struct efi_device_path *)buf) = END;
+ *((struct efi_device_path *)buf) = EFI_DP_END;
return start;
}