On 19 February 2016 at 14:49, Laszlo Ersek <ler...@redhat.com> wrote:
> On 02/19/16 11:54, Ard Biesheuvel wrote:
>> This implements a UEFI driver model driver for Virtio devices of type
>> VIRTIO_SUBSYSTEM_ENTROPY_SOURCE, and exposes them via instances of
>> the EFI_RNG_PROTOCOL protocol, supporting the EFI_RNG_ALGORITHM_RAW
>> algorithm only.
>>
>> Contributed-under: TianoCore Contribution Agreement 1.0
>> Signed-off-by: Ard Biesheuvel <ard.biesheu...@linaro.org>
>> ---
>>
>> 90% of this driver is boilerplate taken from the virtio-scsi driver.
>>
>> The purpose of this driver is to expose the EFI_RNG_PROTOCOL to the arm64
>> Linux kernel UEFI stub, which will use it to randomize the kernel address
>> space [1]
>>
>> This driver can be tested from the UEFI shell using the RngTest UEFI
>> application (SecurityPkg/Application/RngTest/RngTest.inf), example output
>> can be found after the patch
>>
>> [1] http://thread.gmane.org/gmane.linux.kernel.efi/7446
>>
>>  OvmfPkg/VirtioRngDxe/VirtioRng.c      | 593 ++++++++++++++++++++
>>  OvmfPkg/VirtioRngDxe/VirtioRngDxe.inf |  45 ++
>>  2 files changed, 638 insertions(+)
>
> Can you push this to your repo please?
>

Weblink:
https://git.linaro.org/people/ard.biesheuvel/uefi-next.git/shortlog/refs/heads/virtio-rng

Git URL:
git://git.linaro.org/people/ard.biesheuvel/uefi-next.git virtio-rng



