[edk2-devel] [edk2-platforms][PATCH 2/5] Silicon/Bcm283x: Add FIFO mode for RNG

Ard Biesheuvel via Groups.Io ard.biesheuvel=linaro.org at groups.io
Wed Nov 27 12:44:14 UTC 2019


On Wed, 27 Nov 2019 at 13:37, Pete Batard <pete at akeo.ie> wrote:
>
> The Bcm283x Random Number Generator does not work in regular mode
> on the Bcm2711 powered Raspberry Pi 4. It does however work when
> using FIFO mode. So we add this new mode, which is governed by the
> use of the new PcdBcm283xRngUseFifo boolean PCD.
>
> Note that just as a Pi 4 doesn't seem to support regular mode, a
> Pi 3 doesn't seem to support FIFO mode, which is why we can't
> switch to simply using FIFO mode for both platforms.
>
> We also fix the register to which RNG_WARMUP_COUNT is written,
> which was incorrect.
>

At the risk of triggering another endless debate, could we /please/
not mix in trivial bugfixes with more complicated refactoring like
this?

> Signed-off-by: Pete Batard <pete at akeo.ie>
> ---
>  Silicon/Broadcom/Bcm283x/Bcm283x.dec               |  1 +
>  Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c   | 96 +++++++++++++++-----
>  Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf |  2 +
>  3 files changed, 74 insertions(+), 25 deletions(-)
>
> diff --git a/Silicon/Broadcom/Bcm283x/Bcm283x.dec b/Silicon/Broadcom/Bcm283x/Bcm283x.dec
> index 5b839b00d286..4a9be7b18c97 100644
> --- a/Silicon/Broadcom/Bcm283x/Bcm283x.dec
> +++ b/Silicon/Broadcom/Bcm283x/Bcm283x.dec
> @@ -21,3 +21,4 @@ [Guids]
>
>  [PcdsFixedAtBuild.common]
>    gBcm283xTokenSpaceGuid.PcdBcm283xRegistersAddress|0x0|UINT32|0x00000001
> +  gBcm283xTokenSpaceGuid.PcdBcm283xRngUseFifo|0x0|BOOLEAN|0x00000002
> diff --git a/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c
> index 722815d32f06..462a21a6f3c3 100644
> --- a/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c
> +++ b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c
> @@ -2,6 +2,7 @@
>
>    This driver produces an EFI_RNG_PROTOCOL instance for the Broadcom 2836 RNG
>
> +  Copyright (C) 2019, Pete Batard <pete at akeo.ie>
>    Copyright (C) 2019, Linaro Ltd. All rights reserved.<BR>
>
>    SPDX-License-Identifier: BSD-2-Clause-Patent
> @@ -12,6 +13,8 @@
>  #include <Library/BaseMemoryLib.h>
>  #include <Library/DebugLib.h>
>  #include <Library/IoLib.h>
> +#include <Library/PcdLib.h>
> +#include <Library/TimerLib.h>
>  #include <Library/UefiBootServicesTableLib.h>
>
>  #include <IndustryStandard/Bcm2836.h>
> @@ -20,6 +23,8 @@
>
>  #define RNG_WARMUP_COUNT        0x40000
>  #define RNG_MAX_RETRIES         0x100         // arbitrary upper bound
> +#define RNG_FIFO_NUMVAL_MASK    0xff
> +#define RNG_STATUS_NUMVAL_SHIFT 24
>
>  /**
>    Returns information about the random number generation implementation.
> @@ -84,6 +89,54 @@ Bcm2836RngGetInfo (
>    return EFI_SUCCESS;
>  }
>
> +/**
> +  Read a single random value, in either FIFO or regular mode.
> +
> +  @param[in]  Val                     A pointer to the 32-bit word that is to
> +                                      be filled with a random value.
> +
> +  @retval EFI_SUCCESS                 A random value was successfully read.
> +  @retval EFI_NOT_READY               The number of retries elapsed before a
> +                                      random value was generated.
> +
> +**/
> +STATIC
> +EFI_STATUS
> +EFIAPI
> +Bcm2836RngReadValue (
> +  IN OUT  UINT32                  *Val
> +)
> +{
> +  UINT32 Avail;
> +  UINT32 i;
> +  BOOLEAN UseFifo = FixedPcdGetBool (PcdBcm283xRngUseFifo);
> +
> +  ASSERT (Val != NULL);
> +
> +  Avail = UseFifo ?
> +    (MmioRead32 (RNG_FIFO_COUNT) & RNG_FIFO_NUMVAL_MASK) :
> +    (MmioRead32 (RNG_STATUS) >> RNG_STATUS_NUMVAL_SHIFT);
> +
> +  //
> +  // If we don't have a value ready, wait 1 us and retry.
> +  //
> +  for (i = 0; Avail < 1 && i < RNG_MAX_RETRIES; i++) {
> +    MicroSecondDelay (1);
> +    Avail = UseFifo ?
> +      (MmioRead32 (RNG_FIFO_COUNT) & RNG_FIFO_NUMVAL_MASK) :
> +      (MmioRead32 (RNG_STATUS) >> RNG_STATUS_NUMVAL_SHIFT);
> +  }
> +  if (Avail < 1) {
> +    return EFI_NOT_READY;
> +  }
> +
> +  *Val = UseFifo ?
> +    MmioRead32 (RNG_FIFO_DATA):
> +    MmioRead32 (RNG_DATA);
> +
> +  return EFI_SUCCESS;
> +}
> +
>  /**
>    Produces and returns an RNG value using either the default or specified RNG
>    algorithm.
> @@ -123,9 +176,8 @@ Bcm2836RngGetRNG (
>    OUT UINT8                      *RNGValue
>    )
>  {
> -  UINT32 Val;
> -  UINT32 Num;
> -  UINT32 Retries;
> +  EFI_STATUS      Status;
> +  UINT32          Val;
>
>    if (This == NULL || RNGValueLength == 0 || RNGValue == NULL) {
>      return EFI_INVALID_PARAMETER;
> @@ -139,30 +191,24 @@ Bcm2836RngGetRNG (
>      return EFI_UNSUPPORTED;
>    }
>
> -  while (RNGValueLength > 0) {
> -    Retries = RNG_MAX_RETRIES;
> -    do {
> -      Num = MmioRead32 (RNG_STATUS) >> 24;
> -      MemoryFence ();
> -    } while (!Num && Retries-- > 0);
> -
> -    if (!Num) {
> -      return EFI_DEVICE_ERROR;
> +  while (RNGValueLength >= sizeof (UINT32)) {
> +    Status = Bcm2836RngReadValue (&Val);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
>      }
> +    WriteUnaligned32 ((VOID *)RNGValue, Val);
> +    RNGValue += sizeof (UINT32);
> +    RNGValueLength -= sizeof (UINT32);
> +  }
>
> -    while (RNGValueLength >= sizeof (UINT32) && Num > 0) {
> -      WriteUnaligned32 ((VOID *)RNGValue, MmioRead32 (RNG_DATA));
> -      RNGValue += sizeof (UINT32);
> -      RNGValueLength -= sizeof (UINT32);
> -      Num--;
> +  if (RNGValueLength > 0) {
> +    Status = Bcm2836RngReadValue (&Val);
> +    if (EFI_ERROR (Status)) {
> +      return Status;
>      }
> -
> -    if (RNGValueLength > 0 && Num > 0) {
> -      Val = MmioRead32 (RNG_DATA);
> -      while (RNGValueLength--) {
> -        *RNGValue++ = (UINT8)Val;
> -        Val >>= 8;
> -      }
> +    while (RNGValueLength--) {
> +      *RNGValue++ = (UINT8)Val;
> +      Val >>= 8;
>      }
>    }
>    return EFI_SUCCESS;
> @@ -190,7 +236,7 @@ Bcm2836RngEntryPoint (
>                    NULL);
>    ASSERT_EFI_ERROR (Status);
>
> -  MmioWrite32 (RNG_STATUS, RNG_WARMUP_COUNT);
> +  MmioWrite32 (RNG_BIT_COUNT_THRESHOLD, RNG_WARMUP_COUNT);
>    MmioWrite32 (RNG_CTRL, RNG_CTRL_ENABLE);
>
>    return EFI_SUCCESS;
> diff --git a/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf
> index 8eb90de85cfd..31415231ae0b 100644
> --- a/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf
> +++ b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf
> @@ -28,6 +28,7 @@ [LibraryClasses]
>    DebugLib
>    IoLib
>    PcdLib
> +  TimerLib
>    UefiBootServicesTableLib
>    UefiDriverEntryPoint
>
> @@ -39,6 +40,7 @@ [Guids]
>
>  [FixedPcd]
>    gBcm283xTokenSpaceGuid.PcdBcm283xRegistersAddress
> +  gBcm283xTokenSpaceGuid.PcdBcm283xRngUseFifo
>
>  [Depex]
>    TRUE
> --
> 2.21.0.windows.1
>

-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.

View/Reply Online (#51340): https://edk2.groups.io/g/devel/message/51340
Mute This Topic: https://groups.io/mt/62504740/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub  [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-





More information about the edk2-devel-archive mailing list