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