1 /* 2 * EFI block driver 3 * 4 * Copyright (c) 2017 Heinrich Schuchardt 5 * 6 * SPDX-License-Identifier: GPL-2.0+ 7 * 8 * The EFI uclass creates a handle for this driver and installs the 9 * driver binding protocol on it. 10 * 11 * The EFI block driver binds to controllers implementing the block io 12 * protocol. 13 * 14 * When the bind function of the EFI block driver is called it creates a 15 * new U-Boot block device. It installs child handles for all partitions and 16 * installs the simple file protocol on these. 17 * 18 * The read and write functions of the EFI block driver delegate calls to the 19 * controller that it is bound to. 20 * 21 * A usage example is as following: 22 * 23 * U-Boot loads the iPXE snp.efi executable. iPXE connects an iSCSI drive and 24 * exposes a handle with the block IO protocol. It calls ConnectController. 25 * 26 * Now the EFI block driver installs the partitions with the simple file 27 * protocol. 28 * 29 * iPXE uses the simple file protocol to load Grub or the Linux Kernel. 30 */ 31 32 #include <efi_driver.h> 33 #include <dm/device-internal.h> 34 #include <dm/root.h> 35 36 /* 37 * EFI attributes of the udevice handled by this driver. 38 * 39 * handle handle of the controller on which this driver is installed 40 * io block io protocol proxied by this driver 41 */ 42 struct efi_blk_priv { 43 efi_handle_t handle; 44 struct efi_block_io *io; 45 }; 46 47 /* 48 * Read from block device 49 * 50 * @dev device 51 * @blknr first block to be read 52 * @blkcnt number of blocks to read 53 * @buffer output buffer 54 * @return number of blocks transferred 55 */ 56 static ulong efi_bl_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, 57 void *buffer) 58 { 59 struct efi_blk_priv *priv = dev->priv; 60 struct efi_block_io *io = priv->io; 61 efi_status_t ret; 62 63 EFI_PRINT("%s: read '%s', from block " LBAFU ", " LBAFU " blocks\n", 64 __func__, dev->name, blknr, blkcnt); 65 ret = EFI_CALL(io->read_blocks( 66 io, io->media->media_id, (u64)blknr, 67 (efi_uintn_t)blkcnt * 68 (efi_uintn_t)io->media->block_size, buffer)); 69 EFI_PRINT("%s: r = %u\n", __func__, 70 (unsigned int)(ret & ~EFI_ERROR_MASK)); 71 if (ret != EFI_SUCCESS) 72 return 0; 73 return blkcnt; 74 } 75 76 /* 77 * Write to block device 78 * 79 * @dev device 80 * @blknr first block to be write 81 * @blkcnt number of blocks to write 82 * @buffer input buffer 83 * @return number of blocks transferred 84 */ 85 static ulong efi_bl_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, 86 const void *buffer) 87 { 88 struct efi_blk_priv *priv = dev->priv; 89 struct efi_block_io *io = priv->io; 90 efi_status_t ret; 91 92 EFI_PRINT("%s: write '%s', from block " LBAFU ", " LBAFU " blocks\n", 93 __func__, dev->name, blknr, blkcnt); 94 ret = EFI_CALL(io->write_blocks( 95 io, io->media->media_id, (u64)blknr, 96 (efi_uintn_t)blkcnt * 97 (efi_uintn_t)io->media->block_size, 98 (void *)buffer)); 99 EFI_PRINT("%s: r = %u\n", __func__, 100 (unsigned int)(ret & ~EFI_ERROR_MASK)); 101 if (ret != EFI_SUCCESS) 102 return 0; 103 return blkcnt; 104 } 105 106 /* 107 * Create partions for the block device. 108 * 109 * @handle EFI handle of the block device 110 * @dev udevice of the block device 111 */ 112 static int efi_bl_bind_partitions(efi_handle_t handle, struct udevice *dev) 113 { 114 struct blk_desc *desc; 115 const char *if_typename; 116 117 desc = dev_get_uclass_platdata(dev); 118 if_typename = blk_get_if_type_name(desc->if_type); 119 120 return efi_disk_create_partitions(handle, desc, if_typename, 121 desc->devnum, dev->name); 122 } 123 124 /* 125 * Create a block device for a handle 126 * 127 * @handle handle 128 * @interface block io protocol 129 * @return 0 = success 130 */ 131 static int efi_bl_bind(efi_handle_t handle, void *interface) 132 { 133 struct udevice *bdev, *parent = dm_root(); 134 int ret, devnum; 135 char *name; 136 struct efi_object *obj = efi_search_obj(handle); 137 struct efi_block_io *io = interface; 138 int disks; 139 struct efi_blk_priv *priv; 140 141 EFI_PRINT("%s: handle %p, interface %p\n", __func__, handle, io); 142 143 if (!obj) 144 return -ENOENT; 145 146 devnum = blk_find_max_devnum(IF_TYPE_EFI); 147 if (devnum == -ENODEV) 148 devnum = 0; 149 else if (devnum < 0) 150 return devnum; 151 152 name = calloc(1, 18); /* strlen("efiblk#2147483648") + 1 */ 153 if (!name) 154 return -ENOMEM; 155 sprintf(name, "efiblk#%d", devnum); 156 157 /* Create driver model udevice for the EFI block io device */ 158 ret = blk_create_device(parent, "efi_blk", name, IF_TYPE_EFI, devnum, 159 io->media->block_size, 160 (lbaint_t)io->media->last_block, &bdev); 161 if (ret) 162 return ret; 163 if (!bdev) 164 return -ENOENT; 165 /* Allocate priv */ 166 ret = device_probe(bdev); 167 if (ret) 168 return ret; 169 EFI_PRINT("%s: block device '%s' created\n", __func__, bdev->name); 170 171 priv = bdev->priv; 172 priv->handle = handle; 173 priv->io = interface; 174 175 ret = blk_prepare_device(bdev); 176 177 /* Create handles for the partions of the block device */ 178 disks = efi_bl_bind_partitions(handle, bdev); 179 EFI_PRINT("Found %d partitions\n", disks); 180 181 return 0; 182 } 183 184 /* Block device driver operators */ 185 static const struct blk_ops efi_blk_ops = { 186 .read = efi_bl_read, 187 .write = efi_bl_write, 188 }; 189 190 /* Identify as block device driver */ 191 U_BOOT_DRIVER(efi_blk) = { 192 .name = "efi_blk", 193 .id = UCLASS_BLK, 194 .ops = &efi_blk_ops, 195 .priv_auto_alloc_size = sizeof(struct efi_blk_priv), 196 }; 197 198 /* EFI driver operators */ 199 static const struct efi_driver_ops driver_ops = { 200 .protocol = &efi_block_io_guid, 201 .child_protocol = &efi_block_io_guid, 202 .bind = efi_bl_bind, 203 }; 204 205 /* Identify as EFI driver */ 206 U_BOOT_DRIVER(efi_block) = { 207 .name = "EFI block driver", 208 .id = UCLASS_EFI, 209 .ops = &driver_ops, 210 }; 211