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