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