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