>> diff --git a/OvmfPkg/VirtioRngDxe/VirtioRng.c 
>> b/OvmfPkg/VirtioRngDxe/VirtioRng.c
>> new file mode 100644
>> index 000000000000..ab52f269fc3f
>> --- /dev/null
>> +++ b/OvmfPkg/VirtioRngDxe/VirtioRng.c
>> @@ -0,0 +1,593 @@
>> +/** @file
>> +
>> +  This driver produces EFI_RNG_PROTOCOL instances for virtio-rng devices.
>> +
>> +  The implementation is based on OvmfPkg/VirtioScsiDxe/VirtioScsi.c
>> +
>> +  Copyright (C) 2012, Red Hat, Inc.
>> +  Copyright (c) 2012 - 2014, Intel Corporation. All rights reserved.<BR>
>> +
>> +  This driver:
>> +
>> +  Copyright (C) 2016, Linaro Ltd.
>> +
>> +  This program and the accompanying materials are licensed and made 
>> available
>> +  under the terms and conditions of the BSD License which accompanies this
>> +  distribution. The full text of the license may be found at
>> +  http://opensource.org/licenses/bsd-license.php
>> +
>> +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 
>> WITHOUT
>> +  WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +
>> +**/
>> +
>> +#include <Library/BaseMemoryLib.h>
>> +#include <Library/DebugLib.h>
>> +#include <Library/MemoryAllocationLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +#include <Library/UefiLib.h>
>> +#include <Library/VirtioLib.h>
>> +
>> +#include <Protocol/ComponentName.h>
>> +#include <Protocol/DriverBinding.h>
>> +#include <Protocol/Rng.h>
>> +
>> +#include <IndustryStandard/Virtio.h>
>> +
>> +#define VIRTIO_RNG_SIG      SIGNATURE_32 ('V', 'R', 'N', 'G')
>> +
>> +typedef struct {
>> +  UINT32                          Signature;
>> +  VIRTIO_DEVICE_PROTOCOL          *VirtIo;
>> +  EFI_EVENT                       ExitBoot;
>> +  VRING                           Ring;
>> +  EFI_RNG_PROTOCOL                Rng;
>> +} VIRTIO_RNG_DEV;
>> +
>> +#define VIRTIO_ENTROPY_SOURCE_FROM_RNG(RngPointer) \
>> +        CR (RngPointer, VIRTIO_RNG_DEV, Rng, VIRTIO_RNG_SIG)
>> +
>> +
>> +/**
>> +  Returns information about the random number generation implementation.
>> +
>> +  @param[in]     This                 A pointer to the EFI_RNG_PROTOCOL 
>> instance.
>> +  @param[in,out] RNGAlgorithmListSize On input, the size in bytes of 
>> RNGAlgorithmList.
>> +                                      On output with a return code of 
>> EFI_SUCCESS, the size
>> +                                      in bytes of the data returned in 
>> RNGAlgorithmList. On output
>> +                                      with a return code of 
>> EFI_BUFFER_TOO_SMALL,
>> +                                      the size of RNGAlgorithmList required 
>> to obtain the list.
>> +  @param[out] RNGAlgorithmList        A caller-allocated memory buffer 
>> filled by the driver
>> +                                      with one EFI_RNG_ALGORITHM element 
>> for each supported
>> +                                      RNG algorithm. The list must not 
>> change across multiple
>> +                                      calls to the same driver. The first 
>> algorithm in the list
>> +                                      is the default algorithm for the 
>> driver.
>> +
>> +  @retval EFI_SUCCESS                 The RNG algorithm list was returned 
>> successfully.
>> +  @retval EFI_UNSUPPORTED             The services is not supported by this 
>> driver.
>> +  @retval EFI_DEVICE_ERROR            The list of algorithms could not be 
>> retrieved due to a
>> +                                      hardware or firmware error.
>> +  @retval EFI_INVALID_PARAMETER       One or more of the parameters are 
>> incorrect.
>> +  @retval EFI_BUFFER_TOO_SMALL        The buffer RNGAlgorithmList is too 
>> small to hold the result.
>> +
>> +**/
>> +STATIC
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioRngGetInfo (
>> +  IN      EFI_RNG_PROTOCOL        *This,
>> +  IN OUT  UINTN                   *RNGAlgorithmListSize,
>> +  OUT     EFI_RNG_ALGORITHM       *RNGAlgorithmList
>> +  )
>> +{
>> +  ASSERT (This != NULL);
>> +  ASSERT (RNGAlgorithmListSize != NULL);
>> +
>> +  if (*RNGAlgorithmListSize < sizeof (EFI_RNG_ALGORITHM)) {
>> +    *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
>> +    return EFI_BUFFER_TOO_SMALL;
>> +  }
>> +
>> +  ASSERT (RNGAlgorithmList != NULL);
>> +
>> +  *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
>> +  CopyGuid (RNGAlgorithmList, &gEfiRngAlgorithmRaw);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +/**
>> +  Produces and returns an RNG value using either the default or specified 
>> RNG algorithm.
>> +
>> +  @param[in]  This                    A pointer to the EFI_RNG_PROTOCOL 
>> instance.
>> +  @param[in]  RNGAlgorithm            A pointer to the EFI_RNG_ALGORITHM 
>> that identifies the RNG
>> +                                      algorithm to use. May be NULL in 
>> which case the function will
>> +                                      use its default RNG algorithm.
>> +  @param[in]  RNGValueLength          The length in bytes of the memory 
>> buffer pointed to by
>> +                                      RNGValue. The driver shall return 
>> exactly this numbers of bytes.
>> +  @param[out] RNGValue                A caller-allocated memory buffer 
>> filled by the driver with the
>> +                                      resulting RNG value.
>> +
>> +  @retval EFI_SUCCESS                 The RNG value was returned 
>> successfully.
>> +  @retval EFI_UNSUPPORTED             The algorithm specified by 
>> RNGAlgorithm is not supported by
>> +                                      this driver.
>> +  @retval EFI_DEVICE_ERROR            An RNG value could not be retrieved 
>> due to a hardware or
>> +                                      firmware error.
>> +  @retval EFI_NOT_READY               There is not enough random data 
>> available to satisfy the length
>> +                                      requested by RNGValueLength.
>> +  @retval EFI_INVALID_PARAMETER       RNGValue is NULL or RNGValueLength is 
>> zero.
>> +
>> +**/
>> +STATIC
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioRngGetRNG (
>> +  IN EFI_RNG_PROTOCOL            *This,
>> +  IN EFI_RNG_ALGORITHM           *RNGAlgorithm, OPTIONAL
>> +  IN UINTN                       RNGValueLength,
>> +  OUT UINT8                      *RNGValue
>> +  )
>> +{
>> +  VIRTIO_RNG_DEV            *Dev;
>> +  DESC_INDICES              Indices;
>> +
>> +  ASSERT (This != NULL);
>> +  ASSERT (RNGValue != NULL);
>> +
>> +  //
>> +  // We only support the raw algorithm, so reject requests for anything else
>> +  //
>> +  if (RNGAlgorithm && !CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
>> +    return EFI_UNSUPPORTED;
>> +  }
>> +
>> +  Dev = VIRTIO_ENTROPY_SOURCE_FROM_RNG (This);
>> +
>> +  VirtioPrepare (&Dev->Ring, &Indices);
>> +  VirtioAppendDesc (&Dev->Ring,
>> +    (UINTN) RNGValue,
>> +    RNGValueLength,
>> +    VRING_DESC_F_WRITE,
>> +    &Indices);
>> +
>> +  if (VirtioFlush (Dev->VirtIo, 0, &Dev->Ring, &Indices) != EFI_SUCCESS) {
>> +    return EFI_DEVICE_ERROR;
>> +  }
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioRngInit (
>> +  IN OUT VIRTIO_RNG_DEV *Dev
>> +  )
>> +{
>> +  UINT8      NextDevStat;
>> +  EFI_STATUS Status;
>> +  UINT16     QueueSize;
>> +
>> +  //
>> +  // Execute virtio-0.9.5, 2.2.1 Device Initialization Sequence.
>> +  //
>> +  NextDevStat = 0;             // step 1 -- reset device
>> +  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
>> +  if (EFI_ERROR (Status)) {
>> +    goto Failed;
>> +  }
>> +
>> +  NextDevStat |= VSTAT_ACK;    // step 2 -- acknowledge device presence
>> +  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
>> +  if (EFI_ERROR (Status)) {
>> +    goto Failed;
>> +  }
>> +
>> +  NextDevStat |= VSTAT_DRIVER; // step 3 -- we know how to drive it
>> +  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
>> +  if (EFI_ERROR (Status)) {
>> +    goto Failed;
>> +  }
>> +
>> +  //
>> +  // Set Page Size - MMIO VirtIo Specific
>> +  //
>> +  Status = Dev->VirtIo->SetPageSize (Dev->VirtIo, EFI_PAGE_SIZE);
>> +  if (EFI_ERROR (Status)) {
>> +    goto Failed;
>> +  }
>> +
>> +  //
>> +  // allocate request virtqueue, just use #0
>> +  //
>> +  Status = Dev->VirtIo->SetQueueSel (Dev->VirtIo, 0);
>> +  if (EFI_ERROR (Status)) {
>> +    goto Failed;
>> +  }
>> +  Status = Dev->VirtIo->GetQueueNumMax (Dev->VirtIo, &QueueSize);
>> +  if (EFI_ERROR (Status)) {
>> +    goto Failed;
>> +  }
>> +
>> +  //
>> +  // Single queue required
>> +  //
>> +  if (QueueSize < 1) {
>> +    Status = EFI_UNSUPPORTED;
>> +    goto Failed;
>> +  }
>> +
>> +  Status = VirtioRingInit (QueueSize, &Dev->Ring);
>> +  if (EFI_ERROR (Status)) {
>> +    goto Failed;
>> +  }
>> +
>> +  //
>> +  // Additional steps for MMIO: align the queue appropriately, and set the
>> +  // size. If anything fails from here on, we must release the ring 
>> resources.
>> +  //
>> +  Status = Dev->VirtIo->SetQueueNum (Dev->VirtIo, QueueSize);
>> +  if (EFI_ERROR (Status)) {
>> +    goto ReleaseQueue;
>> +  }
>> +
>> +  Status = Dev->VirtIo->SetQueueAlign (Dev->VirtIo, EFI_PAGE_SIZE);
>> +  if (EFI_ERROR (Status)) {
>> +    goto ReleaseQueue;
>> +  }
>> +
>> +  //
>> +  // Report GPFN (guest-physical frame number) of queue.
>> +  //
>> +  Status = Dev->VirtIo->SetQueueAddress (Dev->VirtIo,
>> +      (UINT32) ((UINTN) Dev->Ring.Base >> EFI_PAGE_SHIFT));
>> +  if (EFI_ERROR (Status)) {
>> +    goto ReleaseQueue;
>> +  }
>> +
>> +  //
>> +  // initialization complete
>> +  //
>> +  NextDevStat |= VSTAT_DRIVER_OK;
>> +  Status = Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
>> +  if (EFI_ERROR (Status)) {
>> +    goto ReleaseQueue;
>> +  }
>> +
>> +  //
>> +  // populate the exported interface's attributes
>> +  //
>> +  Dev->Rng.GetInfo    = VirtioRngGetInfo;
>> +  Dev->Rng.GetRNG     = VirtioRngGetRNG;
>> +
>> +  return EFI_SUCCESS;
>> +
>> +ReleaseQueue:
>> +  VirtioRingUninit (&Dev->Ring);
>> +
>> +Failed:
>> +  //
>> +  // Notify the host about our failure to setup: virtio-0.9.5, 2.2.2.1 
>> Device
>> +  // Status. VirtIo access failure here should not mask the original error.
>> +  //
>> +  NextDevStat |= VSTAT_FAILED;
>> +  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, NextDevStat);
>> +
>> +  return Status; // reached only via Failed above
>> +}
>> +
>> +
>> +STATIC
>> +VOID
>> +EFIAPI
>> +VirtioRngUninit (
>> +  IN OUT VIRTIO_RNG_DEV *Dev
>> +  )
>> +{
>> +  //
>> +  // Reset the virtual device -- see virtio-0.9.5, 2.2.2.1 Device Status. 
>> When
>> +  // VIRTIO_CFG_WRITE() returns, the host will have learned to stay away 
>> from
>> +  // the old comms area.
>> +  //
>> +  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
>> +  VirtioRingUninit (&Dev->Ring);
>> +}
>> +
>> +//
>> +// Event notification function enqueued by ExitBootServices().
>> +//
>> +
>> +STATIC
>> +VOID
>> +EFIAPI
>> +VirtioRngExitBoot (
>> +  IN  EFI_EVENT Event,
>> +  IN  VOID      *Context
>> +  )
>> +{
>> +  VIRTIO_RNG_DEV *Dev;
>> +
>> +  //
>> +  // Reset the device. This causes the hypervisor to forget about the virtio
>> +  // ring.
>> +  //
>> +  // We allocated said ring in EfiBootServicesData type memory, and code
>> +  // executing after ExitBootServices() is permitted to overwrite it.
>> +  //
>> +  Dev = Context;
>> +  Dev->VirtIo->SetDeviceStatus (Dev->VirtIo, 0);
>> +}
>> +
>> +
>> +//
>> +// Probe, start and stop functions of this driver, called by the DXE core 
>> for
>> +// specific devices.
>> +//
>> +// The following specifications document these interfaces:
>> +// - Driver Writer's Guide for UEFI 2.3.1 v1.01, 9 Driver Binding Protocol
>> +// - UEFI Spec 2.3.1 + Errata C, 10.1 EFI Driver Binding Protocol
>> +//
>> +// The implementation follows:
>> +// - Driver Writer's Guide for UEFI 2.3.1 v1.01
>> +//   - 5.1.3.4 OpenProtocol() and CloseProtocol()
>> +// - UEFI Spec 2.3.1 + Errata C
>> +//   -  6.3 Protocol Handler Services
>> +//
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioRngDriverBindingSupported (
>> +  IN EFI_DRIVER_BINDING_PROTOCOL *This,
>> +  IN EFI_HANDLE                  DeviceHandle,
>> +  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
>> +  )
>> +{
>> +  EFI_STATUS             Status;
>> +  VIRTIO_DEVICE_PROTOCOL *VirtIo;
>> +
>> +  //
>> +  // Attempt to open the device with the VirtIo set of interfaces. On 
>> success,
>> +  // the protocol is "instantiated" for the VirtIo device. Covers duplicate 
>> open
>> +  // attempts (EFI_ALREADY_STARTED).
>> +  //
>> +  Status = gBS->OpenProtocol (
>> +                  DeviceHandle,               // candidate device
>> +                  &gVirtioDeviceProtocolGuid, // for generic VirtIo access
>> +                  (VOID **)&VirtIo,           // handle to instantiate
>> +                  This->DriverBindingHandle,  // requestor driver identity
>> +                  DeviceHandle,               // ControllerHandle, 
>> according to
>> +                                              // the UEFI Driver Model
>> +                  EFI_OPEN_PROTOCOL_BY_DRIVER // get exclusive VirtIo 
>> access to
>> +                                              // the device; to be released
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  if (VirtIo->SubSystemDeviceId != VIRTIO_SUBSYSTEM_ENTROPY_SOURCE) {
>> +    Status = EFI_UNSUPPORTED;
>> +  }
>> +
>> +  //
>> +  // We needed VirtIo access only transitorily, to see whether we support 
>> the
>> +  // device or not.
>> +  //
>> +  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
>> +         This->DriverBindingHandle, DeviceHandle);
>> +  return Status;
>> +}
>> +
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioRngDriverBindingStart (
>> +  IN EFI_DRIVER_BINDING_PROTOCOL *This,
>> +  IN EFI_HANDLE                  DeviceHandle,
>> +  IN EFI_DEVICE_PATH_PROTOCOL    *RemainingDevicePath
>> +  )
>> +{
>> +  VIRTIO_RNG_DEV  *Dev;
>> +  EFI_STATUS Status;
>> +
>> +  Dev = (VIRTIO_RNG_DEV *) AllocateZeroPool (sizeof *Dev);
>> +  if (Dev == NULL) {
>> +    return EFI_OUT_OF_RESOURCES;
>> +  }
>> +
>> +  Status = gBS->OpenProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
>> +                  (VOID **)&Dev->VirtIo, This->DriverBindingHandle,
>> +                  DeviceHandle, EFI_OPEN_PROTOCOL_BY_DRIVER);
>> +  if (EFI_ERROR (Status)) {
>> +    goto FreeVirtioRng;
>> +  }
>> +
>> +  //
>> +  // VirtIo access granted, configure virtio-rng device.
>> +  //
>> +  Status = VirtioRngInit (Dev);
>> +  if (EFI_ERROR (Status)) {
>> +    goto CloseVirtIo;
>> +  }
>> +
>> +  Status = gBS->CreateEvent (EVT_SIGNAL_EXIT_BOOT_SERVICES, TPL_CALLBACK,
>> +                  &VirtioRngExitBoot, Dev, &Dev->ExitBoot);
>> +  if (EFI_ERROR (Status)) {
>> +    goto UninitDev;
>> +  }
>> +
>> +  //
>> +  // Setup complete, attempt to export the driver instance's 
>> EFI_RNG_PROTOCOL
>> +  // interface.
>> +  //
>> +  Dev->Signature = VIRTIO_RNG_SIG;
>> +  Status = gBS->InstallProtocolInterface (&DeviceHandle,
>> +                  &gEfiRngProtocolGuid, EFI_NATIVE_INTERFACE,
>> +                  &Dev->Rng);
>> +  if (EFI_ERROR (Status)) {
>> +    goto CloseExitBoot;
>> +  }
>> +
>> +  return EFI_SUCCESS;
>> +
>> +CloseExitBoot:
>> +  gBS->CloseEvent (Dev->ExitBoot);
>> +
>> +UninitDev:
>> +  VirtioRngUninit (Dev);
>> +
>> +CloseVirtIo:
>> +  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
>> +         This->DriverBindingHandle, DeviceHandle);
>> +
>> +FreeVirtioRng:
>> +  FreePool (Dev);
>> +
>> +  return Status;
>> +}
>> +
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioRngDriverBindingStop (
>> +  IN EFI_DRIVER_BINDING_PROTOCOL *This,
>> +  IN EFI_HANDLE                  DeviceHandle,
>> +  IN UINTN                       NumberOfChildren,
>> +  IN EFI_HANDLE                  *ChildHandleBuffer
>> +  )
>> +{
>> +  EFI_STATUS                      Status;
>> +  EFI_RNG_PROTOCOL                *Rng;
>> +  VIRTIO_RNG_DEV                  *Dev;
>> +
>> +  Status = gBS->OpenProtocol (
>> +                  DeviceHandle,                     // candidate device
>> +                  &gEfiRngProtocolGuid,             // retrieve the RNG 
>> iface
>> +                  (VOID **)&Rng,                    // target pointer
>> +                  This->DriverBindingHandle,        // requestor driver 
>> ident.
>> +                  DeviceHandle,                     // lookup req. for dev.
>> +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL    // lookup only, no new 
>> ref.
>> +                  );
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  Dev = VIRTIO_ENTROPY_SOURCE_FROM_RNG (Rng);
>> +
>> +  //
>> +  // Handle Stop() requests for in-use driver instances gracefully.
>> +  //
>> +  Status = gBS->UninstallProtocolInterface (DeviceHandle,
>> +                  &gEfiRngProtocolGuid, &Dev->Rng);
>> +  if (EFI_ERROR (Status)) {
>> +    return Status;
>> +  }
>> +
>> +  gBS->CloseEvent (Dev->ExitBoot);
>> +
>> +  VirtioRngUninit (Dev);
>> +
>> +  gBS->CloseProtocol (DeviceHandle, &gVirtioDeviceProtocolGuid,
>> +         This->DriverBindingHandle, DeviceHandle);
>> +
>> +  FreePool (Dev);
>> +
>> +  return EFI_SUCCESS;
>> +}
>> +
>> +
>> +//
>> +// The static object that groups the Supported() (ie. probe), Start() and
>> +// Stop() functions of the driver together. Refer to UEFI Spec 2.3.1 + 
>> Errata
>> +// C, 10.1 EFI Driver Binding Protocol.
>> +//
>> +STATIC EFI_DRIVER_BINDING_PROTOCOL gDriverBinding = {
>> +  &VirtioRngDriverBindingSupported,
>> +  &VirtioRngDriverBindingStart,
>> +  &VirtioRngDriverBindingStop,
>> +  0x10, // Version, must be in [0x10 .. 0xFFFFFFEF] for IHV-developed 
>> drivers
>> +  NULL, // ImageHandle, to be overwritten by
>> +        // EfiLibInstallDriverBindingComponentName2() in 
>> VirtioRngEntryPoint()
>> +  NULL  // DriverBindingHandle, ditto
>> +};
>> +
>> +
>> +//
>> +// The purpose of the following scaffolding (EFI_COMPONENT_NAME_PROTOCOL and
>> +// EFI_COMPONENT_NAME2_PROTOCOL implementation) is to format the driver's 
>> name
>> +// in English, for display on standard console devices. This is recommended 
>> for
>> +// UEFI drivers that follow the UEFI Driver Model. Refer to the Driver 
>> Writer's
>> +// Guide for UEFI 2.3.1 v1.01, 11 UEFI Driver and Controller Names.
>> +//
>> +
>> +STATIC
>> +EFI_UNICODE_STRING_TABLE mDriverNameTable[] = {
>> +  { "eng;en", L"Virtio Random Number Generator Driver" },
>> +  { NULL,     NULL                   }
>> +};
>> +
>> +STATIC
>> +EFI_COMPONENT_NAME_PROTOCOL gComponentName;
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioRngGetDriverName (
>> +  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
>> +  IN  CHAR8                       *Language,
>> +  OUT CHAR16                      **DriverName
>> +  )
>> +{
>> +  return LookupUnicodeString2 (
>> +           Language,
>> +           This->SupportedLanguages,
>> +           mDriverNameTable,
>> +           DriverName,
>> +           (BOOLEAN)(This == &gComponentName) // Iso639Language
>> +           );
>> +}
>> +
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioRngGetDeviceName (
>> +  IN  EFI_COMPONENT_NAME_PROTOCOL *This,
>> +  IN  EFI_HANDLE                  DeviceHandle,
>> +  IN  EFI_HANDLE                  ChildHandle,
>> +  IN  CHAR8                       *Language,
>> +  OUT CHAR16                      **ControllerName
>> +  )
>> +{
>> +  return EFI_UNSUPPORTED;
>> +}
>> +
>> +STATIC
>> +EFI_COMPONENT_NAME_PROTOCOL gComponentName = {
>> +  &VirtioRngGetDriverName,
>> +  &VirtioRngGetDeviceName,
>> +  "eng" // SupportedLanguages, ISO 639-2 language codes
>> +};
>> +
>> +STATIC
>> +EFI_COMPONENT_NAME2_PROTOCOL gComponentName2 = {
>> +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)     &VirtioRngGetDriverName,
>> +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) &VirtioRngGetDeviceName,
>> +  "en" // SupportedLanguages, RFC 4646 language codes
>> +};
>> +
>> +
>> +//
>> +// Entry point of this driver.
>> +//
>> +EFI_STATUS
>> +EFIAPI
>> +VirtioRngEntryPoint (
>> +  IN EFI_HANDLE       ImageHandle,
>> +  IN EFI_SYSTEM_TABLE *SystemTable
>> +  )
>> +{
>> +  return EfiLibInstallDriverBindingComponentName2 (
>> +           ImageHandle,
>> +           SystemTable,
>> +           &gDriverBinding,
>> +           ImageHandle,
>> +           &gComponentName,
>> +           &gComponentName2
>> +           );
>> +}
>> diff --git a/OvmfPkg/VirtioRngDxe/VirtioRngDxe.inf 
>> b/OvmfPkg/VirtioRngDxe/VirtioRngDxe.inf
>> new file mode 100644
>> index 000000000000..471beb37bc7f
>> --- /dev/null
>> +++ b/OvmfPkg/VirtioRngDxe/VirtioRngDxe.inf
>> @@ -0,0 +1,45 @@
>> +## @file
>> +# This driver produces EFI_RNG_PROTOCOL instances for virtio-rng devices.
>> +#
>> +# Copyright (C) 2016, Linaro Ltd.
>> +#
>> +# This program and the accompanying materials are licensed and made 
>> available
>> +# under the terms and conditions of the BSD License which accompanies this
>> +# distribution. The full text of the license may be found at
>> +# http://opensource.org/licenses/bsd-license.php
>> +#
>> +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 
>> WITHOUT
>> +# WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
>> +#
>> +##
>> +
>> +[Defines]
>> +  INF_VERSION                    = 0x00010005
>> +  BASE_NAME                      = VirtioRngDxe
>> +  FILE_GUID                      = 58E26F0D-CBAC-4BBA-B70F-18221415665A
>> +  MODULE_TYPE                    = UEFI_DRIVER
>> +  VERSION_STRING                 = 1.0
>> +  ENTRY_POINT                    = VirtioRngEntryPoint
>> +
>> +[Sources]
>> +  VirtioRng.c
>> +
>> +[Packages]
>> +  MdePkg/MdePkg.dec
>> +  OvmfPkg/OvmfPkg.dec
>> +
>> +[LibraryClasses]
>> +  BaseMemoryLib
>> +  DebugLib
>> +  MemoryAllocationLib
>> +  UefiBootServicesTableLib
>> +  UefiDriverEntryPoint
>> +  UefiLib
>> +  VirtioLib
>> +
>> +[Protocols]
>> +  gEfiRngProtocolGuid              ## BY_START
>> +  gVirtioDeviceProtocolGuid        ## TO_START
>> +
>> +[Guids]
>> +  gEfiRngAlgorithmRaw
>>
>
_______________________________________________
edk2-devel mailing list
edk2-devel@lists.01.org
https://lists.01.org/mailman/listinfo/edk2-devel

Reply via email to