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