• 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 - 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
VirtioPciIoRead(IN VIRTIO_PCI_DEVICE * Dev,IN UINTN FieldOffset,IN UINTN FieldSize,IN UINTN BufferSize,OUT VOID * Buffer)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
VirtioPciIoWrite(IN VIRTIO_PCI_DEVICE * Dev,IN UINTN FieldOffset,IN UINTN FieldSize,IN UINT64 Value)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
VirtioPciDeviceBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE DeviceHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)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
VirtioPciInit(IN OUT VIRTIO_PCI_DEVICE * Device)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
VirtioPciUninit(IN OUT VIRTIO_PCI_DEVICE * Device)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
VirtioPciDeviceBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE DeviceHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)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
VirtioPciDeviceBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE DeviceHandle,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)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
VirtioPciGetDriverName(IN EFI_COMPONENT_NAME_PROTOCOL * This,IN CHAR8 * Language,OUT CHAR16 ** DriverName)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
VirtioPciGetDeviceName(IN EFI_COMPONENT_NAME_PROTOCOL * This,IN EFI_HANDLE DeviceHandle,IN EFI_HANDLE ChildHandle,IN CHAR8 * Language,OUT CHAR16 ** ControllerName)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
VirtioPciDeviceEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)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