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