VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/OvmfPkg/VirtioBlkDxe/VirtioBlk.c@ 58464

Last change on this file since 58464 was 58464, checked in by vboxsync, 9 years ago

EFI/Firmware: Export new files and directories.

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

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette