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