"Das U-Boot" Source Tree
at master 1314 lines 32 kB view raw
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}