efi_blk.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Block driver for EFI devices
  4. * This supports a media driver of UCLASS_EFI with a child UCLASS_BLK
  5. * It allows block-level access to EFI devices made available via EFI boot
  6. * services
  7. *
  8. * Copyright 2021 Google LLC
  9. */
  10. #include <common.h>
  11. #include <blk.h>
  12. #include <dm.h>
  13. #include <efi.h>
  14. #include <efi_api.h>
  15. struct efi_block_plat {
  16. struct efi_block_io *blkio;
  17. };
  18. /**
  19. * Read from block device
  20. *
  21. * @dev: device
  22. * @blknr: first block to be read
  23. * @blkcnt: number of blocks to read
  24. * @buffer: output buffer
  25. * Return: number of blocks transferred
  26. */
  27. static ulong efi_bl_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
  28. void *buffer)
  29. {
  30. struct efi_block_plat *plat = dev_get_plat(dev);
  31. struct efi_block_io *io = plat->blkio;
  32. efi_status_t ret;
  33. log_debug("read buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr,
  34. (ulong)blkcnt);
  35. ret = io->read_blocks(io, io->media->media_id, blknr,
  36. blkcnt * io->media->block_size, buffer);
  37. log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK,
  38. ret & ~EFI_ERROR_MASK);
  39. if (ret)
  40. return 0;
  41. return blkcnt;
  42. }
  43. /**
  44. * Write to block device
  45. *
  46. * @dev: device
  47. * @blknr: first block to be write
  48. * @blkcnt: number of blocks to write
  49. * @buffer: input buffer
  50. * Return: number of blocks transferred
  51. */
  52. static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
  53. const void *buffer)
  54. {
  55. struct efi_block_plat *plat = dev_get_plat(dev);
  56. struct efi_block_io *io = plat->blkio;
  57. efi_status_t ret;
  58. log_debug("write buf=%p, block=%lx, count=%lx: ", buffer, (ulong)blknr,
  59. (ulong)blkcnt);
  60. ret = io->write_blocks(io, io->media->media_id, blknr,
  61. blkcnt * io->media->block_size, (void *)buffer);
  62. log_debug("ret=%lx (dec %ld)\n", ret & ~EFI_ERROR_MASK,
  63. ret & ~EFI_ERROR_MASK);
  64. if (ret)
  65. return 0;
  66. return blkcnt;
  67. }
  68. /* Block device driver operators */
  69. static const struct blk_ops efi_blk_ops = {
  70. .read = efi_bl_read,
  71. .write = efi_bl_write,
  72. };
  73. U_BOOT_DRIVER(efi_block) = {
  74. .name = "efi_block",
  75. .id = UCLASS_BLK,
  76. .ops = &efi_blk_ops,
  77. .plat_auto = sizeof(struct efi_block_plat),
  78. };
  79. static int efi_media_bind(struct udevice *dev)
  80. {
  81. struct efi_media_plat *plat = dev_get_plat(dev);
  82. struct efi_block_plat *blk_plat;
  83. struct udevice *blk;
  84. int ret;
  85. ret = blk_create_devicef(dev, "efi_block", "blk", UCLASS_EFI_MEDIA,
  86. dev_seq(dev), plat->blkio->media->block_size,
  87. plat->blkio->media->last_block, &blk);
  88. if (ret) {
  89. debug("Cannot create block device\n");
  90. return ret;
  91. }
  92. blk_plat = dev_get_plat(blk);
  93. blk_plat->blkio = plat->blkio;
  94. return 0;
  95. }
  96. U_BOOT_DRIVER(efi_media) = {
  97. .name = "efi_media",
  98. .id = UCLASS_EFI_MEDIA,
  99. .bind = efi_media_bind,
  100. .plat_auto = sizeof(struct efi_media_plat),
  101. };