Home | History | Annotate | Download | only in VirtioBlkDxe
      1 /** @file
      2 
      3   This driver produces Block I/O Protocol instances for virtio-blk devices.
      4 
      5   The implementation is basic:
      6 
      7   - No attach/detach (ie. removable media).
      8 
      9   - Although the non-blocking interfaces of EFI_BLOCK_IO2_PROTOCOL could be a
     10     good match for multiple in-flight virtio-blk requests, we stick to
     11     synchronous requests and EFI_BLOCK_IO_PROTOCOL for now.
     12 
     13   Copyright (C) 2012, Red Hat, Inc.
     14   Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR>
     15 
     16   This program and the accompanying materials are licensed and made available
     17   under the terms and conditions of the BSD License which accompanies this
     18   distribution. The full text of the license may be found at
     19   http://opensource.org/licenses/bsd-license.php
     20 
     21   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
     22   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     23 
     24 **/
     25 
     26 #include <IndustryStandard/VirtioBlk.h>
     27 #include <Library/BaseMemoryLib.h>
     28 #include <Library/DebugLib.h>
     29 #include <Library/MemoryAllocationLib.h>
     30 #include <Library/UefiBootServicesTableLib.h>
     31 #include <Library/UefiLib.h>
     32 #include <Library/VirtioLib.h>
     33 
     34 #include "VirtioBlk.h"
     35 
     36 /**
     37 
     38   Convenience macros to read and write region 0 IO space elements of the
     39   virtio-blk device, for configuration purposes.
     40 
     41   The following macros make it possible to specify only the "core parameters"
     42   for such accesses and to derive the rest. By the time VIRTIO_CFG_WRITE()
     43   returns, the transaction will have been completed.
     44 
     45   @param[in] Dev       Pointer to the VBLK_DEV structure whose VirtIo space
     46                        we're accessing. Dev->VirtIo must be valid.
     47 
     48   @param[in] Field     A field name from VBLK_HDR, identifying the virtio-blk
     49                        configuration item to access.
     50 
     51   @param[in] Value     (VIRTIO_CFG_WRITE() only.) The value to write to the
     52                        selected configuration item.
     53 
     54   @param[out] Pointer  (VIRTIO_CFG_READ() only.) The object to receive the
     55                        value read from the configuration item. Its type must be
     56                        one of UINT8, UINT16, UINT32, UINT64.
     57 
     58 
     59   @return  Status code returned by Virtio->WriteDevice() /
     60            Virtio->ReadDevice().
     61 
     62 **/
     63 
     64 #define VIRTIO_CFG_WRITE(Dev, Field, Value)  ((Dev)->VirtIo->WriteDevice ( \
     65                                                 (Dev)->VirtIo,             \
     66                                                 OFFSET_OF_VBLK (Field),    \
     67                                                 SIZE_OF_VBLK (Field),      \
     68                                                 (Value)                    \
     69                                                 ))
     70 
     71 #define VIRTIO_CFG_READ(Dev, Field, Pointer) ((Dev)->VirtIo->ReadDevice (  \
     72                                                 (Dev)->VirtIo,             \
     73                                                 OFFSET_OF_VBLK (Field),    \
     74                                                 SIZE_OF_VBLK (Field),      \
     75                                                 sizeof *(Pointer),         \
     76                                                 (Pointer)                  \
     77                                                 ))
     78 
     79 
     80 //
     81 // UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol
     82 // Driver Writer's Guide for UEFI 2.3.1 v1.01,
     83 //   24.2 Block I/O Protocol Implementations
     84 //
     85 EFI_STATUS
     86 EFIAPI
     87 VirtioBlkReset (
     88   IN EFI_BLOCK_IO_PROTOCOL *This,
     89   IN BOOLEAN               ExtendedVerification
     90   )
     91 {
     92   //
     93   // If we managed to initialize and install the driver, then the device is
     94   // working correctly.
     95   //
     96   return EFI_SUCCESS;
     97 }
     98 
     99 /**
    100 
    101   Verify correctness of the read/write (not flush) request submitted to the
    102   EFI_BLOCK_IO_PROTOCOL instance.
    103 
    104   This function provides most verification steps described in:
    105 
    106     UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O
    107     Protocol,
    108     - EFI_BLOCK_IO_PROTOCOL.ReadBlocks()
    109     - EFI_BLOCK_IO_PROTOCOL.WriteBlocks()
    110 
    111     Driver Writer's Guide for UEFI 2.3.1 v1.01,
    112     - 24.2.2. ReadBlocks() and ReadBlocksEx() Implementation
    113     - 24.2.3 WriteBlocks() and WriteBlockEx() Implementation
    114 
    115   Request sizes are limited to 1 GB (checked). This is not a practical
    116   limitation, just conformance to virtio-0.9.5, 2.3.2 Descriptor Table: "no
    117   descriptor chain may be more than 2^32 bytes long in total".
    118 
    119   Some Media characteristics are hardcoded in VirtioBlkInit() below (like
    120   non-removable media, no restriction on buffer alignment etc); we rely on
    121   those here without explicit mention.
    122 
    123   @param[in] Media               The EFI_BLOCK_IO_MEDIA characteristics for
    124                                  this driver instance, extracted from the
    125                                  underlying virtio-blk device at initialization
    126                                  time. We validate the request against this set
    127                                  of attributes.
    128 
    129 
    130   @param[in] Lba                 Logical Block Address: number of logical
    131                                  blocks to skip from the beginning of the
    132                                  device.
    133 
    134   @param[in] PositiveBufferSize  Size of buffer to transfer, in bytes. The
    135                                  caller is responsible to ensure this parameter
    136                                  is positive.
    137 
    138   @param[in] RequestIsWrite      TRUE iff data transfer goes from guest to
    139                                  device.
    140 
    141 
    142   @@return                       Validation result to be forwarded outwards by
    143                                  ReadBlocks() and WriteBlocks, as required by
    144                                  the specs above.
    145 
    146 **/
    147 STATIC
    148 EFI_STATUS
    149 EFIAPI
    150 VerifyReadWriteRequest (
    151   IN  EFI_BLOCK_IO_MEDIA *Media,
    152   IN  EFI_LBA            Lba,
    153   IN  UINTN              PositiveBufferSize,
    154   IN  BOOLEAN            RequestIsWrite
    155   )
    156 {
    157   UINTN BlockCount;
    158 
    159   ASSERT (PositiveBufferSize > 0);
    160 
    161   if (PositiveBufferSize > SIZE_1GB ||
    162       PositiveBufferSize % Media->BlockSize > 0) {
    163     return EFI_BAD_BUFFER_SIZE;
    164   }
    165   BlockCount = PositiveBufferSize / Media->BlockSize;
    166 
    167   //
    168   // Avoid unsigned wraparound on either side in the second comparison.
    169   //
    170   if (Lba > Media->LastBlock || BlockCount - 1 > Media->LastBlock - Lba) {
    171     return EFI_INVALID_PARAMETER;
    172   }
    173 
    174   if (RequestIsWrite && Media->ReadOnly) {
    175     return EFI_WRITE_PROTECTED;
    176   }
    177 
    178   return EFI_SUCCESS;
    179 }
    180 
    181 
    182 
    183 
    184 /**
    185 
    186   Format a read / write / flush request as three consecutive virtio
    187   descriptors, push them to the host, and poll for the response.
    188 
    189   This is the main workhorse function. Two use cases are supported, read/write
    190   and flush. The function may only be called after the request parameters have
    191   been verified by
    192   - specific checks in ReadBlocks() / WriteBlocks() / FlushBlocks(), and
    193   - VerifyReadWriteRequest() (for read/write only).
    194 
    195   Parameters handled commonly:
    196 
    197     @param[in] Dev             The virtio-blk device the request is targeted
    198                                at.
    199 
    200   Flush request:
    201 
    202     @param[in] Lba             Must be zero.
    203 
    204     @param[in] BufferSize      Must be zero.
    205 
    206     @param[in out] Buffer      Ignored by the function.
    207 
    208     @param[in] RequestIsWrite  Must be TRUE.
    209 
    210   Read/Write request:
    211 
    212     @param[in] Lba             Logical Block Address: number of logical blocks
    213                                to skip from the beginning of the device.
    214 
    215     @param[in] BufferSize      Size of buffer to transfer, in bytes. The caller
    216                                is responsible to ensure this parameter is
    217                                positive.
    218 
    219     @param[in out] Buffer      The guest side area to read data from the device
    220                                into, or write data to the device from.
    221 
    222     @param[in] RequestIsWrite  TRUE iff data transfer goes from guest to
    223                                device.
    224 
    225   Return values are common to both use cases, and are appropriate to be
    226   forwarded by the EFI_BLOCK_IO_PROTOCOL functions (ReadBlocks(),
    227   WriteBlocks(), FlushBlocks()).
    228 
    229 
    230   @retval EFI_SUCCESS          Transfer complete.
    231 
    232   @retval EFI_DEVICE_ERROR     Failed to notify host side via VirtIo write, or
    233                                unable to parse host response, or host response
    234                                is not VIRTIO_BLK_S_OK.
    235 
    236 **/
    237 
    238 STATIC
    239 EFI_STATUS
    240 EFIAPI
    241 SynchronousRequest (
    242   IN              VBLK_DEV *Dev,
    243   IN              EFI_LBA  Lba,
    244   IN              UINTN    BufferSize,
    245   IN OUT volatile VOID     *Buffer,
    246   IN              BOOLEAN  RequestIsWrite
    247   )
    248 {
    249   UINT32                  BlockSize;
    250   volatile VIRTIO_BLK_REQ Request;
    251   volatile UINT8          HostStatus;
    252   DESC_INDICES            Indices;
    253 
    254   BlockSize = Dev->BlockIoMedia.BlockSize;
    255 
    256   //
    257   // ensured by VirtioBlkInit()
    258   //
    259   ASSERT (BlockSize > 0);
    260   ASSERT (BlockSize % 512 == 0);
    261 
    262   //
    263   // ensured by contract above, plus VerifyReadWriteRequest()
    264   //
    265   ASSERT (BufferSize % BlockSize == 0);
    266 
    267   //
    268   // Prepare virtio-blk request header, setting zero size for flush.
    269   // IO Priority is homogeneously 0.
    270   //
    271   Request.Type   = RequestIsWrite ?
    272                    (BufferSize == 0 ? VIRTIO_BLK_T_FLUSH : VIRTIO_BLK_T_OUT) :
    273                    VIRTIO_BLK_T_IN;
    274   Request.IoPrio = 0;
    275   Request.Sector = MultU64x32(Lba, BlockSize / 512);
    276 
    277   VirtioPrepare (&Dev->Ring, &Indices);
    278 
    279   //
    280   // preset a host status for ourselves that we do not accept as success
    281   //
    282   HostStatus = VIRTIO_BLK_S_IOERR;
    283 
    284   //
    285   // ensured by VirtioBlkInit() -- this predicate, in combination with the
    286   // lock-step progress, ensures we don't have to track free descriptors.
    287   //
    288   ASSERT (Dev->Ring.QueueSize >= 3);
    289 
    290   //
    291   // virtio-blk header in first desc
    292   //
    293   VirtioAppendDesc (&Dev->Ring, (UINTN) &Request, sizeof Request,
    294     VRING_DESC_F_NEXT, &Indices);
    295 
    296   //
    297   // data buffer for read/write in second desc
    298   //
    299   if (BufferSize > 0) {
    300     //
    301     // From virtio-0.9.5, 2.3.2 Descriptor Table:
    302     // "no descriptor chain may be more than 2^32 bytes long in total".
    303     //
    304     // The predicate is ensured by the call contract above (for flush), or
    305     // VerifyReadWriteRequest() (for read/write). It also implies that
    306     // converting BufferSize to UINT32 will not truncate it.
    307     //
    308     ASSERT (BufferSize <= SIZE_1GB);
    309 
    310     //
    311     // VRING_DESC_F_WRITE is interpreted from the host's point of view.
    312     //
    313     VirtioAppendDesc (&Dev->Ring, (UINTN) Buffer, (UINT32) BufferSize,
    314       VRING_DESC_F_NEXT | (RequestIsWrite ? 0 : VRING_DESC_F_WRITE),
    315       &Indices);
    316   }
    317 
    318   //
    319   // host status in last (second or third) desc
    320   //
    321   VirtioAppendDesc (&Dev->Ring, (UINTN) &HostStatus, sizeof HostStatus,
    322     VRING_DESC_F_WRITE, &Indices);
    323 
    324   //
    325   // virtio-blk's only virtqueue is #0, called "requestq" (see Appendix D).
    326   //
    327   if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices,
    328         NULL) == EFI_SUCCESS &&
    329       HostStatus == VIRTIO_BLK_S_OK) {
    330     return EFI_SUCCESS;
    331   }
    332 
    333   return EFI_DEVICE_ERROR;
    334 }
    335 
    336 
    337 /**
    338 
    339   ReadBlocks() operation for virtio-blk.
    340 
    341   See
    342   - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O
    343     Protocol, EFI_BLOCK_IO_PROTOCOL.ReadBlocks().
    344   - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.2. ReadBlocks() and
    345     ReadBlocksEx() Implementation.
    346 
    347   Parameter checks and conformant return values are implemented in
    348   VerifyReadWriteRequest() and SynchronousRequest().
    349 
    350   A zero BufferSize doesn't seem to be prohibited, so do nothing in that case,
    351   successfully.
    352 
    353 **/
    354 
    355 EFI_STATUS
    356 EFIAPI
    357 VirtioBlkReadBlocks (
    358   IN  EFI_BLOCK_IO_PROTOCOL *This,
    359   IN  UINT32                MediaId,
    360   IN  EFI_LBA               Lba,
    361   IN  UINTN                 BufferSize,
    362   OUT VOID                  *Buffer
    363   )
    364 {
    365   VBLK_DEV   *Dev;
    366   EFI_STATUS Status;
    367 
    368   if (BufferSize == 0) {
    369     return EFI_SUCCESS;
    370   }
    371 
    372   Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
    373   Status = VerifyReadWriteRequest (
    374              &Dev->BlockIoMedia,
    375              Lba,
    376              BufferSize,
    377              FALSE               // RequestIsWrite
    378              );
    379   if (EFI_ERROR (Status)) {
    380     return Status;
    381   }
    382 
    383   return SynchronousRequest (
    384            Dev,
    385            Lba,
    386            BufferSize,
    387            Buffer,
    388            FALSE       // RequestIsWrite
    389            );
    390 }
    391 
    392 /**
    393 
    394   WriteBlocks() operation for virtio-blk.
    395 
    396   See
    397   - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O
    398     Protocol, EFI_BLOCK_IO_PROTOCOL.WriteBlocks().
    399   - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.3 WriteBlocks() and
    400     WriteBlockEx() Implementation.
    401 
    402   Parameter checks and conformant return values are implemented in
    403   VerifyReadWriteRequest() and SynchronousRequest().
    404 
    405   A zero BufferSize doesn't seem to be prohibited, so do nothing in that case,
    406   successfully.
    407 
    408 **/
    409 
    410 EFI_STATUS
    411 EFIAPI
    412 VirtioBlkWriteBlocks (
    413   IN EFI_BLOCK_IO_PROTOCOL *This,
    414   IN UINT32                MediaId,
    415   IN EFI_LBA               Lba,
    416   IN UINTN                 BufferSize,
    417   IN VOID                  *Buffer
    418   )
    419 {
    420   VBLK_DEV   *Dev;
    421   EFI_STATUS Status;
    422 
    423   if (BufferSize == 0) {
    424     return EFI_SUCCESS;
    425   }
    426 
    427   Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
    428   Status = VerifyReadWriteRequest (
    429              &Dev->BlockIoMedia,
    430              Lba,
    431              BufferSize,
    432              TRUE                // RequestIsWrite
    433              );
    434   if (EFI_ERROR (Status)) {
    435     return Status;
    436   }
    437 
    438   return SynchronousRequest (
    439            Dev,
    440            Lba,
    441            BufferSize,
    442            Buffer,
    443            TRUE        // RequestIsWrite
    444            );
    445 }
    446 
    447 
    448 /**
    449 
    450   FlushBlocks() operation for virtio-blk.
    451 
    452   See
    453   - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O
    454     Protocol, EFI_BLOCK_IO_PROTOCOL.FlushBlocks().
    455   - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.4 FlushBlocks() and
    456     FlushBlocksEx() Implementation.
    457 
    458   If the underlying virtio-blk device doesn't support flushing (ie.
    459   write-caching), then this function should not be called by higher layers,
    460   according to EFI_BLOCK_IO_MEDIA characteristics set in VirtioBlkInit().
    461   Should they do nonetheless, we do nothing, successfully.
    462 
    463 **/
    464 
    465 EFI_STATUS
    466 EFIAPI
    467 VirtioBlkFlushBlocks (
    468   IN EFI_BLOCK_IO_PROTOCOL *This
    469   )
    470 {
    471   VBLK_DEV *Dev;
    472 
    473   Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
    474   return Dev->BlockIoMedia.WriteCaching ?
    475            SynchronousRequest (
    476              Dev,
    477              0,    // Lba
    478              0,    // BufferSize
    479              NULL, // Buffer
    480              TRUE  // RequestIsWrite
    481              ) :
    482            EFI_SUCCESS;
    483 }
    484 
    485 
    486 /**
    487 
    488   Device probe function for this driver.
    489 
    490   The DXE core calls this function for any given device in order to see if the
    491   driver can drive the device.
    492 
    493   Specs relevant in the general sense:
    494 
    495   - UEFI Spec 2.3.1 + Errata C:
    496     - 6.3 Protocol Handler Services -- for accessing the underlying device
    497     - 10.1 EFI Driver Binding Protocol -- for exporting ourselves
    498 
    499   - Driver Writer's Guide for UEFI 2.3.1 v1.01:
    500     - 5.1.3.4 OpenProtocol() and CloseProtocol() -- for accessing the
    501       underlying device
    502     - 9 Driver Binding Protocol -- for exporting ourselves
    503 
    504   @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
    505                                   incorporating this driver (independently of
    506                                   any device).
    507 
    508   @param[in] DeviceHandle         The device to probe.
    509 
    510   @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
    511 
    512 
    513   @retval EFI_SUCCESS      The driver supports the device being probed.
    514 
    515   @retval EFI_UNSUPPORTED  Based on virtio-blk discovery, we do not support
    516                            the device.
    517 
    518   @return                  Error codes from the OpenProtocol() boot service or
    519                            the VirtIo protocol.
    520 
    521 **/
    522 
    523 EFI_STATUS
    524 EFIAPI
    525 VirtioBlkDriverBindingSupported (
    526   IN EFI_DRIVER_BINDING_PROTOCOL *This,
    527   IN EFI_HANDLE                  DeviceHandle,
    528   IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
    529   )
    530 {
    531   EFI_STATUS          Status;
    532   VIRTIO_DEVICE_PROTOCOL *VirtIo;
    533 
    534   //
    535   // Attempt to open the device with the VirtIo set of interfaces. On success,
    536   // the protocol is "instantiated" for the VirtIo device. Covers duplicate
    537   // open attempts (EFI_ALREADY_STARTED).
    538   //
    539   Status = gBS->OpenProtocol (
    540                   DeviceHandle,               // candidate device
    541                   &gVirtioDeviceProtocolGuid, // for generic VirtIo access
    542                   (VOID **)&VirtIo,           // handle to instantiate
    543                   This->DriverBindingHandle,  // requestor driver identity
    544                   DeviceHandle,               // ControllerHandle, according to
    545                                               // the UEFI Driver Model
    546                   EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive VirtIo access to
    547                                               // the device; to be released
    548                   );
    549   if (EFI_ERROR (Status)) {
    550     return Status;
    551   }
    552 
    553   if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_BLOCK_DEVICE) {
    554     Status = EFI_UNSUPPORTED;
    555   }
    556 
    557   //
    558   // We needed VirtIo access only transitorily, to see whether we support the
    559   // device or not.
    560   //
    561   gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
    562          This->DriverBindingHandle, DeviceHandle);
    563   return Status;
    564 }
    565 
    566 
    567 /**
    568 
    569   Set up all BlockIo and virtio-blk aspects of this driver for the specified
    570   device.
    571 
    572   @param[in out] Dev  The driver instance to configure. The caller is
    573                       responsible for Dev->VirtIo's validity (ie. working IO
    574                       access to the underlying virtio-blk device).
    575 
    576   @retval EFI_SUCCESS      Setup complete.
    577 
    578   @retval EFI_UNSUPPORTED  The driver is unable to work with the virtio ring or
    579                            virtio-blk attributes the host provides.
    580 
    581   @return                  Error codes from VirtioRingInit() or
    582                            VIRTIO_CFG_READ() / VIRTIO_CFG_WRITE().
    583 
    584 **/
    585 
    586 STATIC
    587 EFI_STATUS
    588 EFIAPI
    589 VirtioBlkInit (
    590   IN OUT VBLK_DEV *Dev
    591   )
    592 {
    593   UINT8      NextDevStat;
    594   EFI_STATUS Status;
    595 
    596   UINT64     Features;
    597   UINT64     NumSectors;
    598   UINT32     BlockSize;
    599   UINT8      PhysicalBlockExp;
    600   UINT8      AlignmentOffset;
    601   UINT32     OptIoSize;
    602   UINT16     QueueSize;
    603 
    604   PhysicalBlockExp = 0;
    605   AlignmentOffset = 0;
    606   OptIoSize = 0;
    607 
    608   //
    609   // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
    610   //
    611   NextDevStat = 0;             // step 1 -- reset device
    612   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
    613   if (EFI_ERROR (Status)) {
    614     goto Failed;
    615   }
    616 
    617   NextDevStat |= VSTAT_ACK;    // step 2 -- acknowledge device presence
    618   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
    619   if (EFI_ERROR (Status)) {
    620     goto Failed;
    621   }
    622 
    623   NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
    624   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
    625   if (EFI_ERROR (Status)) {
    626     goto Failed;
    627   }
    628 
    629   //
    630   // Set Page Size - MMIO VirtIo Specific
    631   //
    632   Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
    633   if (EFI_ERROR (Status)) {
    634     goto Failed;
    635   }
    636 
    637   //
    638   // step 4a -- retrieve and validate features
    639   //
    640   Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);
    641   if (EFI_ERROR (Status)) {
    642     goto Failed;
    643   }
    644 
    645   Status = VIRTIO_CFG_READ (Dev, Capacity, &NumSectors);
    646   if (EFI_ERROR (Status)) {
    647     goto Failed;
    648   }
    649   if (NumSectors == 0) {
    650     Status = EFI_UNSUPPORTED;
    651     goto Failed;
    652   }
    653 
    654   if (Features & VIRTIO_BLK_F_BLK_SIZE) {
    655     Status = VIRTIO_CFG_READ (Dev, BlkSize, &BlockSize);
    656     if (EFI_ERROR (Status)) {
    657       goto Failed;
    658     }
    659     if (BlockSize == 0 || BlockSize % 512 != 0 ||
    660         ModU64x32 (NumSectors, BlockSize / 512) != 0) {
    661       //
    662       // We can only handle a logical block consisting of whole sectors,
    663       // and only a disk composed of whole logical blocks.
    664       //
    665       Status = EFI_UNSUPPORTED;
    666       goto Failed;
    667     }
    668   }
    669   else {
    670     BlockSize = 512;
    671   }
    672 
    673   if (Features & VIRTIO_BLK_F_TOPOLOGY) {
    674     Status = VIRTIO_CFG_READ (Dev, Topology.PhysicalBlockExp,
    675                &PhysicalBlockExp);
    676     if (EFI_ERROR (Status)) {
    677       goto Failed;
    678     }
    679     if (PhysicalBlockExp >= 32) {
    680       Status = EFI_UNSUPPORTED;
    681       goto Failed;
    682     }
    683 
    684     Status = VIRTIO_CFG_READ (Dev, Topology.AlignmentOffset, &AlignmentOffset);
    685     if (EFI_ERROR (Status)) {
    686       goto Failed;
    687     }
    688 
    689     Status = VIRTIO_CFG_READ (Dev, Topology.OptIoSize, &OptIoSize);
    690     if (EFI_ERROR (Status)) {
    691       goto Failed;
    692     }
    693   }
    694 
    695   Features &= VIRTIO_BLK_F_BLK_SIZE | VIRTIO_BLK_F_TOPOLOGY | VIRTIO_BLK_F_RO |
    696               VIRTIO_BLK_F_FLUSH | VIRTIO_F_VERSION_1;
    697 
    698   //
    699   // In virtio-1.0, feature negotiation is expected to complete before queue
    700   // discovery, and the device can also reject the selected set of features.
    701   //
    702   if (Dev->VirtIo->Revision >= VIRTIO_SPEC_REVISION (1, 0, 0)) {
    703     Status = Virtio10WriteFeatures (Dev->VirtIo, Features, &NextDevStat);
    704     if (EFI_ERROR (Status)) {
    705       goto Failed;
    706     }
    707   }
    708 
    709   //
    710   // step 4b -- allocate virtqueue
    711   //
    712   Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, 0);
    713   if (EFI_ERROR (Status)) {
    714     goto Failed;
    715   }
    716   Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);
    717   if (EFI_ERROR (Status)) {
    718     goto Failed;
    719   }
    720   if (QueueSize < 3) { // SynchronousRequest() uses at most three descriptors
    721     Status = EFI_UNSUPPORTED;
    722     goto Failed;
    723   }
    724 
    725   Status = VirtioRingInit (QueueSize, &Dev->Ring);
    726   if (EFI_ERROR (Status)) {
    727     goto Failed;
    728   }
    729 
    730   //
    731   // Additional steps for MMIO: align the queue appropriately, and set the
    732   // size. If anything fails from here on, we must release the ring resources.
    733   //
    734   Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
    735   if (EFI_ERROR (Status)) {
    736     goto ReleaseQueue;
    737   }
    738 
    739   Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
    740   if (EFI_ERROR (Status)) {
    741     goto ReleaseQueue;
    742   }
    743 
    744   //
    745   // step 4c -- Report GPFN (guest-physical frame number) of queue.
    746   //
    747   Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);
    748   if (EFI_ERROR (Status)) {
    749     goto ReleaseQueue;
    750   }
    751 
    752 
    753   //
    754   // step 5 -- Report understood features.
    755   //
    756   if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
    757     Features &= ~(UINT64)VIRTIO_F_VERSION_1;
    758     Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
    759     if (EFI_ERROR (Status)) {
    760       goto ReleaseQueue;
    761     }
    762   }
    763 
    764   //
    765   // step 6 -- initialization complete
    766   //
    767   NextDevStat |= VSTAT_DRIVER_OK;
    768   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
    769   if (EFI_ERROR (Status)) {
    770     goto ReleaseQueue;
    771   }
    772 
    773   //
    774   // Populate the exported interface's attributes; see UEFI spec v2.4, 12.9 EFI
    775   // Block I/O Protocol.
    776   //
    777   Dev->BlockIo.Revision              = 0;
    778   Dev->BlockIo.Media                 = &Dev->BlockIoMedia;
    779   Dev->BlockIo.Reset                 = &VirtioBlkReset;
    780   Dev->BlockIo.ReadBlocks            = &VirtioBlkReadBlocks;
    781   Dev->BlockIo.WriteBlocks           = &VirtioBlkWriteBlocks;
    782   Dev->BlockIo.FlushBlocks           = &VirtioBlkFlushBlocks;
    783   Dev->BlockIoMedia.MediaId          = 0;
    784   Dev->BlockIoMedia.RemovableMedia   = FALSE;
    785   Dev->BlockIoMedia.MediaPresent     = TRUE;
    786   Dev->BlockIoMedia.LogicalPartition = FALSE;
    787   Dev->BlockIoMedia.ReadOnly         = (BOOLEAN) ((Features & VIRTIO_BLK_F_RO) != 0);
    788   Dev->BlockIoMedia.WriteCaching     = (BOOLEAN) ((Features & VIRTIO_BLK_F_FLUSH) != 0);
    789   Dev->BlockIoMedia.BlockSize        = BlockSize;
    790   Dev->BlockIoMedia.IoAlign          = 0;
    791   Dev->BlockIoMedia.LastBlock        = DivU64x32 (NumSectors,
    792                                          BlockSize / 512) - 1;
    793 
    794   DEBUG ((DEBUG_INFO, "%a: LbaSize=0x%x[B] NumBlocks=0x%Lx[Lba]\n",
    795     __FUNCTION__, Dev->BlockIoMedia.BlockSize,
    796     Dev->BlockIoMedia.LastBlock + 1));
    797 
    798   if (Features & VIRTIO_BLK_F_TOPOLOGY) {
    799     Dev->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
    800 
    801     Dev->BlockIoMedia.LowestAlignedLba = AlignmentOffset;
    802     Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock = 1u << PhysicalBlockExp;
    803     Dev->BlockIoMedia.OptimalTransferLengthGranularity = OptIoSize;
    804 
    805     DEBUG ((DEBUG_INFO, "%a: FirstAligned=0x%Lx[Lba] PhysBlkSize=0x%x[Lba]\n",
    806       __FUNCTION__, Dev->BlockIoMedia.LowestAlignedLba,
    807       Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock));
    808     DEBUG ((DEBUG_INFO, "%a: OptimalTransferLengthGranularity=0x%x[Lba]\n",
    809       __FUNCTION__, Dev->BlockIoMedia.OptimalTransferLengthGranularity));
    810   }
    811   return EFI_SUCCESS;
    812 
    813 ReleaseQueue:
    814   VirtioRingUninit (&Dev->Ring);
    815 
    816 Failed:
    817   //
    818   // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device
    819   // Status. VirtIo access failure here should not mask the original error.
    820   //
    821   NextDevStat |= VSTAT_FAILED;
    822   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
    823 
    824   return Status; // reached only via Failed above
    825 }
    826 
    827 
    828 /**
    829 
    830   Uninitialize the internals of a virtio-blk device that has been successfully
    831   set up with VirtioBlkInit().
    832 
    833   @param[in out]  Dev  The device to clean up.
    834 
    835 **/
    836 
    837 STATIC
    838 VOID
    839 EFIAPI
    840 VirtioBlkUninit (
    841   IN OUT VBLK_DEV *Dev
    842   )
    843 {
    844   //
    845   // Reset the virtual device -- see virtio-0.9.5, 2.2.2.1 Device Status. When
    846   // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from
    847   // the old comms area.
    848   //
    849   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
    850 
    851   VirtioRingUninit (&Dev->Ring);
    852 
    853   SetMem (&Dev->BlockIo,      sizeof Dev->BlockIo,      0x00);
    854   SetMem (&Dev->BlockIoMedia, sizeof Dev->BlockIoMedia, 0x00);
    855 }
    856 
    857 
    858 /**
    859 
    860   Event notification function enqueued by ExitBootServices().
    861 
    862   @param[in] Event    Event whose notification function is being invoked.
    863 
    864   @param[in] Context  Pointer to the VBLK_DEV structure.
    865 
    866 **/
    867 
    868 STATIC
    869 VOID
    870 EFIAPI
    871 VirtioBlkExitBoot (
    872   IN  EFI_EVENT Event,
    873   IN  VOID      *Context
    874   )
    875 {
    876   VBLK_DEV *Dev;
    877 
    878   //
    879   // Reset the device. This causes the hypervisor to forget about the virtio
    880   // ring.
    881   //
    882   // We allocated said ring in EfiBootServicesData type memory, and code
    883   // executing after ExitBootServices() is permitted to overwrite it.
    884   //
    885   Dev = Context;
    886   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
    887 }
    888 
    889 /**
    890 
    891   After we've pronounced support for a specific device in
    892   DriverBindingSupported(), we start managing said device (passed in by the
    893   Driver Execution Environment) with the following service.
    894 
    895   See DriverBindingSupported() for specification references.
    896 
    897   @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
    898                                   incorporating this driver (independently of
    899                                   any device).
    900 
    901   @param[in] DeviceHandle         The supported device to drive.
    902 
    903   @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
    904 
    905 
    906   @retval EFI_SUCCESS           Driver instance has been created and
    907                                 initialized  for the virtio-blk device, it
    908                                 is now accessible via EFI_BLOCK_IO_PROTOCOL.
    909 
    910   @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
    911 
    912   @return                       Error codes from the OpenProtocol() boot
    913                                 service, the VirtIo protocol, VirtioBlkInit(),
    914                                 or the InstallProtocolInterface() boot service.
    915 
    916 **/
    917 
    918 EFI_STATUS
    919 EFIAPI
    920 VirtioBlkDriverBindingStart (
    921   IN EFI_DRIVER_BINDING_PROTOCOL *This,
    922   IN EFI_HANDLE                  DeviceHandle,
    923   IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
    924   )
    925 {
    926   VBLK_DEV   *Dev;
    927   EFI_STATUS Status;
    928 
    929   Dev = (VBLK_DEV *) AllocateZeroPool (sizeof *Dev);
    930   if (Dev == NULL) {
    931     return EFI_OUT_OF_RESOURCES;
    932   }
    933 
    934   Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
    935                   (VOID **)&Dev->VirtIo, This->DriverBindingHandle,
    936                   DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
    937   if (EFI_ERROR (Status)) {
    938     goto FreeVirtioBlk;
    939   }
    940 
    941   //
    942   // VirtIo access granted, configure virtio-blk device.
    943   //
    944   Status = VirtioBlkInit (Dev);
    945   if (EFI_ERROR (Status)) {
    946     goto CloseVirtIo;
    947   }
    948 
    949   Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
    950                   &VirtioBlkExitBoot, Dev, &Dev->ExitBoot);
    951   if (EFI_ERROR (Status)) {
    952     goto UninitDev;
    953   }
    954 
    955   //
    956   // Setup complete, attempt to export the driver instance's BlockIo interface.
    957   //
    958   Dev->Signature = VBLK_SIG;
    959   Status = gBS->InstallProtocolInterface (&DeviceHandle,
    960                   &gEfiBlockIoProtocolGuid, EFI_NATIVE_INTERFACE,
    961                   &Dev->BlockIo);
    962   if (EFI_ERROR (Status)) {
    963     goto CloseExitBoot;
    964   }
    965 
    966   return EFI_SUCCESS;
    967 
    968 CloseExitBoot:
    969   gBS->CloseEvent (Dev->ExitBoot);
    970 
    971 UninitDev:
    972   VirtioBlkUninit (Dev);
    973 
    974 CloseVirtIo:
    975   gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
    976          This->DriverBindingHandle, DeviceHandle);
    977 
    978 FreeVirtioBlk:
    979   FreePool (Dev);
    980 
    981   return Status;
    982 }
    983 
    984 
    985 /**
    986 
    987   Stop driving a virtio-blk device and remove its BlockIo interface.
    988 
    989   This function replays the success path of DriverBindingStart() in reverse.
    990   The host side virtio-blk device is reset, so that the OS boot loader or the
    991   OS may reinitialize it.
    992 
    993   @param[in] This               The EFI_DRIVER_BINDING_PROTOCOL object
    994                                 incorporating this driver (independently of any
    995                                 device).
    996 
    997   @param[in] DeviceHandle       Stop driving this device.
    998 
    999   @param[in] NumberOfChildren   Since this function belongs to a device driver
   1000                                 only (as opposed to a bus driver), the caller
   1001                                 environment sets NumberOfChildren to zero, and
   1002                                 we ignore it.
   1003 
   1004   @param[in] ChildHandleBuffer  Ignored (corresponding to NumberOfChildren).
   1005 
   1006 **/
   1007 
   1008 EFI_STATUS
   1009 EFIAPI
   1010 VirtioBlkDriverBindingStop (
   1011   IN EFI_DRIVER_BINDING_PROTOCOL *This,
   1012   IN EFI_HANDLE                  DeviceHandle,
   1013   IN UINTN                       NumberOfChildren,
   1014   IN EFI_HANDLE                  *ChildHandleBuffer
   1015   )
   1016 {
   1017   EFI_STATUS            Status;
   1018   EFI_BLOCK_IO_PROTOCOL *BlockIo;
   1019   VBLK_DEV              *Dev;
   1020 
   1021   Status = gBS->OpenProtocol (
   1022                   DeviceHandle,                  // candidate device
   1023                   &gEfiBlockIoProtocolGuid,      // retrieve the BlockIo iface
   1024                   (VOID **)&BlockIo,             // target pointer
   1025                   This->DriverBindingHandle,     // requestor driver identity
   1026                   DeviceHandle,                  // requesting lookup for dev.
   1027                   EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added
   1028                   );
   1029   if (EFI_ERROR (Status)) {
   1030     return Status;
   1031   }
   1032 
   1033   Dev = VIRTIO_BLK_FROM_BLOCK_IO (BlockIo);
   1034 
   1035   //
   1036   // Handle Stop() requests for in-use driver instances gracefully.
   1037   //
   1038   Status = gBS->UninstallProtocolInterface (DeviceHandle,
   1039                   &gEfiBlockIoProtocolGuid, &Dev->BlockIo);
   1040   if (EFI_ERROR (Status)) {
   1041     return Status;
   1042   }
   1043 
   1044   gBS->CloseEvent (Dev->ExitBoot);
   1045 
   1046   VirtioBlkUninit (Dev);
   1047 
   1048   gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
   1049          This->DriverBindingHandle, DeviceHandle);
   1050 
   1051   FreePool (Dev);
   1052 
   1053   return EFI_SUCCESS;
   1054 }
   1055 
   1056 
   1057 //
   1058 // The static object that groups the Supported() (ie. probe), Start() and
   1059 // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
   1060 // C, 10.1 EFI Driver Binding Protocol.
   1061 //
   1062 STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
   1063   &VirtioBlkDriverBindingSupported,
   1064   &VirtioBlkDriverBindingStart,
   1065   &VirtioBlkDriverBindingStop,
   1066   0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
   1067   NULL, // ImageHandle, to be overwritten by
   1068         // EfiLibInstallDriverBindingComponentName2() in VirtioBlkEntryPoint()
   1069   NULL  // DriverBindingHandle, ditto
   1070 };
   1071 
   1072 
   1073 //
   1074 // The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
   1075 // EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
   1076 // in English, for display on standard console devices. This is recommended for
   1077 // UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
   1078 // Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
   1079 //
   1080 // Device type names ("Virtio Block Device") are not formatted because the
   1081 // driver supports only that device type. Therefore the driver name suffices
   1082 // for unambiguous identification.
   1083 //
   1084 
   1085 STATIC
   1086 EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
   1087   { "eng;en", L"Virtio Block Driver" },
   1088   { NULL,     NULL                   }
   1089 };
   1090 
   1091 STATIC
   1092 EFI_COMPONENT_NAME_PROTOCOL gComponentName;
   1093 
   1094 EFI_STATUS
   1095 EFIAPI
   1096 VirtioBlkGetDriverName (
   1097   IN  EFI_COMPONENT_NAME_PROTOCOL *This,
   1098   IN  CHAR8                       *Language,
   1099   OUT CHAR16                      **DriverName
   1100   )
   1101 {
   1102   return LookupUnicodeString2 (
   1103            Language,
   1104            This->SupportedLanguages,
   1105            mDriverNameTable,
   1106            DriverName,
   1107            (BOOLEAN)(This == &gComponentName) // Iso639Language
   1108            );
   1109 }
   1110 
   1111 EFI_STATUS
   1112 EFIAPI
   1113 VirtioBlkGetDeviceName (
   1114   IN  EFI_COMPONENT_NAME_PROTOCOL *This,
   1115   IN  EFI_HANDLE                  DeviceHandle,
   1116   IN  EFI_HANDLE                  ChildHandle,
   1117   IN  CHAR8                       *Language,
   1118   OUT CHAR16                      **ControllerName
   1119   )
   1120 {
   1121   return EFI_UNSUPPORTED;
   1122 }
   1123 
   1124 STATIC
   1125 EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
   1126   &VirtioBlkGetDriverName,
   1127   &VirtioBlkGetDeviceName,
   1128   "eng" // SupportedLanguages, ISO 639-2 language codes
   1129 };
   1130 
   1131 STATIC
   1132 EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
   1133   (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)     &VirtioBlkGetDriverName,
   1134   (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &VirtioBlkGetDeviceName,
   1135   "en" // SupportedLanguages, RFC 4646 language codes
   1136 };
   1137 
   1138 
   1139 //
   1140 // Entry point of this driver.
   1141 //
   1142 EFI_STATUS
   1143 EFIAPI
   1144 VirtioBlkEntryPoint (
   1145   IN EFI_HANDLE       ImageHandle,
   1146   IN EFI_SYSTEM_TABLE *SystemTable
   1147   )
   1148 {
   1149   return EfiLibInstallDriverBindingComponentName2 (
   1150            ImageHandle,
   1151            SystemTable,
   1152            &gDriverBinding,
   1153            ImageHandle,
   1154            &gComponentName,
   1155            &gComponentName2
   1156            );
   1157 }
   1158 
   1159