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