VirtioBlk.c revision 7fcacd6c92616fd993a5befd93bcc9cad2610c90
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// 84EFI_STATUS 85EFIAPI 86VirtioBlkReset ( 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**/ 146STATIC 147EFI_STATUS 148EFIAPI 149VerifyReadWriteRequest ( 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 237STATIC 238EFI_STATUS 239EFIAPI 240SynchronousRequest ( 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 UINT16 FirstAvailIdx; 252 UINT16 NextAvailIdx; 253 UINTN PollPeriodUsecs; 254 255 BlockSize = Dev->BlockIoMedia.BlockSize; 256 257 // 258 // ensured by VirtioBlkInit() 259 // 260 ASSERT (BlockSize > 0); 261 ASSERT (BlockSize % 512 == 0); 262 263 // 264 // ensured by contract above, plus VerifyReadWriteRequest() 265 // 266 ASSERT (BufferSize % BlockSize == 0); 267 268 // 269 // Prepare virtio-blk request header, setting zero size for flush. 270 // IO Priority is homogeneously 0. 271 // 272 Request.Type = RequestIsWrite ? 273 (BufferSize == 0 ? VIRTIO_BLK_T_FLUSH : VIRTIO_BLK_T_OUT) : 274 VIRTIO_BLK_T_IN; 275 Request.IoPrio = 0; 276 Request.Sector = Lba * (BlockSize / 512); 277 278 // 279 // Prepare for virtio-0.9.5, 2.4.2 Receiving Used Buffers From the Device. 280 // We're going to poll the answer, the host should not send an interrupt. 281 // 282 *Dev->Ring.Avail.Flags = (UINT16) VRING_AVAIL_F_NO_INTERRUPT; 283 284 // 285 // preset a host status for ourselves that we do not accept as success 286 // 287 HostStatus = VIRTIO_BLK_S_IOERR; 288 289 // 290 // ensured by VirtioBlkInit() -- this predicate, in combination with the 291 // lock-step progress, ensures we don't have to track free descriptors. 292 // 293 ASSERT (Dev->Ring.QueueSize >= 3); 294 295 // 296 // Implement virtio-0.9.5, 2.4.1 Supplying Buffers to the Device. 297 // 298 FirstAvailIdx = *Dev->Ring.Avail.Idx; 299 NextAvailIdx = FirstAvailIdx; 300 301 // 302 // virtio-blk header in first desc 303 // 304 VirtioAppendDesc (&Dev->Ring, (UINTN) &Request, sizeof Request, 305 VRING_DESC_F_NEXT, FirstAvailIdx, &NextAvailIdx); 306 307 // 308 // data buffer for read/write in second desc 309 // 310 if (BufferSize > 0) { 311 // 312 // From virtio-0.9.5, 2.3.2 Descriptor Table: 313 // "no descriptor chain may be more than 2^32 bytes long in total". 314 // 315 // The predicate is ensured by the call contract above (for flush), or 316 // VerifyReadWriteRequest() (for read/write). It also implies that 317 // converting BufferSize to UINT32 will not truncate it. 318 // 319 ASSERT (BufferSize <= SIZE_1GB); 320 321 // 322 // VRING_DESC_F_WRITE is interpreted from the host's point of view. 323 // 324 VirtioAppendDesc (&Dev->Ring, (UINTN) Buffer, (UINT32) BufferSize, 325 VRING_DESC_F_NEXT | (RequestIsWrite ? 0 : VRING_DESC_F_WRITE), 326 FirstAvailIdx, &NextAvailIdx); 327 } 328 329 // 330 // host status in last (second or third) desc 331 // 332 VirtioAppendDesc (&Dev->Ring, (UINTN) &HostStatus, sizeof HostStatus, 333 VRING_DESC_F_WRITE, FirstAvailIdx, &NextAvailIdx); 334 335 // 336 // virtio-0.9.5, 2.4.1.3 Updating the Index Field 337 // 338 MemoryFence(); 339 *Dev->Ring.Avail.Idx = NextAvailIdx; 340 341 // 342 // virtio-0.9.5, 2.4.1.4 Notifying the Device -- gratuitous notifications are 343 // OK. virtio-blk's only virtqueue is #0, called "requestq" (see Appendix D). 344 // 345 MemoryFence(); 346 if (EFI_ERROR (VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueNotify, 0))) { 347 return EFI_DEVICE_ERROR; 348 } 349 350 // 351 // virtio-0.9.5, 2.4.2 Receiving Used Buffers From the Device 352 // Wait until the host processes and acknowledges our 3-part descriptor 353 // chain. The condition we use for polling is greatly simplified and relies 354 // on synchronous, the lock-step progress. 355 // 356 // Keep slowing down until we reach a poll period of slightly above 1 ms. 357 // 358 PollPeriodUsecs = 1; 359 MemoryFence(); 360 while (*Dev->Ring.Used.Idx != NextAvailIdx) { 361 gBS->Stall (PollPeriodUsecs); // calls AcpiTimerLib::MicroSecondDelay 362 363 if (PollPeriodUsecs < 1024) { 364 PollPeriodUsecs *= 2; 365 } 366 MemoryFence(); 367 } 368 369 if (HostStatus == VIRTIO_BLK_S_OK) { 370 return EFI_SUCCESS; 371 } 372 373 return EFI_DEVICE_ERROR; 374} 375 376 377/** 378 379 ReadBlocks() operation for virtio-blk. 380 381 See 382 - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O 383 Protocol, EFI_BLOCK_IO_PROTOCOL.ReadBlocks(). 384 - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.2. ReadBlocks() and 385 ReadBlocksEx() Implementation. 386 387 Parameter checks and conformant return values are implemented in 388 VerifyReadWriteRequest() and SynchronousRequest(). 389 390 A zero BufferSize doesn't seem to be prohibited, so do nothing in that case, 391 successfully. 392 393**/ 394 395EFI_STATUS 396EFIAPI 397VirtioBlkReadBlocks ( 398 IN EFI_BLOCK_IO_PROTOCOL *This, 399 IN UINT32 MediaId, 400 IN EFI_LBA Lba, 401 IN UINTN BufferSize, 402 OUT VOID *Buffer 403 ) 404{ 405 VBLK_DEV *Dev; 406 EFI_STATUS Status; 407 408 if (BufferSize == 0) { 409 return EFI_SUCCESS; 410 } 411 412 Dev = VIRTIO_BLK_FROM_BLOCK_IO (This); 413 Status = VerifyReadWriteRequest ( 414 &Dev->BlockIoMedia, 415 Lba, 416 BufferSize, 417 FALSE // RequestIsWrite 418 ); 419 if (EFI_ERROR (Status)) { 420 return Status; 421 } 422 423 return SynchronousRequest ( 424 Dev, 425 Lba, 426 BufferSize, 427 Buffer, 428 FALSE // RequestIsWrite 429 ); 430} 431 432/** 433 434 WriteBlocks() operation for virtio-blk. 435 436 See 437 - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O 438 Protocol, EFI_BLOCK_IO_PROTOCOL.WriteBlocks(). 439 - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.3 WriteBlocks() and 440 WriteBlockEx() Implementation. 441 442 Parameter checks and conformant return values are implemented in 443 VerifyReadWriteRequest() and SynchronousRequest(). 444 445 A zero BufferSize doesn't seem to be prohibited, so do nothing in that case, 446 successfully. 447 448**/ 449 450EFI_STATUS 451EFIAPI 452VirtioBlkWriteBlocks ( 453 IN EFI_BLOCK_IO_PROTOCOL *This, 454 IN UINT32 MediaId, 455 IN EFI_LBA Lba, 456 IN UINTN BufferSize, 457 IN VOID *Buffer 458 ) 459{ 460 VBLK_DEV *Dev; 461 EFI_STATUS Status; 462 463 if (BufferSize == 0) { 464 return EFI_SUCCESS; 465 } 466 467 Dev = VIRTIO_BLK_FROM_BLOCK_IO (This); 468 Status = VerifyReadWriteRequest ( 469 &Dev->BlockIoMedia, 470 Lba, 471 BufferSize, 472 TRUE // RequestIsWrite 473 ); 474 if (EFI_ERROR (Status)) { 475 return Status; 476 } 477 478 return SynchronousRequest ( 479 Dev, 480 Lba, 481 BufferSize, 482 Buffer, 483 TRUE // RequestIsWrite 484 ); 485} 486 487 488/** 489 490 FlushBlocks() operation for virtio-blk. 491 492 See 493 - UEFI Spec 2.3.1 + Errata C, 12.8 EFI Block I/O Protocol, 12.8 EFI Block I/O 494 Protocol, EFI_BLOCK_IO_PROTOCOL.FlushBlocks(). 495 - Driver Writer's Guide for UEFI 2.3.1 v1.01, 24.2.4 FlushBlocks() and 496 FlushBlocksEx() Implementation. 497 498 If the underlying virtio-blk device doesn't support flushing (ie. 499 write-caching), then this function should not be called by higher layers, 500 according to EFI_BLOCK_IO_MEDIA characteristics set in VirtioBlkInit(). 501 Should they do nonetheless, we do nothing, successfully. 502 503**/ 504 505EFI_STATUS 506EFIAPI 507VirtioBlkFlushBlocks ( 508 IN EFI_BLOCK_IO_PROTOCOL *This 509 ) 510{ 511 VBLK_DEV *Dev; 512 513 Dev = VIRTIO_BLK_FROM_BLOCK_IO (This); 514 return Dev->BlockIoMedia.WriteCaching ? 515 SynchronousRequest ( 516 Dev, 517 0, // Lba 518 0, // BufferSize 519 NULL, // Buffer 520 TRUE // RequestIsWrite 521 ) : 522 EFI_SUCCESS; 523} 524 525 526/** 527 528 Device probe function for this driver. 529 530 The DXE core calls this function for any given device in order to see if the 531 driver can drive the device. 532 533 Specs relevant in the general sense: 534 535 - UEFI Spec 2.3.1 + Errata C: 536 - 6.3 Protocol Handler Services -- for accessing the underlying device 537 - 10.1 EFI Driver Binding Protocol -- for exporting ourselves 538 539 - Driver Writer's Guide for UEFI 2.3.1 v1.01: 540 - 5.1.3.4 OpenProtocol() and CloseProtocol() -- for accessing the 541 underlying device 542 - 9 Driver Binding Protocol -- for exporting ourselves 543 544 Specs relevant in the specific sense: 545 - UEFI Spec 2.3.1 + Errata C, 13.4 EFI PCI I/O Protocol 546 - Driver Writer's Guide for UEFI 2.3.1 v1.01, 18 PCI Driver Design 547 Guidelines, 18.3 PCI drivers. 548 549 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object 550 incorporating this driver (independently of 551 any device). 552 553 @param[in] DeviceHandle The device to probe. 554 555 @param[in] RemainingDevicePath Relevant only for bus drivers, ignored. 556 557 558 @retval EFI_SUCCESS The driver supports the device being probed. 559 560 @retval EFI_UNSUPPORTED Based on virtio-blk PCI discovery, we do not support 561 the device. 562 563 @return Error codes from the OpenProtocol() boot service or 564 the PciIo protocol. 565 566**/ 567 568EFI_STATUS 569EFIAPI 570VirtioBlkDriverBindingSupported ( 571 IN EFI_DRIVER_BINDING_PROTOCOL *This, 572 IN EFI_HANDLE DeviceHandle, 573 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 574 ) 575{ 576 EFI_STATUS Status; 577 EFI_PCI_IO_PROTOCOL *PciIo; 578 PCI_TYPE00 Pci; 579 580 // 581 // Attempt to open the device with the PciIo set of interfaces. On success, 582 // the protocol is "instantiated" for the PCI device. Covers duplicate open 583 // attempts (EFI_ALREADY_STARTED). 584 // 585 Status = gBS->OpenProtocol ( 586 DeviceHandle, // candidate device 587 &gEfiPciIoProtocolGuid, // for generic PCI access 588 (VOID **)&PciIo, // handle to instantiate 589 This->DriverBindingHandle, // requestor driver identity 590 DeviceHandle, // ControllerHandle, according to 591 // the UEFI Driver Model 592 EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive PciIo access to 593 // the device; to be released 594 ); 595 if (EFI_ERROR (Status)) { 596 return Status; 597 } 598 599 // 600 // Read entire PCI configuration header for more extensive check ahead. 601 // 602 Status = PciIo->Pci.Read ( 603 PciIo, // (protocol, device) 604 // handle 605 EfiPciIoWidthUint32, // access width & copy 606 // mode 607 0, // Offset 608 sizeof Pci / sizeof (UINT32), // Count 609 &Pci // target buffer 610 ); 611 612 if (Status == EFI_SUCCESS) { 613 // 614 // virtio-0.9.5, 2.1 PCI Discovery 615 // 616 Status = (Pci.Hdr.VendorId == 0x1AF4 && 617 Pci.Hdr.DeviceId >= 0x1000 && Pci.Hdr.DeviceId <= 0x103F && 618 Pci.Hdr.RevisionID == 0x00 && 619 Pci.Device.SubsystemID == 0x02) ? EFI_SUCCESS : EFI_UNSUPPORTED; 620 } 621 622 // 623 // We needed PCI IO access only transitorily, to see whether we support the 624 // device or not. 625 // 626 gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, 627 This->DriverBindingHandle, DeviceHandle); 628 return Status; 629} 630 631 632/** 633 634 Set up all BlockIo and virtio-blk aspects of this driver for the specified 635 device. 636 637 @param[in out] Dev The driver instance to configure. The caller is 638 responsible for Dev->PciIo's validity (ie. working IO 639 access to the underlying virtio-blk PCI device). 640 641 @retval EFI_SUCCESS Setup complete. 642 643 @retval EFI_UNSUPPORTED The driver is unable to work with the virtio ring or 644 virtio-blk attributes the host provides. 645 646 @return Error codes from VirtioRingInit() or 647 VIRTIO_CFG_READ() / VIRTIO_CFG_WRITE(). 648 649**/ 650 651STATIC 652EFI_STATUS 653EFIAPI 654VirtioBlkInit ( 655 IN OUT VBLK_DEV *Dev 656 ) 657{ 658 UINT8 NextDevStat; 659 EFI_STATUS Status; 660 661 UINT32 Features; 662 UINT64 NumSectors; 663 UINT32 BlockSize; 664 UINT16 QueueSize; 665 666 // 667 // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence. 668 // 669 NextDevStat = 0; // step 1 -- reset device 670 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat); 671 if (EFI_ERROR (Status)) { 672 goto Failed; 673 } 674 675 NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence 676 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat); 677 if (EFI_ERROR (Status)) { 678 goto Failed; 679 } 680 681 NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it 682 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat); 683 if (EFI_ERROR (Status)) { 684 goto Failed; 685 } 686 687 // 688 // step 4a -- retrieve and validate features 689 // 690 Status = VIRTIO_CFG_READ (Dev, Generic.VhdrDeviceFeatureBits, &Features); 691 if (EFI_ERROR (Status)) { 692 goto Failed; 693 } 694 Status = VIRTIO_CFG_READ (Dev, VhdrCapacity, &NumSectors); 695 if (EFI_ERROR (Status)) { 696 goto Failed; 697 } 698 if (NumSectors == 0) { 699 Status = EFI_UNSUPPORTED; 700 goto Failed; 701 } 702 703 if (Features & VIRTIO_BLK_F_BLK_SIZE) { 704 Status = VIRTIO_CFG_READ (Dev, VhdrBlkSize, &BlockSize); 705 if (EFI_ERROR (Status)) { 706 goto Failed; 707 } 708 if (BlockSize == 0 || BlockSize % 512 != 0 || 709 NumSectors % (BlockSize / 512) != 0) { 710 // 711 // We can only handle a logical block consisting of whole sectors, 712 // and only a disk composed of whole logical blocks. 713 // 714 Status = EFI_UNSUPPORTED; 715 goto Failed; 716 } 717 } 718 else { 719 BlockSize = 512; 720 } 721 722 // 723 // step 4b -- allocate virtqueue 724 // 725 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueSelect, 0); 726 if (EFI_ERROR (Status)) { 727 goto Failed; 728 } 729 Status = VIRTIO_CFG_READ (Dev, Generic.VhdrQueueSize, &QueueSize); 730 if (EFI_ERROR (Status)) { 731 goto Failed; 732 } 733 if (QueueSize < 3) { // SynchronousRequest() uses at most three descriptors 734 Status = EFI_UNSUPPORTED; 735 goto Failed; 736 } 737 738 Status = VirtioRingInit (QueueSize, &Dev->Ring); 739 if (EFI_ERROR (Status)) { 740 goto Failed; 741 } 742 743 // 744 // step 4c -- Report GPFN (guest-physical frame number) of queue. If anything 745 // fails from here on, we must release the ring resources. 746 // 747 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrQueueAddress, 748 (UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT); 749 if (EFI_ERROR (Status)) { 750 goto ReleaseQueue; 751 } 752 753 // 754 // step 5 -- Report understood features. There are no virtio-blk specific 755 // features to negotiate in virtio-0.9.5, plus we do not want any of the 756 // device-independent (known or unknown) VIRTIO_F_* capabilities (see 757 // Appendix B). 758 // 759 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrGuestFeatureBits, 0); 760 if (EFI_ERROR (Status)) { 761 goto ReleaseQueue; 762 } 763 764 // 765 // step 6 -- initialization complete 766 // 767 NextDevStat |= VSTAT_DRIVER_OK; 768 Status = VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat); 769 if (EFI_ERROR (Status)) { 770 goto ReleaseQueue; 771 } 772 773 // 774 // Populate the exported interface's attributes; see UEFI spec v2.3.1 + 775 // Errata C, 12.8 EFI Block I/O Protocol. We stick to the lowest possible 776 // EFI_BLOCK_IO_PROTOCOL revision for now. 777 // 778 Dev->BlockIo.Revision = 0; 779 Dev->BlockIo.Media = &Dev->BlockIoMedia; 780 Dev->BlockIo.Reset = &VirtioBlkReset; 781 Dev->BlockIo.ReadBlocks = &VirtioBlkReadBlocks; 782 Dev->BlockIo.WriteBlocks = &VirtioBlkWriteBlocks; 783 Dev->BlockIo.FlushBlocks = &VirtioBlkFlushBlocks; 784 Dev->BlockIoMedia.MediaId = 0; 785 Dev->BlockIoMedia.RemovableMedia = FALSE; 786 Dev->BlockIoMedia.MediaPresent = TRUE; 787 Dev->BlockIoMedia.LogicalPartition = FALSE; 788 Dev->BlockIoMedia.ReadOnly = !!(Features & VIRTIO_BLK_F_RO); 789 Dev->BlockIoMedia.WriteCaching = !!(Features & VIRTIO_BLK_F_FLUSH); 790 Dev->BlockIoMedia.BlockSize = BlockSize; 791 Dev->BlockIoMedia.IoAlign = 0; 792 Dev->BlockIoMedia.LastBlock = NumSectors / (BlockSize / 512) - 1; 793 return EFI_SUCCESS; 794 795ReleaseQueue: 796 VirtioRingUninit (&Dev->Ring); 797 798Failed: 799 // 800 // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device 801 // Status. PCI IO access failure here should not mask the original error. 802 // 803 NextDevStat |= VSTAT_FAILED; 804 VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, NextDevStat); 805 806 return Status; // reached only via Failed above 807} 808 809 810/** 811 812 Uninitialize the internals of a virtio-blk device that has been successfully 813 set up with VirtioBlkInit(). 814 815 @param[in out] Dev The device to clean up. 816 817**/ 818 819STATIC 820VOID 821EFIAPI 822VirtioBlkUninit ( 823 IN OUT VBLK_DEV *Dev 824 ) 825{ 826 // 827 // Reset the virtual device -- see virtio-0.9.5, 2.2.2.1 Device Status. When 828 // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from 829 // the old comms area. 830 // 831 VIRTIO_CFG_WRITE (Dev, Generic.VhdrDeviceStatus, 0); 832 833 VirtioRingUninit (&Dev->Ring); 834 835 SetMem (&Dev->BlockIo, sizeof Dev->BlockIo, 0x00); 836 SetMem (&Dev->BlockIoMedia, sizeof Dev->BlockIoMedia, 0x00); 837} 838 839 840/** 841 842 After we've pronounced support for a specific device in 843 DriverBindingSupported(), we start managing said device (passed in by the 844 Driver Exeuction Environment) with the following service. 845 846 See DriverBindingSupported() for specification references. 847 848 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object 849 incorporating this driver (independently of 850 any device). 851 852 @param[in] DeviceHandle The supported device to drive. 853 854 @param[in] RemainingDevicePath Relevant only for bus drivers, ignored. 855 856 857 @retval EFI_SUCCESS Driver instance has been created and 858 initialized for the virtio-blk PCI device, it 859 is now accessibla via EFI_BLOCK_IO_PROTOCOL. 860 861 @retval EFI_OUT_OF_RESOURCES Memory allocation failed. 862 863 @return Error codes from the OpenProtocol() boot 864 service, the PciIo protocol, VirtioBlkInit(), 865 or the InstallProtocolInterface() boot service. 866 867**/ 868 869EFI_STATUS 870EFIAPI 871VirtioBlkDriverBindingStart ( 872 IN EFI_DRIVER_BINDING_PROTOCOL *This, 873 IN EFI_HANDLE DeviceHandle, 874 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 875 ) 876{ 877 VBLK_DEV *Dev; 878 EFI_STATUS Status; 879 880 Dev = (VBLK_DEV *) AllocateZeroPool (sizeof *Dev); 881 if (Dev == NULL) { 882 return EFI_OUT_OF_RESOURCES; 883 } 884 885 Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, 886 (VOID **)&Dev->PciIo, This->DriverBindingHandle, 887 DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); 888 if (EFI_ERROR (Status)) { 889 goto FreeVirtioBlk; 890 } 891 892 // 893 // We must retain and ultimately restore the original PCI attributes of the 894 // device. See Driver Writer's Guide for UEFI 2.3.1 v1.01, 18.3 PCI drivers / 895 // 18.3.2 Start() and Stop(). 896 // 897 // The third parameter ("Attributes", input) is ignored by the Get operation. 898 // The fourth parameter ("Result", output) is ignored by the Enable and Set 899 // operations. 900 // 901 // For virtio-blk we only need IO space access. 902 // 903 Status = Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationGet, 904 0, &Dev->OriginalPciAttributes); 905 if (EFI_ERROR (Status)) { 906 goto ClosePciIo; 907 } 908 909 Status = Dev->PciIo->Attributes (Dev->PciIo, 910 EfiPciIoAttributeOperationEnable, 911 EFI_PCI_IO_ATTRIBUTE_IO, NULL); 912 if (EFI_ERROR (Status)) { 913 goto ClosePciIo; 914 } 915 916 // 917 // PCI IO access granted, configure virtio-blk device. 918 // 919 Status = VirtioBlkInit (Dev); 920 if (EFI_ERROR (Status)) { 921 goto RestorePciAttributes; 922 } 923 924 // 925 // Setup complete, attempt to export the driver instance's BlockIo interface. 926 // 927 Dev->Signature = VBLK_SIG; 928 Status = gBS->InstallProtocolInterface (&DeviceHandle, 929 &gEfiBlockIoProtocolGuid, EFI_NATIVE_INTERFACE, 930 &Dev->BlockIo); 931 if (EFI_ERROR (Status)) { 932 goto UninitDev; 933 } 934 935 return EFI_SUCCESS; 936 937UninitDev: 938 VirtioBlkUninit (Dev); 939 940RestorePciAttributes: 941 Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet, 942 Dev->OriginalPciAttributes, NULL); 943 944ClosePciIo: 945 gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, 946 This->DriverBindingHandle, DeviceHandle); 947 948FreeVirtioBlk: 949 FreePool (Dev); 950 951 return Status; 952} 953 954 955/** 956 957 Stop driving a virtio-blk device and remove its BlockIo interface. 958 959 This function replays the success path of DriverBindingStart() in reverse. 960 The host side virtio-blk device is reset, so that the OS boot loader or the 961 OS may reinitialize it. 962 963 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object 964 incorporating this driver (independently of any 965 device). 966 967 @param[in] DeviceHandle Stop driving this device. 968 969 @param[in] NumberOfChildren Since this function belongs to a device driver 970 only (as opposed to a bus driver), the caller 971 environment sets NumberOfChildren to zero, and 972 we ignore it. 973 974 @param[in] ChildHandleBuffer Ignored (corresponding to NumberOfChildren). 975 976**/ 977 978EFI_STATUS 979EFIAPI 980VirtioBlkDriverBindingStop ( 981 IN EFI_DRIVER_BINDING_PROTOCOL *This, 982 IN EFI_HANDLE DeviceHandle, 983 IN UINTN NumberOfChildren, 984 IN EFI_HANDLE *ChildHandleBuffer 985 ) 986{ 987 VBLK_DEV *Dev; 988 EFI_STATUS Status; 989 990 Dev = VIRTIO_BLK_FROM_BLOCK_IO (This); 991 992 // 993 // If DriverBindingStop() is called with the driver instance still in use, 994 // or any of the parameters are invalid, we've caught a bug. 995 // 996 Status = gBS->UninstallProtocolInterface (DeviceHandle, 997 &gEfiBlockIoProtocolGuid, &Dev->BlockIo); 998 ASSERT (Status == EFI_SUCCESS); 999 1000 VirtioBlkUninit (Dev); 1001 1002 Dev->PciIo->Attributes (Dev->PciIo, EfiPciIoAttributeOperationSet, 1003 Dev->OriginalPciAttributes, NULL); 1004 1005 gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, 1006 This->DriverBindingHandle, DeviceHandle); 1007 1008 FreePool (Dev); 1009 1010 return EFI_SUCCESS; 1011} 1012 1013 1014// 1015// The static object that groups the Supported() (ie. probe), Start() and 1016// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata 1017// C, 10.1 EFI Driver Binding Protocol. 1018// 1019STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = { 1020 &VirtioBlkDriverBindingSupported, 1021 &VirtioBlkDriverBindingStart, 1022 &VirtioBlkDriverBindingStop, 1023 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers 1024 NULL, // ImageHandle, to be overwritten by 1025 // EfiLibInstallDriverBindingComponentName2() in VirtioBlkEntryPoint() 1026 NULL // DriverBindingHandle, ditto 1027}; 1028 1029 1030// 1031// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and 1032// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name 1033// in English, for display on standard console devices. This is recommended for 1034// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's 1035// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names. 1036// 1037// Device type names ("Virtio Block Device") are not formatted because the 1038// driver supports only that device type. Therefore the driver name suffices 1039// for unambiguous identification. 1040// 1041 1042STATIC GLOBAL_REMOVE_IF_UNREFERENCED 1043EFI_UNICODE_STRING_TABLE mDriverNameTable[] = { 1044 { "eng;en", L"Virtio Block Driver" }, 1045 { NULL, NULL } 1046}; 1047 1048STATIC GLOBAL_REMOVE_IF_UNREFERENCED 1049EFI_COMPONENT_NAME_PROTOCOL gComponentName; 1050 1051EFI_STATUS 1052EFIAPI 1053VirtioBlkGetDriverName ( 1054 IN EFI_COMPONENT_NAME_PROTOCOL *This, 1055 IN CHAR8 *Language, 1056 OUT CHAR16 **DriverName 1057 ) 1058{ 1059 return LookupUnicodeString2 ( 1060 Language, 1061 This->SupportedLanguages, 1062 mDriverNameTable, 1063 DriverName, 1064 (BOOLEAN)(This == &gComponentName) // Iso639Language 1065 ); 1066} 1067 1068EFI_STATUS 1069EFIAPI 1070VirtioBlkGetDeviceName ( 1071 IN EFI_COMPONENT_NAME_PROTOCOL *This, 1072 IN EFI_HANDLE DeviceHandle, 1073 IN EFI_HANDLE ChildHandle, 1074 IN CHAR8 *Language, 1075 OUT CHAR16 **ControllerName 1076 ) 1077{ 1078 return EFI_UNSUPPORTED; 1079} 1080 1081STATIC GLOBAL_REMOVE_IF_UNREFERENCED 1082EFI_COMPONENT_NAME_PROTOCOL gComponentName = { 1083 &VirtioBlkGetDriverName, 1084 &VirtioBlkGetDeviceName, 1085 "eng" // SupportedLanguages, ISO 639-2 language codes 1086}; 1087 1088STATIC GLOBAL_REMOVE_IF_UNREFERENCED 1089EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = { 1090 (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) &VirtioBlkGetDriverName, 1091 (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &VirtioBlkGetDeviceName, 1092 "en" // SupportedLanguages, RFC 4646 language codes 1093}; 1094 1095 1096// 1097// Entry point of this driver. 1098// 1099EFI_STATUS 1100EFIAPI 1101VirtioBlkEntryPoint ( 1102 IN EFI_HANDLE ImageHandle, 1103 IN EFI_SYSTEM_TABLE *SystemTable 1104 ) 1105{ 1106 return EfiLibInstallDriverBindingComponentName2 ( 1107 ImageHandle, 1108 SystemTable, 1109 &gDriverBinding, 1110 ImageHandle, 1111 &gComponentName, 1112 &gComponentName2 1113 ); 1114} 1115 1116