• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include <common.h>
9 #include <blk.h>
10 #include <dm.h>
11 #include <usb.h>
12 #include <mmc.h>
13 #include <nvme.h>
14 #include <efi_loader.h>
15 #include <part.h>
16 #include <sandboxblockdev.h>
17 #include <asm-generic/unaligned.h>
18 #include <linux/compat.h> /* U16_MAX */
19 
20 #ifdef CONFIG_SANDBOX
21 const efi_guid_t efi_guid_host_dev = U_BOOT_HOST_DEV_GUID;
22 #endif
23 
24 /* template END node: */
25 static 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 /* template ROOT node: */
32 static const struct efi_device_path_vendor ROOT = {
33 	.dp = {
34 		.type     = DEVICE_PATH_TYPE_HARDWARE_DEVICE,
35 		.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR,
36 		.length   = sizeof(ROOT),
37 	},
38 	.guid = U_BOOT_GUID,
39 };
40 
41 #if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
42 /*
43  * Determine if an MMC device is an SD card.
44  *
45  * @desc	block device descriptor
46  * @return	true if the device is an SD card
47  */
is_sd(struct blk_desc * desc)48 static bool is_sd(struct blk_desc *desc)
49 {
50 	struct mmc *mmc = find_mmc_device(desc->devnum);
51 
52 	if (!mmc)
53 		return false;
54 
55 	return IS_SD(mmc) != 0U;
56 }
57 #endif
58 
dp_alloc(size_t sz)59 static void *dp_alloc(size_t sz)
60 {
61 	void *buf;
62 
63 	if (efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, sz, &buf) !=
64 	    EFI_SUCCESS) {
65 		debug("EFI: ERROR: out of memory in %s\n", __func__);
66 		return NULL;
67 	}
68 
69 	memset(buf, 0, sz);
70 	return buf;
71 }
72 
73 /*
74  * Iterate to next block in device-path, terminating (returning NULL)
75  * at /End* node.
76  */
efi_dp_next(const struct efi_device_path * dp)77 struct efi_device_path *efi_dp_next(const struct efi_device_path *dp)
78 {
79 	if (dp == NULL)
80 		return NULL;
81 	if (dp->type == DEVICE_PATH_TYPE_END)
82 		return NULL;
83 	dp = ((void *)dp) + dp->length;
84 	if (dp->type == DEVICE_PATH_TYPE_END)
85 		return NULL;
86 	return (struct efi_device_path *)dp;
87 }
88 
89 /*
90  * Compare two device-paths, stopping when the shorter of the two hits
91  * an End* node. This is useful to, for example, compare a device-path
92  * representing a device with one representing a file on the device, or
93  * a device with a parent device.
94  */
efi_dp_match(const struct efi_device_path * a,const struct efi_device_path * b)95 int efi_dp_match(const struct efi_device_path *a,
96 		 const struct efi_device_path *b)
97 {
98 	while (1) {
99 		int ret;
100 
101 		ret = memcmp(&a->length, &b->length, sizeof(a->length));
102 		if (ret)
103 			return ret;
104 
105 		ret = memcmp(a, b, a->length);
106 		if (ret)
107 			return ret;
108 
109 		a = efi_dp_next(a);
110 		b = efi_dp_next(b);
111 
112 		if (!a || !b)
113 			return 0;
114 	}
115 }
116 
117 /*
118  * We can have device paths that start with a USB WWID or a USB Class node,
119  * and a few other cases which don't encode the full device path with bus
120  * hierarchy:
121  *
122  *   - MESSAGING:USB_WWID
123  *   - MESSAGING:USB_CLASS
124  *   - MEDIA:FILE_PATH
125  *   - MEDIA:HARD_DRIVE
126  *   - MESSAGING:URI
127  *
128  * See UEFI spec (section 3.1.2, about short-form device-paths)
129  */
shorten_path(struct efi_device_path * dp)130 static struct efi_device_path *shorten_path(struct efi_device_path *dp)
131 {
132 	while (dp) {
133 		/*
134 		 * TODO: Add MESSAGING:USB_WWID and MESSAGING:URI..
135 		 * in practice fallback.efi just uses MEDIA:HARD_DRIVE
136 		 * so not sure when we would see these other cases.
137 		 */
138 		if (EFI_DP_TYPE(dp, MESSAGING_DEVICE, MSG_USB_CLASS) ||
139 		    EFI_DP_TYPE(dp, MEDIA_DEVICE, HARD_DRIVE_PATH) ||
140 		    EFI_DP_TYPE(dp, MEDIA_DEVICE, FILE_PATH))
141 			return dp;
142 
143 		dp = efi_dp_next(dp);
144 	}
145 
146 	return dp;
147 }
148 
find_obj(struct efi_device_path * dp,bool short_path,struct efi_device_path ** rem)149 static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path,
150 				   struct efi_device_path **rem)
151 {
152 	struct efi_object *efiobj;
153 	efi_uintn_t dp_size = efi_dp_instance_size(dp);
154 
155 	list_for_each_entry(efiobj, &efi_obj_list, link) {
156 		struct efi_handler *handler;
157 		struct efi_device_path *obj_dp;
158 		efi_status_t ret;
159 
160 		ret = efi_search_protocol(efiobj,
161 					  &efi_guid_device_path, &handler);
162 		if (ret != EFI_SUCCESS)
163 			continue;
164 		obj_dp = handler->protocol_interface;
165 
166 		do {
167 			if (efi_dp_match(dp, obj_dp) == 0) {
168 				if (rem) {
169 					/*
170 					 * Allow partial matches, but inform
171 					 * the caller.
172 					 */
173 					*rem = ((void *)dp) +
174 						efi_dp_instance_size(obj_dp);
175 					return efiobj;
176 				} else {
177 					/* Only return on exact matches */
178 					if (efi_dp_instance_size(obj_dp) ==
179 					    dp_size)
180 						return efiobj;
181 				}
182 			}
183 
184 			obj_dp = shorten_path(efi_dp_next(obj_dp));
185 		} while (short_path && obj_dp);
186 	}
187 
188 	return NULL;
189 }
190 
191 /*
192  * Find an efiobj from device-path, if 'rem' is not NULL, returns the
193  * remaining part of the device path after the matched object.
194  */
efi_dp_find_obj(struct efi_device_path * dp,struct efi_device_path ** rem)195 struct efi_object *efi_dp_find_obj(struct efi_device_path *dp,
196 				   struct efi_device_path **rem)
197 {
198 	struct efi_object *efiobj;
199 
200 	/* Search for an exact match first */
201 	efiobj = find_obj(dp, false, NULL);
202 
203 	/* Then for a fuzzy match */
204 	if (!efiobj)
205 		efiobj = find_obj(dp, false, rem);
206 
207 	/* And now for a fuzzy short match */
208 	if (!efiobj)
209 		efiobj = find_obj(dp, true, rem);
210 
211 	return efiobj;
212 }
213 
214 /*
215  * Determine the last device path node that is not the end node.
216  *
217  * @dp		device path
218  * @return	last node before the end node if it exists
219  *		otherwise NULL
220  */
efi_dp_last_node(const struct efi_device_path * dp)221 const struct efi_device_path *efi_dp_last_node(const struct efi_device_path *dp)
222 {
223 	struct efi_device_path *ret;
224 
225 	if (!dp || dp->type == DEVICE_PATH_TYPE_END)
226 		return NULL;
227 	while (dp) {
228 		ret = (struct efi_device_path *)dp;
229 		dp = efi_dp_next(dp);
230 	}
231 	return ret;
232 }
233 
234 /* get size of the first device path instance excluding end node */
efi_dp_instance_size(const struct efi_device_path * dp)235 efi_uintn_t efi_dp_instance_size(const struct efi_device_path *dp)
236 {
237 	efi_uintn_t sz = 0;
238 
239 	if (!dp || dp->type == DEVICE_PATH_TYPE_END)
240 		return 0;
241 	while (dp) {
242 		sz += dp->length;
243 		dp = efi_dp_next(dp);
244 	}
245 
246 	return sz;
247 }
248 
249 /* get size of multi-instance device path excluding end node */
efi_dp_size(const struct efi_device_path * dp)250 efi_uintn_t efi_dp_size(const struct efi_device_path *dp)
251 {
252 	const struct efi_device_path *p = dp;
253 
254 	if (!p)
255 		return 0;
256 	while (p->type != DEVICE_PATH_TYPE_END ||
257 	       p->sub_type != DEVICE_PATH_SUB_TYPE_END)
258 		p = (void *)p + p->length;
259 
260 	return (void *)p - (void *)dp;
261 }
262 
263 /* copy multi-instance device path */
efi_dp_dup(const struct efi_device_path * dp)264 struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp)
265 {
266 	struct efi_device_path *ndp;
267 	size_t sz = efi_dp_size(dp) + sizeof(END);
268 
269 	if (!dp)
270 		return NULL;
271 
272 	ndp = dp_alloc(sz);
273 	if (!ndp)
274 		return NULL;
275 	memcpy(ndp, dp, sz);
276 
277 	return ndp;
278 }
279 
efi_dp_append(const struct efi_device_path * dp1,const struct efi_device_path * dp2)280 struct efi_device_path *efi_dp_append(const struct efi_device_path *dp1,
281 				      const struct efi_device_path *dp2)
282 {
283 	struct efi_device_path *ret;
284 
285 	if (!dp1 && !dp2) {
286 		/* return an end node */
287 		ret = efi_dp_dup(&END);
288 	} else if (!dp1) {
289 		ret = efi_dp_dup(dp2);
290 	} else if (!dp2) {
291 		ret = efi_dp_dup(dp1);
292 	} else {
293 		/* both dp1 and dp2 are non-null */
294 		unsigned sz1 = efi_dp_size(dp1);
295 		unsigned sz2 = efi_dp_size(dp2);
296 		void *p = dp_alloc(sz1 + sz2 + sizeof(END));
297 		if (!p)
298 			return NULL;
299 		memcpy(p, dp1, sz1);
300 		/* the end node of the second device path has to be retained */
301 		memcpy(p + sz1, dp2, sz2 + sizeof(END));
302 		ret = p;
303 	}
304 
305 	return ret;
306 }
307 
efi_dp_append_node(const struct efi_device_path * dp,const struct efi_device_path * node)308 struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp,
309 					   const struct efi_device_path *node)
310 {
311 	struct efi_device_path *ret;
312 
313 	if (!node && !dp) {
314 		ret = efi_dp_dup(&END);
315 	} else if (!node) {
316 		ret = efi_dp_dup(dp);
317 	} else if (!dp) {
318 		size_t sz = node->length;
319 		void *p = dp_alloc(sz + sizeof(END));
320 		if (!p)
321 			return NULL;
322 		memcpy(p, node, sz);
323 		memcpy(p + sz, &END, sizeof(END));
324 		ret = p;
325 	} else {
326 		/* both dp and node are non-null */
327 		size_t sz = efi_dp_size(dp);
328 		void *p = dp_alloc(sz + node->length + sizeof(END));
329 		if (!p)
330 			return NULL;
331 		memcpy(p, dp, sz);
332 		memcpy(p + sz, node, node->length);
333 		memcpy(p + sz + node->length, &END, sizeof(END));
334 		ret = p;
335 	}
336 
337 	return ret;
338 }
339 
efi_dp_create_device_node(const u8 type,const u8 sub_type,const u16 length)340 struct efi_device_path *efi_dp_create_device_node(const u8 type,
341 						  const u8 sub_type,
342 						  const u16 length)
343 {
344 	struct efi_device_path *ret;
345 
346 	if (length < sizeof(struct efi_device_path))
347 		return NULL;
348 
349 	ret = dp_alloc(length);
350 	if (!ret)
351 		return ret;
352 	ret->type = type;
353 	ret->sub_type = sub_type;
354 	ret->length = length;
355 	return ret;
356 }
357 
efi_dp_append_instance(const struct efi_device_path * dp,const struct efi_device_path * dpi)358 struct efi_device_path *efi_dp_append_instance(
359 		const struct efi_device_path *dp,
360 		const struct efi_device_path *dpi)
361 {
362 	size_t sz, szi;
363 	struct efi_device_path *p, *ret;
364 
365 	if (!dpi)
366 		return NULL;
367 	if (!dp)
368 		return efi_dp_dup(dpi);
369 	sz = efi_dp_size(dp);
370 	szi = efi_dp_instance_size(dpi);
371 	p = dp_alloc(sz + szi + 2 * sizeof(END));
372 	if (!p)
373 		return NULL;
374 	ret = p;
375 	memcpy(p, dp, sz + sizeof(END));
376 	p = (void *)p + sz;
377 	p->sub_type = DEVICE_PATH_SUB_TYPE_INSTANCE_END;
378 	p = (void *)p + sizeof(END);
379 	memcpy(p, dpi, szi);
380 	p = (void *)p + szi;
381 	memcpy(p, &END, sizeof(END));
382 	return ret;
383 }
384 
efi_dp_get_next_instance(struct efi_device_path ** dp,efi_uintn_t * size)385 struct efi_device_path *efi_dp_get_next_instance(struct efi_device_path **dp,
386 						 efi_uintn_t *size)
387 {
388 	size_t sz;
389 	struct efi_device_path *p;
390 
391 	if (size)
392 		*size = 0;
393 	if (!dp || !*dp)
394 		return NULL;
395 	sz = efi_dp_instance_size(*dp);
396 	p = dp_alloc(sz + sizeof(END));
397 	if (!p)
398 		return NULL;
399 	memcpy(p, *dp, sz + sizeof(END));
400 	*dp = (void *)*dp + sz;
401 	if ((*dp)->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END)
402 		*dp = (void *)*dp + sizeof(END);
403 	else
404 		*dp = NULL;
405 	if (size)
406 		*size = sz + sizeof(END);
407 	return p;
408 }
409 
efi_dp_is_multi_instance(const struct efi_device_path * dp)410 bool efi_dp_is_multi_instance(const struct efi_device_path *dp)
411 {
412 	const struct efi_device_path *p = dp;
413 
414 	if (!p)
415 		return false;
416 	while (p->type != DEVICE_PATH_TYPE_END)
417 		p = (void *)p + p->length;
418 	return p->sub_type == DEVICE_PATH_SUB_TYPE_INSTANCE_END;
419 }
420 
421 #ifdef CONFIG_DM
422 /* size of device-path not including END node for device and all parents
423  * up to the root device.
424  */
dp_size(struct udevice * dev)425 __maybe_unused static unsigned int dp_size(struct udevice *dev)
426 {
427 	if (!dev || !dev->driver)
428 		return sizeof(ROOT);
429 
430 	switch (dev->driver->id) {
431 	case UCLASS_ROOT:
432 	case UCLASS_SIMPLE_BUS:
433 		/* stop traversing parents at this point: */
434 		return sizeof(ROOT);
435 	case UCLASS_ETH:
436 		return dp_size(dev->parent) +
437 			sizeof(struct efi_device_path_mac_addr);
438 #ifdef CONFIG_BLK
439 	case UCLASS_BLK:
440 		switch (dev->parent->uclass->uc_drv->id) {
441 #ifdef CONFIG_IDE
442 		case UCLASS_IDE:
443 			return dp_size(dev->parent) +
444 				sizeof(struct efi_device_path_atapi);
445 #endif
446 #if defined(CONFIG_SCSI) && defined(CONFIG_DM_SCSI)
447 		case UCLASS_SCSI:
448 			return dp_size(dev->parent) +
449 				sizeof(struct efi_device_path_scsi);
450 #endif
451 #if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
452 		case UCLASS_MMC:
453 			return dp_size(dev->parent) +
454 				sizeof(struct efi_device_path_sd_mmc_path);
455 #endif
456 #if defined(CONFIG_NVME)
457 		case UCLASS_NVME:
458 			return dp_size(dev->parent) +
459 				sizeof(struct efi_device_path_nvme);
460 #endif
461 #ifdef CONFIG_SANDBOX
462 		case UCLASS_ROOT:
463 			 /*
464 			  * Sandbox's host device will be represented
465 			  * as vendor device with extra one byte for
466 			  * device number
467 			  */
468 			return dp_size(dev->parent)
469 				+ sizeof(struct efi_device_path_vendor) + 1;
470 #endif
471 		default:
472 			return dp_size(dev->parent);
473 		}
474 #endif
475 #if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
476 	case UCLASS_MMC:
477 		return dp_size(dev->parent) +
478 			sizeof(struct efi_device_path_sd_mmc_path);
479 #endif
480 	case UCLASS_MASS_STORAGE:
481 	case UCLASS_USB_HUB:
482 		return dp_size(dev->parent) +
483 			sizeof(struct efi_device_path_usb_class);
484 	default:
485 		/* just skip over unknown classes: */
486 		return dp_size(dev->parent);
487 	}
488 }
489 
490 /*
491  * Recursively build a device path.
492  *
493  * @buf		pointer to the end of the device path
494  * @dev		device
495  * @return	pointer to the end of the device path
496  */
dp_fill(void * buf,struct udevice * dev)497 __maybe_unused static void *dp_fill(void *buf, struct udevice *dev)
498 {
499 	if (!dev || !dev->driver)
500 		return buf;
501 
502 	switch (dev->driver->id) {
503 	case UCLASS_ROOT:
504 	case UCLASS_SIMPLE_BUS: {
505 		/* stop traversing parents at this point: */
506 		struct efi_device_path_vendor *vdp = buf;
507 		*vdp = ROOT;
508 		return &vdp[1];
509 	}
510 #ifdef CONFIG_DM_ETH
511 	case UCLASS_ETH: {
512 		struct efi_device_path_mac_addr *dp =
513 			dp_fill(buf, dev->parent);
514 		struct eth_pdata *pdata = dev->platdata;
515 
516 		dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
517 		dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR;
518 		dp->dp.length = sizeof(*dp);
519 		memset(&dp->mac, 0, sizeof(dp->mac));
520 		/* We only support IPv4 */
521 		memcpy(&dp->mac, &pdata->enetaddr, ARP_HLEN);
522 		/* Ethernet */
523 		dp->if_type = 1;
524 		return &dp[1];
525 	}
526 #endif
527 #ifdef CONFIG_BLK
528 	case UCLASS_BLK:
529 		switch (dev->parent->uclass->uc_drv->id) {
530 #ifdef CONFIG_SANDBOX
531 		case UCLASS_ROOT: {
532 			/* stop traversing parents at this point: */
533 			struct efi_device_path_vendor *dp = buf;
534 			struct blk_desc *desc = dev_get_uclass_platdata(dev);
535 
536 			dp_fill(buf, dev->parent);
537 			dp = buf;
538 			++dp;
539 			dp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
540 			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_VENDOR;
541 			dp->dp.length = sizeof(*dp) + 1;
542 			memcpy(&dp->guid, &efi_guid_host_dev,
543 			       sizeof(efi_guid_t));
544 			dp->vendor_data[0] = desc->devnum;
545 			return &dp->vendor_data[1];
546 			}
547 #endif
548 #ifdef CONFIG_IDE
549 		case UCLASS_IDE: {
550 			struct efi_device_path_atapi *dp =
551 			dp_fill(buf, dev->parent);
552 			struct blk_desc *desc = dev_get_uclass_platdata(dev);
553 
554 			dp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
555 			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_ATAPI;
556 			dp->dp.length = sizeof(*dp);
557 			dp->logical_unit_number = desc->devnum;
558 			dp->primary_secondary = IDE_BUS(desc->devnum);
559 			dp->slave_master = desc->devnum %
560 				(CONFIG_SYS_IDE_MAXDEVICE /
561 				 CONFIG_SYS_IDE_MAXBUS);
562 			return &dp[1];
563 			}
564 #endif
565 #if defined(CONFIG_SCSI) && defined(CONFIG_DM_SCSI)
566 		case UCLASS_SCSI: {
567 			struct efi_device_path_scsi *dp =
568 				dp_fill(buf, dev->parent);
569 			struct blk_desc *desc = dev_get_uclass_platdata(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_DM_MMC) && defined(CONFIG_MMC)
580 		case UCLASS_MMC: {
581 			struct efi_device_path_sd_mmc_path *sddp =
582 				dp_fill(buf, dev->parent);
583 			struct blk_desc *desc = dev_get_uclass_platdata(dev);
584 
585 			sddp->dp.type     = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
586 			sddp->dp.sub_type = is_sd(desc) ?
587 				DEVICE_PATH_SUB_TYPE_MSG_SD :
588 				DEVICE_PATH_SUB_TYPE_MSG_MMC;
589 			sddp->dp.length   = sizeof(*sddp);
590 			sddp->slot_number = dev->seq;
591 			return &sddp[1];
592 			}
593 #endif
594 #if defined(CONFIG_NVME)
595 		case UCLASS_NVME: {
596 			struct efi_device_path_nvme *dp =
597 				dp_fill(buf, dev->parent);
598 			u32 ns_id;
599 
600 			dp->dp.type     = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
601 			dp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_NVME;
602 			dp->dp.length   = sizeof(*dp);
603 			nvme_get_namespace_id(dev, &ns_id, dp->eui64);
604 			memcpy(&dp->ns_id, &ns_id, sizeof(ns_id));
605 			return &dp[1];
606 			}
607 #endif
608 		default:
609 			debug("%s(%u) %s: unhandled parent class: %s (%u)\n",
610 			      __FILE__, __LINE__, __func__,
611 			      dev->name, dev->parent->uclass->uc_drv->id);
612 			return dp_fill(buf, dev->parent);
613 		}
614 #endif
615 #if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
616 	case UCLASS_MMC: {
617 		struct efi_device_path_sd_mmc_path *sddp =
618 			dp_fill(buf, dev->parent);
619 		struct mmc *mmc = mmc_get_mmc_dev(dev);
620 		struct blk_desc *desc = mmc_get_blk_desc(mmc);
621 
622 		sddp->dp.type     = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
623 		sddp->dp.sub_type = is_sd(desc) ?
624 			DEVICE_PATH_SUB_TYPE_MSG_SD :
625 			DEVICE_PATH_SUB_TYPE_MSG_MMC;
626 		sddp->dp.length   = sizeof(*sddp);
627 		sddp->slot_number = dev->seq;
628 
629 		return &sddp[1];
630 	}
631 #endif
632 	case UCLASS_MASS_STORAGE:
633 	case UCLASS_USB_HUB: {
634 		struct efi_device_path_usb_class *udp =
635 			dp_fill(buf, dev->parent);
636 		struct usb_device *udev = dev_get_parent_priv(dev);
637 		struct usb_device_descriptor *desc = &udev->descriptor;
638 
639 		udp->dp.type     = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
640 		udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS;
641 		udp->dp.length   = sizeof(*udp);
642 		udp->vendor_id   = desc->idVendor;
643 		udp->product_id  = desc->idProduct;
644 		udp->device_class    = desc->bDeviceClass;
645 		udp->device_subclass = desc->bDeviceSubClass;
646 		udp->device_protocol = desc->bDeviceProtocol;
647 
648 		return &udp[1];
649 	}
650 	default:
651 		debug("%s(%u) %s: unhandled device class: %s (%u)\n",
652 		      __FILE__, __LINE__, __func__,
653 		      dev->name, dev->driver->id);
654 		return dp_fill(buf, dev->parent);
655 	}
656 }
657 #endif
658 
dp_part_size(struct blk_desc * desc,int part)659 static unsigned dp_part_size(struct blk_desc *desc, int part)
660 {
661 	unsigned dpsize;
662 
663 #ifdef CONFIG_BLK
664 	{
665 		struct udevice *dev;
666 		int ret = blk_find_device(desc->if_type, desc->devnum, &dev);
667 
668 		if (ret)
669 			dev = desc->bdev->parent;
670 		dpsize = dp_size(dev);
671 	}
672 #else
673 	dpsize = sizeof(ROOT) + sizeof(struct efi_device_path_usb);
674 #endif
675 
676 	if (part == 0) /* the actual disk, not a partition */
677 		return dpsize;
678 
679 	if (desc->part_type == PART_TYPE_ISO)
680 		dpsize += sizeof(struct efi_device_path_cdrom_path);
681 	else
682 		dpsize += sizeof(struct efi_device_path_hard_drive_path);
683 
684 	return dpsize;
685 }
686 
687 /*
688  * Create a device node for a block device partition.
689  *
690  * @buf		buffer to which the device path is written
691  * @desc	block device descriptor
692  * @part	partition number, 0 identifies a block device
693  */
dp_part_node(void * buf,struct blk_desc * desc,int part)694 static void *dp_part_node(void *buf, struct blk_desc *desc, int part)
695 {
696 	disk_partition_t info;
697 
698 	part_get_info(desc, part, &info);
699 
700 	if (desc->part_type == PART_TYPE_ISO) {
701 		struct efi_device_path_cdrom_path *cddp = buf;
702 
703 		cddp->boot_entry = part;
704 		cddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
705 		cddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CDROM_PATH;
706 		cddp->dp.length = sizeof(*cddp);
707 		cddp->partition_start = info.start;
708 		cddp->partition_size = info.size;
709 
710 		buf = &cddp[1];
711 	} else {
712 		struct efi_device_path_hard_drive_path *hddp = buf;
713 
714 		hddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
715 		hddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH;
716 		hddp->dp.length = sizeof(*hddp);
717 		hddp->partition_number = part;
718 		hddp->partition_start = info.start;
719 		hddp->partition_end = info.size;
720 		if (desc->part_type == PART_TYPE_EFI)
721 			hddp->partmap_type = 2;
722 		else
723 			hddp->partmap_type = 1;
724 
725 		switch (desc->sig_type) {
726 		case SIG_TYPE_NONE:
727 		default:
728 			hddp->signature_type = 0;
729 			memset(hddp->partition_signature, 0,
730 			       sizeof(hddp->partition_signature));
731 			break;
732 		case SIG_TYPE_MBR:
733 			hddp->signature_type = 1;
734 			memset(hddp->partition_signature, 0,
735 			       sizeof(hddp->partition_signature));
736 			memcpy(hddp->partition_signature, &desc->mbr_sig,
737 			       sizeof(desc->mbr_sig));
738 			break;
739 		case SIG_TYPE_GUID:
740 			hddp->signature_type = 2;
741 			memcpy(hddp->partition_signature, &desc->guid_sig,
742 			       sizeof(hddp->partition_signature));
743 			break;
744 		}
745 
746 		buf = &hddp[1];
747 	}
748 
749 	return buf;
750 }
751 
752 /*
753  * Create a device path for a block device or one of its partitions.
754  *
755  * @buf		buffer to which the device path is written
756  * @desc	block device descriptor
757  * @part	partition number, 0 identifies a block device
758  */
dp_part_fill(void * buf,struct blk_desc * desc,int part)759 static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
760 {
761 #ifdef CONFIG_BLK
762 	{
763 		struct udevice *dev;
764 		int ret = blk_find_device(desc->if_type, desc->devnum, &dev);
765 
766 		if (ret)
767 			dev = desc->bdev->parent;
768 		buf = dp_fill(buf, dev);
769 	}
770 #else
771 	/*
772 	 * We *could* make a more accurate path, by looking at if_type
773 	 * and handling all the different cases like we do for non-
774 	 * legacy (i.e. CONFIG_BLK=y) case. But most important thing
775 	 * is just to have a unique device-path for if_type+devnum.
776 	 * So map things to a fictitious USB device.
777 	 */
778 	struct efi_device_path_usb *udp;
779 
780 	memcpy(buf, &ROOT, sizeof(ROOT));
781 	buf += sizeof(ROOT);
782 
783 	udp = buf;
784 	udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
785 	udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB;
786 	udp->dp.length = sizeof(*udp);
787 	udp->parent_port_number = desc->if_type;
788 	udp->usb_interface = desc->devnum;
789 	buf = &udp[1];
790 #endif
791 
792 	if (part == 0) /* the actual disk, not a partition */
793 		return buf;
794 
795 	return dp_part_node(buf, desc, part);
796 }
797 
798 /* Construct a device-path from a partition on a block device: */
efi_dp_from_part(struct blk_desc * desc,int part)799 struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part)
800 {
801 	void *buf, *start;
802 
803 	start = buf = dp_alloc(dp_part_size(desc, part) + sizeof(END));
804 	if (!buf)
805 		return NULL;
806 
807 	buf = dp_part_fill(buf, desc, part);
808 
809 	*((struct efi_device_path *)buf) = END;
810 
811 	return start;
812 }
813 
814 /*
815  * Create a device node for a block device partition.
816  *
817  * @buf		buffer to which the device path is written
818  * @desc	block device descriptor
819  * @part	partition number, 0 identifies a block device
820  */
efi_dp_part_node(struct blk_desc * desc,int part)821 struct efi_device_path *efi_dp_part_node(struct blk_desc *desc, int part)
822 {
823 	efi_uintn_t dpsize;
824 	void *buf;
825 
826 	if (desc->part_type == PART_TYPE_ISO)
827 		dpsize = sizeof(struct efi_device_path_cdrom_path);
828 	else
829 		dpsize = sizeof(struct efi_device_path_hard_drive_path);
830 	buf = dp_alloc(dpsize);
831 
832 	dp_part_node(buf, desc, part);
833 
834 	return buf;
835 }
836 
837 /**
838  * path_to_uefi() - convert UTF-8 path to an UEFI style path
839  *
840  * Convert UTF-8 path to a UEFI style path (i.e. with backslashes as path
841  * separators and UTF-16).
842  *
843  * @src:	source buffer
844  * @uefi:	target buffer, possibly unaligned
845  */
path_to_uefi(void * uefi,const char * src)846 static void path_to_uefi(void *uefi, const char *src)
847 {
848 	u16 *pos = uefi;
849 
850 	/*
851 	 * efi_set_bootdev() calls this routine indirectly before the UEFI
852 	 * subsystem is initialized. So we cannot assume unaligned access to be
853 	 * enabled.
854 	 */
855 	allow_unaligned();
856 
857 	while (*src) {
858 		s32 code = utf8_get(&src);
859 
860 		if (code < 0)
861 			code = '?';
862 		else if (code == '/')
863 			code = '\\';
864 		utf16_put(code, &pos);
865 	}
866 	*pos = 0;
867 }
868 
869 /*
870  * If desc is NULL, this creates a path with only the file component,
871  * otherwise it creates a full path with both device and file components
872  */
efi_dp_from_file(struct blk_desc * desc,int part,const char * path)873 struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part,
874 		const char *path)
875 {
876 	struct efi_device_path_file_path *fp;
877 	void *buf, *start;
878 	size_t dpsize = 0, fpsize;
879 
880 	if (desc)
881 		dpsize = dp_part_size(desc, part);
882 
883 	fpsize = sizeof(struct efi_device_path) +
884 		 2 * (utf8_utf16_strlen(path) + 1);
885 	if (fpsize > U16_MAX)
886 		return NULL;
887 
888 	dpsize += fpsize;
889 
890 	start = buf = dp_alloc(dpsize + sizeof(END));
891 	if (!buf)
892 		return NULL;
893 
894 	if (desc)
895 		buf = dp_part_fill(buf, desc, part);
896 
897 	/* add file-path: */
898 	fp = buf;
899 	fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
900 	fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
901 	fp->dp.length = (u16)fpsize;
902 	path_to_uefi(fp->str, path);
903 	buf += fpsize;
904 
905 	*((struct efi_device_path *)buf) = END;
906 
907 	return start;
908 }
909 
910 #ifdef CONFIG_NET
efi_dp_from_eth(void)911 struct efi_device_path *efi_dp_from_eth(void)
912 {
913 #ifndef CONFIG_DM_ETH
914 	struct efi_device_path_mac_addr *ndp;
915 #endif
916 	void *buf, *start;
917 	unsigned dpsize = 0;
918 
919 	assert(eth_get_dev());
920 
921 #ifdef CONFIG_DM_ETH
922 	dpsize += dp_size(eth_get_dev());
923 #else
924 	dpsize += sizeof(ROOT);
925 	dpsize += sizeof(*ndp);
926 #endif
927 
928 	start = buf = dp_alloc(dpsize + sizeof(END));
929 	if (!buf)
930 		return NULL;
931 
932 #ifdef CONFIG_DM_ETH
933 	buf = dp_fill(buf, eth_get_dev());
934 #else
935 	memcpy(buf, &ROOT, sizeof(ROOT));
936 	buf += sizeof(ROOT);
937 
938 	ndp = buf;
939 	ndp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
940 	ndp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR;
941 	ndp->dp.length = sizeof(*ndp);
942 	ndp->if_type = 1; /* Ethernet */
943 	memcpy(ndp->mac.addr, eth_get_ethaddr(), ARP_HLEN);
944 	buf = &ndp[1];
945 #endif
946 
947 	*((struct efi_device_path *)buf) = END;
948 
949 	return start;
950 }
951 #endif
952 
953 /* Construct a device-path for memory-mapped image */
efi_dp_from_mem(uint32_t memory_type,uint64_t start_address,uint64_t end_address)954 struct efi_device_path *efi_dp_from_mem(uint32_t memory_type,
955 					uint64_t start_address,
956 					uint64_t end_address)
957 {
958 	struct efi_device_path_memory *mdp;
959 	void *buf, *start;
960 
961 	start = buf = dp_alloc(sizeof(*mdp) + sizeof(END));
962 	if (!buf)
963 		return NULL;
964 
965 	mdp = buf;
966 	mdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE;
967 	mdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MEMORY;
968 	mdp->dp.length = sizeof(*mdp);
969 	mdp->memory_type = memory_type;
970 	mdp->start_address = start_address;
971 	mdp->end_address = end_address;
972 	buf = &mdp[1];
973 
974 	*((struct efi_device_path *)buf) = END;
975 
976 	return start;
977 }
978 
979 /**
980  * efi_dp_split_file_path() - split of relative file path from device path
981  *
982  * Given a device path indicating a file on a device, separate the device
983  * path in two: the device path of the actual device and the file path
984  * relative to this device.
985  *
986  * @full_path:		device path including device and file path
987  * @device_path:	path of the device
988  * @file_path:		relative path of the file or NULL if there is none
989  * Return:		status code
990  */
efi_dp_split_file_path(struct efi_device_path * full_path,struct efi_device_path ** device_path,struct efi_device_path ** file_path)991 efi_status_t efi_dp_split_file_path(struct efi_device_path *full_path,
992 				    struct efi_device_path **device_path,
993 				    struct efi_device_path **file_path)
994 {
995 	struct efi_device_path *p, *dp, *fp = NULL;
996 
997 	*device_path = NULL;
998 	*file_path = NULL;
999 	dp = efi_dp_dup(full_path);
1000 	if (!dp)
1001 		return EFI_OUT_OF_RESOURCES;
1002 	p = dp;
1003 	while (!EFI_DP_TYPE(p, MEDIA_DEVICE, FILE_PATH)) {
1004 		p = efi_dp_next(p);
1005 		if (!p)
1006 			goto out;
1007 	}
1008 	fp = efi_dp_dup(p);
1009 	if (!fp)
1010 		return EFI_OUT_OF_RESOURCES;
1011 	p->type = DEVICE_PATH_TYPE_END;
1012 	p->sub_type = DEVICE_PATH_SUB_TYPE_END;
1013 	p->length = sizeof(*p);
1014 
1015 out:
1016 	*device_path = dp;
1017 	*file_path = fp;
1018 	return EFI_SUCCESS;
1019 }
1020 
1021 /**
1022  * efi_dp_from_name() - convert U-Boot device and file path to device path
1023  *
1024  * @dev:	U-Boot device, e.g. 'mmc'
1025  * @devnr:	U-Boot device number, e.g. 1 for 'mmc:1'
1026  * @path:	file path relative to U-Boot device, may be NULL
1027  * @device:	pointer to receive device path of the device
1028  * @file:	pointer to receive device path for the file
1029  * Return:	status code
1030  */
efi_dp_from_name(const char * dev,const char * devnr,const char * path,struct efi_device_path ** device,struct efi_device_path ** file)1031 efi_status_t efi_dp_from_name(const char *dev, const char *devnr,
1032 			      const char *path,
1033 			      struct efi_device_path **device,
1034 			      struct efi_device_path **file)
1035 {
1036 	int is_net;
1037 	struct blk_desc *desc = NULL;
1038 	disk_partition_t fs_partition;
1039 	int part = 0;
1040 	char filename[32] = { 0 }; /* dp->str is u16[32] long */
1041 	char *s;
1042 
1043 	if (path && !file)
1044 		return EFI_INVALID_PARAMETER;
1045 
1046 	is_net = !strcmp(dev, "Net");
1047 	if (!is_net) {
1048 		part = blk_get_device_part_str(dev, devnr, &desc, &fs_partition,
1049 					       1);
1050 		if (part < 0 || !desc)
1051 			return EFI_INVALID_PARAMETER;
1052 
1053 		if (device)
1054 			*device = efi_dp_from_part(desc, part);
1055 	} else {
1056 #ifdef CONFIG_NET
1057 		if (device)
1058 			*device = efi_dp_from_eth();
1059 #endif
1060 	}
1061 
1062 	if (!path)
1063 		return EFI_SUCCESS;
1064 
1065 	snprintf(filename, sizeof(filename), "%s", path);
1066 	/* DOS style file path: */
1067 	s = filename;
1068 	while ((s = strchr(s, '/')))
1069 		*s++ = '\\';
1070 	*file = efi_dp_from_file(is_net ? NULL : desc, part, filename);
1071 
1072 	if (!*file)
1073 		return EFI_INVALID_PARAMETER;
1074 
1075 	return EFI_SUCCESS;
1076 }
1077