1 // SPDX-License-Identifier: GPL-2.0+
3 * EFI device path from u-boot device-model mapping
5 * (C) Copyright 2017 Rob Clark
8 #define LOG_CATEGORY LOGC_EFI
18 #include <efi_loader.h>
21 #include <asm-generic/unaligned.h>
22 #include <linux/compat.h> /* U16_MAX */
24 /* template END node: */
25 const struct efi_device_path END = {
26 .type = DEVICE_PATH_TYPE_END,
27 .sub_type = DEVICE_PATH_SUB_TYPE_END,
28 .length = sizeof(END),
31 #if defined(CONFIG_MMC)
33 * Determine if an MMC device is an SD card.
35 * @desc block device descriptor
36 * Return: true if the device is an SD card
38 static bool is_sd(struct blk_desc *desc)
40 struct mmc *mmc = find_mmc_device(desc->devnum);
45 return IS_SD(mmc) != 0U;
50 * Iterate to next block in device-path, terminating (returning NULL)
53 struct efi_device_path *efi_dp_next(const struct efi_device_path *dp)
57 if (dp->type == DEVICE_PATH_TYPE_END)
59 dp = ((void *)dp) + dp->length;
60 if (dp->type == DEVICE_PATH_TYPE_END)
62 return (struct efi_device_path *)dp;
66 * Compare two device-paths, stopping when the shorter of the two hits
67 * an End* node. This is useful to, for example, compare a device-path
68 * representing a device with one representing a file on the device, or
69 * a device with a parent device.
71 int efi_dp_match(const struct efi_device_path *a,
72 const struct efi_device_path *b)
77 ret = memcmp(&a->length, &b->length, sizeof(a->length));
81 ret = memcmp(a, b, a->length);
94 * efi_dp_shorten() - shorten device-path
96 * When creating a short boot option we want to use a device-path that is
97 * independent of the location where the block device is plugged in.
99 * UsbWwi() nodes contain a serial number, hard drive paths a partition
100 * UUID. Both should be unique.
102 * See UEFI spec, section 3.1.2 for "short-form device path".
104 * @dp: original device-path
105 * Return: shortened device-path or NULL
107 struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp)
110 if (EFI_DP_TYPE(dp, MESSAGING_DEVICE, MSG_USB_WWI) ||
111 EFI_DP_TYPE(dp, MEDIA_DEVICE, HARD_DRIVE_PATH) ||
112 EFI_DP_TYPE(dp, MEDIA_DEVICE, FILE_PATH))
115 dp = efi_dp_next(dp);
122 * find_handle() - find handle by device path and installed protocol
124 * If @rem is provided, the handle with the longest partial match is returned.
126 * @dp: device path to search
127 * @guid: GUID of protocol that must be installed on path or NULL
128 * @short_path: use short form device path for matching
129 * @rem: pointer to receive remaining device path
130 * Return: matching handle
132 static efi_handle_t find_handle(struct efi_device_path *dp,
133 const efi_guid_t *guid, bool short_path,
134 struct efi_device_path **rem)
136 efi_handle_t handle, best_handle = NULL;
137 efi_uintn_t len, best_len = 0;
139 len = efi_dp_instance_size(dp);
141 list_for_each_entry(handle, &efi_obj_list, link) {
142 struct efi_handler *handler;
143 struct efi_device_path *dp_current;
144 efi_uintn_t len_current;
148 ret = efi_search_protocol(handle, guid, &handler);
149 if (ret != EFI_SUCCESS)
152 ret = efi_search_protocol(handle, &efi_guid_device_path,
154 if (ret != EFI_SUCCESS)
156 dp_current = handler->protocol_interface;
158 dp_current = efi_dp_shorten(dp_current);
162 len_current = efi_dp_instance_size(dp_current);
164 if (len_current > len)
167 if (len_current != len)
170 if (memcmp(dp_current, dp, len_current))
174 if (len_current > best_len) {
175 best_len = len_current;
176 best_handle = handle;
177 *rem = (void*)((u8 *)dp + len_current);
184 * efi_dp_find_obj() - find handle by device path
186 * If @rem is provided, the handle with the longest partial match is returned.
188 * @dp: device path to search
189 * @guid: GUID of protocol that must be installed on path or NULL
190 * @rem: pointer to receive remaining device path
191 * Return: matching handle
193 efi_handle_t efi_dp_find_obj(struct efi_device_path *dp,
194 const efi_guid_t *guid,
195 struct efi_device_path **rem)
199 handle = find_handle(dp, guid, false, rem);
201 /* Match short form device path */
202 handle = find_handle(dp, guid, true, rem);
208 * Determine the last device path node that is not the end node.
211 * Return: last node before the end node if it exists
214 const struct efi_device_path *efi_dp_last_node(const struct efi_device_path *dp)
216 struct efi_device_path *ret;
218 if (!dp || dp->type == DEVICE_PATH_TYPE_END)
221 ret = (struct efi_device_path *)dp;
222 dp = efi_dp_next(dp);
227 /* get size of the first device path instance excluding end node */
228 efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp)
232 if (!dp || dp->type == DEVICE_PATH_TYPE_END)
236 dp = efi_dp_next(dp);
242 /* get size of multi-instance device path excluding end node */
243 efi_uintn_t efi_dp_size(const struct efi_device_path *dp)
245 const struct efi_device_path *p = dp;
249 while (p->type != DEVICE_PATH_TYPE_END ||
250 p->sub_type != DEVICE_PATH_SUB_TYPE_END)
251 p = (void *)p + p->length;
253 return (void *)p - (void *)dp;
256 /* copy multi-instance device path */
257 struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp)
259 struct efi_device_path *ndp;
260 size_t sz = efi_dp_size(dp) + sizeof(END);
274 * efi_dp_concat() - Concatenate two device paths and add and terminate them
277 * @dp1: First device path
278 * @dp2: Second device path
279 * @split_end_node: If true the two device paths will be concatenated and
280 * separated by an end node (DEVICE_PATH_SUB_TYPE_END).
281 * If false the second device path will be concatenated to the
285 * concatenated device path or NULL. Caller must free the returned value
288 efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
289 const struct efi_device_path *dp2,
292 struct efi_device_path *ret;
296 /* return an end node */
297 ret = efi_dp_dup(&END);
299 ret = efi_dp_dup(dp2);
301 ret = efi_dp_dup(dp1);
303 /* both dp1 and dp2 are non-null */
304 unsigned sz1 = efi_dp_size(dp1);
305 unsigned sz2 = efi_dp_size(dp2);
309 end_size = 2 * sizeof(END);
311 end_size = sizeof(END);
312 p = efi_alloc(sz1 + sz2 + end_size);
319 if (split_end_node) {
320 memcpy(p, &END, sizeof(END));
324 /* the end node of the second device path has to be retained */
327 memcpy(p, &END, sizeof(END));
333 struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
334 const struct efi_device_path *node)
336 struct efi_device_path *ret;
339 ret = efi_dp_dup(&END);
341 ret = efi_dp_dup(dp);
343 size_t sz = node->length;
344 void *p = efi_alloc(sz + sizeof(END));
348 memcpy(p + sz, &END, sizeof(END));
351 /* both dp and node are non-null */
352 size_t sz = efi_dp_size(dp);
353 void *p = efi_alloc(sz + node->length + sizeof(END));
357 memcpy(p + sz, node, node->length);
358 memcpy(p + sz + node->length, &END, sizeof(END));
365 struct efi_device_path *efi_dp_create_device_node(const u8 type,
369 struct efi_device_path *ret;
371 if (length < sizeof(struct efi_device_path))
374 ret = efi_alloc(length);
378 ret->sub_type = sub_type;
379 ret->length = length;
383 struct efi_device_path *efi_dp_append_instance(
384 const struct efi_device_path *dp,
385 const struct efi_device_path *dpi)
388 struct efi_device_path *p, *ret;
393 return efi_dp_dup(dpi);
394 sz = efi_dp_size(dp);
395 szi = efi_dp_instance_size(dpi);
396 p = efi_alloc(sz + szi + 2 * sizeof(END));
400 memcpy(p, dp, sz + sizeof(END));
402 p->sub_type = DEVICE_PATH_SUB_TYPE_INSTANCE_END;
403 p = (void *)p + sizeof(END);
406 memcpy(p, &END, sizeof(END));
410 struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp,
414 struct efi_device_path *p;
420 sz = efi_dp_instance_size(*dp);
421 p = efi_alloc(sz + sizeof(END));
424 memcpy(p, *dp, sz + sizeof(END));
425 *dp = (void *)*dp + sz;
426 if ((*dp)->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END)
427 *dp = (void *)*dp + sizeof(END);
431 *size = sz + sizeof(END);
435 bool efi_dp_is_multi_instance(const struct efi_device_path *dp)
437 const struct efi_device_path *p = dp;
441 while (p->type != DEVICE_PATH_TYPE_END)
442 p = (void *)p + p->length;
443 return p->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END;
446 /* size of device-path not including END node for device and all parents
447 * up to the root device.
449 __maybe_unused static unsigned int dp_size(struct udevice *dev)
451 if (!dev || !dev->driver)
452 return sizeof(struct efi_device_path_udevice);
454 switch (device_get_uclass_id(dev)) {
456 /* stop traversing parents at this point: */
457 return sizeof(struct efi_device_path_udevice);
459 return dp_size(dev->parent) +
460 sizeof(struct efi_device_path_mac_addr);
462 switch (dev->parent->uclass->uc_drv->id) {
465 return dp_size(dev->parent) +
466 sizeof(struct efi_device_path_atapi);
468 #if defined(CONFIG_SCSI)
470 return dp_size(dev->parent) +
471 sizeof(struct efi_device_path_scsi);
473 #if defined(CONFIG_MMC)
475 return dp_size(dev->parent) +
476 sizeof(struct efi_device_path_sd_mmc_path);
478 #if defined(CONFIG_AHCI) || defined(CONFIG_SATA)
480 return dp_size(dev->parent) +
481 sizeof(struct efi_device_path_sata);
483 #if defined(CONFIG_NVME)
485 return dp_size(dev->parent) +
486 sizeof(struct efi_device_path_nvme);
489 case UCLASS_MASS_STORAGE:
490 return dp_size(dev->parent)
491 + sizeof(struct efi_device_path_controller);
494 /* UCLASS_BLKMAP, UCLASS_HOST, UCLASS_VIRTIO */
495 return dp_size(dev->parent) +
496 sizeof(struct efi_device_path_udevice);
498 #if defined(CONFIG_MMC)
500 return dp_size(dev->parent) +
501 sizeof(struct efi_device_path_sd_mmc_path);
503 case UCLASS_MASS_STORAGE:
505 return dp_size(dev->parent) +
506 sizeof(struct efi_device_path_usb);
508 return dp_size(dev->parent) +
509 sizeof(struct efi_device_path_udevice);
514 * Recursively build a device path.
516 * @buf pointer to the end of the device path
518 * Return: pointer to the end of the device path
520 __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
522 enum uclass_id uclass_id;
524 if (!dev || !dev->driver)
527 uclass_id = device_get_uclass_id(dev);
528 if (uclass_id != UCLASS_ROOT)
529 buf = dp_fill(buf, dev->parent);
532 #ifdef CONFIG_NETDEVICES
534 struct efi_device_path_mac_addr *dp = buf;
535 struct eth_pdata *pdata = dev_get_plat(dev);
537 dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
538 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR;
539 dp->dp.length = sizeof(*dp);
540 memset(&dp->mac, 0, sizeof(dp->mac));
541 /* We only support IPv4 */
542 memcpy(&dp->mac, &pdata->enetaddr, ARP_HLEN);
549 switch (device_get_uclass_id(dev->parent)) {
552 struct efi_device_path_atapi *dp = buf;
553 struct blk_desc *desc = dev_get_uclass_plat(dev);
555 dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
556 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_ATAPI;
557 dp->dp.length = sizeof(*dp);
558 dp->logical_unit_number = desc->devnum;
559 dp->primary_secondary = IDE_BUS(desc->devnum);
560 dp->slave_master = desc->devnum %
561 (CONFIG_SYS_IDE_MAXDEVICE /
562 CONFIG_SYS_IDE_MAXBUS);
566 #if defined(CONFIG_SCSI)
568 struct efi_device_path_scsi *dp = buf;
569 struct blk_desc *desc = dev_get_uclass_plat(dev);
571 dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
572 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_SCSI;
573 dp->dp.length = sizeof(*dp);
574 dp->logical_unit_number = desc->lun;
575 dp->target_id = desc->target;
579 #if defined(CONFIG_MMC)
581 struct efi_device_path_sd_mmc_path *sddp = buf;
582 struct blk_desc *desc = dev_get_uclass_plat(dev);
584 sddp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
585 sddp->dp.sub_type = is_sd(desc) ?
586 DEVICE_PATH_SUB_TYPE_MSG_SD :
587 DEVICE_PATH_SUB_TYPE_MSG_MMC;
588 sddp->dp.length = sizeof(*sddp);
589 sddp->slot_number = dev_seq(dev);
593 #if defined(CONFIG_AHCI) || defined(CONFIG_SATA)
595 struct efi_device_path_sata *dp = buf;
596 struct blk_desc *desc = dev_get_uclass_plat(dev);
598 dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
599 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_SATA;
600 dp->dp.length = sizeof(*dp);
601 dp->hba_port = desc->devnum;
602 /* default 0xffff implies no port multiplier */
603 dp->port_multiplier_port = 0xffff;
604 dp->logical_unit_number = desc->lun;
608 #if defined(CONFIG_NVME)
610 struct efi_device_path_nvme *dp = buf;
613 dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
614 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_NVME;
615 dp->dp.length = sizeof(*dp);
616 nvme_get_namespace_id(dev, &ns_id, dp->eui64);
617 memcpy(&dp->ns_id, &ns_id, sizeof(ns_id));
621 #if defined(CONFIG_USB)
622 case UCLASS_MASS_STORAGE: {
623 struct blk_desc *desc = dev_get_uclass_plat(dev);
624 struct efi_device_path_controller *dp = buf;
626 dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
627 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CONTROLLER;
628 dp->dp.length = sizeof(*dp);
629 dp->controller_number = desc->lun;
634 /* UCLASS_BLKMAP, UCLASS_HOST, UCLASS_VIRTIO */
635 struct efi_device_path_udevice *dp = buf;
636 struct blk_desc *desc = dev_get_uclass_plat(dev);
638 dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
639 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
640 dp->dp.length = sizeof(*dp);
641 memcpy(&dp->guid, &efi_u_boot_guid,
643 dp->uclass_id = (UCLASS_BLK & 0xffff) |
644 (desc->uclass_id << 16);
645 dp->dev_number = desc->devnum;
650 #if defined(CONFIG_MMC)
652 struct efi_device_path_sd_mmc_path *sddp = buf;
653 struct mmc *mmc = mmc_get_mmc_dev(dev);
654 struct blk_desc *desc = mmc_get_blk_desc(mmc);
656 sddp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
657 sddp->dp.sub_type = is_sd(desc) ?
658 DEVICE_PATH_SUB_TYPE_MSG_SD :
659 DEVICE_PATH_SUB_TYPE_MSG_MMC;
660 sddp->dp.length = sizeof(*sddp);
661 sddp->slot_number = dev_seq(dev);
666 case UCLASS_MASS_STORAGE:
667 case UCLASS_USB_HUB: {
668 struct efi_device_path_usb *udp = buf;
670 switch (device_get_uclass_id(dev->parent)) {
671 case UCLASS_USB_HUB: {
672 struct usb_device *udev = dev_get_parent_priv(dev);
674 udp->parent_port_number = udev->portnr;
678 udp->parent_port_number = 0;
680 udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
681 udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB;
682 udp->dp.length = sizeof(*udp);
683 udp->usb_interface = 0;
688 struct efi_device_path_udevice *vdp = buf;
690 vdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
691 vdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
692 vdp->dp.length = sizeof(*vdp);
693 memcpy(&vdp->guid, &efi_u_boot_guid, sizeof(efi_guid_t));
694 vdp->uclass_id = uclass_id;
695 vdp->dev_number = dev->seq_;
702 static unsigned dp_part_size(struct blk_desc *desc, int part)
705 struct udevice *dev = desc->bdev;
707 dpsize = dp_size(dev);
709 if (part == 0) /* the actual disk, not a partition */
712 if (desc->part_type == PART_TYPE_ISO)
713 dpsize += sizeof(struct efi_device_path_cdrom_path);
715 dpsize += sizeof(struct efi_device_path_hard_drive_path);
721 * Create a device node for a block device partition.
723 * @buf buffer to which the device path is written
724 * @desc block device descriptor
725 * @part partition number, 0 identifies a block device
727 * Return: pointer to position after the node
729 static void *dp_part_node(void *buf, struct blk_desc *desc, int part)
731 struct disk_partition info;
734 ret = part_get_info(desc, part, &info);
738 if (desc->part_type == PART_TYPE_ISO) {
739 struct efi_device_path_cdrom_path *cddp = buf;
741 cddp->boot_entry = part;
742 cddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
743 cddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CDROM_PATH;
744 cddp->dp.length = sizeof(*cddp);
745 cddp->partition_start = info.start;
746 cddp->partition_size = info.size;
750 struct efi_device_path_hard_drive_path *hddp = buf;
752 hddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
753 hddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH;
754 hddp->dp.length = sizeof(*hddp);
755 hddp->partition_number = part;
756 hddp->partition_start = info.start;
757 hddp->partition_end = info.size;
758 if (desc->part_type == PART_TYPE_EFI)
759 hddp->partmap_type = 2;
761 hddp->partmap_type = 1;
763 switch (desc->sig_type) {
766 hddp->signature_type = 0;
767 memset(hddp->partition_signature, 0,
768 sizeof(hddp->partition_signature));
771 hddp->signature_type = 1;
772 memset(hddp->partition_signature, 0,
773 sizeof(hddp->partition_signature));
774 memcpy(hddp->partition_signature, &desc->mbr_sig,
775 sizeof(desc->mbr_sig));
778 hddp->signature_type = 2;
779 #if CONFIG_IS_ENABLED(PARTITION_UUIDS)
780 /* info.uuid exists only with PARTITION_UUIDS */
781 if (uuid_str_to_bin(info.uuid,
782 hddp->partition_signature,
783 UUID_STR_FORMAT_GUID)) {
785 "Partition %d: invalid GUID %s\n",
799 * Create a device path for a block device or one of its partitions.
801 * @buf buffer to which the device path is written
802 * @desc block device descriptor
803 * @part partition number, 0 identifies a block device
805 static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
807 struct udevice *dev = desc->bdev;
809 buf = dp_fill(buf, dev);
811 if (part == 0) /* the actual disk, not a partition */
814 return dp_part_node(buf, desc, part);
817 /* Construct a device-path from a partition on a block device: */
818 struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part)
822 start = buf = efi_alloc(dp_part_size(desc, part) + sizeof(END));
826 buf = dp_part_fill(buf, desc, part);
828 *((struct efi_device_path *)buf) = END;
834 * Create a device node for a block device partition.
836 * @buf buffer to which the device path is written
837 * @desc block device descriptor
838 * @part partition number, 0 identifies a block device
840 struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part)
845 if (desc->part_type == PART_TYPE_ISO)
846 dpsize = sizeof(struct efi_device_path_cdrom_path);
848 dpsize = sizeof(struct efi_device_path_hard_drive_path);
849 buf = efi_alloc(dpsize);
852 dp_part_node(buf, desc, part);
858 * path_to_uefi() - convert UTF-8 path to an UEFI style path
860 * Convert UTF-8 path to a UEFI style path (i.e. with backslashes as path
861 * separators and UTF-16).
863 * @src: source buffer
864 * @uefi: target buffer, possibly unaligned
866 static void path_to_uefi(void *uefi, const char *src)
871 * efi_set_bootdev() calls this routine indirectly before the UEFI
872 * subsystem is initialized. So we cannot assume unaligned access to be
878 s32 code = utf8_get(&src);
882 else if (code == '/')
884 utf16_put(code, &pos);
890 * efi_dp_from_file() - append file path node to device path.
892 * @dp: device path or NULL
893 * @path: file path or NULL
894 * Return: device path or NULL in case of an error
896 struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
899 struct efi_device_path_file_path *fp;
901 size_t dpsize, fpsize;
903 dpsize = efi_dp_size(dp);
904 fpsize = sizeof(struct efi_device_path) +
905 2 * (utf8_utf16_strlen(path) + 1);
906 if (fpsize > U16_MAX)
909 buf = efi_alloc(dpsize + fpsize + sizeof(END));
913 memcpy(buf, dp, dpsize);
919 fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
920 fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
921 fp->dp.length = (u16)fpsize;
922 path_to_uefi(fp->str, path);
926 memcpy(pos, &END, sizeof(END));
931 struct efi_device_path *efi_dp_from_uart(void)
934 struct efi_device_path_uart *uart;
935 size_t dpsize = dp_size(dm_root()) + sizeof(*uart) + sizeof(END);
937 buf = efi_alloc(dpsize);
940 pos = dp_fill(buf, dm_root());
942 uart->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
943 uart->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_UART;
944 uart->dp.length = sizeof(*uart);
945 pos += sizeof(*uart);
946 memcpy(pos, &END, sizeof(END));
951 struct efi_device_path __maybe_unused *efi_dp_from_eth(void)
956 assert(eth_get_dev());
958 dpsize += dp_size(eth_get_dev());
960 start = buf = efi_alloc(dpsize + sizeof(END));
964 buf = dp_fill(buf, eth_get_dev());
966 *((struct efi_device_path *)buf) = END;
971 /* Construct a device-path for memory-mapped image */
972 struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
973 uint64_t start_address,
974 uint64_t end_address)
976 struct efi_device_path_memory *mdp;
979 start = buf = efi_alloc(sizeof(*mdp) + sizeof(END));
984 mdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
985 mdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MEMORY;
986 mdp->dp.length = sizeof(*mdp);
987 mdp->memory_type = memory_type;
988 mdp->start_address = start_address;
989 mdp->end_address = end_address;
992 *((struct efi_device_path *)buf) = END;
998 * efi_dp_split_file_path() - split of relative file path from device path
1000 * Given a device path indicating a file on a device, separate the device
1001 * path in two: the device path of the actual device and the file path
1002 * relative to this device.
1004 * @full_path: device path including device and file path
1005 * @device_path: path of the device
1006 * @file_path: relative path of the file or NULL if there is none
1007 * Return: status code
1009 efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
1010 struct efi_device_path **device_path,
1011 struct efi_device_path **file_path)
1013 struct efi_device_path *p, *dp, *fp = NULL;
1015 *device_path = NULL;
1017 dp = efi_dp_dup(full_path);
1019 return EFI_OUT_OF_RESOURCES;
1021 while (!EFI_DP_TYPE(p, MEDIA_DEVICE, FILE_PATH)) {
1028 return EFI_OUT_OF_RESOURCES;
1029 p->type = DEVICE_PATH_TYPE_END;
1030 p->sub_type = DEVICE_PATH_SUB_TYPE_END;
1031 p->length = sizeof(*p);
1040 * efi_dp_from_name() - convert U-Boot device and file path to device path
1042 * @dev: U-Boot device, e.g. 'mmc'
1043 * @devnr: U-Boot device number, e.g. 1 for 'mmc:1'
1044 * @path: file path relative to U-Boot device, may be NULL
1045 * @device: pointer to receive device path of the device
1046 * @file: pointer to receive device path for the file
1047 * Return: status code
1049 efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
1051 struct efi_device_path **device,
1052 struct efi_device_path **file)
1054 struct blk_desc *desc = NULL;
1055 struct efi_device_path *dp;
1056 struct disk_partition fs_partition;
1062 return EFI_INVALID_PARAMETER;
1064 if (IS_ENABLED(CONFIG_EFI_BINARY_EXEC) &&
1065 (!strcmp(dev, "Mem") || !strcmp(dev, "hostfs"))) {
1066 /* loadm command and semihosting */
1067 efi_get_image_parameters(&image_addr, &image_size);
1069 dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
1070 (uintptr_t)image_addr, image_size);
1071 } else if (IS_ENABLED(CONFIG_NETDEVICES) && !strcmp(dev, "Net")) {
1072 dp = efi_dp_from_eth();
1073 } else if (!strcmp(dev, "Uart")) {
1074 dp = efi_dp_from_uart();
1076 part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
1078 if (part < 0 || !desc)
1079 return EFI_INVALID_PARAMETER;
1081 dp = efi_dp_from_part(desc, part);
1089 *file = efi_dp_from_file(dp, path);
1091 return EFI_OUT_OF_RESOURCES;
1097 * efi_dp_check_length() - check length of a device path
1099 * @dp: pointer to device path
1100 * @maxlen: maximum length of the device path
1102 * * length of the device path if it is less or equal @maxlen
1103 * * -1 if the device path is longer then @maxlen
1104 * * -1 if a device path node has a length of less than 4
1105 * * -EINVAL if maxlen exceeds SSIZE_MAX
1107 ssize_t efi_dp_check_length(const struct efi_device_path *dp,
1108 const size_t maxlen)
1113 if (maxlen > SSIZE_MAX)
1122 if (dp->type == DEVICE_PATH_TYPE_END &&
1123 dp->sub_type == DEVICE_PATH_SUB_TYPE_END)
1125 dp = (const struct efi_device_path *)((const u8 *)dp + len);
1130 * efi_dp_from_lo() - Get the instance of a VenMedia node in a
1131 * multi-instance device path that matches
1132 * a specific GUID. This kind of device paths
1133 * is found in Boot#### options describing an
1136 * @lo: EFI_LOAD_OPTION containing a valid device path
1137 * @guid: guid to search for
1140 * device path including the VenMedia node or NULL.
1141 * Caller must free the returned value.
1144 efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
1145 const efi_guid_t *guid)
1147 struct efi_device_path *fp = lo->file_path;
1148 struct efi_device_path_vendor *vendor;
1149 int lo_len = lo->file_path_length;
1151 for (; lo_len >= sizeof(struct efi_device_path);
1152 lo_len -= fp->length, fp = (void *)fp + fp->length) {
1153 if (lo_len < 0 || efi_dp_check_length(fp, lo_len) < 0)
1155 if (fp->type != DEVICE_PATH_TYPE_MEDIA_DEVICE ||
1156 fp->sub_type != DEVICE_PATH_SUB_TYPE_VENDOR_PATH)
1159 vendor = (struct efi_device_path_vendor *)fp;
1160 if (!guidcmp(&vendor->guid, guid))
1161 return efi_dp_dup(efi_dp_next(fp));
1163 log_debug("VenMedia(%pUl) not found in %ls\n", &guid, lo->label);
1169 * search_gpt_dp_node() - search gpt device path node
1171 * @device_path: device path
1173 * Return: pointer to the gpt device path node
1175 struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path)
1177 struct efi_device_path *dp = device_path;
1180 if (dp->type == DEVICE_PATH_TYPE_MEDIA_DEVICE &&
1181 dp->sub_type == DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH) {
1182 struct efi_device_path_hard_drive_path *hd_dp =
1183 (struct efi_device_path_hard_drive_path *)dp;
1185 if (hd_dp->partmap_type == PART_FORMAT_GPT &&
1186 hd_dp->signature_type == SIG_TYPE_GUID)
1189 dp = efi_dp_next(dp);