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