From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
To: Leif Lindholm <leif.lindholm@linaro.org>
Cc: "Marcin Wojtas" <mw@semihalf.com>,
"edk2-devel@lists.01.org" <edk2-devel@lists.01.org>,
"Nadav Haklai" <nadavh@marvell.com>,
"Neta Zur Hershkovits" <neta@marvell.com>,
"Kostya Porotchkin" <kostap@marvell.com>,
"Hua Jing" <jinghua@marvell.com>, "Jan Dąbroś" <jsd@semihalf.com>
Subject: Re: [platforms: PATCH 1/8] Marvell/Armada: Implement EFI_RNG_PROTOCOL driver for EIP76 TRNG
Date: Wed, 11 Oct 2017 19:15:01 +0100 [thread overview]
Message-ID: <CAKv+Gu9WBXYNGdytc3wHchKKNNxtjxi4NKUyLZhqorSsRYPpNA@mail.gmail.com> (raw)
In-Reply-To: <20171011164713.qgkiekieolvjiyk5@bivouac.eciton.net>
On 11 October 2017 at 17:47, Leif Lindholm <leif.lindholm@linaro.org> wrote:
> On Wed, Oct 11, 2017 at 05:40:42PM +0200, Marcin Wojtas wrote:
>> From: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>>
>> Add an implementation of EFI_RNG_PROTOCOL so that the OS loader has
>> access to entropy for KASLR and other purposes (i.e., seeding the OS's
>> entropy pool very early on).
>>
>> Contributed-under: TianoCore Contribution Agreement 1.1
>> Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org>
>> Signed-off-by: Marcin Wojtas <mw@semihalf.com>
>> ---
>> Platform/Marvell/Armada/Armada.dsc.inc | 4 +
>> Platform/Marvell/Armada/Armada70x0.fdf | 1 +
>> Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.c | 254 ++++++++++++++++++++
>> Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf | 47 ++++
>> Platform/Marvell/Marvell.dec | 3 +
>> 5 files changed, 309 insertions(+)
>>
>> diff --git a/Platform/Marvell/Armada/Armada.dsc.inc b/Platform/Marvell/Armada/Armada.dsc.inc
>> index 1aa485c..ec24d76 100644
>> --- a/Platform/Marvell/Armada/Armada.dsc.inc
>> +++ b/Platform/Marvell/Armada/Armada.dsc.inc
>> @@ -364,6 +364,9 @@
>> gArmTokenSpaceGuid.PcdSystemMemorySize|0x40000000
>> gArmTokenSpaceGuid.PcdArmScr|0x531
>>
>> + # TRNG
>> + gMarvellTokenSpaceGuid.PcdEip76TrngBaseAddress|0xF2760000
>> +
>> ################################################################################
>> #
>> # Components Section - list of all EDK II Modules needed by this Platform
>> @@ -400,6 +403,7 @@
>> Platform/Marvell/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf
>> Platform/Marvell/Drivers/Spi/MvSpiDxe.inf
>> Platform/Marvell/Drivers/Spi/Devices/MvSpiFlash.inf
>> + Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf
>>
>> # Network support
>> MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
>> diff --git a/Platform/Marvell/Armada/Armada70x0.fdf b/Platform/Marvell/Armada/Armada70x0.fdf
>> index 933c3ed..a94a9ff 100644
>> --- a/Platform/Marvell/Armada/Armada70x0.fdf
>> +++ b/Platform/Marvell/Armada/Armada70x0.fdf
>> @@ -113,6 +113,7 @@ FvNameGuid = 5eda4200-2c5f-43cb-9da3-0baf74b1b30c
>> INF Platform/Marvell/Drivers/I2c/Devices/MvEeprom/MvEeprom.inf
>> INF Platform/Marvell/Drivers/Spi/MvSpiDxe.inf
>> INF Platform/Marvell/Drivers/Spi/Devices/MvSpiFlash.inf
>> + INF Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf
>>
>> # Network support
>> INF MdeModulePkg/Universal/Network/SnpDxe/SnpDxe.inf
>> diff --git a/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.c b/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.c
>> new file mode 100644
>> index 0000000..dca6dcc
>> --- /dev/null
>> +++ b/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.c
>> @@ -0,0 +1,254 @@
>> +/** @file
>> +
>> + This driver produces an EFI_RNG_PROTOCOL instance for the Armada 70x0 TRNG
>> +
>> + Copyright (C) 2017, Linaro Ltd. All rights reserved.<BR>
>> +
>> + 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/IoLib.h>
>> +#include <Library/PcdLib.h>
>> +#include <Library/UefiBootServicesTableLib.h>
>> +
>> +#include <Protocol/Rng.h>
>> +
>> +#define TRNG_OUTPUT_REG mTrngBaseAddress
>> +#define TRNG_OUTPUT_SIZE 0x10
>> +
>> +#define TRNG_STATUS_REG (mTrngBaseAddress + 0x10)
>> +#define TRNG_STATUS_READY BIT0
>> +
>> +#define TRNG_INTACK_REG (mTrngBaseAddress + 0x10)
>> +#define TRNG_INTACK_READY BIT0
>> +
>> +#define TRNG_CONTROL_REG (mTrngBaseAddress + 0x14)
>> +#define TRNG_CONTROL_REG_ENABLE BIT10
>> +
>> +#define TRNG_CONFIG_REG (mTrngBaseAddress + 0x18)
>> +#define __MIN_REFILL_SHIFT 0
>> +#define __MAX_REFILL_SHIFT 16
>> +#define TRNG_CONFIG_MIN_REFILL_CYCLES (0x05 << __MIN_REFILL_SHIFT)
>> +#define TRNG_CONFIG_MAX_REFILL_CYCLES (0x22 << __MAX_REFILL_SHIFT)
>> +
>> +#define TRNG_FRODETUNE_REG (mTrngBaseAddress + 0x24)
>> +#define TRNG_FRODETUNE_MASK 0x0
>> +
>> +#define TRNG_FROENABLE_REG (mTrngBaseAddress + 0x20)
>> +#define TRNG_FROENABLE_MASK 0xffffff
>> +
>> +#define TRNG_MAX_RETRIES 20
>> +
>> +STATIC EFI_PHYSICAL_ADDRESS mTrngBaseAddress;
>> +
>> +/**
>> + 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
>> +Armada70x0RngGetInfo (
>> + IN EFI_RNG_PROTOCOL *This,
>> + IN OUT UINTN *RNGAlgorithmListSize,
>> + OUT EFI_RNG_ALGORITHM *RNGAlgorithmList
>> + )
>> +{
>> + if (This == NULL || RNGAlgorithmListSize == NULL) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> +
>> + if (*RNGAlgorithmListSize < sizeof (EFI_RNG_ALGORITHM)) {
>> + *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
>> + return EFI_BUFFER_TOO_SMALL;
>> + }
>> +
>> + if (RNGAlgorithmList == NULL) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> +
>> + *RNGAlgorithmListSize = sizeof (EFI_RNG_ALGORITHM);
>> + CopyGuid (RNGAlgorithmList, &gEfiRngAlgorithmRaw);
>> +
>> + return EFI_SUCCESS;
>> +}
>> +
>> +STATIC
>> +EFI_STATUS
>> +GetTrngData (
>> + IN UINTN Length,
>> + OUT UINT8 *Bits
>> + )
>> +{
>> + UINTN Tries;
>> + UINT32 Buf[TRNG_OUTPUT_SIZE / sizeof (UINT32)];
>> + UINTN Index;
>> +
>> + for (Tries = 0; Tries < TRNG_MAX_RETRIES; Tries++) {
>> + if (MmioRead32 (TRNG_STATUS_REG) & TRNG_STATUS_READY) {
>> + for (Index = 0; Index < ARRAY_SIZE (Buf); Index++) {
>> + Buf[Index] = MmioRead32 (TRNG_OUTPUT_REG + Index * sizeof (UINT32));
>> + }
>> + CopyMem (Bits, Buf, Length);
>> + MmioWrite32 (TRNG_INTACK_REG, TRNG_INTACK_READY);
>> +
>> + return EFI_SUCCESS;
>> + }
>> + gBS->Stall (10);
>
> Why? Why 10? Please add a comment.
>
> No other comments on this patch.
>
I don't remember the details, and I think the 1 ms delay was chosen
arbitrarily, but the purpose of the delay is to allow the hardware to
assume the 'ready' state.
>> + }
>> + return EFI_DEVICE_ERROR;
>> +}
>> +
>> +/**
>> + 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
>> +Armada70x0RngGetRNG (
>> + IN EFI_RNG_PROTOCOL *This,
>> + IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL
>> + IN UINTN RNGValueLength,
>> + OUT UINT8 *RNGValue
>> + )
>> +{
>> + UINTN Length;
>> + EFI_STATUS Status;
>> +
>> + if (This == NULL || RNGValueLength == 0 || RNGValue == NULL) {
>> + return EFI_INVALID_PARAMETER;
>> + }
>> +
>> + //
>> + // We only support the raw algorithm, so reject requests for anything else
>> + //
>> + if (RNGAlgorithm != NULL &&
>> + !CompareGuid (RNGAlgorithm, &gEfiRngAlgorithmRaw)) {
>> + return EFI_UNSUPPORTED;
>> + }
>> +
>> + do {
>> + Length = MIN (RNGValueLength, TRNG_OUTPUT_SIZE);
>> + Status = GetTrngData (Length, RNGValue);
>> + if (EFI_ERROR (Status)) {
>> + return Status;
>> + }
>> +
>> + RNGValue += Length;
>> + RNGValueLength -= Length;
>> + } while (RNGValueLength > 0);
>> +
>> + return EFI_SUCCESS;
>> +}
>> +
>> +STATIC EFI_RNG_PROTOCOL mArmada70x0RngProtocol = {
>> + Armada70x0RngGetInfo,
>> + Armada70x0RngGetRNG
>> +};
>> +
>> +//
>> +// Entry point of this driver.
>> +//
>> +EFI_STATUS
>> +EFIAPI
>> +Armada70x0RngDxeEntryPoint (
>> + IN EFI_HANDLE ImageHandle,
>> + IN EFI_SYSTEM_TABLE *SystemTable
>> + )
>> +{
>> + mTrngBaseAddress = PcdGet64 (PcdEip76TrngBaseAddress);
>> +
>> + //
>> + // Disable the TRNG before updating its configuration
>> + //
>> + MmioAnd32 (TRNG_CONTROL_REG, ~TRNG_CONTROL_REG_ENABLE);
>> +
>> + //
>> + // Configure the internal conditioning parameters of the TRNG
>> + //
>> + MmioWrite32 (TRNG_CONFIG_REG, TRNG_CONFIG_MIN_REFILL_CYCLES |
>> + TRNG_CONFIG_MAX_REFILL_CYCLES);
>> +
>> + //
>> + // Configure the FROs
>> + //
>> + MmioWrite32 (TRNG_FRODETUNE_REG, TRNG_FRODETUNE_MASK);
>> + MmioWrite32 (TRNG_FROENABLE_REG, TRNG_FROENABLE_MASK);
>> +
>> + //
>> + // Enable the TRNG
>> + //
>> + MmioOr32 (TRNG_CONTROL_REG, TRNG_CONTROL_REG_ENABLE);
>> +
>> + return SystemTable->BootServices->InstallMultipleProtocolInterfaces (
>> + &ImageHandle,
>> + &gEfiRngProtocolGuid,
>> + &mArmada70x0RngProtocol,
>> + NULL
>> + );
>> +}
>> diff --git a/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf b/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf
>> new file mode 100644
>> index 0000000..189ffc5
>> --- /dev/null
>> +++ b/Platform/Marvell/Armada/Drivers/Armada70x0RngDxe/Armada70x0RngDxe.inf
>> @@ -0,0 +1,47 @@
>> +## @file
>> +# This driver produces an EFI_RNG_PROTOCOL instance for the Armada 70x0 TRNG
>> +#
>> +# Copyright (C) 2017, Linaro Ltd. All rights reserved.<BR>
>> +#
>> +# 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 = 0x00010019
>> + BASE_NAME = Armada70x0RngDxe
>> + FILE_GUID = dd87096a-cae5-4328-bec1-2ddb755f2e08
>> + MODULE_TYPE = DXE_DRIVER
>> + VERSION_STRING = 1.0
>> + ENTRY_POINT = Armada70x0RngDxeEntryPoint
>> +
>> +[Sources]
>> + Armada70x0RngDxe.c
>> +
>> +[Packages]
>> + MdePkg/MdePkg.dec
>> + Platform/Marvell/Marvell.dec
>> +
>> +[LibraryClasses]
>> + BaseMemoryLib
>> + IoLib
>> + PcdLib
>> + UefiDriverEntryPoint
>> +
>> +[Pcd]
>> + gMarvellTokenSpaceGuid.PcdEip76TrngBaseAddress
>> +
>> +[Protocols]
>> + gEfiRngProtocolGuid ## PRODUCES
>> +
>> +[Guids]
>> + gEfiRngAlgorithmRaw
>> +
>> +[Depex]
>> + TRUE
>> diff --git a/Platform/Marvell/Marvell.dec b/Platform/Marvell/Marvell.dec
>> index e7d7c2c..78f5e53 100644
>> --- a/Platform/Marvell/Marvell.dec
>> +++ b/Platform/Marvell/Marvell.dec
>> @@ -195,6 +195,9 @@
>> #RTC
>> gMarvellTokenSpaceGuid.PcdRtcEnabled|{ 0x0 }|VOID*|0x40000052
>>
>> +#TRNG
>> + gMarvellTokenSpaceGuid.PcdEip76TrngBaseAddress|0x0|UINT64|0x50000053
>> +
>> [Protocols]
>> gMarvellEepromProtocolGuid = { 0x71954bda, 0x60d3, 0x4ef8, { 0x8e, 0x3c, 0x0e, 0x33, 0x9f, 0x3b, 0xc2, 0x2b }}
>> gMarvellMdioProtocolGuid = { 0x40010b03, 0x5f08, 0x496a, { 0xa2, 0x64, 0x10, 0x5e, 0x72, 0xd3, 0x71, 0xaa }}
>> --
>> 2.7.4
>>
next prev parent reply other threads:[~2017-10-11 18:11 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-10-11 15:40 [platforms: PATCH 0/8] Armada 7k/8k - memory improvements Marcin Wojtas
2017-10-11 15:40 ` [platforms: PATCH 1/8] Marvell/Armada: Implement EFI_RNG_PROTOCOL driver for EIP76 TRNG Marcin Wojtas
2017-10-11 16:47 ` Leif Lindholm
2017-10-11 18:15 ` Ard Biesheuvel [this message]
2017-10-12 4:39 ` Marcin Wojtas
2017-10-12 10:24 ` Leif Lindholm
2017-10-11 15:40 ` [platforms: PATCH 2/8] Marvell/Armada: Increase preallocated memory region size Marcin Wojtas
2017-10-11 16:56 ` Leif Lindholm
2017-10-11 15:40 ` [platforms: PATCH 3/8] Marvell/Armada: Remove custom reset library residues Marcin Wojtas
2017-10-11 16:56 ` Leif Lindholm
2017-10-11 15:40 ` [platforms: PATCH 4/8] Marvell/Armada: Add support from DRAM remapping Marcin Wojtas
2017-10-11 17:08 ` Leif Lindholm
2017-10-11 18:18 ` Ard Biesheuvel
2017-10-12 4:58 ` Marcin Wojtas
2017-10-12 10:29 ` Leif Lindholm
2017-10-11 15:40 ` [platforms: PATCH 5/8] Marvell/Armada: Add MemoryInitPeiLib that reserves secure region Marcin Wojtas
2017-10-11 17:11 ` Leif Lindholm
2017-10-11 15:40 ` [platforms: PATCH 6/8] Marvell/Armada: Enable dynamic DRAM size detection Marcin Wojtas
2017-10-11 17:56 ` Leif Lindholm
2017-10-12 5:47 ` Marcin Wojtas
2017-10-12 10:50 ` Leif Lindholm
2017-10-12 10:58 ` Marcin Wojtas
2017-10-11 15:40 ` [platforms: PATCH 7/8] Marvell/Armada: Armada70x0Lib: Add support for 32-bit ARM Marcin Wojtas
2017-10-11 17:57 ` Leif Lindholm
2017-10-11 15:40 ` [platforms: PATCH 8/8] Marvell/Armada: Add 32-bit ARM support Marcin Wojtas
2017-10-11 17:58 ` Leif Lindholm
2017-10-11 18:20 ` Ard Biesheuvel
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CAKv+Gu9WBXYNGdytc3wHchKKNNxtjxi4NKUyLZhqorSsRYPpNA@mail.gmail.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox