efi_device_path.c 25 KB

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