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