]> git.proxmox.com Git - mirror_edk2.git/blob - OvmfPkg/VirtioBlkDxe/VirtioBlk.c
Ovmfpkg/VirtioBlkDxe: map virtio-blk request and response buffers
[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
813 //
814 // In virtio-1.0, feature negotiation is expected to complete before queue
815 // discovery, and the device can also reject the selected set of features.
816 //
817 if (Dev->VirtIo->Revision >= VIRTIO_SPEC_REVISION (1, 0, 0)) {
818 Status = Virtio10WriteFeatures (Dev->VirtIo, Features, &NextDevStat);
819 if (EFI_ERROR (Status)) {
820 goto Failed;
821 }
822 }
823
824 //
825 // step 4b -- allocate virtqueue
826 //
827 Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, 0);
828 if (EFI_ERROR (Status)) {
829 goto Failed;
830 }
831 Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);
832 if (EFI_ERROR (Status)) {
833 goto Failed;
834 }
835 if (QueueSize < 3) { // SynchronousRequest() uses at most three descriptors
836 Status = EFI_UNSUPPORTED;
837 goto Failed;
838 }
839
840 Status = VirtioRingInit (Dev->VirtIo, QueueSize, &Dev->Ring);
841 if (EFI_ERROR (Status)) {
842 goto Failed;
843 }
844
845 //
846 // If anything fails from here on, we must release the ring resources
847 //
848 Status = VirtioRingMap (
849 Dev->VirtIo,
850 &Dev->Ring,
851 &RingBaseShift,
852 &Dev->RingMap
853 );
854 if (EFI_ERROR (Status)) {
855 goto ReleaseQueue;
856 }
857
858 //
859 // Additional steps for MMIO: align the queue appropriately, and set the
860 // size. If anything fails from here on, we must unmap the ring resources.
861 //
862 Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
863 if (EFI_ERROR (Status)) {
864 goto UnmapQueue;
865 }
866
867 Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
868 if (EFI_ERROR (Status)) {
869 goto UnmapQueue;
870 }
871
872 //
873 // step 4c -- Report GPFN (guest-physical frame number) of queue.
874 //
875 Status = Dev->VirtIo->SetQueueAddress (
876 Dev->VirtIo,
877 &Dev->Ring,
878 RingBaseShift
879 );
880 if (EFI_ERROR (Status)) {
881 goto UnmapQueue;
882 }
883
884
885 //
886 // step 5 -- Report understood features.
887 //
888 if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
889 Features &= ~(UINT64)VIRTIO_F_VERSION_1;
890 Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
891 if (EFI_ERROR (Status)) {
892 goto UnmapQueue;
893 }
894 }
895
896 //
897 // step 6 -- initialization complete
898 //
899 NextDevStat |= VSTAT_DRIVER_OK;
900 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
901 if (EFI_ERROR (Status)) {
902 goto UnmapQueue;
903 }
904
905 //
906 // Populate the exported interface's attributes; see UEFI spec v2.4, 12.9 EFI
907 // Block I/O Protocol.
908 //
909 Dev->BlockIo.Revision = 0;
910 Dev->BlockIo.Media = &Dev->BlockIoMedia;
911 Dev->BlockIo.Reset = &VirtioBlkReset;
912 Dev->BlockIo.ReadBlocks = &VirtioBlkReadBlocks;
913 Dev->BlockIo.WriteBlocks = &VirtioBlkWriteBlocks;
914 Dev->BlockIo.FlushBlocks = &VirtioBlkFlushBlocks;
915 Dev->BlockIoMedia.MediaId = 0;
916 Dev->BlockIoMedia.RemovableMedia = FALSE;
917 Dev->BlockIoMedia.MediaPresent = TRUE;
918 Dev->BlockIoMedia.LogicalPartition = FALSE;
919 Dev->BlockIoMedia.ReadOnly = (BOOLEAN) ((Features & VIRTIO_BLK_F_RO) != 0);
920 Dev->BlockIoMedia.WriteCaching = (BOOLEAN) ((Features & VIRTIO_BLK_F_FLUSH) != 0);
921 Dev->BlockIoMedia.BlockSize = BlockSize;
922 Dev->BlockIoMedia.IoAlign = 0;
923 Dev->BlockIoMedia.LastBlock = DivU64x32 (NumSectors,
924 BlockSize / 512) - 1;
925
926 DEBUG ((DEBUG_INFO, "%a: LbaSize=0x%x[B] NumBlocks=0x%Lx[Lba]\n",
927 __FUNCTION__, Dev->BlockIoMedia.BlockSize,
928 Dev->BlockIoMedia.LastBlock + 1));
929
930 if (Features & VIRTIO_BLK_F_TOPOLOGY) {
931 Dev->BlockIo.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
932
933 Dev->BlockIoMedia.LowestAlignedLba = AlignmentOffset;
934 Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock = 1u << PhysicalBlockExp;
935 Dev->BlockIoMedia.OptimalTransferLengthGranularity = OptIoSize;
936
937 DEBUG ((DEBUG_INFO, "%a: FirstAligned=0x%Lx[Lba] PhysBlkSize=0x%x[Lba]\n",
938 __FUNCTION__, Dev->BlockIoMedia.LowestAlignedLba,
939 Dev->BlockIoMedia.LogicalBlocksPerPhysicalBlock));
940 DEBUG ((DEBUG_INFO, "%a: OptimalTransferLengthGranularity=0x%x[Lba]\n",
941 __FUNCTION__, Dev->BlockIoMedia.OptimalTransferLengthGranularity));
942 }
943 return EFI_SUCCESS;
944
945 UnmapQueue:
946 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
947
948 ReleaseQueue:
949 VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
950
951 Failed:
952 //
953 // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device
954 // Status. VirtIo access failure here should not mask the original error.
955 //
956 NextDevStat |= VSTAT_FAILED;
957 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
958
959 return Status; // reached only via Failed above
960 }
961
962
963 /**
964
965 Uninitialize the internals of a virtio-blk device that has been successfully
966 set up with VirtioBlkInit().
967
968 @param[in out] Dev The device to clean up.
969
970 **/
971
972 STATIC
973 VOID
974 EFIAPI
975 VirtioBlkUninit (
976 IN OUT VBLK_DEV *Dev
977 )
978 {
979 //
980 // Reset the virtual device -- see virtio-0.9.5, 2.2.2.1 Device Status. When
981 // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from
982 // the old comms area.
983 //
984 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
985
986 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
987 VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
988
989 SetMem (&Dev->BlockIo, sizeof Dev->BlockIo, 0x00);
990 SetMem (&Dev->BlockIoMedia, sizeof Dev->BlockIoMedia, 0x00);
991 }
992
993
994 /**
995
996 Event notification function enqueued by ExitBootServices().
997
998 @param[in] Event Event whose notification function is being invoked.
999
1000 @param[in] Context Pointer to the VBLK_DEV structure.
1001
1002 **/
1003
1004 STATIC
1005 VOID
1006 EFIAPI
1007 VirtioBlkExitBoot (
1008 IN EFI_EVENT Event,
1009 IN VOID *Context
1010 )
1011 {
1012 VBLK_DEV *Dev;
1013
1014 //
1015 // Reset the device. This causes the hypervisor to forget about the virtio
1016 // ring.
1017 //
1018 // We allocated said ring in EfiBootServicesData type memory, and code
1019 // executing after ExitBootServices() is permitted to overwrite it.
1020 //
1021 Dev = Context;
1022 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
1023
1024 //
1025 // Unmap the ring buffer so that hypervisor will not be able to get
1026 // readable data after device is reset.
1027 //
1028 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
1029 }
1030
1031 /**
1032
1033 After we've pronounced support for a specific device in
1034 DriverBindingSupported(), we start managing said device (passed in by the
1035 Driver Execution Environment) with the following service.
1036
1037 See DriverBindingSupported() for specification references.
1038
1039 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object
1040 incorporating this driver (independently of
1041 any device).
1042
1043 @param[in] DeviceHandle The supported device to drive.
1044
1045 @param[in] RemainingDevicePath Relevant only for bus drivers, ignored.
1046
1047
1048 @retval EFI_SUCCESS Driver instance has been created and
1049 initialized for the virtio-blk device, it
1050 is now accessible via EFI_BLOCK_IO_PROTOCOL.
1051
1052 @retval EFI_OUT_OF_RESOURCES Memory allocation failed.
1053
1054 @return Error codes from the OpenProtocol() boot
1055 service, the VirtIo protocol, VirtioBlkInit(),
1056 or the InstallProtocolInterface() boot service.
1057
1058 **/
1059
1060 EFI_STATUS
1061 EFIAPI
1062 VirtioBlkDriverBindingStart (
1063 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1064 IN EFI_HANDLE DeviceHandle,
1065 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
1066 )
1067 {
1068 VBLK_DEV *Dev;
1069 EFI_STATUS Status;
1070
1071 Dev = (VBLK_DEV *) AllocateZeroPool (sizeof *Dev);
1072 if (Dev == NULL) {
1073 return EFI_OUT_OF_RESOURCES;
1074 }
1075
1076 Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
1077 (VOID **)&Dev->VirtIo, This->DriverBindingHandle,
1078 DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
1079 if (EFI_ERROR (Status)) {
1080 goto FreeVirtioBlk;
1081 }
1082
1083 //
1084 // VirtIo access granted, configure virtio-blk device.
1085 //
1086 Status = VirtioBlkInit (Dev);
1087 if (EFI_ERROR (Status)) {
1088 goto CloseVirtIo;
1089 }
1090
1091 Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
1092 &VirtioBlkExitBoot, Dev, &Dev->ExitBoot);
1093 if (EFI_ERROR (Status)) {
1094 goto UninitDev;
1095 }
1096
1097 //
1098 // Setup complete, attempt to export the driver instance's BlockIo interface.
1099 //
1100 Dev->Signature = VBLK_SIG;
1101 Status = gBS->InstallProtocolInterface (&DeviceHandle,
1102 &gEfiBlockIoProtocolGuid, EFI_NATIVE_INTERFACE,
1103 &Dev->BlockIo);
1104 if (EFI_ERROR (Status)) {
1105 goto CloseExitBoot;
1106 }
1107
1108 return EFI_SUCCESS;
1109
1110 CloseExitBoot:
1111 gBS->CloseEvent (Dev->ExitBoot);
1112
1113 UninitDev:
1114 VirtioBlkUninit (Dev);
1115
1116 CloseVirtIo:
1117 gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
1118 This->DriverBindingHandle, DeviceHandle);
1119
1120 FreeVirtioBlk:
1121 FreePool (Dev);
1122
1123 return Status;
1124 }
1125
1126
1127 /**
1128
1129 Stop driving a virtio-blk device and remove its BlockIo interface.
1130
1131 This function replays the success path of DriverBindingStart() in reverse.
1132 The host side virtio-blk device is reset, so that the OS boot loader or the
1133 OS may reinitialize it.
1134
1135 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object
1136 incorporating this driver (independently of any
1137 device).
1138
1139 @param[in] DeviceHandle Stop driving this device.
1140
1141 @param[in] NumberOfChildren Since this function belongs to a device driver
1142 only (as opposed to a bus driver), the caller
1143 environment sets NumberOfChildren to zero, and
1144 we ignore it.
1145
1146 @param[in] ChildHandleBuffer Ignored (corresponding to NumberOfChildren).
1147
1148 **/
1149
1150 EFI_STATUS
1151 EFIAPI
1152 VirtioBlkDriverBindingStop (
1153 IN EFI_DRIVER_BINDING_PROTOCOL *This,
1154 IN EFI_HANDLE DeviceHandle,
1155 IN UINTN NumberOfChildren,
1156 IN EFI_HANDLE *ChildHandleBuffer
1157 )
1158 {
1159 EFI_STATUS Status;
1160 EFI_BLOCK_IO_PROTOCOL *BlockIo;
1161 VBLK_DEV *Dev;
1162
1163 Status = gBS->OpenProtocol (
1164 DeviceHandle, // candidate device
1165 &gEfiBlockIoProtocolGuid, // retrieve the BlockIo iface
1166 (VOID **)&BlockIo, // target pointer
1167 This->DriverBindingHandle, // requestor driver identity
1168 DeviceHandle, // requesting lookup for dev.
1169 EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added
1170 );
1171 if (EFI_ERROR (Status)) {
1172 return Status;
1173 }
1174
1175 Dev = VIRTIO_BLK_FROM_BLOCK_IO (BlockIo);
1176
1177 //
1178 // Handle Stop() requests for in-use driver instances gracefully.
1179 //
1180 Status = gBS->UninstallProtocolInterface (DeviceHandle,
1181 &gEfiBlockIoProtocolGuid, &Dev->BlockIo);
1182 if (EFI_ERROR (Status)) {
1183 return Status;
1184 }
1185
1186 gBS->CloseEvent (Dev->ExitBoot);
1187
1188 VirtioBlkUninit (Dev);
1189
1190 gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
1191 This->DriverBindingHandle, DeviceHandle);
1192
1193 FreePool (Dev);
1194
1195 return EFI_SUCCESS;
1196 }
1197
1198
1199 //
1200 // The static object that groups the Supported() (ie. probe), Start() and
1201 // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
1202 // C, 10.1 EFI Driver Binding Protocol.
1203 //
1204 STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
1205 &VirtioBlkDriverBindingSupported,
1206 &VirtioBlkDriverBindingStart,
1207 &VirtioBlkDriverBindingStop,
1208 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
1209 NULL, // ImageHandle, to be overwritten by
1210 // EfiLibInstallDriverBindingComponentName2() in VirtioBlkEntryPoint()
1211 NULL // DriverBindingHandle, ditto
1212 };
1213
1214
1215 //
1216 // The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
1217 // EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
1218 // in English, for display on standard console devices. This is recommended for
1219 // UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
1220 // Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
1221 //
1222 // Device type names ("Virtio Block Device") are not formatted because the
1223 // driver supports only that device type. Therefore the driver name suffices
1224 // for unambiguous identification.
1225 //
1226
1227 STATIC
1228 EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
1229 { "eng;en", L"Virtio Block Driver" },
1230 { NULL, NULL }
1231 };
1232
1233 STATIC
1234 EFI_COMPONENT_NAME_PROTOCOL gComponentName;
1235
1236 EFI_STATUS
1237 EFIAPI
1238 VirtioBlkGetDriverName (
1239 IN EFI_COMPONENT_NAME_PROTOCOL *This,
1240 IN CHAR8 *Language,
1241 OUT CHAR16 **DriverName
1242 )
1243 {
1244 return LookupUnicodeString2 (
1245 Language,
1246 This->SupportedLanguages,
1247 mDriverNameTable,
1248 DriverName,
1249 (BOOLEAN)(This == &gComponentName) // Iso639Language
1250 );
1251 }
1252
1253 EFI_STATUS
1254 EFIAPI
1255 VirtioBlkGetDeviceName (
1256 IN EFI_COMPONENT_NAME_PROTOCOL *This,
1257 IN EFI_HANDLE DeviceHandle,
1258 IN EFI_HANDLE ChildHandle,
1259 IN CHAR8 *Language,
1260 OUT CHAR16 **ControllerName
1261 )
1262 {
1263 return EFI_UNSUPPORTED;
1264 }
1265
1266 STATIC
1267 EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
1268 &VirtioBlkGetDriverName,
1269 &VirtioBlkGetDeviceName,
1270 "eng" // SupportedLanguages, ISO 639-2 language codes
1271 };
1272
1273 STATIC
1274 EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
1275 (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) &VirtioBlkGetDriverName,
1276 (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &VirtioBlkGetDeviceName,
1277 "en" // SupportedLanguages, RFC 4646 language codes
1278 };
1279
1280
1281 //
1282 // Entry point of this driver.
1283 //
1284 EFI_STATUS
1285 EFIAPI
1286 VirtioBlkEntryPoint (
1287 IN EFI_HANDLE ImageHandle,
1288 IN EFI_SYSTEM_TABLE *SystemTable
1289 )
1290 {
1291 return EfiLibInstallDriverBindingComponentName2 (
1292 ImageHandle,
1293 SystemTable,
1294 &gDriverBinding,
1295 ImageHandle,
1296 &gComponentName,
1297 &gComponentName2
1298 );
1299 }
1300