]> Git Repo - J-u-boot.git/blob - lib/efi_loader/efi_device_path.c
aec224d846622583731f5a5c6ac92a2f29c48aba
[J-u-boot.git] / lib / efi_loader / efi_device_path.c
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 <uuid.h>
21 #include <asm-generic/unaligned.h>
22 #include <linux/compat.h> /* U16_MAX */
23
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),
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  */
38 static 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  */
53 struct 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  */
71 int 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  */
107 struct 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  */
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)
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  */
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)
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  */
214 const 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 */
228 efi_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 */
243 efi_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 */
257 struct 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: 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
282  *                  first one as-is.
283  *
284  * Return:
285  * concatenated device path or NULL. Caller must free the returned value
286  */
287 struct
288 efi_device_path *efi_dp_concat(const struct efi_device_path *dp1,
289                                const struct efi_device_path *dp2,
290                                bool split_end_node)
291 {
292         struct efi_device_path *ret;
293         size_t end_size;
294
295         if (!dp1 && !dp2) {
296                 /* return an end node */
297                 ret = efi_dp_dup(&END);
298         } else if (!dp1) {
299                 ret = efi_dp_dup(dp2);
300         } else if (!dp2) {
301                 ret = efi_dp_dup(dp1);
302         } else {
303                 /* both dp1 and dp2 are non-null */
304                 unsigned sz1 = efi_dp_size(dp1);
305                 unsigned sz2 = efi_dp_size(dp2);
306                 void *p;
307
308                 if (split_end_node)
309                         end_size = 2 * sizeof(END);
310                 else
311                         end_size = sizeof(END);
312                 p = efi_alloc(sz1 + sz2 + end_size);
313                 if (!p)
314                         return NULL;
315                 ret = p;
316                 memcpy(p, dp1, sz1);
317                 p += sz1;
318
319                 if (split_end_node) {
320                         memcpy(p, &END, sizeof(END));
321                         p += sizeof(END);
322                 }
323
324                 /* the end node of the second device path has to be retained */
325                 memcpy(p, dp2, sz2);
326                 p += sz2;
327                 memcpy(p, &END, sizeof(END));
328         }
329
330         return ret;
331 }
332
333 struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
334                                            const struct efi_device_path *node)
335 {
336         struct efi_device_path *ret;
337
338         if (!node && !dp) {
339                 ret = efi_dp_dup(&END);
340         } else if (!node) {
341                 ret = efi_dp_dup(dp);
342         } else if (!dp) {
343                 size_t sz = node->length;
344                 void *p = efi_alloc(sz + sizeof(END));
345                 if (!p)
346                         return NULL;
347                 memcpy(p, node, sz);
348                 memcpy(p + sz, &END, sizeof(END));
349                 ret = p;
350         } else {
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));
354                 if (!p)
355                         return NULL;
356                 memcpy(p, dp, sz);
357                 memcpy(p + sz, node, node->length);
358                 memcpy(p + sz + node->length, &END, sizeof(END));
359                 ret = p;
360         }
361
362         return ret;
363 }
364
365 struct efi_device_path *efi_dp_create_device_node(const u8 type,
366                                                   const u8 sub_type,
367                                                   const u16 length)
368 {
369         struct efi_device_path *ret;
370
371         if (length < sizeof(struct efi_device_path))
372                 return NULL;
373
374         ret = efi_alloc(length);
375         if (!ret)
376                 return ret;
377         ret->type = type;
378         ret->sub_type = sub_type;
379         ret->length = length;
380         return ret;
381 }
382
383 struct efi_device_path *efi_dp_append_instance(
384                 const struct efi_device_path *dp,
385                 const struct efi_device_path *dpi)
386 {
387         size_t sz, szi;
388         struct efi_device_path *p, *ret;
389
390         if (!dpi)
391                 return NULL;
392         if (!dp)
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));
397         if (!p)
398                 return NULL;
399         ret = p;
400         memcpy(p, dp, sz + sizeof(END));
401         p = (void *)p + sz;
402         p->sub_type = DEVICE_PATH_SUB_TYPE_INSTANCE_END;
403         p = (void *)p + sizeof(END);
404         memcpy(p, dpi, szi);
405         p = (void *)p + szi;
406         memcpy(p, &END, sizeof(END));
407         return ret;
408 }
409
410 struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp,
411                                                  efi_uintn_t *size)
412 {
413         size_t sz;
414         struct efi_device_path *p;
415
416         if (size)
417                 *size = 0;
418         if (!dp || !*dp)
419                 return NULL;
420         sz = efi_dp_instance_size(*dp);
421         p = efi_alloc(sz + sizeof(END));
422         if (!p)
423                 return NULL;
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);
428         else
429                 *dp = NULL;
430         if (size)
431                 *size = sz + sizeof(END);
432         return p;
433 }
434
435 bool efi_dp_is_multi_instance(const struct efi_device_path *dp)
436 {
437         const struct efi_device_path *p = dp;
438
439         if (!p)
440                 return false;
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;
444 }
445
446 /* size of device-path not including END node for device and all parents
447  * up to the root device.
448  */
449 __maybe_unused static unsigned int dp_size(struct udevice *dev)
450 {
451         if (!dev || !dev->driver)
452                 return sizeof(struct efi_device_path_udevice);
453
454         switch (device_get_uclass_id(dev)) {
455         case UCLASS_ROOT:
456                 /* stop traversing parents at this point: */
457                 return sizeof(struct efi_device_path_udevice);
458         case UCLASS_ETH:
459                 return dp_size(dev->parent) +
460                         sizeof(struct efi_device_path_mac_addr);
461         case UCLASS_BLK:
462                 switch (dev->parent->uclass->uc_drv->id) {
463 #ifdef CONFIG_IDE
464                 case UCLASS_IDE:
465                         return dp_size(dev->parent) +
466                                 sizeof(struct efi_device_path_atapi);
467 #endif
468 #if defined(CONFIG_SCSI)
469                 case UCLASS_SCSI:
470                         return dp_size(dev->parent) +
471                                 sizeof(struct efi_device_path_scsi);
472 #endif
473 #if defined(CONFIG_MMC)
474                 case UCLASS_MMC:
475                         return dp_size(dev->parent) +
476                                 sizeof(struct efi_device_path_sd_mmc_path);
477 #endif
478 #if defined(CONFIG_AHCI) || defined(CONFIG_SATA)
479                 case UCLASS_AHCI:
480                         return dp_size(dev->parent) +
481                                 sizeof(struct efi_device_path_sata);
482 #endif
483 #if defined(CONFIG_NVME)
484                 case UCLASS_NVME:
485                         return dp_size(dev->parent) +
486                                 sizeof(struct efi_device_path_nvme);
487 #endif
488 #ifdef CONFIG_USB
489                 case UCLASS_MASS_STORAGE:
490                         return dp_size(dev->parent)
491                                 + sizeof(struct efi_device_path_controller);
492 #endif
493                 default:
494                         /* UCLASS_BLKMAP, UCLASS_HOST, UCLASS_VIRTIO */
495                         return dp_size(dev->parent) +
496                                 sizeof(struct efi_device_path_udevice);
497                 }
498 #if defined(CONFIG_MMC)
499         case UCLASS_MMC:
500                 return dp_size(dev->parent) +
501                         sizeof(struct efi_device_path_sd_mmc_path);
502 #endif
503         case UCLASS_MASS_STORAGE:
504         case UCLASS_USB_HUB:
505                 return dp_size(dev->parent) +
506                         sizeof(struct efi_device_path_usb);
507         default:
508                 return dp_size(dev->parent) +
509                         sizeof(struct efi_device_path_udevice);
510         }
511 }
512
513 /*
514  * Recursively build a device path.
515  *
516  * @buf         pointer to the end of the device path
517  * @dev         device
518  * Return:      pointer to the end of the device path
519  */
520 __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
521 {
522         enum uclass_id uclass_id;
523
524         if (!dev || !dev->driver)
525                 return buf;
526
527         uclass_id = device_get_uclass_id(dev);
528         if (uclass_id != UCLASS_ROOT)
529                 buf = dp_fill(buf, dev->parent);
530
531         switch (uclass_id) {
532 #ifdef CONFIG_NETDEVICES
533         case UCLASS_ETH: {
534                 struct efi_device_path_mac_addr *dp = buf;
535                 struct eth_pdata *pdata = dev_get_plat(dev);
536
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);
543                 /* Ethernet */
544                 dp->if_type = 1;
545                 return &dp[1];
546         }
547 #endif
548         case UCLASS_BLK:
549                 switch (device_get_uclass_id(dev->parent)) {
550 #ifdef CONFIG_IDE
551                 case UCLASS_IDE: {
552                         struct efi_device_path_atapi *dp = buf;
553                         struct blk_desc *desc = dev_get_uclass_plat(dev);
554
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);
563                         return &dp[1];
564                         }
565 #endif
566 #if defined(CONFIG_SCSI)
567                 case UCLASS_SCSI: {
568                         struct efi_device_path_scsi *dp = buf;
569                         struct blk_desc *desc = dev_get_uclass_plat(dev);
570
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;
576                         return &dp[1];
577                         }
578 #endif
579 #if defined(CONFIG_MMC)
580                 case UCLASS_MMC: {
581                         struct efi_device_path_sd_mmc_path *sddp = buf;
582                         struct blk_desc *desc = dev_get_uclass_plat(dev);
583
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);
590                         return &sddp[1];
591                         }
592 #endif
593 #if defined(CONFIG_AHCI) || defined(CONFIG_SATA)
594                 case UCLASS_AHCI: {
595                         struct efi_device_path_sata *dp = buf;
596                         struct blk_desc *desc = dev_get_uclass_plat(dev);
597
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;
605                         return &dp[1];
606                         }
607 #endif
608 #if defined(CONFIG_NVME)
609                 case UCLASS_NVME: {
610                         struct efi_device_path_nvme *dp = buf;
611                         u32 ns_id;
612
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));
618                         return &dp[1];
619                         }
620 #endif
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;
625
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;
630                         return &dp[1];
631                 }
632 #endif
633                 default: {
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);
637
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,
642                                sizeof(efi_guid_t));
643                         dp->uclass_id = (UCLASS_BLK & 0xffff) |
644                                         (desc->uclass_id << 16);
645                         dp->dev_number = desc->devnum;
646
647                         return &dp[1];
648                 }
649         }
650 #if defined(CONFIG_MMC)
651         case UCLASS_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);
655
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);
662
663                 return &sddp[1];
664         }
665 #endif
666         case UCLASS_MASS_STORAGE:
667         case UCLASS_USB_HUB: {
668                 struct efi_device_path_usb *udp = buf;
669
670                 switch (device_get_uclass_id(dev->parent)) {
671                 case UCLASS_USB_HUB: {
672                         struct usb_device *udev = dev_get_parent_priv(dev);
673
674                         udp->parent_port_number = udev->portnr;
675                         break;
676                 }
677                 default:
678                         udp->parent_port_number = 0;
679                 }
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;
684
685                 return &udp[1];
686         }
687         default: {
688                 struct efi_device_path_udevice *vdp = buf;
689
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_;
696
697                 return &vdp[1];
698             }
699         }
700 }
701
702 static unsigned dp_part_size(struct blk_desc *desc, int part)
703 {
704         unsigned dpsize;
705         struct udevice *dev = desc->bdev;
706
707         dpsize = dp_size(dev);
708
709         if (part == 0) /* the actual disk, not a partition */
710                 return dpsize;
711
712         if (desc->part_type == PART_TYPE_ISO)
713                 dpsize += sizeof(struct efi_device_path_cdrom_path);
714         else
715                 dpsize += sizeof(struct efi_device_path_hard_drive_path);
716
717         return dpsize;
718 }
719
720 /*
721  * Create a device node for a block device partition.
722  *
723  * @buf         buffer to which the device path is written
724  * @desc        block device descriptor
725  * @part        partition number, 0 identifies a block device
726  *
727  * Return:      pointer to position after the node
728  */
729 static void *dp_part_node(void *buf, struct blk_desc *desc, int part)
730 {
731         struct disk_partition info;
732         int ret;
733
734         ret = part_get_info(desc, part, &info);
735         if (ret < 0)
736                 return buf;
737
738         if (desc->part_type == PART_TYPE_ISO) {
739                 struct efi_device_path_cdrom_path *cddp = buf;
740
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;
747
748                 buf = &cddp[1];
749         } else {
750                 struct efi_device_path_hard_drive_path *hddp = buf;
751
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;
760                 else
761                         hddp->partmap_type = 1;
762
763                 switch (desc->sig_type) {
764                 case SIG_TYPE_NONE:
765                 default:
766                         hddp->signature_type = 0;
767                         memset(hddp->partition_signature, 0,
768                                sizeof(hddp->partition_signature));
769                         break;
770                 case SIG_TYPE_MBR:
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));
776                         break;
777                 case SIG_TYPE_GUID:
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)) {
784                                 log_warning(
785                                         "Partition %d: invalid GUID %s\n",
786                                         part, info.uuid);
787                         }
788 #endif
789                         break;
790                 }
791
792                 buf = &hddp[1];
793         }
794
795         return buf;
796 }
797
798 /*
799  * Create a device path for a block device or one of its partitions.
800  *
801  * @buf         buffer to which the device path is written
802  * @desc        block device descriptor
803  * @part        partition number, 0 identifies a block device
804  */
805 static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
806 {
807         struct udevice *dev = desc->bdev;
808
809         buf = dp_fill(buf, dev);
810
811         if (part == 0) /* the actual disk, not a partition */
812                 return buf;
813
814         return dp_part_node(buf, desc, part);
815 }
816
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)
819 {
820         void *buf, *start;
821
822         start = buf = efi_alloc(dp_part_size(desc, part) + sizeof(END));
823         if (!buf)
824                 return NULL;
825
826         buf = dp_part_fill(buf, desc, part);
827
828         *((struct efi_device_path *)buf) = END;
829
830         return start;
831 }
832
833 /*
834  * Create a device node for a block device partition.
835  *
836  * @buf         buffer to which the device path is written
837  * @desc        block device descriptor
838  * @part        partition number, 0 identifies a block device
839  */
840 struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part)
841 {
842         efi_uintn_t dpsize;
843         void *buf;
844
845         if (desc->part_type == PART_TYPE_ISO)
846                 dpsize = sizeof(struct efi_device_path_cdrom_path);
847         else
848                 dpsize = sizeof(struct efi_device_path_hard_drive_path);
849         buf = efi_alloc(dpsize);
850
851         if (buf)
852                 dp_part_node(buf, desc, part);
853
854         return buf;
855 }
856
857 /**
858  * path_to_uefi() - convert UTF-8 path to an UEFI style path
859  *
860  * Convert UTF-8 path to a UEFI style path (i.e. with backslashes as path
861  * separators and UTF-16).
862  *
863  * @src:        source buffer
864  * @uefi:       target buffer, possibly unaligned
865  */
866 static void path_to_uefi(void *uefi, const char *src)
867 {
868         u16 *pos = uefi;
869
870         /*
871          * efi_set_bootdev() calls this routine indirectly before the UEFI
872          * subsystem is initialized. So we cannot assume unaligned access to be
873          * enabled.
874          */
875         allow_unaligned();
876
877         while (*src) {
878                 s32 code = utf8_get(&src);
879
880                 if (code < 0)
881                         code = '?';
882                 else if (code == '/')
883                         code = '\\';
884                 utf16_put(code, &pos);
885         }
886         *pos = 0;
887 }
888
889 /**
890  * efi_dp_from_file() - append file path node to device path.
891  *
892  * @dp:         device path or NULL
893  * @path:       file path or NULL
894  * Return:      device path or NULL in case of an error
895  */
896 struct efi_device_path *efi_dp_from_file(const struct efi_device_path *dp,
897                                          const char *path)
898 {
899         struct efi_device_path_file_path *fp;
900         void *buf, *pos;
901         size_t dpsize, fpsize;
902
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)
907                 return NULL;
908
909         buf = efi_alloc(dpsize + fpsize + sizeof(END));
910         if (!buf)
911                 return NULL;
912
913         memcpy(buf, dp, dpsize);
914         pos = buf + dpsize;
915
916         /* add file-path: */
917         if (*path) {
918                 fp = pos;
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);
923                 pos += fpsize;
924         }
925
926         memcpy(pos, &END, sizeof(END));
927
928         return buf;
929 }
930
931 struct efi_device_path *efi_dp_from_uart(void)
932 {
933         void *buf, *pos;
934         struct efi_device_path_uart *uart;
935         size_t dpsize = dp_size(dm_root()) + sizeof(*uart) + sizeof(END);
936
937         buf = efi_alloc(dpsize);
938         if (!buf)
939                 return NULL;
940         pos = dp_fill(buf, dm_root());
941         uart = pos;
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));
947
948         return buf;
949 }
950
951 struct efi_device_path __maybe_unused *efi_dp_from_eth(void)
952 {
953         void *buf, *start;
954         unsigned dpsize = 0;
955
956         assert(eth_get_dev());
957
958         dpsize += dp_size(eth_get_dev());
959
960         start = buf = efi_alloc(dpsize + sizeof(END));
961         if (!buf)
962                 return NULL;
963
964         buf = dp_fill(buf, eth_get_dev());
965
966         *((struct efi_device_path *)buf) = END;
967
968         return start;
969 }
970
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)
975 {
976         struct efi_device_path_memory *mdp;
977         void *buf, *start;
978
979         start = buf = efi_alloc(sizeof(*mdp) + sizeof(END));
980         if (!buf)
981                 return NULL;
982
983         mdp = buf;
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;
990         buf = &mdp[1];
991
992         *((struct efi_device_path *)buf) = END;
993
994         return start;
995 }
996
997 /**
998  * efi_dp_split_file_path() - split of relative file path from device path
999  *
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.
1003  *
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
1008  */
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)
1012 {
1013         struct efi_device_path *p, *dp, *fp = NULL;
1014
1015         *device_path = NULL;
1016         *file_path = NULL;
1017         dp = efi_dp_dup(full_path);
1018         if (!dp)
1019                 return EFI_OUT_OF_RESOURCES;
1020         p = dp;
1021         while (!EFI_DP_TYPE(p, MEDIA_DEVICE, FILE_PATH)) {
1022                 p = efi_dp_next(p);
1023                 if (!p)
1024                         goto out;
1025         }
1026         fp = efi_dp_dup(p);
1027         if (!fp)
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);
1032
1033 out:
1034         *device_path = dp;
1035         *file_path = fp;
1036         return EFI_SUCCESS;
1037 }
1038
1039 /**
1040  * efi_dp_from_name() - convert U-Boot device and file path to device path
1041  *
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
1048  */
1049 efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
1050                               const char *path,
1051                               struct efi_device_path **device,
1052                               struct efi_device_path **file)
1053 {
1054         struct blk_desc *desc = NULL;
1055         struct efi_device_path *dp;
1056         struct disk_partition fs_partition;
1057         size_t image_size;
1058         void *image_addr;
1059         int part = 0;
1060
1061         if (path && !file)
1062                 return EFI_INVALID_PARAMETER;
1063
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);
1068
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();
1075         } else {
1076                 part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
1077                                                1);
1078                 if (part < 0 || !desc)
1079                         return EFI_INVALID_PARAMETER;
1080
1081                 dp = efi_dp_from_part(desc, part);
1082         }
1083         if (device)
1084                 *device = dp;
1085
1086         if (!path)
1087                 return EFI_SUCCESS;
1088
1089         *file = efi_dp_from_file(dp, path);
1090         if (!*file)
1091                 return EFI_OUT_OF_RESOURCES;
1092
1093         return EFI_SUCCESS;
1094 }
1095
1096 /**
1097  * efi_dp_check_length() - check length of a device path
1098  *
1099  * @dp:         pointer to device path
1100  * @maxlen:     maximum length of the device path
1101  * Return:
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
1106  */
1107 ssize_t efi_dp_check_length(const struct efi_device_path *dp,
1108                             const size_t maxlen)
1109 {
1110         ssize_t ret = 0;
1111         u16 len;
1112
1113         if (maxlen > SSIZE_MAX)
1114                 return -EINVAL;
1115         for (;;) {
1116                 len = dp->length;
1117                 if (len < 4)
1118                         return -1;
1119                 ret += len;
1120                 if (ret > maxlen)
1121                         return -1;
1122                 if (dp->type == DEVICE_PATH_TYPE_END &&
1123                     dp->sub_type == DEVICE_PATH_SUB_TYPE_END)
1124                         return ret;
1125                 dp = (const struct efi_device_path *)((const u8 *)dp + len);
1126         }
1127 }
1128
1129 /**
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
1134  *                    initrd location
1135  *
1136  * @lo:         EFI_LOAD_OPTION containing a valid device path
1137  * @guid:       guid to search for
1138  *
1139  * Return:
1140  * device path including the VenMedia node or NULL.
1141  * Caller must free the returned value.
1142  */
1143 struct
1144 efi_device_path *efi_dp_from_lo(struct efi_load_option *lo,
1145                                 const efi_guid_t *guid)
1146 {
1147         struct efi_device_path *fp = lo->file_path;
1148         struct efi_device_path_vendor *vendor;
1149         int lo_len = lo->file_path_length;
1150
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)
1154                         break;
1155                 if (fp->type != DEVICE_PATH_TYPE_MEDIA_DEVICE ||
1156                     fp->sub_type != DEVICE_PATH_SUB_TYPE_VENDOR_PATH)
1157                         continue;
1158
1159                 vendor = (struct efi_device_path_vendor *)fp;
1160                 if (!guidcmp(&vendor->guid, guid))
1161                         return efi_dp_dup(efi_dp_next(fp));
1162         }
1163         log_debug("VenMedia(%pUl) not found in %ls\n", &guid, lo->label);
1164
1165         return NULL;
1166 }
1167
1168 /**
1169  * search_gpt_dp_node() - search gpt device path node
1170  *
1171  * @device_path:        device path
1172  *
1173  * Return:      pointer to the gpt device path node
1174  */
1175 struct efi_device_path *search_gpt_dp_node(struct efi_device_path *device_path)
1176 {
1177         struct efi_device_path *dp = device_path;
1178
1179         while (dp) {
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;
1184
1185                         if (hd_dp->partmap_type == PART_FORMAT_GPT &&
1186                             hd_dp->signature_type == SIG_TYPE_GUID)
1187                                 return dp;
1188                 }
1189                 dp = efi_dp_next(dp);
1190         }
1191
1192         return NULL;
1193 }
This page took 0.09266 seconds and 2 git commands to generate.