1 /* 2 * EFI device path from u-boot device-model mapping 3 * 4 * (C) Copyright 2017 Rob Clark 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 */ 8 9 #include <common.h> 10 #include <blk.h> 11 #include <dm.h> 12 #include <usb.h> 13 #include <mmc.h> 14 #include <efi_loader.h> 15 #include <inttypes.h> 16 #include <part.h> 17 18 /* template END node: */ 19 static const struct efi_device_path END = { 20 .type = DEVICE_PATH_TYPE_END, 21 .sub_type = DEVICE_PATH_SUB_TYPE_END, 22 .length = sizeof(END), 23 }; 24 25 #define U_BOOT_GUID \ 26 EFI_GUID(0xe61d73b9, 0xa384, 0x4acc, \ 27 0xae, 0xab, 0x82, 0xe8, 0x28, 0xf3, 0x62, 0x8b) 28 29 /* template ROOT node: */ 30 static const struct efi_device_path_vendor ROOT = { 31 .dp = { 32 .type = DEVICE_PATH_TYPE_HARDWARE_DEVICE, 33 .sub_type = DEVICE_PATH_SUB_TYPE_VENDOR, 34 .length = sizeof(ROOT), 35 }, 36 .guid = U_BOOT_GUID, 37 }; 38 39 static void *dp_alloc(size_t sz) 40 { 41 void *buf; 42 43 if (efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, sz, &buf) != EFI_SUCCESS) 44 return NULL; 45 46 return buf; 47 } 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(struct efi_device_path *a, struct efi_device_path *b) 72 { 73 while (1) { 74 int ret; 75 76 ret = memcmp(&a->length, &b->length, sizeof(a->length)); 77 if (ret) 78 return ret; 79 80 ret = memcmp(a, b, a->length); 81 if (ret) 82 return ret; 83 84 a = efi_dp_next(a); 85 b = efi_dp_next(b); 86 87 if (!a || !b) 88 return 0; 89 } 90 } 91 92 93 /* 94 * See UEFI spec (section 3.1.2, about short-form device-paths.. 95 * tl;dr: we can have a device-path that starts with a USB WWID 96 * or USB Class node, and a few other cases which don't encode 97 * the full device path with bus hierarchy: 98 * 99 * - MESSAGING:USB_WWID 100 * - MESSAGING:USB_CLASS 101 * - MEDIA:FILE_PATH 102 * - MEDIA:HARD_DRIVE 103 * - MESSAGING:URI 104 */ 105 static struct efi_device_path *shorten_path(struct efi_device_path *dp) 106 { 107 while (dp) { 108 /* 109 * TODO: Add MESSAGING:USB_WWID and MESSAGING:URI.. 110 * in practice fallback.efi just uses MEDIA:HARD_DRIVE 111 * so not sure when we would see these other cases. 112 */ 113 if (EFI_DP_TYPE(dp, MESSAGING_DEVICE, MSG_USB_CLASS) || 114 EFI_DP_TYPE(dp, MEDIA_DEVICE, HARD_DRIVE_PATH) || 115 EFI_DP_TYPE(dp, MEDIA_DEVICE, FILE_PATH)) 116 return dp; 117 118 dp = efi_dp_next(dp); 119 } 120 121 return dp; 122 } 123 124 static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path, 125 struct efi_device_path **rem) 126 { 127 struct efi_object *efiobj; 128 129 list_for_each_entry(efiobj, &efi_obj_list, link) { 130 int i; 131 132 for (i = 0; i < ARRAY_SIZE(efiobj->protocols); i++) { 133 struct efi_handler *handler = &efiobj->protocols[i]; 134 struct efi_device_path *obj_dp; 135 136 if (!handler->guid) 137 break; 138 139 if (guidcmp(handler->guid, &efi_guid_device_path)) 140 continue; 141 142 obj_dp = handler->protocol_interface; 143 144 do { 145 if (efi_dp_match(dp, obj_dp) == 0) { 146 if (rem) { 147 *rem = ((void *)dp) + 148 efi_dp_size(obj_dp); 149 } 150 return efiobj; 151 } 152 153 obj_dp = shorten_path(efi_dp_next(obj_dp)); 154 } while (short_path && obj_dp); 155 } 156 } 157 158 return NULL; 159 } 160 161 162 /* 163 * Find an efiobj from device-path, if 'rem' is not NULL, returns the 164 * remaining part of the device path after the matched object. 165 */ 166 struct efi_object *efi_dp_find_obj(struct efi_device_path *dp, 167 struct efi_device_path **rem) 168 { 169 struct efi_object *efiobj; 170 171 efiobj = find_obj(dp, false, rem); 172 173 if (!efiobj) 174 efiobj = find_obj(dp, true, rem); 175 176 return efiobj; 177 } 178 179 /* return size not including End node: */ 180 unsigned efi_dp_size(const struct efi_device_path *dp) 181 { 182 unsigned sz = 0; 183 184 while (dp) { 185 sz += dp->length; 186 dp = efi_dp_next(dp); 187 } 188 189 return sz; 190 } 191 192 struct efi_device_path *efi_dp_dup(const struct efi_device_path *dp) 193 { 194 struct efi_device_path *ndp; 195 unsigned sz = efi_dp_size(dp) + sizeof(END); 196 197 if (!dp) 198 return NULL; 199 200 ndp = dp_alloc(sz); 201 memcpy(ndp, dp, sz); 202 203 return ndp; 204 } 205 206 struct efi_device_path *efi_dp_append(const struct efi_device_path *dp1, 207 const struct efi_device_path *dp2) 208 { 209 struct efi_device_path *ret; 210 211 if (!dp1) { 212 ret = efi_dp_dup(dp2); 213 } else if (!dp2) { 214 ret = efi_dp_dup(dp1); 215 } else { 216 /* both dp1 and dp2 are non-null */ 217 unsigned sz1 = efi_dp_size(dp1); 218 unsigned sz2 = efi_dp_size(dp2); 219 void *p = dp_alloc(sz1 + sz2 + sizeof(END)); 220 memcpy(p, dp1, sz1); 221 memcpy(p + sz1, dp2, sz2); 222 memcpy(p + sz1 + sz2, &END, sizeof(END)); 223 ret = p; 224 } 225 226 return ret; 227 } 228 229 struct efi_device_path *efi_dp_append_node(const struct efi_device_path *dp, 230 const struct efi_device_path *node) 231 { 232 struct efi_device_path *ret; 233 234 if (!node && !dp) { 235 ret = efi_dp_dup(&END); 236 } else if (!node) { 237 ret = efi_dp_dup(dp); 238 } else if (!dp) { 239 unsigned sz = node->length; 240 void *p = dp_alloc(sz + sizeof(END)); 241 memcpy(p, node, sz); 242 memcpy(p + sz, &END, sizeof(END)); 243 ret = p; 244 } else { 245 /* both dp and node are non-null */ 246 unsigned sz = efi_dp_size(dp); 247 void *p = dp_alloc(sz + node->length + sizeof(END)); 248 memcpy(p, dp, sz); 249 memcpy(p + sz, node, node->length); 250 memcpy(p + sz + node->length, &END, sizeof(END)); 251 ret = p; 252 } 253 254 return ret; 255 } 256 257 #ifdef CONFIG_DM 258 /* size of device-path not including END node for device and all parents 259 * up to the root device. 260 */ 261 static unsigned dp_size(struct udevice *dev) 262 { 263 if (!dev || !dev->driver) 264 return sizeof(ROOT); 265 266 switch (dev->driver->id) { 267 case UCLASS_ROOT: 268 case UCLASS_SIMPLE_BUS: 269 /* stop traversing parents at this point: */ 270 return sizeof(ROOT); 271 case UCLASS_MMC: 272 return dp_size(dev->parent) + 273 sizeof(struct efi_device_path_sd_mmc_path); 274 case UCLASS_MASS_STORAGE: 275 case UCLASS_USB_HUB: 276 return dp_size(dev->parent) + 277 sizeof(struct efi_device_path_usb_class); 278 default: 279 /* just skip over unknown classes: */ 280 return dp_size(dev->parent); 281 } 282 } 283 284 static void *dp_fill(void *buf, struct udevice *dev) 285 { 286 if (!dev || !dev->driver) 287 return buf; 288 289 switch (dev->driver->id) { 290 case UCLASS_ROOT: 291 case UCLASS_SIMPLE_BUS: { 292 /* stop traversing parents at this point: */ 293 struct efi_device_path_vendor *vdp = buf; 294 *vdp = ROOT; 295 return &vdp[1]; 296 } 297 #if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC) 298 case UCLASS_MMC: { 299 struct efi_device_path_sd_mmc_path *sddp = 300 dp_fill(buf, dev->parent); 301 struct mmc *mmc = mmc_get_mmc_dev(dev); 302 struct blk_desc *desc = mmc_get_blk_desc(mmc); 303 304 sddp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; 305 sddp->dp.sub_type = (desc->if_type == IF_TYPE_MMC) ? 306 DEVICE_PATH_SUB_TYPE_MSG_MMC : 307 DEVICE_PATH_SUB_TYPE_MSG_SD; 308 sddp->dp.length = sizeof(*sddp); 309 sddp->slot_number = dev->seq; 310 311 return &sddp[1]; 312 } 313 #endif 314 case UCLASS_MASS_STORAGE: 315 case UCLASS_USB_HUB: { 316 struct efi_device_path_usb_class *udp = 317 dp_fill(buf, dev->parent); 318 struct usb_device *udev = dev_get_parent_priv(dev); 319 struct usb_device_descriptor *desc = &udev->descriptor; 320 321 udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; 322 udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB_CLASS; 323 udp->dp.length = sizeof(*udp); 324 udp->vendor_id = desc->idVendor; 325 udp->product_id = desc->idProduct; 326 udp->device_class = desc->bDeviceClass; 327 udp->device_subclass = desc->bDeviceSubClass; 328 udp->device_protocol = desc->bDeviceProtocol; 329 330 return &udp[1]; 331 } 332 default: 333 debug("unhandled device class: %s (%u)\n", 334 dev->name, dev->driver->id); 335 return dp_fill(buf, dev->parent); 336 } 337 } 338 339 /* Construct a device-path from a device: */ 340 struct efi_device_path *efi_dp_from_dev(struct udevice *dev) 341 { 342 void *buf, *start; 343 344 start = buf = dp_alloc(dp_size(dev) + sizeof(END)); 345 buf = dp_fill(buf, dev); 346 *((struct efi_device_path *)buf) = END; 347 348 return start; 349 } 350 #endif 351 352 static unsigned dp_part_size(struct blk_desc *desc, int part) 353 { 354 unsigned dpsize; 355 356 #ifdef CONFIG_BLK 357 dpsize = dp_size(desc->bdev->parent); 358 #else 359 dpsize = sizeof(ROOT) + sizeof(struct efi_device_path_usb); 360 #endif 361 362 if (part == 0) /* the actual disk, not a partition */ 363 return dpsize; 364 365 if (desc->part_type == PART_TYPE_ISO) 366 dpsize += sizeof(struct efi_device_path_cdrom_path); 367 else 368 dpsize += sizeof(struct efi_device_path_hard_drive_path); 369 370 return dpsize; 371 } 372 373 static void *dp_part_fill(void *buf, struct blk_desc *desc, int part) 374 { 375 disk_partition_t info; 376 377 #ifdef CONFIG_BLK 378 buf = dp_fill(buf, desc->bdev->parent); 379 #else 380 /* 381 * We *could* make a more accurate path, by looking at if_type 382 * and handling all the different cases like we do for non- 383 * legacy (ie CONFIG_BLK=y) case. But most important thing 384 * is just to have a unique device-path for if_type+devnum. 385 * So map things to a fictional USB device: 386 */ 387 struct efi_device_path_usb *udp; 388 389 memcpy(buf, &ROOT, sizeof(ROOT)); 390 buf += sizeof(ROOT); 391 392 udp = buf; 393 udp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; 394 udp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_USB; 395 udp->dp.length = sizeof(*udp); 396 udp->parent_port_number = desc->if_type; 397 udp->usb_interface = desc->devnum; 398 buf = &udp[1]; 399 #endif 400 401 if (part == 0) /* the actual disk, not a partition */ 402 return buf; 403 404 part_get_info(desc, part, &info); 405 406 if (desc->part_type == PART_TYPE_ISO) { 407 struct efi_device_path_cdrom_path *cddp = buf; 408 409 cddp->boot_entry = part - 1; 410 cddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; 411 cddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CDROM_PATH; 412 cddp->dp.length = sizeof(*cddp); 413 cddp->partition_start = info.start; 414 cddp->partition_end = info.size; 415 416 buf = &cddp[1]; 417 } else { 418 struct efi_device_path_hard_drive_path *hddp = buf; 419 420 hddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; 421 hddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH; 422 hddp->dp.length = sizeof(*hddp); 423 hddp->partition_number = part - 1; 424 hddp->partition_start = info.start; 425 hddp->partition_end = info.size; 426 if (desc->part_type == PART_TYPE_EFI) 427 hddp->partmap_type = 2; 428 else 429 hddp->partmap_type = 1; 430 hddp->signature_type = desc->sig_type; 431 if (hddp->signature_type != 0) 432 memcpy(hddp->partition_signature, &desc->guid_sig, 433 sizeof(hddp->partition_signature)); 434 435 buf = &hddp[1]; 436 } 437 438 return buf; 439 } 440 441 442 /* Construct a device-path from a partition on a blk device: */ 443 struct efi_device_path *efi_dp_from_part(struct blk_desc *desc, int part) 444 { 445 void *buf, *start; 446 447 start = buf = dp_alloc(dp_part_size(desc, part) + sizeof(END)); 448 449 buf = dp_part_fill(buf, desc, part); 450 451 *((struct efi_device_path *)buf) = END; 452 453 return start; 454 } 455 456 /* convert path to an UEFI style path (ie. DOS style backslashes and utf16) */ 457 static void path_to_uefi(u16 *uefi, const char *path) 458 { 459 while (*path) { 460 char c = *(path++); 461 if (c == '/') 462 c = '\\'; 463 *(uefi++) = c; 464 } 465 *uefi = '\0'; 466 } 467 468 /* 469 * If desc is NULL, this creates a path with only the file component, 470 * otherwise it creates a full path with both device and file components 471 */ 472 struct efi_device_path *efi_dp_from_file(struct blk_desc *desc, int part, 473 const char *path) 474 { 475 struct efi_device_path_file_path *fp; 476 void *buf, *start; 477 unsigned dpsize = 0, fpsize; 478 479 if (desc) 480 dpsize = dp_part_size(desc, part); 481 482 fpsize = sizeof(struct efi_device_path) + 2 * (strlen(path) + 1); 483 dpsize += fpsize; 484 485 start = buf = dp_alloc(dpsize + sizeof(END)); 486 487 if (desc) 488 buf = dp_part_fill(buf, desc, part); 489 490 /* add file-path: */ 491 fp = buf; 492 fp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE; 493 fp->dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH; 494 fp->dp.length = fpsize; 495 path_to_uefi(fp->str, path); 496 buf += fpsize; 497 498 *((struct efi_device_path *)buf) = END; 499 500 return start; 501 } 502 503 #ifdef CONFIG_NET 504 struct efi_device_path *efi_dp_from_eth(void) 505 { 506 struct efi_device_path_mac_addr *ndp; 507 void *buf, *start; 508 unsigned dpsize = 0; 509 510 assert(eth_get_dev()); 511 512 #ifdef CONFIG_DM_ETH 513 dpsize += dp_size(eth_get_dev()); 514 #else 515 dpsize += sizeof(ROOT); 516 #endif 517 dpsize += sizeof(*ndp); 518 519 start = buf = dp_alloc(dpsize + sizeof(END)); 520 521 #ifdef CONFIG_DM_ETH 522 buf = dp_fill(buf, eth_get_dev()); 523 #else 524 memcpy(buf, &ROOT, sizeof(ROOT)); 525 buf += sizeof(ROOT); 526 #endif 527 528 ndp = buf; 529 ndp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE; 530 ndp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR; 531 ndp->dp.length = sizeof(*ndp); 532 memcpy(ndp->mac.addr, eth_get_ethaddr(), ARP_HLEN); 533 buf = &ndp[1]; 534 535 *((struct efi_device_path *)buf) = END; 536 537 return start; 538 } 539 #endif 540 541 /* Construct a device-path for memory-mapped image */ 542 struct efi_device_path *efi_dp_from_mem(uint32_t memory_type, 543 uint64_t start_address, 544 uint64_t end_address) 545 { 546 struct efi_device_path_memory *mdp; 547 void *buf, *start; 548 549 start = buf = dp_alloc(sizeof(*mdp) + sizeof(END)); 550 551 mdp = buf; 552 mdp->dp.type = DEVICE_PATH_TYPE_HARDWARE_DEVICE; 553 mdp->dp.sub_type = DEVICE_PATH_SUB_TYPE_MEMORY; 554 mdp->dp.length = sizeof(*mdp); 555 mdp->memory_type = memory_type; 556 mdp->start_address = start_address; 557 mdp->end_address = end_address; 558 buf = &mdp[1]; 559 560 *((struct efi_device_path *)buf) = END; 561 562 return start; 563 } 564 565 /* 566 * Helper to split a full device path (containing both device and file 567 * parts) into it's constituent parts. 568 */ 569 void efi_dp_split_file_path(struct efi_device_path *full_path, 570 struct efi_device_path **device_path, 571 struct efi_device_path **file_path) 572 { 573 struct efi_device_path *p, *dp, *fp; 574 575 dp = efi_dp_dup(full_path); 576 p = dp; 577 while (!EFI_DP_TYPE(p, MEDIA_DEVICE, FILE_PATH)) 578 p = efi_dp_next(p); 579 fp = efi_dp_dup(p); 580 581 p->type = DEVICE_PATH_TYPE_END; 582 p->sub_type = DEVICE_PATH_SUB_TYPE_END; 583 p->length = sizeof(*p); 584 585 *device_path = dp; 586 *file_path = fp; 587 } 588