• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /** @file
2 
3   This driver produces EFI_RNG_PROTOCOL instances for virtio-rng devices.
4 
5   The implementation is based on OvmfPkg/VirtioScsiDxe/VirtioScsi.c
6 
7   Copyright (C) 2012, Red Hat, Inc.
8   Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
9 
10   This driver:
11 
12   Copyright (C) 2016, Linaro Ltd.
13 
14   This program and the accompanying materials are licensed and made available
15   under the terms and conditions of the BSD License which accompanies this
16   distribution. The full text of the license may be found at
17   http://opensource.org/licenses/bsd-license.php
18 
19   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT
20   WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
21 
22 **/
23 
24 #include <Library/BaseMemoryLib.h>
25 #include <Library/DebugLib.h>
26 #include <Library/MemoryAllocationLib.h>
27 #include <Library/UefiBootServicesTableLib.h>
28 #include <Library/UefiLib.h>
29 #include <Library/VirtioLib.h>
30 
31 #include "VirtioRng.h"
32 
33 /**
34   Returns information about the random number generation implementation.
35 
36   @param[in]     This                 A pointer to the EFI_RNG_PROTOCOL
37                                       instance.
38   @param[in,out] RNGAlgorithmListSize On input, the size in bytes of
39                                       RNGAlgorithmList.
40                                       On output with a return code of
41                                       EFI_SUCCESS, the size in bytes of the
42                                       data returned in RNGAlgorithmList. On
43                                       output with a return code of
44                                       EFI_BUFFER_TOO_SMALL, the size of
45                                       RNGAlgorithmList required to obtain the
46                                       list.
47   @param[out] RNGAlgorithmList        A caller-allocated memory buffer filled
48                                       by the driver with one EFI_RNG_ALGORITHM
49                                       element for each supported RNG algorithm.
50                                       The list must not change across multiple
51                                       calls to the same driver. The first
52                                       algorithm in the list is the default
53                                       algorithm for the driver.
54 
55   @retval EFI_SUCCESS                 The RNG algorithm list was returned
56                                       successfully.
57   @retval EFI_UNSUPPORTED             The services is not supported by this
58                                       driver.
59   @retval EFI_DEVICE_ERROR            The list of algorithms could not be
60                                       retrieved due to a hardware or firmware
61                                       error.
62   @retval EFI_INVALID_PARAMETER       One or more of the parameters are
63                                       incorrect.
64   @retval EFI_BUFFER_TOO_SMALL        The buffer RNGAlgorithmList is too small
65                                       to hold the result.
66 
67 **/
68 STATIC
69 EFI_STATUS
70 EFIAPI
VirtioRngGetInfo(IN EFI_RNG_PROTOCOL * This,IN OUT UINTN * RNGAlgorithmListSize,OUT EFI_RNG_ALGORITHM * RNGAlgorithmList)71 VirtioRngGetInfo (
72   IN      EFI_RNG_PROTOCOL        *This,
73   IN OUT  UINTN                   *RNGAlgorithmListSize,
74   OUT     EFI_RNG_ALGORITHM       *RNGAlgorithmList
75   )
76 {
77   if (This == NULL || RNGAlgorithmListSize == NULL) {
78     return EFI_INVALID_PARAMETER;
79   }
80 
81   if (*RNGAlgorithmListSize < sizeof (EFI_RNG_ALGORITHM)) {
82     *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
83     return EFI_BUFFER_TOO_SMALL;
84   }
85 
86   if (RNGAlgorithmList == NULL) {
87     return EFI_INVALID_PARAMETER;
88   }
89 
90   *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
91   CopyGuid (RNGAlgorithmList, &gEfiRngAlgorithmRaw);
92 
93   return EFI_SUCCESS;
94 }
95 
96 /**
97   Produces and returns an RNG value using either the default or specified RNG
98   algorithm.
99 
100   @param[in]  This                    A pointer to the EFI_RNG_PROTOCOL
101                                       instance.
102   @param[in]  RNGAlgorithm            A pointer to the EFI_RNG_ALGORITHM that
103                                       identifies the RNG algorithm to use. May
104                                       be NULL in which case the function will
105                                       use its default RNG algorithm.
106   @param[in]  RNGValueLength          The length in bytes of the memory buffer
107                                       pointed to by RNGValue. The driver shall
108                                       return exactly this numbers of bytes.
109   @param[out] RNGValue                A caller-allocated memory buffer filled
110                                       by the driver with the resulting RNG
111                                       value.
112 
113   @retval EFI_SUCCESS                 The RNG value was returned successfully.
114   @retval EFI_UNSUPPORTED             The algorithm specified by RNGAlgorithm
115                                       is not supported by this driver.
116   @retval EFI_DEVICE_ERROR            An RNG value could not be retrieved due
117                                       to a hardware or firmware error.
118   @retval EFI_NOT_READY               There is not enough random data available
119                                       to satisfy the length requested by
120                                       RNGValueLength.
121   @retval EFI_INVALID_PARAMETER       RNGValue is NULL or RNGValueLength is
122                                       zero.
123 
124 **/
125 STATIC
126 EFI_STATUS
127 EFIAPI
VirtioRngGetRNG(IN EFI_RNG_PROTOCOL * This,IN EFI_RNG_ALGORITHM * RNGAlgorithm,OPTIONAL IN UINTN RNGValueLength,OUT UINT8 * RNGValue)128 VirtioRngGetRNG (
129   IN EFI_RNG_PROTOCOL            *This,
130   IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
131   IN UINTN                       RNGValueLength,
132   OUT UINT8                      *RNGValue
133   )
134 {
135   VIRTIO_RNG_DEV            *Dev;
136   DESC_INDICES              Indices;
137   volatile UINT8            *Buffer;
138   UINTN                     Index;
139   UINT32                    Len;
140   UINT32                    BufferSize;
141   EFI_STATUS                Status;
142 
143   if (This == NULL || RNGValueLength == 0 || RNGValue == NULL) {
144     return EFI_INVALID_PARAMETER;
145   }
146 
147   //
148   // We only support the raw algorithm, so reject requests for anything else
149   //
150   if (RNGAlgorithm != NULL &&
151       !CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
152     return EFI_UNSUPPORTED;
153   }
154 
155   Buffer = (volatile UINT8 *)AllocatePool (RNGValueLength);
156   if (Buffer == NULL) {
157     return EFI_DEVICE_ERROR;
158   }
159 
160   Dev = VIRTIO_ENTROPY_SOURCE_FROM_RNG (This);
161 
162   //
163   // The Virtio RNG device may return less data than we asked it to, and can
164   // only return MAX_UINT32 bytes per invocation. So loop as long as needed to
165   // get all the entropy we were asked for.
166   //
167   for (Index = 0; Index < RNGValueLength; Index += Len) {
168     BufferSize = (UINT32)MIN (RNGValueLength - Index, (UINTN)MAX_UINT32);
169 
170     VirtioPrepare (&Dev->Ring, &Indices);
171     VirtioAppendDesc (&Dev->Ring,
172       (UINTN)Buffer + Index,
173       BufferSize,
174       VRING_DESC_F_WRITE,
175       &Indices);
176 
177     if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices, &Len) !=
178         EFI_SUCCESS) {
179       Status = EFI_DEVICE_ERROR;
180       goto FreeBuffer;
181     }
182     ASSERT (Len > 0);
183     ASSERT (Len <= BufferSize);
184   }
185 
186   for (Index = 0; Index < RNGValueLength; Index++) {
187     RNGValue[Index] = Buffer[Index];
188   }
189   Status = EFI_SUCCESS;
190 
191 FreeBuffer:
192   FreePool ((VOID *)Buffer);
193   return Status;
194 }
195 
196 STATIC
197 EFI_STATUS
198 EFIAPI
VirtioRngInit(IN OUT VIRTIO_RNG_DEV * Dev)199 VirtioRngInit (
200   IN OUT VIRTIO_RNG_DEV *Dev
201   )
202 {
203   UINT8      NextDevStat;
204   EFI_STATUS Status;
205   UINT16     QueueSize;
206   UINT64     Features;
207 
208   //
209   // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
210   //
211   NextDevStat = 0;             // step 1 -- reset device
212   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
213   if (EFI_ERROR (Status)) {
214     goto Failed;
215   }
216 
217   NextDevStat |= VSTAT_ACK;    // step 2 -- acknowledge device presence
218   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
219   if (EFI_ERROR (Status)) {
220     goto Failed;
221   }
222 
223   NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
224   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
225   if (EFI_ERROR (Status)) {
226     goto Failed;
227   }
228 
229   //
230   // Set Page Size - MMIO VirtIo Specific
231   //
232   Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
233   if (EFI_ERROR (Status)) {
234     goto Failed;
235   }
236 
237   //
238   // step 4a -- retrieve and validate features
239   //
240   Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);
241   if (EFI_ERROR (Status)) {
242     goto Failed;
243   }
244 
245   Features &= VIRTIO_F_VERSION_1;
246 
247   //
248   // In virtio-1.0, feature negotiation is expected to complete before queue
249   // discovery, and the device can also reject the selected set of features.
250   //
251   if (Dev->VirtIo->Revision >= VIRTIO_SPEC_REVISION (1, 0, 0)) {
252     Status = Virtio10WriteFeatures (Dev->VirtIo, Features, &NextDevStat);
253     if (EFI_ERROR (Status)) {
254       goto Failed;
255     }
256   }
257 
258   //
259   // step 4b -- allocate request virtqueue, just use #0
260   //
261   Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, 0);
262   if (EFI_ERROR (Status)) {
263     goto Failed;
264   }
265   Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);
266   if (EFI_ERROR (Status)) {
267     goto Failed;
268   }
269 
270   //
271   // VirtioRngGetRNG() uses one descriptor
272   //
273   if (QueueSize < 1) {
274     Status = EFI_UNSUPPORTED;
275     goto Failed;
276   }
277 
278   Status = VirtioRingInit (QueueSize, &Dev->Ring);
279   if (EFI_ERROR (Status)) {
280     goto Failed;
281   }
282 
283   //
284   // Additional steps for MMIO: align the queue appropriately, and set the
285   // size. If anything fails from here on, we must release the ring resources.
286   //
287   Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
288   if (EFI_ERROR (Status)) {
289     goto ReleaseQueue;
290   }
291 
292   Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
293   if (EFI_ERROR (Status)) {
294     goto ReleaseQueue;
295   }
296 
297   //
298   // step 4c -- Report GPFN (guest-physical frame number) of queue.
299   //
300   Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo, &Dev->Ring);
301   if (EFI_ERROR (Status)) {
302     goto ReleaseQueue;
303   }
304 
305   //
306   // step 5 -- Report understood features and guest-tuneables.
307   //
308   if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
309     Features &= ~(UINT64)VIRTIO_F_VERSION_1;
310     Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
311     if (EFI_ERROR (Status)) {
312       goto ReleaseQueue;
313     }
314   }
315 
316   //
317   // step 6 -- initialization complete
318   //
319   NextDevStat |= VSTAT_DRIVER_OK;
320   Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
321   if (EFI_ERROR (Status)) {
322     goto ReleaseQueue;
323   }
324 
325   //
326   // populate the exported interface's attributes
327   //
328   Dev->Rng.GetInfo    = VirtioRngGetInfo;
329   Dev->Rng.GetRNG     = VirtioRngGetRNG;
330 
331   return EFI_SUCCESS;
332 
333 ReleaseQueue:
334   VirtioRingUninit (&Dev->Ring);
335 
336 Failed:
337   //
338   // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device
339   // Status. VirtIo access failure here should not mask the original error.
340   //
341   NextDevStat |= VSTAT_FAILED;
342   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
343 
344   return Status; // reached only via Failed above
345 }
346 
347 
348 STATIC
349 VOID
350 EFIAPI
VirtioRngUninit(IN OUT VIRTIO_RNG_DEV * Dev)351 VirtioRngUninit (
352   IN OUT VIRTIO_RNG_DEV *Dev
353   )
354 {
355   //
356   // Reset the virtual device -- see virtio-0.9.5, 2.2.2.1 Device Status. When
357   // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from
358   // the old comms area.
359   //
360   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
361   VirtioRingUninit (&Dev->Ring);
362 }
363 
364 //
365 // Event notification function enqueued by ExitBootServices().
366 //
367 
368 STATIC
369 VOID
370 EFIAPI
VirtioRngExitBoot(IN EFI_EVENT Event,IN VOID * Context)371 VirtioRngExitBoot (
372   IN  EFI_EVENT Event,
373   IN  VOID      *Context
374   )
375 {
376   VIRTIO_RNG_DEV *Dev;
377 
378   //
379   // Reset the device. This causes the hypervisor to forget about the virtio
380   // ring.
381   //
382   // We allocated said ring in EfiBootServicesData type memory, and code
383   // executing after ExitBootServices() is permitted to overwrite it.
384   //
385   Dev = Context;
386   Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
387 }
388 
389 
390 //
391 // Probe, start and stop functions of this driver, called by the DXE core for
392 // specific devices.
393 //
394 // The following specifications document these interfaces:
395 // - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol
396 // - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol
397 //
398 // The implementation follows:
399 // - Driver Writer's Guide for UEFI 2.3.1 v1.01
400 //   - 5.1.3.4 OpenProtocol() and CloseProtocol()
401 // - UEFI Spec 2.3.1 + Errata C
402 //   -  6.3 Protocol Handler Services
403 //
404 
405 STATIC
406 EFI_STATUS
407 EFIAPI
VirtioRngDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE DeviceHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)408 VirtioRngDriverBindingSupported (
409   IN EFI_DRIVER_BINDING_PROTOCOL *This,
410   IN EFI_HANDLE                  DeviceHandle,
411   IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
412   )
413 {
414   EFI_STATUS             Status;
415   VIRTIO_DEVICE_PROTOCOL *VirtIo;
416 
417   //
418   // Attempt to open the device with the VirtIo set of interfaces. On success,
419   // the protocol is "instantiated" for the VirtIo device. Covers duplicate
420   // open attempts (EFI_ALREADY_STARTED).
421   //
422   Status = gBS->OpenProtocol (
423                   DeviceHandle,               // candidate device
424                   &gVirtioDeviceProtocolGuid, // for generic VirtIo access
425                   (VOID **)&VirtIo,           // handle to instantiate
426                   This->DriverBindingHandle,  // requestor driver identity
427                   DeviceHandle,               // ControllerHandle, according to
428                                               // the UEFI Driver Model
429                   EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive VirtIo access to
430                                               // the device; to be released
431                   );
432   if (EFI_ERROR (Status)) {
433     return Status;
434   }
435 
436   if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_ENTROPY_SOURCE) {
437     Status = EFI_UNSUPPORTED;
438   }
439 
440   //
441   // We needed VirtIo access only transitorily, to see whether we support the
442   // device or not.
443   //
444   gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
445          This->DriverBindingHandle, DeviceHandle);
446   return Status;
447 }
448 
449 STATIC
450 EFI_STATUS
451 EFIAPI
VirtioRngDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE DeviceHandle,IN EFI_DEVICE_PATH_PROTOCOL * RemainingDevicePath)452 VirtioRngDriverBindingStart (
453   IN EFI_DRIVER_BINDING_PROTOCOL *This,
454   IN EFI_HANDLE                  DeviceHandle,
455   IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
456   )
457 {
458   VIRTIO_RNG_DEV  *Dev;
459   EFI_STATUS Status;
460 
461   Dev = (VIRTIO_RNG_DEV *) AllocateZeroPool (sizeof *Dev);
462   if (Dev == NULL) {
463     return EFI_OUT_OF_RESOURCES;
464   }
465 
466   Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
467                   (VOID **)&Dev->VirtIo, This->DriverBindingHandle,
468                   DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
469   if (EFI_ERROR (Status)) {
470     goto FreeVirtioRng;
471   }
472 
473   //
474   // VirtIo access granted, configure virtio-rng device.
475   //
476   Status = VirtioRngInit (Dev);
477   if (EFI_ERROR (Status)) {
478     goto CloseVirtIo;
479   }
480 
481   Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
482                   &VirtioRngExitBoot, Dev, &Dev->ExitBoot);
483   if (EFI_ERROR (Status)) {
484     goto UninitDev;
485   }
486 
487   //
488   // Setup complete, attempt to export the driver instance's EFI_RNG_PROTOCOL
489   // interface.
490   //
491   Dev->Signature = VIRTIO_RNG_SIG;
492   Status = gBS->InstallProtocolInterface (&DeviceHandle,
493                   &gEfiRngProtocolGuid, EFI_NATIVE_INTERFACE,
494                   &Dev->Rng);
495   if (EFI_ERROR (Status)) {
496     goto CloseExitBoot;
497   }
498 
499   return EFI_SUCCESS;
500 
501 CloseExitBoot:
502   gBS->CloseEvent (Dev->ExitBoot);
503 
504 UninitDev:
505   VirtioRngUninit (Dev);
506 
507 CloseVirtIo:
508   gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
509          This->DriverBindingHandle, DeviceHandle);
510 
511 FreeVirtioRng:
512   FreePool (Dev);
513 
514   return Status;
515 }
516 
517 
518 STATIC
519 EFI_STATUS
520 EFIAPI
VirtioRngDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL * This,IN EFI_HANDLE DeviceHandle,IN UINTN NumberOfChildren,IN EFI_HANDLE * ChildHandleBuffer)521 VirtioRngDriverBindingStop (
522   IN EFI_DRIVER_BINDING_PROTOCOL *This,
523   IN EFI_HANDLE                  DeviceHandle,
524   IN UINTN                       NumberOfChildren,
525   IN EFI_HANDLE                  *ChildHandleBuffer
526   )
527 {
528   EFI_STATUS                      Status;
529   EFI_RNG_PROTOCOL                *Rng;
530   VIRTIO_RNG_DEV                  *Dev;
531 
532   Status = gBS->OpenProtocol (
533                   DeviceHandle,                     // candidate device
534                   &gEfiRngProtocolGuid,             // retrieve the RNG iface
535                   (VOID **)&Rng,                    // target pointer
536                   This->DriverBindingHandle,        // requestor driver ident.
537                   DeviceHandle,                     // lookup req. for dev.
538                   EFI_OPEN_PROTOCOL_GET_PROTOCOL    // lookup only, no new ref.
539                   );
540   if (EFI_ERROR (Status)) {
541     return Status;
542   }
543 
544   Dev = VIRTIO_ENTROPY_SOURCE_FROM_RNG (Rng);
545 
546   //
547   // Handle Stop() requests for in-use driver instances gracefully.
548   //
549   Status = gBS->UninstallProtocolInterface (DeviceHandle,
550                   &gEfiRngProtocolGuid, &Dev->Rng);
551   if (EFI_ERROR (Status)) {
552     return Status;
553   }
554 
555   gBS->CloseEvent (Dev->ExitBoot);
556 
557   VirtioRngUninit (Dev);
558 
559   gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
560          This->DriverBindingHandle, DeviceHandle);
561 
562   FreePool (Dev);
563 
564   return EFI_SUCCESS;
565 }
566 
567 
568 //
569 // The static object that groups the Supported() (ie. probe), Start() and
570 // Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
571 // C, 10.1 EFI Driver Binding Protocol.
572 //
573 STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
574   &VirtioRngDriverBindingSupported,
575   &VirtioRngDriverBindingStart,
576   &VirtioRngDriverBindingStop,
577   0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
578   NULL, // ImageHandle, to be overwritten by
579         // EfiLibInstallDriverBindingComponentName2() in VirtioRngEntryPoint()
580   NULL  // DriverBindingHandle, ditto
581 };
582 
583 
584 //
585 // The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
586 // EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
587 // in English, for display on standard console devices. This is recommended for
588 // UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
589 // Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
590 //
591 
592 STATIC
593 EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
594   { "eng;en", L"Virtio Random Number Generator Driver" },
595   { NULL,     NULL                   }
596 };
597 
598 STATIC
599 EFI_COMPONENT_NAME_PROTOCOL gComponentName;
600 
601 STATIC
602 EFI_STATUS
603 EFIAPI
VirtioRngGetDriverName(IN EFI_COMPONENT_NAME_PROTOCOL * This,IN CHAR8 * Language,OUT CHAR16 ** DriverName)604 VirtioRngGetDriverName (
605   IN  EFI_COMPONENT_NAME_PROTOCOL *This,
606   IN  CHAR8                       *Language,
607   OUT CHAR16                      **DriverName
608   )
609 {
610   return LookupUnicodeString2 (
611            Language,
612            This->SupportedLanguages,
613            mDriverNameTable,
614            DriverName,
615            (BOOLEAN)(This == &gComponentName) // Iso639Language
616            );
617 }
618 
619 STATIC
620 EFI_STATUS
621 EFIAPI
VirtioRngGetDeviceName(IN EFI_COMPONENT_NAME_PROTOCOL * This,IN EFI_HANDLE DeviceHandle,IN EFI_HANDLE ChildHandle,IN CHAR8 * Language,OUT CHAR16 ** ControllerName)622 VirtioRngGetDeviceName (
623   IN  EFI_COMPONENT_NAME_PROTOCOL *This,
624   IN  EFI_HANDLE                  DeviceHandle,
625   IN  EFI_HANDLE                  ChildHandle,
626   IN  CHAR8                       *Language,
627   OUT CHAR16                      **ControllerName
628   )
629 {
630   return EFI_UNSUPPORTED;
631 }
632 
633 STATIC
634 EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
635   &VirtioRngGetDriverName,
636   &VirtioRngGetDeviceName,
637   "eng" // SupportedLanguages, ISO 639-2 language codes
638 };
639 
640 STATIC
641 EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
642   (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)     &VirtioRngGetDriverName,
643   (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &VirtioRngGetDeviceName,
644   "en" // SupportedLanguages, RFC 4646 language codes
645 };
646 
647 
648 //
649 // Entry point of this driver.
650 //
651 EFI_STATUS
652 EFIAPI
VirtioRngEntryPoint(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)653 VirtioRngEntryPoint (
654   IN EFI_HANDLE       ImageHandle,
655   IN EFI_SYSTEM_TABLE *SystemTable
656   )
657 {
658   return EfiLibInstallDriverBindingComponentName2 (
659            ImageHandle,
660            SystemTable,
661            &gDriverBinding,
662            ImageHandle,
663            &gComponentName,
664            &gComponentName2
665            );
666 }
667