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