VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/OvmfPkg/VirtioRngDxe/VirtioRng.c@ 108794

Last change on this file since 108794 was 108794, checked in by vboxsync, 2 weeks ago

Devices/EFI/FirmwareNew: Merge edk2-stable202502 from the vendor branch and make it build for the important platforms, bugref:4643

  • Property svn:eol-style set to native
File size: 21.0 KB
Line 
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**/
63STATIC
64EFI_STATUS
65EFIAPI
66VirtioRngGetInfo (
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**/
120STATIC
121EFI_STATUS
122EFIAPI
123VirtioRngGetRNG (
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 {
150 return EFI_UNSUPPORTED;
151 }
152
153 Buffer = (volatile UINT8 *)AllocatePool (RNGValueLength);
154 if (Buffer == NULL) {
155 return EFI_DEVICE_ERROR;
156 }
157
158 Dev = VIRTIO_ENTROPY_SOURCE_FROM_RNG (This);
159 if (!Dev->Ready) {
160 DEBUG ((DEBUG_INFO, "%a: not ready\n", __func__));
161 return EFI_DEVICE_ERROR;
162 }
163
164 //
165 // Map Buffer's system physical 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 (
190 &Dev->Ring,
191 DeviceAddress + Index,
192 BufferSize,
193 VRING_DESC_F_WRITE,
194 &Indices
195 );
196
197 if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices, &Len) !=
198 EFI_SUCCESS)
199 {
200 Status = EFI_DEVICE_ERROR;
201 goto UnmapBuffer;
202 }
203
204 ASSERT (Len > 0);
205 ASSERT (Len <= BufferSize);
206 }
207
208 //
209 // Unmap the device buffer before accessing it.
210 //
211 Status = Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Mapping);
212 if (EFI_ERROR (Status)) {
213 Status = EFI_DEVICE_ERROR;
214 goto FreeBuffer;
215 }
216
217 for (Index = 0; Index < RNGValueLength; Index++) {
218 RNGValue[Index] = Buffer[Index];
219 }
220
221 Status = EFI_SUCCESS;
222
223UnmapBuffer:
224 //
225 // If we are reached here due to the error then unmap the buffer otherwise
226 // the buffer is already unmapped after VirtioFlush().
227 //
228 if (EFI_ERROR (Status)) {
229 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Mapping);
230 }
231
232FreeBuffer:
233 FreePool ((VOID *)Buffer);
234 return Status;
235}
236
237STATIC
238EFI_STATUS
239EFIAPI
240VirtioRngInit (
241 IN OUT VIRTIO_RNG_DEV *Dev
242 )
243{
244 UINT8 NextDevStat;
245 EFI_STATUS Status;
246 UINT16 QueueSize;
247 UINT64 Features;
248 UINT64 RingBaseShift;
249
250 //
251 // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
252 //
253 NextDevStat = 0; // step 1 -- reset device
254 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
255 if (EFI_ERROR (Status)) {
256 goto Failed;
257 }
258
259 NextDevStat |= VSTAT_ACK; // step 2 -- acknowledge device presence
260 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
261 if (EFI_ERROR (Status)) {
262 goto Failed;
263 }
264
265 NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
266 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
267 if (EFI_ERROR (Status)) {
268 goto Failed;
269 }
270
271 //
272 // Set Page Size - MMIO VirtIo Specific
273 //
274 Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
275 if (EFI_ERROR (Status)) {
276 goto Failed;
277 }
278
279 //
280 // step 4a -- retrieve and validate features
281 //
282 Status = Dev->VirtIo->GetDeviceFeatures (Dev->VirtIo, &Features);
283 if (EFI_ERROR (Status)) {
284 goto Failed;
285 }
286
287 Features &= VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM;
288
289 //
290 // In virtio-1.0, feature negotiation is expected to complete before queue
291 // discovery, and the device can also reject the selected set of features.
292 //
293 if (Dev->VirtIo->Revision >= VIRTIO_SPEC_REVISION (1, 0, 0)) {
294 Status = Virtio10WriteFeatures (Dev->VirtIo, Features, &NextDevStat);
295 if (EFI_ERROR (Status)) {
296 goto Failed;
297 }
298 }
299
300 //
301 // step 4b -- allocate request virtqueue, just use #0
302 //
303 Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, 0);
304 if (EFI_ERROR (Status)) {
305 goto Failed;
306 }
307
308 Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);
309 if (EFI_ERROR (Status)) {
310 goto Failed;
311 }
312
313 //
314 // VirtioRngGetRNG() uses one descriptor
315 //
316 if (QueueSize < 1) {
317 Status = EFI_UNSUPPORTED;
318 goto Failed;
319 }
320
321 Status = VirtioRingInit (Dev->VirtIo, QueueSize, &Dev->Ring);
322 if (EFI_ERROR (Status)) {
323 goto Failed;
324 }
325
326 //
327 // If anything fails from here on, we must release the ring resources.
328 //
329 Status = VirtioRingMap (
330 Dev->VirtIo,
331 &Dev->Ring,
332 &RingBaseShift,
333 &Dev->RingMap
334 );
335 if (EFI_ERROR (Status)) {
336 goto ReleaseQueue;
337 }
338
339 //
340 // Additional steps for MMIO: align the queue appropriately, and set the
341 // size. If anything fails from here on, we must unmap the ring resources.
342 //
343 Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
344 if (EFI_ERROR (Status)) {
345 goto UnmapQueue;
346 }
347
348 Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
349 if (EFI_ERROR (Status)) {
350 goto UnmapQueue;
351 }
352
353 //
354 // step 4c -- Report GPFN (guest-physical frame number) of queue.
355 //
356 Status = Dev->VirtIo->SetQueueAddress (
357 Dev->VirtIo,
358 &Dev->Ring,
359 RingBaseShift
360 );
361 if (EFI_ERROR (Status)) {
362 goto UnmapQueue;
363 }
364
365 //
366 // step 5 -- Report understood features and guest-tuneables.
367 //
368 if (Dev->VirtIo->Revision < VIRTIO_SPEC_REVISION (1, 0, 0)) {
369 Features &= ~(UINT64)(VIRTIO_F_VERSION_1 | VIRTIO_F_IOMMU_PLATFORM);
370 Status = Dev->VirtIo->SetGuestFeatures (Dev->VirtIo, Features);
371 if (EFI_ERROR (Status)) {
372 goto UnmapQueue;
373 }
374 }
375
376 //
377 // step 6 -- initialization complete
378 //
379 NextDevStat |= VSTAT_DRIVER_OK;
380 Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
381 if (EFI_ERROR (Status)) {
382 goto UnmapQueue;
383 }
384
385 //
386 // populate the exported interface's attributes
387 //
388 Dev->Rng.GetInfo = VirtioRngGetInfo;
389 Dev->Rng.GetRNG = VirtioRngGetRNG;
390 Dev->Ready = TRUE;
391
392 return EFI_SUCCESS;
393
394UnmapQueue:
395 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
396
397ReleaseQueue:
398 VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
399
400Failed:
401 //
402 // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 Device
403 // Status. VirtIo access failure here should not mask the original error.
404 //
405 NextDevStat |= VSTAT_FAILED;
406 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
407
408 return Status; // reached only via Failed above
409}
410
411STATIC
412VOID
413EFIAPI
414VirtioRngUninit (
415 IN OUT VIRTIO_RNG_DEV *Dev
416 )
417{
418 //
419 // Reset the virtual device -- see virtio-0.9.5, 2.2.2.1 Device Status. When
420 // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away from
421 // the old comms area.
422 //
423 Dev->Ready = FALSE;
424 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
425 Dev->VirtIo->UnmapSharedBuffer (Dev->VirtIo, Dev->RingMap);
426
427 VirtioRingUninit (Dev->VirtIo, &Dev->Ring);
428}
429
430//
431// Event notification function enqueued by ExitBootServices().
432//
433
434STATIC
435VOID
436EFIAPI
437VirtioRngExitBoot (
438 IN EFI_EVENT Event,
439 IN VOID *Context
440 )
441{
442 VIRTIO_RNG_DEV *Dev;
443
444 DEBUG ((DEBUG_INFO, "%a: Context=0x%p\n", __func__, Context));
445 //
446 // Reset the device. This causes the hypervisor to forget about the virtio
447 // ring.
448 //
449 // We allocated said ring in EfiBootServicesData type memory, and code
450 // executing after ExitBootServices() is permitted to overwrite it.
451 //
452 Dev = Context;
453 Dev->Ready = FALSE;
454 Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
455}
456
457//
458// Probe, start and stop functions of this driver, called by the DXE core for
459// specific devices.
460//
461// The following specifications document these interfaces:
462// - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol
463// - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol
464//
465// The implementation follows:
466// - Driver Writer's Guide for UEFI 2.3.1 v1.01
467// - 5.1.3.4 OpenProtocol() and CloseProtocol()
468// - UEFI Spec 2.3.1 + Errata C
469// - 6.3 Protocol Handler Services
470//
471
472STATIC
473EFI_STATUS
474EFIAPI
475VirtioRngDriverBindingSupported (
476 IN EFI_DRIVER_BINDING_PROTOCOL *This,
477 IN EFI_HANDLE DeviceHandle,
478 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
479 )
480{
481 EFI_STATUS Status;
482 VIRTIO_DEVICE_PROTOCOL *VirtIo;
483
484 //
485 // Attempt to open the device with the VirtIo set of interfaces. On success,
486 // the protocol is "instantiated" for the VirtIo device. Covers duplicate
487 // open attempts (EFI_ALREADY_STARTED).
488 //
489 Status = gBS->OpenProtocol (
490 DeviceHandle, // candidate device
491 &gVirtioDeviceProtocolGuid, // for generic VirtIo access
492 (VOID **)&VirtIo, // handle to instantiate
493 This->DriverBindingHandle, // requestor driver identity
494 DeviceHandle, // ControllerHandle, according to
495 // the UEFI Driver Model
496 EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive VirtIo access to
497 // the device; to be released
498 );
499 if (EFI_ERROR (Status)) {
500 return Status;
501 }
502
503 if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_ENTROPY_SOURCE) {
504 Status = EFI_UNSUPPORTED;
505 }
506
507 //
508 // We needed VirtIo access only transitorily, to see whether we support the
509 // device or not.
510 //
511 gBS->CloseProtocol (
512 DeviceHandle,
513 &gVirtioDeviceProtocolGuid,
514 This->DriverBindingHandle,
515 DeviceHandle
516 );
517 return Status;
518}
519
520STATIC
521EFI_STATUS
522EFIAPI
523VirtioRngDriverBindingStart (
524 IN EFI_DRIVER_BINDING_PROTOCOL *This,
525 IN EFI_HANDLE DeviceHandle,
526 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
527 )
528{
529 VIRTIO_RNG_DEV *Dev;
530 EFI_STATUS Status;
531
532 Dev = (VIRTIO_RNG_DEV *)AllocateZeroPool (sizeof *Dev);
533 if (Dev == NULL) {
534 return EFI_OUT_OF_RESOURCES;
535 }
536
537 Status = gBS->OpenProtocol (
538 DeviceHandle,
539 &gVirtioDeviceProtocolGuid,
540 (VOID **)&Dev->VirtIo,
541 This->DriverBindingHandle,
542 DeviceHandle,
543 EFI_OPEN_PROTOCOL_BY_DRIVER
544 );
545 if (EFI_ERROR (Status)) {
546 goto FreeVirtioRng;
547 }
548
549 //
550 // VirtIo access granted, configure virtio-rng device.
551 //
552 Status = VirtioRngInit (Dev);
553 if (EFI_ERROR (Status)) {
554 goto CloseVirtIo;
555 }
556
557 Status = gBS->CreateEvent (
558 EVT_SIGNAL_EXIT_BOOT_SERVICES,
559 TPL_CALLBACK,
560 &VirtioRngExitBoot,
561 Dev,
562 &Dev->ExitBoot
563 );
564 if (EFI_ERROR (Status)) {
565 goto UninitDev;
566 }
567
568 //
569 // Setup complete, attempt to export the driver instance's EFI_RNG_PROTOCOL
570 // interface.
571 //
572 Dev->Signature = VIRTIO_RNG_SIG;
573 Status = gBS->InstallProtocolInterface (
574 &DeviceHandle,
575 &gEfiRngProtocolGuid,
576 EFI_NATIVE_INTERFACE,
577 &Dev->Rng
578 );
579 if (EFI_ERROR (Status)) {
580 goto CloseExitBoot;
581 }
582
583 return EFI_SUCCESS;
584
585CloseExitBoot:
586 gBS->CloseEvent (Dev->ExitBoot);
587
588UninitDev:
589 VirtioRngUninit (Dev);
590
591CloseVirtIo:
592 gBS->CloseProtocol (
593 DeviceHandle,
594 &gVirtioDeviceProtocolGuid,
595 This->DriverBindingHandle,
596 DeviceHandle
597 );
598
599FreeVirtioRng:
600 FreePool (Dev);
601
602 return Status;
603}
604
605STATIC
606EFI_STATUS
607EFIAPI
608VirtioRngDriverBindingStop (
609 IN EFI_DRIVER_BINDING_PROTOCOL *This,
610 IN EFI_HANDLE DeviceHandle,
611 IN UINTN NumberOfChildren,
612 IN EFI_HANDLE *ChildHandleBuffer
613 )
614{
615 EFI_STATUS Status;
616 EFI_RNG_PROTOCOL *Rng;
617 VIRTIO_RNG_DEV *Dev;
618
619 Status = gBS->OpenProtocol (
620 DeviceHandle, // candidate device
621 &gEfiRngProtocolGuid, // retrieve the RNG iface
622 (VOID **)&Rng, // target pointer
623 This->DriverBindingHandle, // requestor driver ident.
624 DeviceHandle, // lookup req. for dev.
625 EFI_OPEN_PROTOCOL_GET_PROTOCOL // lookup only, no new ref.
626 );
627 if (EFI_ERROR (Status)) {
628 return Status;
629 }
630
631 Dev = VIRTIO_ENTROPY_SOURCE_FROM_RNG (Rng);
632
633 //
634 // Handle Stop() requests for in-use driver instances gracefully.
635 //
636 Status = gBS->UninstallProtocolInterface (
637 DeviceHandle,
638 &gEfiRngProtocolGuid,
639 &Dev->Rng
640 );
641 if (EFI_ERROR (Status)) {
642 return Status;
643 }
644
645 gBS->CloseEvent (Dev->ExitBoot);
646
647 VirtioRngUninit (Dev);
648
649 gBS->CloseProtocol (
650 DeviceHandle,
651 &gVirtioDeviceProtocolGuid,
652 This->DriverBindingHandle,
653 DeviceHandle
654 );
655
656 FreePool (Dev);
657
658 return EFI_SUCCESS;
659}
660
661//
662// The static object that groups the Supported() (ie. probe), Start() and
663// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + Errata
664// C, 10.1 EFI Driver Binding Protocol.
665//
666STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
667 &VirtioRngDriverBindingSupported,
668 &VirtioRngDriverBindingStart,
669 &VirtioRngDriverBindingStop,
670 0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed drivers
671 NULL, // ImageHandle, to be overwritten by
672 // EfiLibInstallDriverBindingComponentName2() in VirtioRngEntryPoint()
673 NULL // DriverBindingHandle, ditto
674};
675
676//
677// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
678// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's name
679// in English, for display on standard console devices. This is recommended for
680// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver Writer's
681// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
682//
683
684STATIC
685EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
686 { "eng;en", L"Virtio Random Number Generator Driver" },
687 { NULL, NULL }
688};
689
690STATIC
691EFI_COMPONENT_NAME_PROTOCOL gComponentName;
692
693STATIC
694EFI_STATUS
695EFIAPI
696VirtioRngGetDriverName (
697 IN EFI_COMPONENT_NAME_PROTOCOL *This,
698 IN CHAR8 *Language,
699 OUT CHAR16 **DriverName
700 )
701{
702 return LookupUnicodeString2 (
703 Language,
704 This->SupportedLanguages,
705 mDriverNameTable,
706 DriverName,
707 (BOOLEAN)(This == &gComponentName) // Iso639Language
708 );
709}
710
711STATIC
712EFI_STATUS
713EFIAPI
714VirtioRngGetDeviceName (
715 IN EFI_COMPONENT_NAME_PROTOCOL *This,
716 IN EFI_HANDLE DeviceHandle,
717 IN EFI_HANDLE ChildHandle,
718 IN CHAR8 *Language,
719 OUT CHAR16 **ControllerName
720 )
721{
722 return EFI_UNSUPPORTED;
723}
724
725STATIC
726EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
727 &VirtioRngGetDriverName,
728 &VirtioRngGetDeviceName,
729 "eng" // SupportedLanguages, ISO 639-2 language codes
730};
731
732STATIC
733EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
734 (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)&VirtioRngGetDriverName,
735 (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)&VirtioRngGetDeviceName,
736 "en" // SupportedLanguages, RFC 4646 language codes
737};
738
739//
740// Entry point of this driver.
741//
742EFI_STATUS
743EFIAPI
744VirtioRngEntryPoint (
745 IN EFI_HANDLE ImageHandle,
746 IN EFI_SYSTEM_TABLE *SystemTable
747 )
748{
749 return EfiLibInstallDriverBindingComponentName2 (
750 ImageHandle,
751 SystemTable,
752 &gDriverBinding,
753 ImageHandle,
754 &gComponentName,
755 &gComponentName2
756 );
757}
Note: See TracBrowser for help on using the repository browser.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette