1 /** @file 2 3 This driver produces Virtio Device Protocol instances for Virtio PCI devices. 4 5 Copyright (C) 2012, Red Hat, Inc. 6 Copyright (c) 2012 - 2016, Intel Corporation. All rights reserved.<BR> 7 Copyright (C) 2013, ARM Ltd. 8 9 This program and the accompanying materials are licensed and made available 10 under the terms and conditions of the BSD License which accompanies this 11 distribution. The full text of the license may be found at 12 http://opensource.org/licenses/bsd-license.php 13 14 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT 15 WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 16 17 **/ 18 19 #include <IndustryStandard/Pci.h> 20 #include <Library/BaseMemoryLib.h> 21 #include <Library/DebugLib.h> 22 #include <Library/MemoryAllocationLib.h> 23 #include <Library/UefiBootServicesTableLib.h> 24 #include <Library/UefiLib.h> 25 26 #include "VirtioPciDevice.h" 27 28 STATIC VIRTIO_DEVICE_PROTOCOL mDeviceProtocolTemplate = { 29 0, // Revision 30 0, // SubSystemDeviceId 31 VirtioPciGetDeviceFeatures, // GetDeviceFeatures 32 VirtioPciSetGuestFeatures, // SetGuestFeatures 33 VirtioPciSetQueueAddress, // SetQueueAddress 34 VirtioPciSetQueueSel, // SetQueueSel 35 VirtioPciSetQueueNotify, // SetQueueNotify 36 VirtioPciSetQueueAlignment, // SetQueueAlignment 37 VirtioPciSetPageSize, // SetPageSize 38 VirtioPciGetQueueSize, // GetQueueNumMax 39 VirtioPciSetQueueSize, // SetQueueNum 40 VirtioPciGetDeviceStatus, // GetDeviceStatus 41 VirtioPciSetDeviceStatus, // SetDeviceStatus 42 VirtioPciDeviceWrite, // WriteDevice 43 VirtioPciDeviceRead // ReadDevice 44 }; 45 46 /** 47 48 Read a word from Region 0 of the device specified by PciIo. 49 50 Region 0 must be an iomem region. This is an internal function for the PCI 51 implementation of the protocol. 52 53 @param[in] Dev Virtio PCI device. 54 55 @param[in] FieldOffset Source offset. 56 57 @param[in] FieldSize Source field size, must be in { 1, 2, 4, 8 }. 58 59 @param[in] BufferSize Number of bytes available in the target buffer. Must 60 equal FieldSize. 61 62 @param[out] Buffer Target buffer. 63 64 65 @return Status code returned by PciIo->Io.Read(). 66 67 **/ 68 EFI_STATUS 69 EFIAPI 70 VirtioPciIoRead ( 71 IN VIRTIO_PCI_DEVICE *Dev, 72 IN UINTN FieldOffset, 73 IN UINTN FieldSize, 74 IN UINTN BufferSize, 75 OUT VOID *Buffer 76 ) 77 { 78 UINTN Count; 79 EFI_PCI_IO_PROTOCOL_WIDTH Width; 80 EFI_PCI_IO_PROTOCOL *PciIo; 81 82 ASSERT (FieldSize == BufferSize); 83 84 PciIo = Dev->PciIo; 85 Count = 1; 86 87 switch (FieldSize) { 88 case 1: 89 Width = EfiPciIoWidthUint8; 90 break; 91 92 case 2: 93 Width = EfiPciIoWidthUint16; 94 break; 95 96 case 8: 97 // 98 // The 64bit PCI I/O is broken down into two 32bit reads to prevent 99 // any alignment or width issues. 100 // The UEFI spec says under EFI_PCI_IO_PROTOCOL.Io.Write(): 101 // 102 // The I/O operations are carried out exactly as requested. The caller 103 // is responsible for any alignment and I/O width issues which the 104 // bus, device, platform, or type of I/O might require. For example on 105 // some platforms, width requests of EfiPciIoWidthUint64 do not work. 106 // 107 Count = 2; 108 109 // 110 // fall through 111 // 112 case 4: 113 Width = EfiPciIoWidthUint32; 114 break; 115 116 default: 117 ASSERT (FALSE); 118 return EFI_INVALID_PARAMETER; 119 } 120 121 return PciIo->Io.Read ( 122 PciIo, 123 Width, 124 PCI_BAR_IDX0, 125 FieldOffset, 126 Count, 127 Buffer 128 ); 129 } 130 131 /** 132 133 Write a word into Region 0 of the device specified by PciIo. 134 135 Region 0 must be an iomem region. This is an internal function for the PCI 136 implementation of the protocol. 137 138 @param[in] Dev Virtio PCI device. 139 140 @param[in] FieldOffset Destination offset. 141 142 @param[in] FieldSize Destination field size, must be in { 1, 2, 4, 8 }. 143 144 @param[in] Value Little endian value to write, converted to UINT64. 145 The least significant FieldSize bytes will be used. 146 147 148 @return Status code returned by PciIo->Io.Write(). 149 150 **/ 151 EFI_STATUS 152 EFIAPI 153 VirtioPciIoWrite ( 154 IN VIRTIO_PCI_DEVICE *Dev, 155 IN UINTN FieldOffset, 156 IN UINTN FieldSize, 157 IN UINT64 Value 158 ) 159 { 160 UINTN Count; 161 EFI_PCI_IO_PROTOCOL_WIDTH Width; 162 EFI_PCI_IO_PROTOCOL *PciIo; 163 164 PciIo = Dev->PciIo; 165 Count = 1; 166 167 switch (FieldSize) { 168 case 1: 169 Width = EfiPciIoWidthUint8; 170 break; 171 172 case 2: 173 Width = EfiPciIoWidthUint16; 174 break; 175 176 case 8: 177 // 178 // The 64bit PCI I/O is broken down into two 32bit writes to prevent 179 // any alignment or width issues. 180 // The UEFI spec says under EFI_PCI_IO_PROTOCOL.Io.Write(): 181 // 182 // The I/O operations are carried out exactly as requested. The caller 183 // is responsible for any alignment and I/O width issues which the 184 // bus, device, platform, or type of I/O might require. For example on 185 // some platforms, width requests of EfiPciIoWidthUint64 do not work 186 // 187 Count = Count * 2; 188 189 // 190 // fall through 191 // 192 case 4: 193 Width = EfiPciIoWidthUint32; 194 break; 195 196 default: 197 ASSERT (FALSE); 198 return EFI_INVALID_PARAMETER; 199 } 200 201 return PciIo->Io.Write ( 202 PciIo, 203 Width, 204 PCI_BAR_IDX0, 205 FieldOffset, 206 Count, 207 &Value 208 ); 209 } 210 211 /** 212 213 Device probe function for this driver. 214 215 The DXE core calls this function for any given device in order to see if the 216 driver can drive the device. 217 218 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object 219 incorporating this driver (independently of 220 any device). 221 222 @param[in] DeviceHandle The device to probe. 223 224 @param[in] RemainingDevicePath Relevant only for bus drivers, ignored. 225 226 227 @retval EFI_SUCCESS The driver supports the device being probed. 228 229 @retval EFI_UNSUPPORTED Based on virtio-pci discovery, we do not support 230 the device. 231 232 @return Error codes from the OpenProtocol() boot service or 233 the PciIo protocol. 234 235 **/ 236 STATIC 237 EFI_STATUS 238 EFIAPI 239 VirtioPciDeviceBindingSupported ( 240 IN EFI_DRIVER_BINDING_PROTOCOL *This, 241 IN EFI_HANDLE DeviceHandle, 242 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 243 ) 244 { 245 EFI_STATUS Status; 246 EFI_PCI_IO_PROTOCOL *PciIo; 247 PCI_TYPE00 Pci; 248 249 // 250 // Attempt to open the device with the PciIo set of interfaces. On success, 251 // the protocol is "instantiated" for the PCI device. Covers duplicate open 252 // attempts (EFI_ALREADY_STARTED). 253 // 254 Status = gBS->OpenProtocol ( 255 DeviceHandle, // candidate device 256 &gEfiPciIoProtocolGuid, // for generic PCI access 257 (VOID **)&PciIo, // handle to instantiate 258 This->DriverBindingHandle, // requestor driver identity 259 DeviceHandle, // ControllerHandle, according to 260 // the UEFI Driver Model 261 EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive PciIo access to 262 // the device; to be released 263 ); 264 if (EFI_ERROR (Status)) { 265 return Status; 266 } 267 268 // 269 // Read entire PCI configuration header for more extensive check ahead. 270 // 271 Status = PciIo->Pci.Read ( 272 PciIo, // (protocol, device) 273 // handle 274 EfiPciIoWidthUint32, // access width & copy 275 // mode 276 0, // Offset 277 sizeof Pci / sizeof (UINT32), // Count 278 &Pci // target buffer 279 ); 280 281 if (Status == EFI_SUCCESS) { 282 // 283 // virtio-0.9.5, 2.1 PCI Discovery 284 // 285 if ((Pci.Hdr.VendorId == VIRTIO_VENDOR_ID) && 286 (Pci.Hdr.DeviceId >= 0x1000) && 287 (Pci.Hdr.DeviceId <= 0x103F) && 288 (Pci.Hdr.RevisionID == 0x00)) { 289 Status = EFI_SUCCESS; 290 } else { 291 Status = EFI_UNSUPPORTED; 292 } 293 } 294 295 // 296 // We needed PCI IO access only transitorily, to see whether we support the 297 // device or not. 298 // 299 gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, 300 This->DriverBindingHandle, DeviceHandle); 301 302 return Status; 303 } 304 305 /** 306 307 Initialize the VirtIo PCI Device 308 309 @param[in, out] Dev The driver instance to configure. The caller is 310 responsible for Device->PciIo's validity (ie. working IO 311 access to the underlying virtio-pci device). 312 313 @retval EFI_SUCCESS Setup complete. 314 315 @retval EFI_UNSUPPORTED The underlying IO device doesn't support the 316 provided address offset and read size. 317 318 @return Error codes from PciIo->Pci.Read(). 319 320 **/ 321 STATIC 322 EFI_STATUS 323 EFIAPI 324 VirtioPciInit ( 325 IN OUT VIRTIO_PCI_DEVICE *Device 326 ) 327 { 328 EFI_STATUS Status; 329 EFI_PCI_IO_PROTOCOL *PciIo; 330 PCI_TYPE00 Pci; 331 332 ASSERT (Device != NULL); 333 PciIo = Device->PciIo; 334 ASSERT (PciIo != NULL); 335 ASSERT (PciIo->Pci.Read != NULL); 336 337 Status = PciIo->Pci.Read ( 338 PciIo, // (protocol, device) 339 // handle 340 EfiPciIoWidthUint32, // access width & copy 341 // mode 342 0, // Offset 343 sizeof (Pci) / sizeof (UINT32), // Count 344 &Pci // target buffer 345 ); 346 if (EFI_ERROR (Status)) { 347 return Status; 348 } 349 350 // 351 // Copy protocol template 352 // 353 CopyMem (&Device->VirtioDevice, &mDeviceProtocolTemplate, 354 sizeof (VIRTIO_DEVICE_PROTOCOL)); 355 356 // 357 // Initialize the protocol interface attributes 358 // 359 Device->VirtioDevice.Revision = VIRTIO_SPEC_REVISION (0, 9, 5); 360 Device->VirtioDevice.SubSystemDeviceId = Pci.Device.SubsystemID; 361 362 // 363 // Note: We don't support the MSI-X capability. If we did, 364 // the offset would become 24 after enabling MSI-X. 365 // 366 Device->DeviceSpecificConfigurationOffset = 367 VIRTIO_DEVICE_SPECIFIC_CONFIGURATION_OFFSET_PCI; 368 369 return EFI_SUCCESS; 370 } 371 372 /** 373 374 Uninitialize the internals of a virtio-pci device that has been successfully 375 set up with VirtioPciInit(). 376 377 @param[in, out] Dev The device to clean up. 378 379 **/ 380 381 STATIC 382 VOID 383 EFIAPI 384 VirtioPciUninit ( 385 IN OUT VIRTIO_PCI_DEVICE *Device 386 ) 387 { 388 // Note: This function mirrors VirtioPciInit() that does not allocate any 389 // resources - there's nothing to free here. 390 } 391 392 /** 393 394 After we've pronounced support for a specific device in 395 DriverBindingSupported(), we start managing said device (passed in by the 396 Driver Execution Environment) with the following service. 397 398 See DriverBindingSupported() for specification references. 399 400 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object 401 incorporating this driver (independently of 402 any device). 403 404 @param[in] DeviceHandle The supported device to drive. 405 406 @param[in] RemainingDevicePath Relevant only for bus drivers, ignored. 407 408 409 @retval EFI_SUCCESS Driver instance has been created and 410 initialized for the virtio-pci device, it 411 is now accessible via VIRTIO_DEVICE_PROTOCOL. 412 413 @retval EFI_OUT_OF_RESOURCES Memory allocation failed. 414 415 @return Error codes from the OpenProtocol() boot 416 service, the PciIo protocol, VirtioPciInit(), 417 or the InstallProtocolInterface() boot service. 418 419 **/ 420 STATIC 421 EFI_STATUS 422 EFIAPI 423 VirtioPciDeviceBindingStart ( 424 IN EFI_DRIVER_BINDING_PROTOCOL *This, 425 IN EFI_HANDLE DeviceHandle, 426 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 427 ) 428 { 429 VIRTIO_PCI_DEVICE *Device; 430 EFI_STATUS Status; 431 432 Device = (VIRTIO_PCI_DEVICE *) AllocateZeroPool (sizeof *Device); 433 if (Device == NULL) { 434 return EFI_OUT_OF_RESOURCES; 435 } 436 437 Status = gBS->OpenProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, 438 (VOID **)&Device->PciIo, This->DriverBindingHandle, 439 DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER); 440 if (EFI_ERROR (Status)) { 441 goto FreeVirtioPci; 442 } 443 444 // 445 // We must retain and ultimately restore the original PCI attributes of the 446 // device. See Driver Writer's Guide for UEFI 2.3.1 v1.01, 18.3 PCI drivers / 447 // 18.3.2 Start() and Stop(). 448 // 449 // The third parameter ("Attributes", input) is ignored by the Get operation. 450 // The fourth parameter ("Result", output) is ignored by the Enable and Set 451 // operations. 452 // 453 // For virtio-pci we only need IO space access. 454 // 455 Status = Device->PciIo->Attributes (Device->PciIo, 456 EfiPciIoAttributeOperationGet, 0, &Device->OriginalPciAttributes); 457 if (EFI_ERROR (Status)) { 458 goto ClosePciIo; 459 } 460 461 Status = Device->PciIo->Attributes (Device->PciIo, 462 EfiPciIoAttributeOperationEnable, 463 EFI_PCI_IO_ATTRIBUTE_IO, NULL); 464 if (EFI_ERROR (Status)) { 465 goto ClosePciIo; 466 } 467 468 // 469 // PCI IO access granted, configure protocol instance 470 // 471 472 Status = VirtioPciInit (Device); 473 if (EFI_ERROR (Status)) { 474 goto RestorePciAttributes; 475 } 476 477 // 478 // Setup complete, attempt to export the driver instance's VirtioDevice 479 // interface. 480 // 481 Device->Signature = VIRTIO_PCI_DEVICE_SIGNATURE; 482 Status = gBS->InstallProtocolInterface (&DeviceHandle, 483 &gVirtioDeviceProtocolGuid, EFI_NATIVE_INTERFACE, 484 &Device->VirtioDevice); 485 if (EFI_ERROR (Status)) { 486 goto UninitDev; 487 } 488 489 return EFI_SUCCESS; 490 491 UninitDev: 492 VirtioPciUninit (Device); 493 494 RestorePciAttributes: 495 Device->PciIo->Attributes (Device->PciIo, EfiPciIoAttributeOperationSet, 496 Device->OriginalPciAttributes, NULL); 497 498 ClosePciIo: 499 gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, 500 This->DriverBindingHandle, DeviceHandle); 501 502 FreeVirtioPci: 503 FreePool (Device); 504 505 return Status; 506 } 507 508 /** 509 510 Stop driving the Virtio PCI device 511 512 @param[in] This The EFI_DRIVER_BINDING_PROTOCOL object 513 incorporating this driver (independently of any 514 device). 515 516 @param[in] DeviceHandle Stop driving this device. 517 518 @param[in] NumberOfChildren Since this function belongs to a device driver 519 only (as opposed to a bus driver), the caller 520 environment sets NumberOfChildren to zero, and 521 we ignore it. 522 523 @param[in] ChildHandleBuffer Ignored (corresponding to NumberOfChildren). 524 525 @retval EFI_SUCCESS Driver instance has been stopped and the PCI 526 configuration attributes have been restored. 527 528 @return Error codes from the OpenProtocol() or 529 CloseProtocol(), UninstallProtocolInterface() 530 boot services. 531 532 **/ 533 STATIC 534 EFI_STATUS 535 EFIAPI 536 VirtioPciDeviceBindingStop ( 537 IN EFI_DRIVER_BINDING_PROTOCOL *This, 538 IN EFI_HANDLE DeviceHandle, 539 IN UINTN NumberOfChildren, 540 IN EFI_HANDLE *ChildHandleBuffer 541 ) 542 { 543 EFI_STATUS Status; 544 VIRTIO_DEVICE_PROTOCOL *VirtioDevice; 545 VIRTIO_PCI_DEVICE *Device; 546 547 Status = gBS->OpenProtocol ( 548 DeviceHandle, // candidate device 549 &gVirtioDeviceProtocolGuid, // retrieve the VirtIo iface 550 (VOID **)&VirtioDevice, // target pointer 551 This->DriverBindingHandle, // requestor driver identity 552 DeviceHandle, // requesting lookup for dev. 553 EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no ref. added 554 ); 555 if (EFI_ERROR (Status)) { 556 return Status; 557 } 558 559 Device = VIRTIO_PCI_DEVICE_FROM_VIRTIO_DEVICE (VirtioDevice); 560 561 // 562 // Handle Stop() requests for in-use driver instances gracefully. 563 // 564 Status = gBS->UninstallProtocolInterface (DeviceHandle, 565 &gVirtioDeviceProtocolGuid, &Device->VirtioDevice); 566 if (EFI_ERROR (Status)) { 567 return Status; 568 } 569 570 VirtioPciUninit (Device); 571 572 Device->PciIo->Attributes (Device->PciIo, EfiPciIoAttributeOperationSet, 573 Device->OriginalPciAttributes, NULL); 574 575 Status = gBS->CloseProtocol (DeviceHandle, &gEfiPciIoProtocolGuid, 576 This->DriverBindingHandle, DeviceHandle); 577 578 FreePool (Device); 579 580 return Status; 581 } 582 583 584 // 585 // The static object that groups the Supported() (ie. probe), Start() and 586 // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata 587 // C, 10.1 EFI Driver Binding Protocol. 588 // 589 STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = { 590 &VirtioPciDeviceBindingSupported, 591 &VirtioPciDeviceBindingStart, 592 &VirtioPciDeviceBindingStop, 593 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers 594 NULL, // ImageHandle, to be overwritten by 595 // EfiLibInstallDriverBindingComponentName2() in VirtioPciEntryPoint() 596 NULL // DriverBindingHandle, ditto 597 }; 598 599 600 // 601 // The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and 602 // EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name 603 // in English, for display on standard console devices. This is recommended for 604 // UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's 605 // Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names. 606 // 607 STATIC 608 EFI_UNICODE_STRING_TABLE mDriverNameTable[] = { 609 { "eng;en", L"Virtio PCI Driver" }, 610 { NULL, NULL } 611 }; 612 613 STATIC 614 EFI_COMPONENT_NAME_PROTOCOL gComponentName; 615 616 EFI_STATUS 617 EFIAPI 618 VirtioPciGetDriverName ( 619 IN EFI_COMPONENT_NAME_PROTOCOL *This, 620 IN CHAR8 *Language, 621 OUT CHAR16 **DriverName 622 ) 623 { 624 return LookupUnicodeString2 ( 625 Language, 626 This->SupportedLanguages, 627 mDriverNameTable, 628 DriverName, 629 (BOOLEAN)(This == &gComponentName) // Iso639Language 630 ); 631 } 632 633 EFI_STATUS 634 EFIAPI 635 VirtioPciGetDeviceName ( 636 IN EFI_COMPONENT_NAME_PROTOCOL *This, 637 IN EFI_HANDLE DeviceHandle, 638 IN EFI_HANDLE ChildHandle, 639 IN CHAR8 *Language, 640 OUT CHAR16 **ControllerName 641 ) 642 { 643 return EFI_UNSUPPORTED; 644 } 645 646 STATIC 647 EFI_COMPONENT_NAME_PROTOCOL gComponentName = { 648 &VirtioPciGetDriverName, 649 &VirtioPciGetDeviceName, 650 "eng" // SupportedLanguages, ISO 639-2 language codes 651 }; 652 653 STATIC 654 EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = { 655 (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) &VirtioPciGetDriverName, 656 (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &VirtioPciGetDeviceName, 657 "en" // SupportedLanguages, RFC 4646 language codes 658 }; 659 660 661 // 662 // Entry point of this driver. 663 // 664 EFI_STATUS 665 EFIAPI 666 VirtioPciDeviceEntryPoint ( 667 IN EFI_HANDLE ImageHandle, 668 IN EFI_SYSTEM_TABLE *SystemTable 669 ) 670 { 671 return EfiLibInstallDriverBindingComponentName2 ( 672 ImageHandle, 673 SystemTable, 674 &gDriverBinding, 675 ImageHandle, 676 &gComponentName, 677 &gComponentName2 678 ); 679 } 680