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