efi_device_path.c 15 KB

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