VirtioBlk.c revision c8c2e4d61339592056931dff5c209b7d06fb466c
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, 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/Pci.h>
27#include <IndustryStandard/VirtioBlk.h>
28#include <Library/BaseMemoryLib.h>
29#include <Library/DebugLib.h>
30#include <Library/MemoryAllocationLib.h>
31#include <Library/UefiBootServicesTableLib.h>
32#include <Library/UefiLib.h>
33#include <Library/VirtioLib.h>
34
35#include "VirtioBlk.h"
36
37/**
38
39  Convenience macros to read and write region 0 IO space elements of the
40  virtio-blk PCI device, for configuration purposes.
41
42  The following macros make it possible to specify only the "core parameters"
43  for such accesses and to derive the rest. By the time VIRTIO_CFG_WRITE()
44  returns, the transaction will have been completed.
45
46  @param[in] Dev       Pointer to the VBLK_DEV structure whose PCI IO space
47                       we're accessing. Dev->PciIo must be valid.
48
49  @param[in] Field     A field name from VBLK_HDR, identifying the virtio-blk
50                       configuration item to access.
51
52  @param[in] Value     (VIRTIO_CFG_WRITE() only.) The value to write to the
53                       selected configuration item.
54
55  @param[out] Pointer  (VIRTIO_CFG_READ() only.) The object to receive the
56                       value read from the configuration item. Its type must be
57                       one of UINT8, UINT16, UINT32, UINT64.
58
59
60  @return  Status code returned by VirtioWrite() / VirtioRead().
61
62**/
63
64#define VIRTIO_CFG_WRITE(Dev, Field, Value)  (VirtioWrite (             \
65                                                (Dev)->PciIo,           \
66                                                OFFSET_OF_VBLK (Field), \
67                                                SIZE_OF_VBLK (Field),   \
68                                                (Value)                 \
69                                                ))
70
71#define VIRTIO_CFG_READ(Dev, Field, Pointer) (VirtioRead (              \
72                                                (Dev)->PciIo,           \
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 PCI 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->PciIo, 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  Specs relevant in the specific sense:
504  - UEFI Spec 2.3.1 + Errata C, 13.4 EFI PCI I/O Protocol
505  - Driver Writer's Guide for UEFI 2.3.1 v1.01, 18 PCI Driver Design
506    Guidelines, 18.3 PCI drivers.
507
508  @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
509                                  incorporating this driver (independently of
510                                  any device).
511
512  @param[in] DeviceHandle         The device to probe.
513
514  @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
515
516
517  @retval EFI_SUCCESS      The driver supports the device being probed.
518
519  @retval EFI_UNSUPPORTED  Based on virtio-blk PCI discovery, we do not support
520                           the device.
521
522  @return                  Error codes from the OpenProtocol() boot service or
523                           the PciIo protocol.
524
525**/
526
527EFI_STATUS
528EFIAPI
529VirtioBlkDriverBindingSupported (
530  IN EFI_DRIVER_BINDING_PROTOCOL *This,
531  IN EFI_HANDLE                  DeviceHandle,
532  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
533  )
534{
535  EFI_STATUS          Status;
536  EFI_PCI_IO_PROTOCOL *PciIo;
537  PCI_TYPE00          Pci;
538
539  //
540  // Attempt to open the device with the PciIo set of interfaces. On success,
541  // the protocol is "instantiated" for the PCI device. Covers duplicate open
542  // attempts (EFI_ALREADY_STARTED).
543  //
544  Status = gBS->OpenProtocol (
545                  DeviceHandle,               // candidate device
546                  &gEfiPciIoProtocolGuid,     // for generic PCI access
547                  (VOID **)&PciIo,            // handle to instantiate
548                  This->DriverBindingHandle,  // requestor driver identity
549                  DeviceHandle,               // ControllerHandle, according to
550                                              // the UEFI Driver Model
551                  EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive PciIo access to
552                                              // the device; to be released
553                  );
554  if (EFI_ERROR (Status)) {
555    return Status;
556  }
557
558  //
559  // Read entire PCI configuration header for more extensive check ahead.
560  //
561  Status = PciIo->Pci.Read (
562                        PciIo,                        // (protocol, device)
563                                                      // handle
564                        EfiPciIoWidthUint32,          // access width & copy
565                                                      // mode
566                        0,                            // Offset
567                        sizeof Pci / sizeof (UINT32), // Count
568                        &Pci                          // target buffer
569                        );
570
571  if (Status == EFI_SUCCESS) {
572    //
573    // virtio-0.9.5, 2.1 PCI Discovery
574    //
575    Status = (Pci.Hdr.VendorId == 0x1AF4 &&
576              Pci.Hdr.DeviceId >= 0x1000 && Pci.Hdr.DeviceId <= 0x103F &&
577              Pci.Hdr.RevisionID == 0x00 &&
578              Pci.Device.SubsystemID == 0x02) ? EFI_SUCCESS : EFI_UNSUPPORTED;
579  }
580
581  //
582  // We needed PCI IO access only transitorily, to see whether we support the
583  // device or not.
584  //
585  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
586         This->DriverBindingHandle, DeviceHandle);
587  return Status;
588}
589
590
591/**
592
593  Set up all BlockIo and virtio-blk aspects of this driver for the specified
594  device.
595
596  @param[in out] Dev  The driver instance to configure. The caller is
597                      responsible for Dev->PciIo's validity (ie. working IO
598                      access to the underlying virtio-blk PCI device).
599
600  @retval EFI_SUCCESS      Setup complete.
601
602  @retval EFI_UNSUPPORTED  The driver is unable to work with the virtio ring or
603                           virtio-blk attributes the host provides.
604
605  @return                  Error codes from VirtioRingInit() or
606                           VIRTIO_CFG_READ() / VIRTIO_CFG_WRITE().
607
608**/
609
610STATIC
611EFI_STATUS
612EFIAPI
613VirtioBlkInit (
614  IN OUT VBLK_DEV *Dev
615  )
616{
617  UINT8      NextDevStat;
618  EFI_STATUS Status;
619
620  UINT32     Features;
621  UINT64     NumSectors;
622  UINT32     BlockSize;
623  UINT16     QueueSize;
624
625  //
626  // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
627  //
628  NextDevStat = 0;             // step 1 -- reset device
629  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
630  if (EFI_ERROR (Status)) {
631    goto Failed;
632  }
633
634  NextDevStat |= VSTAT_ACK;    // step 2 -- acknowledge device presence
635  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
636  if (EFI_ERROR (Status)) {
637    goto Failed;
638  }
639
640  NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
641  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
642  if (EFI_ERROR (Status)) {
643    goto Failed;
644  }
645
646  //
647  // step 4a -- retrieve and validate features
648  //
649  Status = VIRTIO_CFG_READ (Dev, Generic.VhdrDeviceFeatureBits, &Features);
650  if (EFI_ERROR (Status)) {
651    goto Failed;
652  }
653  Status = VIRTIO_CFG_READ (Dev, VhdrCapacity, &NumSectors);
654  if (EFI_ERROR (Status)) {
655    goto Failed;
656  }
657  if (NumSectors == 0) {
658    Status = EFI_UNSUPPORTED;
659    goto Failed;
660  }
661
662  if (Features & VIRTIO_BLK_F_BLK_SIZE) {
663    Status = VIRTIO_CFG_READ (Dev, VhdrBlkSize, &BlockSize);
664    if (EFI_ERROR (Status)) {
665      goto Failed;
666    }
667    if (BlockSize == 0 || BlockSize % 512 != 0 ||
668        ModU64x32 (NumSectors, BlockSize / 512) != 0) {
669      //
670      // We can only handle a logical block consisting of whole sectors,
671      // and only a disk composed of whole logical blocks.
672      //
673      Status = EFI_UNSUPPORTED;
674      goto Failed;
675    }
676  }
677  else {
678    BlockSize = 512;
679  }
680
681  //
682  // step 4b -- allocate virtqueue
683  //
684  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueSelect, 0);
685  if (EFI_ERROR (Status)) {
686    goto Failed;
687  }
688  Status = VIRTIO_CFG_READ (Dev, Generic.VhdrQueueSize, &QueueSize);
689  if (EFI_ERROR (Status)) {
690    goto Failed;
691  }
692  if (QueueSize < 3) { // SynchronousRequest() uses at most three descriptors
693    Status = EFI_UNSUPPORTED;
694    goto Failed;
695  }
696
697  Status = VirtioRingInit (QueueSize, &Dev->Ring);
698  if (EFI_ERROR (Status)) {
699    goto Failed;
700  }
701
702  //
703  // step 4c -- Report GPFN (guest-physical frame number) of queue. If anything
704  // fails from here on, we must release the ring resources.
705  //
706  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueAddress,
707             (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT);
708  if (EFI_ERROR (Status)) {
709    goto ReleaseQueue;
710  }
711
712  //
713  // step 5 -- Report understood features. There are no virtio-blk specific
714  // features to negotiate in virtio-0.9.5, plus we do not want any of the
715  // device-independent (known or unknown) VIRTIO_F_* capabilities (see
716  // Appendix B).
717  //
718  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrGuestFeatureBits, 0);
719  if (EFI_ERROR (Status)) {
720    goto ReleaseQueue;
721  }
722
723  //
724  // step 6 -- initialization complete
725  //
726  NextDevStat |= VSTAT_DRIVER_OK;
727  Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
728  if (EFI_ERROR (Status)) {
729    goto ReleaseQueue;
730  }
731
732  //
733  // Populate the exported interface's attributes; see UEFI spec v2.3.1 +
734  // Errata C, 12.8 EFI Block I/O Protocol. We stick to the lowest possible
735  // EFI_BLOCK_IO_PROTOCOL revision for now.
736  //
737  Dev->BlockIo.Revision              = 0;
738  Dev->BlockIo.Media                 = &Dev->BlockIoMedia;
739  Dev->BlockIo.Reset                 = &VirtioBlkReset;
740  Dev->BlockIo.ReadBlocks            = &VirtioBlkReadBlocks;
741  Dev->BlockIo.WriteBlocks           = &VirtioBlkWriteBlocks;
742  Dev->BlockIo.FlushBlocks           = &VirtioBlkFlushBlocks;
743  Dev->BlockIoMedia.MediaId          = 0;
744  Dev->BlockIoMedia.RemovableMedia   = FALSE;
745  Dev->BlockIoMedia.MediaPresent     = TRUE;
746  Dev->BlockIoMedia.LogicalPartition = FALSE;
747  Dev->BlockIoMedia.ReadOnly         = !!(Features & VIRTIO_BLK_F_RO);
748  Dev->BlockIoMedia.WriteCaching     = !!(Features & VIRTIO_BLK_F_FLUSH);
749  Dev->BlockIoMedia.BlockSize        = BlockSize;
750  Dev->BlockIoMedia.IoAlign          = 0;
751  Dev->BlockIoMedia.LastBlock        = DivU64x32 (NumSectors,
752                                         BlockSize / 512) - 1;
753  return EFI_SUCCESS;
754
755ReleaseQueue:
756  VirtioRingUninit (&Dev->Ring);
757
758Failed:
759  //
760  // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device
761  // Status. PCI IO access failure here should not mask the original error.
762  //
763  NextDevStat |= VSTAT_FAILED;
764  VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat);
765
766  return Status; // reached only via Failed above
767}
768
769
770/**
771
772  Uninitialize the internals of a virtio-blk device that has been successfully
773  set up with VirtioBlkInit().
774
775  @param[in out]  Dev  The device to clean up.
776
777**/
778
779STATIC
780VOID
781EFIAPI
782VirtioBlkUninit (
783  IN OUT VBLK_DEV *Dev
784  )
785{
786  //
787  // Reset the virtual device -- see virtio-0.9.5, 2.2.2.1 Device Status. When
788  // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from
789  // the old comms area.
790  //
791  VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0);
792
793  VirtioRingUninit (&Dev->Ring);
794
795  SetMem (&Dev->BlockIo,      sizeof Dev->BlockIo,      0x00);
796  SetMem (&Dev->BlockIoMedia, sizeof Dev->BlockIoMedia, 0x00);
797}
798
799
800/**
801
802  After we've pronounced support for a specific device in
803  DriverBindingSupported(), we start managing said device (passed in by the
804  Driver Exeuction Environment) with the following service.
805
806  See DriverBindingSupported() for specification references.
807
808  @param[in]  This                The EFI_DRIVER_BINDING_PROTOCOL object
809                                  incorporating this driver (independently of
810                                  any device).
811
812  @param[in] DeviceHandle         The supported device to drive.
813
814  @param[in] RemainingDevicePath  Relevant only for bus drivers, ignored.
815
816
817  @retval EFI_SUCCESS           Driver instance has been created and
818                                initialized  for the virtio-blk PCI device, it
819                                is now accessibla via EFI_BLOCK_IO_PROTOCOL.
820
821  @retval EFI_OUT_OF_RESOURCES  Memory allocation failed.
822
823  @return                       Error codes from the OpenProtocol() boot
824                                service, the PciIo protocol, VirtioBlkInit(),
825                                or the InstallProtocolInterface() boot service.
826
827**/
828
829EFI_STATUS
830EFIAPI
831VirtioBlkDriverBindingStart (
832  IN EFI_DRIVER_BINDING_PROTOCOL *This,
833  IN EFI_HANDLE                  DeviceHandle,
834  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
835  )
836{
837  VBLK_DEV   *Dev;
838  EFI_STATUS Status;
839
840  Dev = (VBLK_DEV *) AllocateZeroPool (sizeof *Dev);
841  if (Dev == NULL) {
842    return EFI_OUT_OF_RESOURCES;
843  }
844
845  Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
846                  (VOID **)&Dev->PciIo, This->DriverBindingHandle,
847                  DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
848  if (EFI_ERROR (Status)) {
849    goto FreeVirtioBlk;
850  }
851
852  //
853  // We must retain and ultimately restore the original PCI attributes of the
854  // device. See Driver Writer's Guide for UEFI 2.3.1 v1.01, 18.3 PCI drivers /
855  // 18.3.2 Start() and Stop().
856  //
857  // The third parameter ("Attributes", input) is ignored by the Get operation.
858  // The fourth parameter ("Result", output) is ignored by the Enable and Set
859  // operations.
860  //
861  // For virtio-blk we only need IO space access.
862  //
863  Status = Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationGet,
864                         0, &Dev->OriginalPciAttributes);
865  if (EFI_ERROR (Status)) {
866    goto ClosePciIo;
867  }
868
869  Status = Dev->PciIo->Attributes (Dev->PciIo,
870                         EfiPciIoAttributeOperationEnable,
871                         EFI_PCI_IO_ATTRIBUTE_IO, NULL);
872  if (EFI_ERROR (Status)) {
873    goto ClosePciIo;
874  }
875
876  //
877  // PCI IO access granted, configure virtio-blk device.
878  //
879  Status = VirtioBlkInit (Dev);
880  if (EFI_ERROR (Status)) {
881    goto RestorePciAttributes;
882  }
883
884  //
885  // Setup complete, attempt to export the driver instance's BlockIo interface.
886  //
887  Dev->Signature = VBLK_SIG;
888  Status = gBS->InstallProtocolInterface (&DeviceHandle,
889                  &gEfiBlockIoProtocolGuid, EFI_NATIVE_INTERFACE,
890                  &Dev->BlockIo);
891  if (EFI_ERROR (Status)) {
892    goto UninitDev;
893  }
894
895  return EFI_SUCCESS;
896
897UninitDev:
898  VirtioBlkUninit (Dev);
899
900RestorePciAttributes:
901  Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,
902                Dev->OriginalPciAttributes, NULL);
903
904ClosePciIo:
905  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
906         This->DriverBindingHandle, DeviceHandle);
907
908FreeVirtioBlk:
909  FreePool (Dev);
910
911  return Status;
912}
913
914
915/**
916
917  Stop driving a virtio-blk device and remove its BlockIo interface.
918
919  This function replays the success path of DriverBindingStart() in reverse.
920  The host side virtio-blk device is reset, so that the OS boot loader or the
921  OS may reinitialize it.
922
923  @param[in] This               The EFI_DRIVER_BINDING_PROTOCOL object
924                                incorporating this driver (independently of any
925                                device).
926
927  @param[in] DeviceHandle       Stop driving this device.
928
929  @param[in] NumberOfChildren   Since this function belongs to a device driver
930                                only (as opposed to a bus driver), the caller
931                                environment sets NumberOfChildren to zero, and
932                                we ignore it.
933
934  @param[in] ChildHandleBuffer  Ignored (corresponding to NumberOfChildren).
935
936**/
937
938EFI_STATUS
939EFIAPI
940VirtioBlkDriverBindingStop (
941  IN EFI_DRIVER_BINDING_PROTOCOL *This,
942  IN EFI_HANDLE                  DeviceHandle,
943  IN UINTN                       NumberOfChildren,
944  IN EFI_HANDLE                  *ChildHandleBuffer
945  )
946{
947  EFI_STATUS            Status;
948  EFI_BLOCK_IO_PROTOCOL *BlockIo;
949  VBLK_DEV              *Dev;
950
951  Status = gBS->OpenProtocol (
952                  DeviceHandle,                  // candidate device
953                  &gEfiBlockIoProtocolGuid,      // retrieve the BlockIo iface
954                  (VOID **)&BlockIo,             // target pointer
955                  This->DriverBindingHandle,     // requestor driver identity
956                  DeviceHandle,                  // requesting lookup for dev.
957                  EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added
958                  );
959  if (EFI_ERROR (Status)) {
960    return Status;
961  }
962
963  Dev = VIRTIO_BLK_FROM_BLOCK_IO (BlockIo);
964
965  //
966  // Handle Stop() requests for in-use driver instances gracefully.
967  //
968  Status = gBS->UninstallProtocolInterface (DeviceHandle,
969                  &gEfiBlockIoProtocolGuid, &Dev->BlockIo);
970  if (EFI_ERROR (Status)) {
971    return Status;
972  }
973
974  VirtioBlkUninit (Dev);
975
976  Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet,
977                Dev->OriginalPciAttributes, NULL);
978
979  gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid,
980         This->DriverBindingHandle, DeviceHandle);
981
982  FreePool (Dev);
983
984  return EFI_SUCCESS;
985}
986
987
988//
989// The static object that groups the Supported() (ie. probe), Start() and
990// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
991// C, 10.1 EFI Driver Binding Protocol.
992//
993STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
994  &VirtioBlkDriverBindingSupported,
995  &VirtioBlkDriverBindingStart,
996  &VirtioBlkDriverBindingStop,
997  0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
998  NULL, // ImageHandle, to be overwritten by
999        // EfiLibInstallDriverBindingComponentName2() in VirtioBlkEntryPoint()
1000  NULL  // DriverBindingHandle, ditto
1001};
1002
1003
1004//
1005// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
1006// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
1007// in English, for display on standard console devices. This is recommended for
1008// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
1009// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
1010//
1011// Device type names ("Virtio Block Device") are not formatted because the
1012// driver supports only that device type. Therefore the driver name suffices
1013// for unambiguous identification.
1014//
1015
1016STATIC
1017EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
1018  { "eng;en", L"Virtio Block Driver" },
1019  { NULL,     NULL                   }
1020};
1021
1022STATIC
1023EFI_COMPONENT_NAME_PROTOCOL gComponentName;
1024
1025EFI_STATUS
1026EFIAPI
1027VirtioBlkGetDriverName (
1028  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
1029  IN  CHAR8                       *Language,
1030  OUT CHAR16                      **DriverName
1031  )
1032{
1033  return LookupUnicodeString2 (
1034           Language,
1035           This->SupportedLanguages,
1036           mDriverNameTable,
1037           DriverName,
1038           (BOOLEAN)(This == &gComponentName) // Iso639Language
1039           );
1040}
1041
1042EFI_STATUS
1043EFIAPI
1044VirtioBlkGetDeviceName (
1045  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
1046  IN  EFI_HANDLE                  DeviceHandle,
1047  IN  EFI_HANDLE                  ChildHandle,
1048  IN  CHAR8                       *Language,
1049  OUT CHAR16                      **ControllerName
1050  )
1051{
1052  return EFI_UNSUPPORTED;
1053}
1054
1055STATIC
1056EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
1057  &VirtioBlkGetDriverName,
1058  &VirtioBlkGetDeviceName,
1059  "eng" // SupportedLanguages, ISO 639-2 language codes
1060};
1061
1062STATIC
1063EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
1064  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)     &VirtioBlkGetDriverName,
1065  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &VirtioBlkGetDeviceName,
1066  "en" // SupportedLanguages, RFC 4646 language codes
1067};
1068
1069
1070//
1071// Entry point of this driver.
1072//
1073EFI_STATUS
1074EFIAPI
1075VirtioBlkEntryPoint (
1076  IN EFI_HANDLE       ImageHandle,
1077  IN EFI_SYSTEM_TABLE *SystemTable
1078  )
1079{
1080  return EfiLibInstallDriverBindingComponentName2 (
1081           ImageHandle,
1082           SystemTable,
1083           &gDriverBinding,
1084           ImageHandle,
1085           &gComponentName,
1086           &gComponentName2
1087           );
1088}
1089
1090