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 - 2014, 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//
85EFI_STATUS
86EFIAPI
87VirtioBlkReset (
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**/
147STATIC
148EFI_STATUS
149EFIAPI
150VerifyReadWriteRequest (
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
238STATIC
239EFI_STATUS
240EFIAPI
241SynchronousRequest (
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) == EFI_SUCCESS &&
328      HostStatus == VIRTIO_BLK_S_OK) {
329    return EFI_SUCCESS;
330  }
331
332  return EFI_DEVICE_ERROR;
333}
334
335
336/**
337
338  ReadBlocks() operation for virtio-blk.
339
340  See
341  - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O
342    Protocol, EFI_BLOCK_IO_PROTOCOL.ReadBlocks().
343  - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.2. ReadBlocks() and
344    ReadBlocksEx() Implementation.
345
346  Parameter checks and conformant return values are implemented in
347  VerifyReadWriteRequest() and SynchronousRequest().
348
349  A zero BufferSize doesn't seem to be prohibited, so do nothing in that case,
350  successfully.
351
352**/
353
354EFI_STATUS
355EFIAPI
356VirtioBlkReadBlocks (
357  IN  EFI_BLOCK_IO_PROTOCOL *This,
358  IN  UINT32                MediaId,
359  IN  EFI_LBA               Lba,
360  IN  UINTN                 BufferSize,
361  OUT VOID                  *Buffer
362  )
363{
364  VBLK_DEV   *Dev;
365  EFI_STATUS Status;
366
367  if (BufferSize == 0) {
368    return EFI_SUCCESS;
369  }
370
371  Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
372  Status = VerifyReadWriteRequest (
373             &Dev->BlockIoMedia,
374             Lba,
375             BufferSize,
376             FALSE               // RequestIsWrite
377             );
378  if (EFI_ERROR (Status)) {
379    return Status;
380  }
381
382  return SynchronousRequest (
383           Dev,
384           Lba,
385           BufferSize,
386           Buffer,
387           FALSE       // RequestIsWrite
388           );
389}
390
391/**
392
393  WriteBlocks() operation for virtio-blk.
394
395  See
396  - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O
397    Protocol, EFI_BLOCK_IO_PROTOCOL.WriteBlocks().
398  - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.3 WriteBlocks() and
399    WriteBlockEx() Implementation.
400
401  Parameter checks and conformant return values are implemented in
402  VerifyReadWriteRequest() and SynchronousRequest().
403
404  A zero BufferSize doesn't seem to be prohibited, so do nothing in that case,
405  successfully.
406
407**/
408
409EFI_STATUS
410EFIAPI
411VirtioBlkWriteBlocks (
412  IN EFI_BLOCK_IO_PROTOCOL *This,
413  IN UINT32                MediaId,
414  IN EFI_LBA               Lba,
415  IN UINTN                 BufferSize,
416  IN VOID                  *Buffer
417  )
418{
419  VBLK_DEV   *Dev;
420  EFI_STATUS Status;
421
422  if (BufferSize == 0) {
423    return EFI_SUCCESS;
424  }
425
426  Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
427  Status = VerifyReadWriteRequest (
428             &Dev->BlockIoMedia,
429             Lba,
430             BufferSize,
431             TRUE                // RequestIsWrite
432             );
433  if (EFI_ERROR (Status)) {
434    return Status;
435  }
436
437  return SynchronousRequest (
438           Dev,
439           Lba,
440           BufferSize,
441           Buffer,
442           TRUE        // RequestIsWrite
443           );
444}
445
446
447/**
448
449  FlushBlocks() operation for virtio-blk.
450
451  See
452  - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O
453    Protocol, EFI_BLOCK_IO_PROTOCOL.FlushBlocks().
454  - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.4 FlushBlocks() and
455    FlushBlocksEx() Implementation.
456
457  If the underlying virtio-blk device doesn't support flushing (ie.
458  write-caching), then this function should not be called by higher layers,
459  according to EFI_BLOCK_IO_MEDIA characteristics set in VirtioBlkInit().
460  Should they do nonetheless, we do nothing, successfully.
461
462**/
463
464EFI_STATUS
465EFIAPI
466VirtioBlkFlushBlocks (
467  IN EFI_BLOCK_IO_PROTOCOL *This
468  )
469{
470  VBLK_DEV *Dev;
471
472  Dev = VIRTIO_BLK_FROM_BLOCK_IO (This);
473  return Dev->BlockIoMedia.WriteCaching ?
474           SynchronousRequest (
475             Dev,
476             0,    // Lba
477             0,    // BufferSize
478             NULL, // Buffer
479             TRUE  // RequestIsWrite
480             ) :
481           EFI_SUCCESS;
482}
483
484
485/**
486
487  Device probe function for this driver.
488
489  The DXE core calls this function for any given device in order to see if the
490  driver can drive the device.
491
492  Specs relevant in the general sense:
493
494  - UEFI Spec 2.3.1 + Errata C:
495    - 6.3 Protocol Handler Services -- for accessing the underlying device
496    - 10.1 EFI Driver Binding Protocol -- for exporting ourselves
497
498  - Driver Writer's Guide for UEFI 2.3.1 v1.01:
499    - 5.1.3.4 OpenProtocol() and CloseProtocol() -- for accessing the
500      underlying device
501    - 9 Driver Binding Protocol -- for exporting ourselves
502
503  @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
504                                  incorporating this driver (independently of
505                                  any device).
506
507  @param[in] DeviceHandle         The device to probe.
508
509  @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
510
511
512  @retval EFI_SUCCESS      The driver supports the device being probed.
513
514  @retval EFI_UNSUPPORTED  Based on virtio-blk discovery, we do not support
515                           the device.
516
517  @return                  Error codes from the OpenProtocol() boot service or
518                           the VirtIo protocol.
519
520**/
521
522EFI_STATUS
523EFIAPI
524VirtioBlkDriverBindingSupported (
525  IN EFI_DRIVER_BINDING_PROTOCOL *This,
526  IN EFI_HANDLE                  DeviceHandle,
527  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
528  )
529{
530  EFI_STATUS          Status;
531  VIRTIO_DEVICE_PROTOCOL *VirtIo;
532
533  //
534  // Attempt to open the device with the VirtIo set of interfaces. On success,
535  // the protocol is "instantiated" for the VirtIo device. Covers duplicate
536  // open attempts (EFI_ALREADY_STARTED).
537  //
538  Status = gBS->OpenProtocol (
539                  DeviceHandle,               // candidate device
540                  &gVirtioDeviceProtocolGuid, // for generic VirtIo access
541                  (VOID **)&VirtIo,           // handle to instantiate
542                  This->DriverBindingHandle,  // requestor driver identity
543                  DeviceHandle,               // ControllerHandle, according to
544                                              // the UEFI Driver Model
545                  EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive VirtIo access to
546                                              // the device; to be released
547                  );
548  if (EFI_ERROR (Status)) {
549    return Status;
550  }
551
552  if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_BLOCK_DEVICE) {
553    Status = EFI_UNSUPPORTED;
554  }
555
556  //
557  // We needed VirtIo access only transitorily, to see whether we support the
558  // device or not.
559  //
560  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
561         This->DriverBindingHandle, DeviceHandle);
562  return Status;
563}
564
565
566/**
567
568  Set up all BlockIo and virtio-blk aspects of this driver for the specified
569  device.
570
571  @param[in out] Dev  The driver instance to configure. The caller is
572                      responsible for Dev->VirtIo's validity (ie. working IO
573                      access to the underlying virtio-blk device).
574
575  @retval EFI_SUCCESS      Setup complete.
576
577  @retval EFI_UNSUPPORTED  The driver is unable to work with the virtio ring or
578                           virtio-blk attributes the host provides.
579
580  @return                  Error codes from VirtioRingInit() or
581                           VIRTIO_CFG_READ() / VIRTIO_CFG_WRITE().
582
583**/
584
585STATIC
586EFI_STATUS
587EFIAPI
588VirtioBlkInit (
589  IN OUT VBLK_DEV *Dev
590  )
591{
592  UINT8      NextDevStat;
593  EFI_STATUS Status;
594
595  UINT32     Features;
596  UINT64     NumSectors;
597  UINT32     BlockSize;
598  UINT8      PhysicalBlockExp;
599  UINT8      AlignmentOffset;
600  UINT32     OptIoSize;
601  UINT16     QueueSize;
602
603  PhysicalBlockExp = 0;
604  AlignmentOffset = 0;
605  OptIoSize = 0;
606
607  //
608  // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
609  //
610  NextDevStat = 0;             // step 1 -- reset device
611  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
612  if (EFI_ERROR (Status)) {
613    goto Failed;
614  }
615
616  NextDevStat |= VSTAT_ACK;    // step 2 -- acknowledge device presence
617  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
618  if (EFI_ERROR (Status)) {
619    goto Failed;
620  }
621
622  NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
623  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
624  if (EFI_ERROR (Status)) {
625    goto Failed;
626  }
627
628  //
629  // Set Page Size - MMIO VirtIo Specific
630  //
631  Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
632  if (EFI_ERROR (Status)) {
633    goto Failed;
634  }
635
636  //
637  // step 4a -- retrieve and validate features
638  //
639  Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);
640  if (EFI_ERROR (Status)) {
641    goto Failed;
642  }
643
644  Status = VIRTIO_CFG_READ (Dev, Capacity, &NumSectors);
645  if (EFI_ERROR (Status)) {
646    goto Failed;
647  }
648  if (NumSectors == 0) {
649    Status = EFI_UNSUPPORTED;
650    goto Failed;
651  }
652
653  if (Features & VIRTIO_BLK_F_BLK_SIZE) {
654    Status = VIRTIO_CFG_READ (Dev, BlkSize, &BlockSize);
655    if (EFI_ERROR (Status)) {
656      goto Failed;
657    }
658    if (BlockSize == 0 || BlockSize % 512 != 0 ||
659        ModU64x32 (NumSectors, BlockSize / 512) != 0) {
660      //
661      // We can only handle a logical block consisting of whole sectors,
662      // and only a disk composed of whole logical blocks.
663      //
664      Status = EFI_UNSUPPORTED;
665      goto Failed;
666    }
667  }
668  else {
669    BlockSize = 512;
670  }
671
672  if (Features & VIRTIO_BLK_F_TOPOLOGY) {
673    Status = VIRTIO_CFG_READ (Dev, Topology.PhysicalBlockExp,
674               &PhysicalBlockExp);
675    if (EFI_ERROR (Status)) {
676      goto Failed;
677    }
678    if (PhysicalBlockExp >= 32) {
679      Status = EFI_UNSUPPORTED;
680      goto Failed;
681    }
682
683    Status = VIRTIO_CFG_READ (Dev, Topology.AlignmentOffset, &AlignmentOffset);
684    if (EFI_ERROR (Status)) {
685      goto Failed;
686    }
687
688    Status = VIRTIO_CFG_READ (Dev, Topology.OptIoSize, &OptIoSize);
689    if (EFI_ERROR (Status)) {
690      goto Failed;
691    }
692  }
693
694  //
695  // step 4b -- allocate virtqueue
696  //
697  Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, 0);
698  if (EFI_ERROR (Status)) {
699    goto Failed;
700  }
701  Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);
702  if (EFI_ERROR (Status)) {
703    goto Failed;
704  }
705  if (QueueSize < 3) { // SynchronousRequest() uses at most three descriptors
706    Status = EFI_UNSUPPORTED;
707    goto Failed;
708  }
709
710  Status = VirtioRingInit (QueueSize, &Dev->Ring);
711  if (EFI_ERROR (Status)) {
712    goto Failed;
713  }
714
715  //
716  // Additional steps for MMIO: align the queue appropriately, and set the
717  // size. If anything fails from here on, we must release the ring resources.
718  //
719  Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
720  if (EFI_ERROR (Status)) {
721    goto ReleaseQueue;
722  }
723
724  Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
725  if (EFI_ERROR (Status)) {
726    goto ReleaseQueue;
727  }
728
729  //
730  // step 4c -- Report GPFN (guest-physical frame number) of queue.
731  //
732  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
733      (UINT32) ((UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT));
734  if (EFI_ERROR (Status)) {
735    goto ReleaseQueue;
736  }
737
738
739  //
740  // step 5 -- Report understood features. There are no virtio-blk specific
741  // features to negotiate in virtio-0.9.5, plus we do not want any of the
742  // device-independent (known or unknown) VIRTIO_F_* capabilities (see
743  // Appendix B).
744  //
745  Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, 0);
746  if (EFI_ERROR (Status)) {
747    goto ReleaseQueue;
748  }
749
750  //
751  // step 6 -- initialization complete
752  //
753  NextDevStat |= VSTAT_DRIVER_OK;
754  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
755  if (EFI_ERROR (Status)) {
756    goto ReleaseQueue;
757  }
758
759  //
760  // Populate the exported interface's attributes; see UEFI spec v2.4, 12.9 EFI
761  // Block I/O Protocol.
762  //
763  Dev->BlockIo.Revision              = 0;
764  Dev->BlockIo.Media                 = &Dev->BlockIoMedia;
765  Dev->BlockIo.Reset                 = &VirtioBlkReset;
766  Dev->BlockIo.ReadBlocks            = &VirtioBlkReadBlocks;
767  Dev->BlockIo.WriteBlocks           = &VirtioBlkWriteBlocks;
768  Dev->BlockIo.FlushBlocks           = &VirtioBlkFlushBlocks;
769  Dev->BlockIoMedia.MediaId          = 0;
770  Dev->BlockIoMedia.RemovableMedia   = FALSE;
771  Dev->BlockIoMedia.MediaPresent     = TRUE;
772  Dev->BlockIoMedia.LogicalPartition = FALSE;
773  Dev->BlockIoMedia.ReadOnly         = (BOOLEAN) ((Features & VIRTIO_BLK_F_RO) != 0);
774  Dev->BlockIoMedia.WriteCaching     = (BOOLEAN) ((Features & VIRTIO_BLK_F_FLUSH) != 0);
775  Dev->BlockIoMedia.BlockSize        = BlockSize;
776  Dev->BlockIoMedia.IoAlign          = 0;
777  Dev->BlockIoMedia.LastBlock        = DivU64x32 (NumSectors,
778                                         BlockSize / 512) - 1;
779
780  DEBUG ((DEBUG_INFO, "%a: LbaSize=0x%x[B] NumBlocks=0x%Lx[Lba]\n",
781    __FUNCTION__, Dev->BlockIoMedia.BlockSize,
782    Dev->BlockIoMedia.LastBlock + 1));
783
784  if (Features & VIRTIO_BLK_F_TOPOLOGY) {
785    Dev->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
786
787    Dev->BlockIoMedia.LowestAlignedLba = AlignmentOffset;
788    Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock = 1u << PhysicalBlockExp;
789    Dev->BlockIoMedia.OptimalTransferLengthGranularity = OptIoSize;
790
791    DEBUG ((DEBUG_INFO, "%a: FirstAligned=0x%Lx[Lba] PhysBlkSize=0x%x[Lba]\n",
792      __FUNCTION__, Dev->BlockIoMedia.LowestAlignedLba,
793      Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock));
794    DEBUG ((DEBUG_INFO, "%a: OptimalTransferLengthGranularity=0x%x[Lba]\n",
795      __FUNCTION__, Dev->BlockIoMedia.OptimalTransferLengthGranularity));
796  }
797  return EFI_SUCCESS;
798
799ReleaseQueue:
800  VirtioRingUninit (&Dev->Ring);
801
802Failed:
803  //
804  // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device
805  // Status. VirtIo access failure here should not mask the original error.
806  //
807  NextDevStat |= VSTAT_FAILED;
808  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
809
810  return Status; // reached only via Failed above
811}
812
813
814/**
815
816  Uninitialize the internals of a virtio-blk device that has been successfully
817  set up with VirtioBlkInit().
818
819  @param[in out]  Dev  The device to clean up.
820
821**/
822
823STATIC
824VOID
825EFIAPI
826VirtioBlkUninit (
827  IN OUT VBLK_DEV *Dev
828  )
829{
830  //
831  // Reset the virtual device -- see virtio-0.9.5, 2.2.2.1 Device Status. When
832  // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from
833  // the old comms area.
834  //
835  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
836
837  VirtioRingUninit (&Dev->Ring);
838
839  SetMem (&Dev->BlockIo,      sizeof Dev->BlockIo,      0x00);
840  SetMem (&Dev->BlockIoMedia, sizeof Dev->BlockIoMedia, 0x00);
841}
842
843
844/**
845
846  Event notification function enqueued by ExitBootServices().
847
848  @param[in] Event    Event whose notification function is being invoked.
849
850  @param[in] Context  Pointer to the VBLK_DEV structure.
851
852**/
853
854STATIC
855VOID
856EFIAPI
857VirtioBlkExitBoot (
858  IN  EFI_EVENT Event,
859  IN  VOID      *Context
860  )
861{
862  VBLK_DEV *Dev;
863
864  //
865  // Reset the device. This causes the hypervisor to forget about the virtio
866  // ring.
867  //
868  // We allocated said ring in EfiBootServicesData type memory, and code
869  // executing after ExitBootServices() is permitted to overwrite it.
870  //
871  Dev = Context;
872  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
873}
874
875/**
876
877  After we've pronounced support for a specific device in
878  DriverBindingSupported(), we start managing said device (passed in by the
879  Driver Exeuction Environment) with the following service.
880
881  See DriverBindingSupported() for specification references.
882
883  @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
884                                  incorporating this driver (independently of
885                                  any device).
886
887  @param[in] DeviceHandle         The supported device to drive.
888
889  @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
890
891
892  @retval EFI_SUCCESS           Driver instance has been created and
893                                initialized  for the virtio-blk device, it
894                                is now accessibla via EFI_BLOCK_IO_PROTOCOL.
895
896  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
897
898  @return                       Error codes from the OpenProtocol() boot
899                                service, the VirtIo protocol, VirtioBlkInit(),
900                                or the InstallProtocolInterface() boot service.
901
902**/
903
904EFI_STATUS
905EFIAPI
906VirtioBlkDriverBindingStart (
907  IN EFI_DRIVER_BINDING_PROTOCOL *This,
908  IN EFI_HANDLE                  DeviceHandle,
909  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
910  )
911{
912  VBLK_DEV   *Dev;
913  EFI_STATUS Status;
914
915  Dev = (VBLK_DEV *) AllocateZeroPool (sizeof *Dev);
916  if (Dev == NULL) {
917    return EFI_OUT_OF_RESOURCES;
918  }
919
920  Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
921                  (VOID **)&Dev->VirtIo, This->DriverBindingHandle,
922                  DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
923  if (EFI_ERROR (Status)) {
924    goto FreeVirtioBlk;
925  }
926
927  //
928  // VirtIo access granted, configure virtio-blk device.
929  //
930  Status = VirtioBlkInit (Dev);
931  if (EFI_ERROR (Status)) {
932    goto CloseVirtIo;
933  }
934
935  Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
936                  &VirtioBlkExitBoot, Dev, &Dev->ExitBoot);
937  if (EFI_ERROR (Status)) {
938    goto UninitDev;
939  }
940
941  //
942  // Setup complete, attempt to export the driver instance's BlockIo interface.
943  //
944  Dev->Signature = VBLK_SIG;
945  Status = gBS->InstallProtocolInterface (&DeviceHandle,
946                  &gEfiBlockIoProtocolGuid, EFI_NATIVE_INTERFACE,
947                  &Dev->BlockIo);
948  if (EFI_ERROR (Status)) {
949    goto CloseExitBoot;
950  }
951
952  return EFI_SUCCESS;
953
954CloseExitBoot:
955  gBS->CloseEvent (Dev->ExitBoot);
956
957UninitDev:
958  VirtioBlkUninit (Dev);
959
960CloseVirtIo:
961  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
962         This->DriverBindingHandle, DeviceHandle);
963
964FreeVirtioBlk:
965  FreePool (Dev);
966
967  return Status;
968}
969
970
971/**
972
973  Stop driving a virtio-blk device and remove its BlockIo interface.
974
975  This function replays the success path of DriverBindingStart() in reverse.
976  The host side virtio-blk device is reset, so that the OS boot loader or the
977  OS may reinitialize it.
978
979  @param[in] This               The EFI_DRIVER_BINDING_PROTOCOL object
980                                incorporating this driver (independently of any
981                                device).
982
983  @param[in] DeviceHandle       Stop driving this device.
984
985  @param[in] NumberOfChildren   Since this function belongs to a device driver
986                                only (as opposed to a bus driver), the caller
987                                environment sets NumberOfChildren to zero, and
988                                we ignore it.
989
990  @param[in] ChildHandleBuffer  Ignored (corresponding to NumberOfChildren).
991
992**/
993
994EFI_STATUS
995EFIAPI
996VirtioBlkDriverBindingStop (
997  IN EFI_DRIVER_BINDING_PROTOCOL *This,
998  IN EFI_HANDLE                  DeviceHandle,
999  IN UINTN                       NumberOfChildren,
1000  IN EFI_HANDLE                  *ChildHandleBuffer
1001  )
1002{
1003  EFI_STATUS            Status;
1004  EFI_BLOCK_IO_PROTOCOL *BlockIo;
1005  VBLK_DEV              *Dev;
1006
1007  Status = gBS->OpenProtocol (
1008                  DeviceHandle,                  // candidate device
1009                  &gEfiBlockIoProtocolGuid,      // retrieve the BlockIo iface
1010                  (VOID **)&BlockIo,             // target pointer
1011                  This->DriverBindingHandle,     // requestor driver identity
1012                  DeviceHandle,                  // requesting lookup for dev.
1013                  EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added
1014                  );
1015  if (EFI_ERROR (Status)) {
1016    return Status;
1017  }
1018
1019  Dev = VIRTIO_BLK_FROM_BLOCK_IO (BlockIo);
1020
1021  //
1022  // Handle Stop() requests for in-use driver instances gracefully.
1023  //
1024  Status = gBS->UninstallProtocolInterface (DeviceHandle,
1025                  &gEfiBlockIoProtocolGuid, &Dev->BlockIo);
1026  if (EFI_ERROR (Status)) {
1027    return Status;
1028  }
1029
1030  gBS->CloseEvent (Dev->ExitBoot);
1031
1032  VirtioBlkUninit (Dev);
1033
1034  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
1035         This->DriverBindingHandle, DeviceHandle);
1036
1037  FreePool (Dev);
1038
1039  return EFI_SUCCESS;
1040}
1041
1042
1043//
1044// The static object that groups the Supported() (ie. probe), Start() and
1045// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
1046// C, 10.1 EFI Driver Binding Protocol.
1047//
1048STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
1049  &VirtioBlkDriverBindingSupported,
1050  &VirtioBlkDriverBindingStart,
1051  &VirtioBlkDriverBindingStop,
1052  0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
1053  NULL, // ImageHandle, to be overwritten by
1054        // EfiLibInstallDriverBindingComponentName2() in VirtioBlkEntryPoint()
1055  NULL  // DriverBindingHandle, ditto
1056};
1057
1058
1059//
1060// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
1061// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
1062// in English, for display on standard console devices. This is recommended for
1063// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
1064// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
1065//
1066// Device type names ("Virtio Block Device") are not formatted because the
1067// driver supports only that device type. Therefore the driver name suffices
1068// for unambiguous identification.
1069//
1070
1071STATIC
1072EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
1073  { "eng;en", L"Virtio Block Driver" },
1074  { NULL,     NULL                   }
1075};
1076
1077STATIC
1078EFI_COMPONENT_NAME_PROTOCOL gComponentName;
1079
1080EFI_STATUS
1081EFIAPI
1082VirtioBlkGetDriverName (
1083  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
1084  IN  CHAR8                       *Language,
1085  OUT CHAR16                      **DriverName
1086  )
1087{
1088  return LookupUnicodeString2 (
1089           Language,
1090           This->SupportedLanguages,
1091           mDriverNameTable,
1092           DriverName,
1093           (BOOLEAN)(This == &gComponentName) // Iso639Language
1094           );
1095}
1096
1097EFI_STATUS
1098EFIAPI
1099VirtioBlkGetDeviceName (
1100  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
1101  IN  EFI_HANDLE                  DeviceHandle,
1102  IN  EFI_HANDLE                  ChildHandle,
1103  IN  CHAR8                       *Language,
1104  OUT CHAR16                      **ControllerName
1105  )
1106{
1107  return EFI_UNSUPPORTED;
1108}
1109
1110STATIC
1111EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
1112  &VirtioBlkGetDriverName,
1113  &VirtioBlkGetDeviceName,
1114  "eng" // SupportedLanguages, ISO 639-2 language codes
1115};
1116
1117STATIC
1118EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
1119  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)     &VirtioBlkGetDriverName,
1120  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &VirtioBlkGetDeviceName,
1121  "en" // SupportedLanguages, RFC 4646 language codes
1122};
1123
1124
1125//
1126// Entry point of this driver.
1127//
1128EFI_STATUS
1129EFIAPI
1130VirtioBlkEntryPoint (
1131  IN EFI_HANDLE       ImageHandle,
1132  IN EFI_SYSTEM_TABLE *SystemTable
1133  )
1134{
1135  return EfiLibInstallDriverBindingComponentName2 (
1136           ImageHandle,
1137           SystemTable,
1138           &gDriverBinding,
1139           ImageHandle,
1140           &gComponentName,
1141           &gComponentName2
1142           );
1143}
1144
1145