"Das U-Boot" Source Tree
1// SPDX-License-Identifier: GPL-2.0+
2/*
3 * EFI device path from u-boot device-model mapping
4 *
5 * (C) Copyright 2017 Rob Clark
6 */
7
8#define LOG_CATEGORY LOGC_EFI
9
10#include <blk.h>
11#include <dm.h>
12#include <dm/root.h>
13#include <log.h>
14#include <net.h>
15#include <usb.h>
16#include <mmc.h>
17#include <nvme.h>
18#include <efi_loader.h>
19#include <part.h>
20#include <u-boot/uuid.h>
21#include <asm-generic/unaligned.h>
22#include <linux/compat.h> /* U16_MAX */
23
24/* template END node: */
25const struct efi_device_path END = {
26 .type = DEVICE_PATH_TYPE_END,
27 .sub_type = DEVICE_PATH_SUB_TYPE_END,
28 .length = sizeof(END),
29};
30
31#if defined(CONFIG_MMC)
32/*
33 * Determine if an MMC device is an SD card.
34 *
35 * @desc block device descriptor
36 * Return: true if the device is an SD card
37 */
38static bool is_sd(struct blk_desc *desc)
39{
40 struct mmc *mmc = find_mmc_device(desc->devnum);
41
42 if (!mmc)
43 return false;
44
45 return IS_SD(mmc) != 0U;
46}
47#endif
48
49/*
50 * Iterate to next block in device-path, terminating (returning NULL)
51 * at /End* node.
52 */
53struct efi_device_path *efi_dp_next(const struct efi_device_path *dp)
54{
55 if (dp == NULL)
56 return NULL;
57 if (dp->type == DEVICE_PATH_TYPE_END)
58 return NULL;
59 dp = ((void *)dp) + dp->length;
60 if (dp->type == DEVICE_PATH_TYPE_END)
61 return NULL;
62 return (struct efi_device_path *)dp;
63}
64
65/*
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.
70 */
71int efi_dp_match(const struct efi_device_path *a,
72 const struct efi_device_path *b)
73{
74 while (1) {
75 int ret;
76
77 ret = memcmp(&a->length, &b->length, sizeof(a->length));
78 if (ret)
79 return ret;
80
81 ret = memcmp(a, b, a->length);
82 if (ret)
83 return ret;
84
85 a = efi_dp_next(a);
86 b = efi_dp_next(b);
87
88 if (!a || !b)
89 return 0;
90 }
91}
92
93/**
94 * efi_dp_shorten() - shorten device-path
95 *
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.
98 *
99 * UsbWwi() nodes contain a serial number, hard drive paths a partition
100 * UUID. Both should be unique.
101 *
102 * See UEFI spec, section 3.1.2 for "short-form device path".
103 *
104 * @dp: original device-path
105 * Return: shortened device-path or NULL
106 */
107struct efi_device_path *efi_dp_shorten(struct efi_device_path *dp)
108{
109 while (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))
113 return dp;
114
115 dp = efi_dp_next(dp);
116 }
117
118 return dp;
119}
120
121/**
122 * find_handle() - find handle by device path and installed protocol
123 *
124 * If @rem is provided, the handle with the longest partial match is returned.
125 *
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
131 */
132static 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)
135{
136 efi_handle_t handle, best_handle = NULL;
137 efi_uintn_t len, best_len = 0;
138
139 len = efi_dp_instance_size(dp);
140
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;
145 efi_status_t ret;
146
147 if (guid) {
148 ret = efi_search_protocol(handle, guid, &handler);
149 if (ret != EFI_SUCCESS)
150 continue;
151 }
152 ret = efi_search_protocol(handle, &efi_guid_device_path,
153 &handler);
154 if (ret != EFI_SUCCESS)
155 continue;
156 dp_current = handler->protocol_interface;
157 if (short_path) {
158 dp_current = efi_dp_shorten(dp_current);
159 if (!dp_current)
160 continue;
161 }
162 len_current = efi_dp_instance_size(dp_current);
163 if (rem) {
164 if (len_current > len)
165 continue;
166 } else {
167 if (len_current != len)
168 continue;
169 }
170 if (memcmp(dp_current, dp, len_current))
171 continue;
172 if (!rem)
173 return handle;
174 if (len_current > best_len) {
175 best_len = len_current;
176 best_handle = handle;
177 *rem = (void*)((u8 *)dp + len_current);
178 }
179 }
180 return best_handle;
181}
182
183/**
184 * efi_dp_find_obj() - find handle by device path
185 *
186 * If @rem is provided, the handle with the longest partial match is returned.
187 *
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
192 */
193efi_handle_t efi_dp_find_obj(struct efi_device_path *dp,
194 const efi_guid_t *guid,
195 struct efi_device_path **rem)
196{
197 efi_handle_t handle;
198
199 handle = find_handle(dp, guid, false, rem);
200 if (!handle)
201 /* Match short form device path */
202 handle = find_handle(dp, guid, true, rem);
203
204 return handle;
205}
206
207/*
208 * Determine the last device path node that is not the end node.
209 *
210 * @dp device path
211 * Return: last node before the end node if it exists
212 * otherwise NULL
213 */
214const struct efi_device_path *efi_dp_last_node(const struct efi_device_path *dp)
215{
216 struct efi_device_path *ret;
217
218 if (!dp || dp->type == DEVICE_PATH_TYPE_END)
219 return NULL;
220 while (dp) {
221 ret = (struct efi_device_path *)dp;
222 dp = efi_dp_next(dp);
223 }
224 return ret;
225}
226
227/* get size of the first device path instance excluding end node */
228efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp)
229{
230 efi_uintn_t sz = 0;
231
232 if (!dp || dp->type == DEVICE_PATH_TYPE_END)
233 return 0;
234 while (dp) {
235 sz += dp->length;
236 dp = efi_dp_next(dp);
237 }
238
239 return sz;
240}
241
242/* get size of multi-instance device path excluding end node */
243efi_uintn_t efi_dp_size(const struct efi_device_path *dp)
244{
245 const struct efi_device_path *p = dp;
246
247 if (!p)
248 return 0;
249 while (p->type != DEVICE_PATH_TYPE_END ||
250 p->sub_type != DEVICE_PATH_SUB_TYPE_END)
251 p = (void *)p + p->length;
252
253 return (void *)p - (void *)dp;
254}
255
256/* copy multi-instance device path */
257struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp)
258{
259 struct efi_device_path *ndp;
260 size_t sz = efi_dp_size(dp) + sizeof(END);
261
262 if (!dp)
263 return NULL;
264
265 ndp = efi_alloc(sz);
266 if (!ndp)
267 return NULL;
268 memcpy(ndp, dp, sz);
269
270 return ndp;
271}
272
273/**
274 * efi_dp_concat() - Concatenate two device paths and add and terminate them
275 * with an end node.
276 *
277 * @dp1: First device path
278 * @dp2: Second device path
279 * @split_end_node:
280 * * 0 to concatenate
281 * * 1 to concatenate with end node added as separator
282 * * size of dp1 excluding last end node to concatenate with end node as
283 * separator in case dp1 contains an end node
284 *
285 * Return:
286 * concatenated device path or NULL. Caller must free the returned value
287 */
288struct
289efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
290 const struct efi_device_path *dp2,
291 size_t split_end_node)
292{
293 struct efi_device_path *ret;
294 size_t end_size;
295
296 if (!dp1 && !dp2) {
297 /* return an end node */
298 ret = efi_dp_dup(&END);
299 } else if (!dp1) {
300 ret = efi_dp_dup(dp2);
301 } else if (!dp2) {
302 ret = efi_dp_dup(dp1);
303 } else {
304 /* both dp1 and dp2 are non-null */
305 size_t sz1;
306 size_t sz2 = efi_dp_size(dp2);
307 void *p;
308
309 if (split_end_node < sizeof(struct efi_device_path))
310 sz1 = efi_dp_size(dp1);
311 else
312 sz1 = split_end_node;
313
314 if (split_end_node)
315 end_size = 2 * sizeof(END);
316 else
317 end_size = sizeof(END);
318 p = efi_alloc(sz1 + sz2 + end_size);
319 if (!p)
320 return NULL;
321 ret = p;
322 memcpy(p, dp1, sz1);
323 p += sz1;
324
325 if (split_end_node) {
326 memcpy(p, &END, sizeof(END));
327 p += sizeof(END);
328 }
329
330 /* the end node of the second device path has to be retained */
331 memcpy(p, dp2, sz2);
332 p += sz2;
333 memcpy(p, &END, sizeof(END));
334 }
335
336 return ret;
337}
338
339struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
340 const struct efi_device_path *node)
341{
342 struct efi_device_path *ret;
343
344 if (!node && !dp) {
345 ret = efi_dp_dup(&END);
346 } else if (!node) {
347 ret = efi_dp_dup(dp);
348 } else if (!dp) {
349 size_t sz = node->length;
350 void *p = efi_alloc(sz + sizeof(END));
351 if (!p)
352 return NULL;
353 memcpy(p, node, sz);
354 memcpy(p + sz, &END, sizeof(END));
355 ret = p;
356 } else {
357 /* both dp and node are non-null */
358 size_t sz = efi_dp_size(dp);
359 void *p = efi_alloc(sz + node->length + sizeof(END));
360 if (!p)
361 return NULL;
362 memcpy(p, dp, sz);
363 memcpy(p + sz, node, node->length);
364 memcpy(p + sz + node->length, &END, sizeof(END));
365 ret = p;
366 }
367
368 return ret;
369}
370
371struct efi_device_path *efi_dp_create_device_node(const u8 type,
372 const u8 sub_type,
373 const u16 length)
374{
375 struct efi_device_path *ret;
376
377 if (length < sizeof(struct efi_device_path))
378 return NULL;
379
380 ret = efi_alloc(length);
381 if (!ret)
382 return ret;
383 ret->type = type;
384 ret->sub_type = sub_type;
385 ret->length = length;
386 return ret;
387}
388
389struct efi_device_path *efi_dp_append_instance(
390 const struct efi_device_path *dp,
391 const struct efi_device_path *dpi)
392{
393 size_t sz, szi;
394 struct efi_device_path *p, *ret;
395
396 if (!dpi)
397 return NULL;
398 if (!dp)
399 return efi_dp_dup(dpi);
400 sz = efi_dp_size(dp);
401 szi = efi_dp_instance_size(dpi);
402 p = efi_alloc(sz + szi + 2 * sizeof(END));
403 if (!p)
404 return NULL;
405 ret = p;
406 memcpy(p, dp, sz + sizeof(END));
407 p = (void *)p + sz;
408 p->sub_type = DEVICE_PATH_SUB_TYPE_INSTANCE_END;
409 p = (void *)p + sizeof(END);
410 memcpy(p, dpi, szi);
411 p = (void *)p + szi;
412 memcpy(p, &END, sizeof(END));
413 return ret;
414}
415
416struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp,
417 efi_uintn_t *size)
418{
419 size_t sz;
420 struct efi_device_path *p;
421
422 if (size)
423 *size = 0;
424 if (!dp || !*dp)
425 return NULL;
426 sz = efi_dp_instance_size(*dp);
427 p = efi_alloc(sz + sizeof(END));
428 if (!p)
429 return NULL;
430 memcpy(p, *dp, sz + sizeof(END));
431 *dp = (void *)*dp + sz;
432 if ((*dp)->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END)
433 *dp = (void *)*dp + sizeof(END);
434 else
435 *dp = NULL;
436 if (size)
437 *size = sz + sizeof(END);
438 return p;
439}
440
441bool efi_dp_is_multi_instance(const struct efi_device_path *dp)
442{
443 const struct efi_device_path *p = dp;
444
445 if (!p)
446 return false;
447 while (p->type != DEVICE_PATH_TYPE_END)
448 p = (void *)p + p->length;
449 return p->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END;
450}
451
452/* size of device-path not including END node for device and all parents
453 * up to the root device.
454 */
455__maybe_unused static unsigned int dp_size(struct udevice *dev)
456{
457 if (!dev || !dev->driver)
458 return sizeof(struct efi_device_path_udevice);
459
460 switch (device_get_uclass_id(dev)) {
461 case UCLASS_ROOT:
462 /* stop traversing parents at this point: */
463 return sizeof(struct efi_device_path_udevice);
464 case UCLASS_ETH:
465 return dp_size(dev->parent) +
466 sizeof(struct efi_device_path_mac_addr);
467 case UCLASS_BLK:
468 switch (dev->parent->uclass->uc_drv->id) {
469#ifdef CONFIG_IDE
470 case UCLASS_IDE:
471 return dp_size(dev->parent) +
472 sizeof(struct efi_device_path_atapi);
473#endif
474#if defined(CONFIG_SCSI)
475 case UCLASS_SCSI:
476 return dp_size(dev->parent) +
477 sizeof(struct efi_device_path_scsi);
478#endif
479#if defined(CONFIG_MMC)
480 case UCLASS_MMC:
481 return dp_size(dev->parent) +
482 sizeof(struct efi_device_path_sd_mmc_path);
483#endif
484#if defined(CONFIG_AHCI) || defined(CONFIG_SATA)
485 case UCLASS_AHCI:
486 return dp_size(dev->parent) +
487 sizeof(struct efi_device_path_sata);
488#endif
489#if defined(CONFIG_NVME)
490 case UCLASS_NVME:
491 return dp_size(dev->parent) +
492 sizeof(struct efi_device_path_nvme);
493#endif
494#ifdef CONFIG_USB
495 case UCLASS_MASS_STORAGE:
496 return dp_size(dev->parent)
497 + sizeof(struct efi_device_path_controller);
498#endif
499 default:
500 /* UCLASS_BLKMAP, UCLASS_HOST, UCLASS_VIRTIO */
501 return dp_size(dev->parent) +
502 sizeof(struct efi_device_path_udevice);
503 }
504#if defined(CONFIG_MMC)
505 case UCLASS_MMC:
506 return dp_size(dev->parent) +
507 sizeof(struct efi_device_path_sd_mmc_path);
508#endif
509 case UCLASS_MASS_STORAGE:
510 case UCLASS_USB_HUB:
511 return dp_size(dev->parent) +
512 sizeof(struct efi_device_path_usb);
513 default:
514 return dp_size(dev->parent) +
515 sizeof(struct efi_device_path_udevice);
516 }
517}
518
519/*
520 * Recursively build a device path.
521 *
522 * @buf pointer to the end of the device path
523 * @dev device
524 * Return: pointer to the end of the device path
525 */
526__maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
527{
528 enum uclass_id uclass_id;
529
530 if (!dev || !dev->driver)
531 return buf;
532
533 uclass_id = device_get_uclass_id(dev);
534 if (uclass_id != UCLASS_ROOT)
535 buf = dp_fill(buf, dev->parent);
536
537 switch (uclass_id) {
538#ifdef CONFIG_NETDEVICES
539 case UCLASS_ETH: {
540 struct efi_device_path_mac_addr *dp = buf;
541 struct eth_pdata *pdata = dev_get_plat(dev);
542
543 dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
544 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR;
545 dp->dp.length = sizeof(*dp);
546 memset(&dp->mac, 0, sizeof(dp->mac));
547 /* We only support IPv4 */
548 memcpy(&dp->mac, &pdata->enetaddr, ARP_HLEN);
549 /* Ethernet */
550 dp->if_type = 1;
551 return &dp[1];
552 }
553#endif
554 case UCLASS_BLK:
555 switch (device_get_uclass_id(dev->parent)) {
556#ifdef CONFIG_IDE
557 case UCLASS_IDE: {
558 struct efi_device_path_atapi *dp = buf;
559 struct blk_desc *desc = dev_get_uclass_plat(dev);
560
561 dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
562 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_ATAPI;
563 dp->dp.length = sizeof(*dp);
564 dp->logical_unit_number = desc->devnum;
565 dp->primary_secondary = IDE_BUS(desc->devnum);
566 dp->slave_master = desc->devnum %
567 (CONFIG_SYS_IDE_MAXDEVICE /
568 CONFIG_SYS_IDE_MAXBUS);
569 return &dp[1];
570 }
571#endif
572#if defined(CONFIG_SCSI)
573 case UCLASS_SCSI: {
574 struct efi_device_path_scsi *dp = buf;
575 struct blk_desc *desc = dev_get_uclass_plat(dev);
576
577 dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
578 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_SCSI;
579 dp->dp.length = sizeof(*dp);
580 dp->logical_unit_number = desc->lun;
581 dp->target_id = desc->target;
582 return &dp[1];
583 }
584#endif
585#if defined(CONFIG_MMC)
586 case UCLASS_MMC: {
587 struct efi_device_path_sd_mmc_path *sddp = buf;
588 struct blk_desc *desc = dev_get_uclass_plat(dev);
589
590 sddp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
591 sddp->dp.sub_type = is_sd(desc) ?
592 DEVICE_PATH_SUB_TYPE_MSG_SD :
593 DEVICE_PATH_SUB_TYPE_MSG_MMC;
594 sddp->dp.length = sizeof(*sddp);
595 sddp->slot_number = dev_seq(dev);
596 return &sddp[1];
597 }
598#endif
599#if defined(CONFIG_AHCI) || defined(CONFIG_SATA)
600 case UCLASS_AHCI: {
601 struct efi_device_path_sata *dp = buf;
602 struct blk_desc *desc = dev_get_uclass_plat(dev);
603
604 dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
605 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_SATA;
606 dp->dp.length = sizeof(*dp);
607 dp->hba_port = desc->devnum;
608 /* default 0xffff implies no port multiplier */
609 dp->port_multiplier_port = 0xffff;
610 dp->logical_unit_number = desc->lun;
611 return &dp[1];
612 }
613#endif
614#if defined(CONFIG_NVME)
615 case UCLASS_NVME: {
616 struct efi_device_path_nvme *dp = buf;
617 u32 ns_id;
618
619 dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
620 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_NVME;
621 dp->dp.length = sizeof(*dp);
622 nvme_get_namespace_id(dev, &ns_id, dp->eui64);
623 memcpy(&dp->ns_id, &ns_id, sizeof(ns_id));
624 return &dp[1];
625 }
626#endif
627#if defined(CONFIG_USB)
628 case UCLASS_MASS_STORAGE: {
629 struct blk_desc *desc = dev_get_uclass_plat(dev);
630 struct efi_device_path_controller *dp = buf;
631
632 dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
633 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CONTROLLER;
634 dp->dp.length = sizeof(*dp);
635 dp->controller_number = desc->lun;
636 return &dp[1];
637 }
638#endif
639 default: {
640 /* UCLASS_BLKMAP, UCLASS_HOST, UCLASS_VIRTIO */
641 struct efi_device_path_udevice *dp = buf;
642 struct blk_desc *desc = dev_get_uclass_plat(dev);
643
644 dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
645 dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
646 dp->dp.length = sizeof(*dp);
647 memcpy(&dp->guid, &efi_u_boot_guid,
648 sizeof(efi_guid_t));
649 dp->uclass_id = (UCLASS_BLK & 0xffff) |
650 (desc->uclass_id << 16);
651 dp->dev_number = desc->devnum;
652
653 return &dp[1];
654 }
655 }
656#if defined(CONFIG_MMC)
657 case UCLASS_MMC: {
658 struct efi_device_path_sd_mmc_path *sddp = buf;
659 struct mmc *mmc = mmc_get_mmc_dev(dev);
660 struct blk_desc *desc = mmc_get_blk_desc(mmc);
661
662 sddp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
663 sddp->dp.sub_type = is_sd(desc) ?
664 DEVICE_PATH_SUB_TYPE_MSG_SD :
665 DEVICE_PATH_SUB_TYPE_MSG_MMC;
666 sddp->dp.length = sizeof(*sddp);
667 sddp->slot_number = dev_seq(dev);
668
669 return &sddp[1];
670 }
671#endif
672 case UCLASS_MASS_STORAGE:
673 case UCLASS_USB_HUB: {
674 struct efi_device_path_usb *udp = buf;
675
676 switch (device_get_uclass_id(dev->parent)) {
677 case UCLASS_USB_HUB: {
678 struct usb_device *udev = dev_get_parent_priv(dev);
679
680 udp->parent_port_number = udev->portnr;
681 break;
682 }
683 default:
684 udp->parent_port_number = 0;
685 }
686 udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
687 udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB;
688 udp->dp.length = sizeof(*udp);
689 udp->usb_interface = 0;
690
691 return &udp[1];
692 }
693 default: {
694 struct efi_device_path_udevice *vdp = buf;
695
696 vdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
697 vdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
698 vdp->dp.length = sizeof(*vdp);
699 memcpy(&vdp->guid, &efi_u_boot_guid, sizeof(efi_guid_t));
700 vdp->uclass_id = uclass_id;
701 vdp->dev_number = dev->seq_;
702
703 return &vdp[1];
704 }
705 }
706}
707
708static unsigned dp_part_size(struct blk_desc *desc, int part)
709{
710 unsigned dpsize;
711 struct udevice *dev = desc->bdev;
712
713 dpsize = dp_size(dev);
714
715 if (part == 0) /* the actual disk, not a partition */
716 return dpsize;
717
718 if (desc->part_type == PART_TYPE_ISO)
719 dpsize += sizeof(struct efi_device_path_cdrom_path);
720 else
721 dpsize += sizeof(struct efi_device_path_hard_drive_path);
722
723 return dpsize;
724}
725
726/*
727 * Create a device node for a block device partition.
728 *
729 * @buf buffer to which the device path is written
730 * @desc block device descriptor
731 * @part partition number, 0 identifies a block device
732 *
733 * Return: pointer to position after the node
734 */
735static void *dp_part_node(void *buf, struct blk_desc *desc, int part)
736{
737 struct disk_partition info;
738 int ret;
739
740 ret = part_get_info(desc, part, &info);
741 if (ret < 0)
742 return buf;
743
744 if (desc->part_type == PART_TYPE_ISO) {
745 struct efi_device_path_cdrom_path *cddp = buf;
746
747 cddp->boot_entry = part;
748 cddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
749 cddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CDROM_PATH;
750 cddp->dp.length = sizeof(*cddp);
751 cddp->partition_start = info.start;
752 cddp->partition_size = info.size;
753
754 buf = &cddp[1];
755 } else {
756 struct efi_device_path_hard_drive_path *hddp = buf;
757
758 hddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
759 hddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH;
760 hddp->dp.length = sizeof(*hddp);
761 hddp->partition_number = part;
762 hddp->partition_start = info.start;
763 hddp->partition_end = info.size;
764 if (desc->part_type == PART_TYPE_EFI)
765 hddp->partmap_type = 2;
766 else
767 hddp->partmap_type = 1;
768
769 switch (desc->sig_type) {
770 case SIG_TYPE_NONE:
771 default:
772 hddp->signature_type = 0;
773 memset(hddp->partition_signature, 0,
774 sizeof(hddp->partition_signature));
775 break;
776 case SIG_TYPE_MBR:
777 hddp->signature_type = 1;
778 memset(hddp->partition_signature, 0,
779 sizeof(hddp->partition_signature));
780 memcpy(hddp->partition_signature, &desc->mbr_sig,
781 sizeof(desc->mbr_sig));
782 break;
783 case SIG_TYPE_GUID:
784 hddp->signature_type = 2;
785#if CONFIG_IS_ENABLED(PARTITION_UUIDS)
786 /* info.uuid exists only with PARTITION_UUIDS */
787 if (uuid_str_to_bin(info.uuid,
788 hddp->partition_signature,
789 UUID_STR_FORMAT_GUID)) {
790 log_warning(
791 "Partition %d: invalid GUID %s\n",
792 part, info.uuid);
793 }
794#endif
795 break;
796 }
797
798 buf = &hddp[1];
799 }
800
801 return buf;
802}
803
804/*
805 * Create a device path for a block device or one of its partitions.
806 *
807 * @buf buffer to which the device path is written
808 * @desc block device descriptor
809 * @part partition number, 0 identifies a block device
810 */
811static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
812{
813 struct udevice *dev = desc->bdev;
814
815 buf = dp_fill(buf, dev);
816
817 if (part == 0) /* the actual disk, not a partition */
818 return buf;
819
820 return dp_part_node(buf, desc, part);
821}
822
823/* Construct a device-path from a partition on a block device: */
824struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part)
825{
826 void *buf, *start;
827
828 start = buf = efi_alloc(dp_part_size(desc, part) + sizeof(END));
829 if (!buf)
830 return NULL;
831
832 buf = dp_part_fill(buf, desc, part);
833
834 *((struct efi_device_path *)buf) = END;
835
836 return start;
837}
838
839/*
840 * Create a device node for a block device partition.
841 *
842 * @buf buffer to which the device path is written
843 * @desc block device descriptor
844 * @part partition number, 0 identifies a block device
845 */
846struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part)
847{
848 efi_uintn_t dpsize;
849 void *buf;
850
851 if (desc->part_type == PART_TYPE_ISO)
852 dpsize = sizeof(struct efi_device_path_cdrom_path);
853 else
854 dpsize = sizeof(struct efi_device_path_hard_drive_path);
855 buf = efi_alloc(dpsize);
856
857 if (buf)
858 dp_part_node(buf, desc, part);
859
860 return buf;
861}
862
863/**
864 * path_to_uefi() - convert UTF-8 path to an UEFI style path
865 *
866 * Convert UTF-8 path to a UEFI style path (i.e. with backslashes as path
867 * separators and UTF-16).
868 *
869 * @src: source buffer
870 * @uefi: target buffer, possibly unaligned
871 */
872static void path_to_uefi(void *uefi, const char *src)
873{
874 u16 *pos = uefi;
875
876 /*
877 * efi_set_bootdev() calls this routine indirectly before the UEFI
878 * subsystem is initialized. So we cannot assume unaligned access to be
879 * enabled.
880 */
881 allow_unaligned();
882
883 while (*src) {
884 s32 code = utf8_get(&src);
885
886 if (code < 0)
887 code = '?';
888 else if (code == '/')
889 code = '\\';
890 utf16_put(code, &pos);
891 }
892 *pos = 0;
893}
894
895/**
896 * efi_dp_from_file() - append file path node to device path.
897 *
898 * @dp: device path or NULL
899 * @path: file path or NULL
900 * Return: device path or NULL in case of an error
901 */
902struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
903 const char *path)
904{
905 struct efi_device_path_file_path *fp;
906 void *buf, *pos;
907 size_t dpsize, fpsize;
908
909 dpsize = efi_dp_size(dp);
910 fpsize = sizeof(struct efi_device_path) +
911 2 * (utf8_utf16_strlen(path) + 1);
912 if (fpsize > U16_MAX)
913 return NULL;
914
915 buf = efi_alloc(dpsize + fpsize + sizeof(END));
916 if (!buf)
917 return NULL;
918
919 memcpy(buf, dp, dpsize);
920 pos = buf + dpsize;
921
922 /* add file-path: */
923 if (*path) {
924 fp = pos;
925 fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
926 fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
927 fp->dp.length = (u16)fpsize;
928 path_to_uefi(fp->str, path);
929 pos += fpsize;
930 }
931
932 memcpy(pos, &END, sizeof(END));
933
934 return buf;
935}
936
937struct efi_device_path *efi_dp_from_uart(void)
938{
939 void *buf, *pos;
940 struct efi_device_path_uart *uart;
941 size_t dpsize = dp_size(dm_root()) + sizeof(*uart) + sizeof(END);
942
943 buf = efi_alloc(dpsize);
944 if (!buf)
945 return NULL;
946 pos = dp_fill(buf, dm_root());
947 uart = pos;
948 uart->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
949 uart->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_UART;
950 uart->dp.length = sizeof(*uart);
951 pos += sizeof(*uart);
952 memcpy(pos, &END, sizeof(END));
953
954 return buf;
955}
956
957struct efi_device_path __maybe_unused *efi_dp_from_eth(void)
958{
959 void *buf, *start;
960 unsigned dpsize = 0;
961
962 assert(eth_get_dev());
963
964 dpsize += dp_size(eth_get_dev());
965
966 start = buf = efi_alloc(dpsize + sizeof(END));
967 if (!buf)
968 return NULL;
969
970 buf = dp_fill(buf, eth_get_dev());
971
972 *((struct efi_device_path *)buf) = END;
973
974 return start;
975}
976
977/**
978 * efi_dp_from_ipv4() - set device path from IPv4 address
979 *
980 * Set the device path to an ethernet device path as provided by
981 * efi_dp_from_eth() concatenated with a device path of subtype
982 * DEVICE_PATH_SUB_TYPE_MSG_IPV4, and an END node.
983 *
984 * @ip: IPv4 local address
985 * @mask: network mask
986 * @srv: IPv4 remote/server address
987 * Return: pointer to device path, NULL on error
988 */
989static struct efi_device_path *efi_dp_from_ipv4(struct efi_ipv4_address *ip,
990 struct efi_ipv4_address *mask,
991 struct efi_ipv4_address *srv)
992{
993 struct efi_device_path *dp1, *dp2, *pos;
994 struct {
995 struct efi_device_path_ipv4 ipv4dp;
996 struct efi_device_path end;
997 } dp;
998
999 memset(&dp.ipv4dp, 0, sizeof(dp.ipv4dp));
1000 dp.ipv4dp.dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
1001 dp.ipv4dp.dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_IPV4;
1002 dp.ipv4dp.dp.length = sizeof(dp.ipv4dp);
1003 dp.ipv4dp.protocol = 6;
1004 if (ip)
1005 memcpy(&dp.ipv4dp.local_ip_address, ip, sizeof(*ip));
1006 if (mask)
1007 memcpy(&dp.ipv4dp.subnet_mask, mask, sizeof(*mask));
1008 if (srv)
1009 memcpy(&dp.ipv4dp.remote_ip_address, srv, sizeof(*srv));
1010 pos = &dp.end;
1011 memcpy(pos, &END, sizeof(END));
1012
1013 dp1 = efi_dp_from_eth();
1014 if (!dp1)
1015 return NULL;
1016
1017 dp2 = efi_dp_concat(dp1, (const struct efi_device_path *)&dp, 0);
1018
1019 efi_free_pool(dp1);
1020
1021 return dp2;
1022}
1023
1024/**
1025 * efi_dp_from_http() - set device path from http
1026 *
1027 * Set the device path to an IPv4 path as provided by efi_dp_from_ipv4
1028 * concatenated with a device path of subtype DEVICE_PATH_SUB_TYPE_MSG_URI,
1029 * and an END node.
1030 *
1031 * @server: URI of remote server
1032 * Return: pointer to HTTP device path, NULL on error
1033 */
1034struct efi_device_path *efi_dp_from_http(const char *server)
1035{
1036 struct efi_device_path *dp1, *dp2;
1037 struct efi_device_path_uri *uridp;
1038 efi_uintn_t uridp_len;
1039 char *pos;
1040 char tmp[128];
1041 struct efi_ipv4_address ip;
1042 struct efi_ipv4_address mask;
1043
1044 if ((server && strlen("http://") + strlen(server) + 1 > sizeof(tmp)) ||
1045 (!server && IS_ENABLED(CONFIG_NET_LWIP)))
1046 return NULL;
1047
1048 efi_net_get_addr(&ip, &mask, NULL);
1049
1050 dp1 = efi_dp_from_ipv4(&ip, &mask, NULL);
1051 if (!dp1)
1052 return NULL;
1053
1054 strcpy(tmp, "http://");
1055
1056 if (server) {
1057 strlcat(tmp, server, sizeof(tmp));
1058#if !IS_ENABLED(CONFIG_NET_LWIP)
1059 } else {
1060 ip_to_string(net_server_ip, tmp + strlen("http://"));
1061#endif
1062 }
1063
1064 uridp_len = sizeof(struct efi_device_path) + strlen(tmp) + 1;
1065 uridp = efi_alloc(uridp_len + sizeof(END));
1066 if (!uridp) {
1067 log_err("Out of memory\n");
1068 return NULL;
1069 }
1070 uridp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
1071 uridp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_URI;
1072 uridp->dp.length = uridp_len;
1073 debug("device path: setting uri device path to %s\n", tmp);
1074 memcpy(uridp->uri, tmp, strlen(tmp) + 1);
1075
1076 pos = (char *)uridp + uridp_len;
1077 memcpy(pos, &END, sizeof(END));
1078
1079 dp2 = efi_dp_concat(dp1, (const struct efi_device_path *)uridp, 0);
1080
1081 efi_free_pool(uridp);
1082 efi_free_pool(dp1);
1083
1084 return dp2;
1085}
1086
1087/* Construct a device-path for memory-mapped image */
1088struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
1089 uint64_t start_address,
1090 size_t size)
1091{
1092 struct efi_device_path_memory *mdp;
1093 void *buf, *start;
1094
1095 start = buf = efi_alloc(sizeof(*mdp) + sizeof(END));
1096 if (!buf)
1097 return NULL;
1098
1099 mdp = buf;
1100 mdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
1101 mdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MEMORY;
1102 mdp->dp.length = sizeof(*mdp);
1103 mdp->memory_type = memory_type;
1104 mdp->start_address = start_address;
1105 mdp->end_address = start_address + size;
1106 buf = &mdp[1];
1107
1108 *((struct efi_device_path *)buf) = END;
1109
1110 return start;
1111}
1112
1113/**
1114 * efi_dp_split_file_path() - split of relative file path from device path
1115 *
1116 * Given a device path indicating a file on a device, separate the device
1117 * path in two: the device path of the actual device and the file path
1118 * relative to this device.
1119 *
1120 * @full_path: device path including device and file path
1121 * @device_path: path of the device
1122 * @file_path: relative path of the file or NULL if there is none
1123 * Return: status code
1124 */
1125efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
1126 struct efi_device_path **device_path,
1127 struct efi_device_path **file_path)
1128{
1129 struct efi_device_path *p, *dp, *fp = NULL;
1130
1131 *device_path = NULL;
1132 *file_path = NULL;
1133 dp = efi_dp_dup(full_path);
1134 if (!dp)
1135 return EFI_OUT_OF_RESOURCES;
1136 p = dp;
1137 while (!EFI_DP_TYPE(p, MEDIA_DEVICE, FILE_PATH)) {
1138 p = efi_dp_next(p);
1139 if (!p)
1140 goto out;
1141 }
1142 fp = efi_dp_dup(p);
1143 if (!fp)
1144 return EFI_OUT_OF_RESOURCES;
1145 p->type = DEVICE_PATH_TYPE_END;
1146 p->sub_type = DEVICE_PATH_SUB_TYPE_END;
1147 p->length = sizeof(*p);
1148
1149out:
1150 *device_path = dp;
1151 *file_path = fp;
1152 return EFI_SUCCESS;
1153}
1154
1155/**
1156 * efi_dp_from_name() - convert U-Boot device and file path to device path
1157 *
1158 * @dev: U-Boot device, e.g. 'mmc'
1159 * @devnr: U-Boot device number, e.g. 1 for 'mmc:1'
1160 * @path: file path relative to U-Boot device, may be NULL
1161 * @device: pointer to receive device path of the device
1162 * @file: pointer to receive device path for the file
1163 * Return: status code
1164 */
1165efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
1166 const char *path,
1167 struct efi_device_path **device,
1168 struct efi_device_path **file)
1169{
1170 struct blk_desc *desc = NULL;
1171 struct efi_device_path *dp;
1172 struct disk_partition fs_partition;
1173 size_t image_size;
1174 void *image_addr;
1175 int part = 0;
1176
1177 if (path && !file)
1178 return EFI_INVALID_PARAMETER;
1179
1180 if (IS_ENABLED(CONFIG_EFI_BINARY_EXEC) &&
1181 (!strcmp(dev, "Mem") || !strcmp(dev, "hostfs"))) {
1182 /* loadm command and semihosting */
1183 efi_get_image_parameters(&image_addr, &image_size);
1184
1185 dp = efi_dp_from_mem(EFI_RESERVED_MEMORY_TYPE,
1186 (uintptr_t)image_addr, image_size);
1187 } else if (IS_ENABLED(CONFIG_NETDEVICES) &&
1188 (!strcmp(dev, "Net") || !strcmp(dev, "Http"))) {
1189 efi_net_get_dp(&dp);
1190 } else if (!strcmp(dev, "Uart")) {
1191 dp = efi_dp_from_uart();
1192 } else {
1193 part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
1194 1);
1195 if (part < 0 || !desc)
1196 return EFI_INVALID_PARAMETER;
1197
1198 dp = efi_dp_from_part(desc, part);
1199 }
1200 if (device)
1201 *device = dp;
1202
1203 if (!path)
1204 return EFI_SUCCESS;
1205
1206 *file = efi_dp_from_file(dp, path);
1207 if (!*file)
1208 return EFI_OUT_OF_RESOURCES;
1209
1210 return EFI_SUCCESS;
1211}
1212
1213/**
1214 * efi_dp_check_length() - check length of a device path
1215 *
1216 * @dp: pointer to device path
1217 * @maxlen: maximum length of the device path
1218 * Return:
1219 * * length of the device path if it is less or equal @maxlen
1220 * * -1 if the device path is longer then @maxlen
1221 * * -1 if a device path node has a length of less than 4
1222 * * -EINVAL if maxlen exceeds SSIZE_MAX
1223 */
1224ssize_t efi_dp_check_length(const struct efi_device_path *dp,
1225 const size_t maxlen)
1226{
1227 ssize_t ret = 0;
1228 u16 len;
1229
1230 if (maxlen > SSIZE_MAX)
1231 return -EINVAL;
1232 for (;;) {
1233 len = dp->length;
1234 if (len < 4)
1235 return -1;
1236 ret += len;
1237 if (ret > maxlen)
1238 return -1;
1239 if (dp->type == DEVICE_PATH_TYPE_END &&
1240 dp->sub_type == DEVICE_PATH_SUB_TYPE_END)
1241 return ret;
1242 dp = (const struct efi_device_path *)((const u8 *)dp + len);
1243 }
1244}
1245
1246/**
1247 * efi_dp_from_lo() - get device-path from load option
1248 *
1249 * The load options in U-Boot may contain multiple concatenated device-paths.
1250 * The first device-path indicates the EFI binary to execute. Subsequent
1251 * device-paths start with a VenMedia node where the GUID identifies the
1252 * function (initrd or fdt).
1253 *
1254 * @lo: EFI load option containing a valid device path
1255 * @guid: GUID identifying device-path or NULL for the EFI binary
1256 *
1257 * Return:
1258 * device path excluding the matched VenMedia node or NULL.
1259 * Caller must free the returned value.
1260 */
1261struct
1262efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
1263 const efi_guid_t *guid)
1264{
1265 struct efi_device_path *fp = lo->file_path;
1266 struct efi_device_path_vendor *vendor;
1267 int lo_len = lo->file_path_length;
1268
1269 if (!guid)
1270 return efi_dp_dup(fp);
1271
1272 for (; lo_len >= sizeof(struct efi_device_path);
1273 lo_len -= fp->length, fp = (void *)fp + fp->length) {
1274 if (lo_len < 0 || efi_dp_check_length(fp, lo_len) < 0)
1275 break;
1276 if (fp->type != DEVICE_PATH_TYPE_MEDIA_DEVICE ||
1277 fp->sub_type != DEVICE_PATH_SUB_TYPE_VENDOR_PATH)
1278 continue;
1279
1280 vendor = (struct efi_device_path_vendor *)fp;
1281 if (!guidcmp(&vendor->guid, guid))
1282 return efi_dp_dup(efi_dp_next(fp));
1283 }
1284 log_debug("VenMedia(%pUl) not found in %ls\n", &guid, lo->label);
1285
1286 return NULL;
1287}
1288
1289/**
1290 * search_gpt_dp_node() - search gpt device path node
1291 *
1292 * @device_path: device path
1293 *
1294 * Return: pointer to the gpt device path node
1295 */
1296struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path)
1297{
1298 struct efi_device_path *dp = device_path;
1299
1300 while (dp) {
1301 if (dp->type == DEVICE_PATH_TYPE_MEDIA_DEVICE &&
1302 dp->sub_type == DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH) {
1303 struct efi_device_path_hard_drive_path *hd_dp =
1304 (struct efi_device_path_hard_drive_path *)dp;
1305
1306 if (hd_dp->partmap_type == PART_FORMAT_GPT &&
1307 hd_dp->signature_type == SIG_TYPE_GUID)
1308 return dp;
1309 }
1310 dp = efi_dp_next(dp);
1311 }
1312
1313 return NULL;
1314}