Message ID | 20190130193943.12023-1-ard.biesheuvel@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | [edk2,edk2-platforms] Silicon/Bcm2836: add random number generator driver | expand |
On Wed, Jan 30, 2019 at 08:39:43PM +0100, Ard Biesheuvel wrote: > Expose the SoC's RNG peripheral via the EFI_RNG_PROTOCOL. > This is used by Linux to seed the KASLR routines. > > Contributed-under: TianoCore Contribution Agreement 1.1 > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Not tested, but looks fine. Only question: could we add those few #defines to IndustryStandard/Bcm2836.h (should that really be #IndustryStandard, btw?) rather than creating a tiny standalone one? (more below) > --- > Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c | 204 ++++++++++++++++++++ > Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf | 45 +++++ > Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h | 26 +++ > 3 files changed, 275 insertions(+) > > diff --git a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h > new file mode 100644 > index 000000000000..8274e2fe8f77 > --- /dev/null > +++ b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h > @@ -0,0 +1,26 @@ > + /** @file > + * > + * Copyright (c) 2019 Linaro, Ltd. All rights reserved. > + * > + * 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. > + * > + **/ > + > +#ifndef __BCM2836_RNG_H__ > +#define __BCM2836_RNG_H__ > + > +#define RNG_BASE_ADDRESS (BCM2836_SOC_REGISTERS + 0x00104000) If we can't, this file needs to pull in Bcm2836.h anyway. / Leif > + > +#define RNG_CTRL (RNG_BASE_ADDRESS + 0x0) > +#define RNG_STATUS (RNG_BASE_ADDRESS + 0x4) > +#define RNG_DATA (RNG_BASE_ADDRESS + 0x8) > + > +#define RNG_CTRL_ENABLE 0x1 > + > +#endif /* __BCM2836_RNG_H__ */ > -- > 2.20.1 > _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
On Thu, 31 Jan 2019 at 16:05, Leif Lindholm <leif.lindholm@linaro.org> wrote: > > On Wed, Jan 30, 2019 at 08:39:43PM +0100, Ard Biesheuvel wrote: > > Expose the SoC's RNG peripheral via the EFI_RNG_PROTOCOL. > > This is used by Linux to seed the KASLR routines. > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> > > Not tested, but looks fine. Only question: could we add those few > #defines to IndustryStandard/Bcm2836.h (should that really be > #IndustryStandard, btw?) rather than creating a tiny standalone one? > (more below) > Sure. Re IndustryStandard/, I deliberately chose something idiomatic for EDK2, and this is the least inappropriate one. I could live with Chipset/ as well, but dumping headers under Include/ directly is not the solution IMO. > > --- > > Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c | 204 ++++++++++++++++++++ > > Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf | 45 +++++ > > Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h | 26 +++ > > 3 files changed, 275 insertions(+) > > > > > diff --git a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h > > new file mode 100644 > > index 000000000000..8274e2fe8f77 > > --- /dev/null > > +++ b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h > > @@ -0,0 +1,26 @@ > > + /** @file > > + * > > + * Copyright (c) 2019 Linaro, Ltd. All rights reserved. > > + * > > + * 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. > > + * > > + **/ > > + > > +#ifndef __BCM2836_RNG_H__ > > +#define __BCM2836_RNG_H__ > > + > > +#define RNG_BASE_ADDRESS (BCM2836_SOC_REGISTERS + 0x00104000) > > If we can't, this file needs to pull in Bcm2836.h anyway. > Yep. _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
On Thu, Jan 31, 2019 at 06:14:45PM +0100, Ard Biesheuvel wrote: > On Thu, 31 Jan 2019 at 16:05, Leif Lindholm <leif.lindholm@linaro.org> wrote: > > > > On Wed, Jan 30, 2019 at 08:39:43PM +0100, Ard Biesheuvel wrote: > > > Expose the SoC's RNG peripheral via the EFI_RNG_PROTOCOL. > > > This is used by Linux to seed the KASLR routines. > > > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> > > > > Not tested, but looks fine. Only question: could we add those few > > #defines to IndustryStandard/Bcm2836.h (should that really be > > #IndustryStandard, btw?) rather than creating a tiny standalone one? > > (more below) > > > > Sure. > > Re IndustryStandard/, I deliberately chose something idiomatic for > EDK2, and this is the least inappropriate one. I could live with > Chipset/ as well, but dumping headers under Include/ directly is not > the solution IMO. I disagree. Dumping the main SoC header under the top-level SoC directory (and same pattern for platform) is idiomatic. Dumping all kinds of random files there isn't, I agree (although that happens too). BeagleBoardPkg/Include/BeagleBoard.h OvmfPkg/Include/OvmfPlatforms.h Vlv2TbltDevicePkg/Include/Platform.h Silicon/Hisilicon/Hi6220/Include/Hi6220.h An alternative pattern is an include directory named after the SoC/Platform. Omap35xxPkg/Include/Omap3530/ You used Silicon/Socionext/SynQuacer/Include/Platform/ which I also don't mind. If you'd prefer it, I'd be happy with Platform/ and Silicon/. But we'd better settle on something before Pete changes too much based on my feedback. / Leif > > > --- > > > Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c | 204 ++++++++++++++++++++ > > > Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf | 45 +++++ > > > Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h | 26 +++ > > > 3 files changed, 275 insertions(+) > > > > > > > > diff --git a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h > > > new file mode 100644 > > > index 000000000000..8274e2fe8f77 > > > --- /dev/null > > > +++ b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h > > > @@ -0,0 +1,26 @@ > > > + /** @file > > > + * > > > + * Copyright (c) 2019 Linaro, Ltd. All rights reserved. > > > + * > > > + * 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. > > > + * > > > + **/ > > > + > > > +#ifndef __BCM2836_RNG_H__ > > > +#define __BCM2836_RNG_H__ > > > + > > > +#define RNG_BASE_ADDRESS (BCM2836_SOC_REGISTERS + 0x00104000) > > > > If we can't, this file needs to pull in Bcm2836.h anyway. > > > > Yep. _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
On Thu, 31 Jan 2019 at 19:35, Leif Lindholm <leif.lindholm@linaro.org> wrote: > > On Thu, Jan 31, 2019 at 06:14:45PM +0100, Ard Biesheuvel wrote: > > On Thu, 31 Jan 2019 at 16:05, Leif Lindholm <leif.lindholm@linaro.org> wrote: > > > > > > On Wed, Jan 30, 2019 at 08:39:43PM +0100, Ard Biesheuvel wrote: > > > > Expose the SoC's RNG peripheral via the EFI_RNG_PROTOCOL. > > > > This is used by Linux to seed the KASLR routines. > > > > > > > > Contributed-under: TianoCore Contribution Agreement 1.1 > > > > Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> > > > > > > Not tested, but looks fine. Only question: could we add those few > > > #defines to IndustryStandard/Bcm2836.h (should that really be > > > #IndustryStandard, btw?) rather than creating a tiny standalone one? > > > (more below) > > > > > > > Sure. > > > > Re IndustryStandard/, I deliberately chose something idiomatic for > > EDK2, and this is the least inappropriate one. I could live with > > Chipset/ as well, but dumping headers under Include/ directly is not > > the solution IMO. > > I disagree. Dumping the main SoC header under the top-level SoC > directory (and same pattern for platform) is idiomatic. > Dumping all kinds of random files there isn't, I agree (although that > happens too). > > BeagleBoardPkg/Include/BeagleBoard.h > OvmfPkg/Include/OvmfPlatforms.h > Vlv2TbltDevicePkg/Include/Platform.h > > Silicon/Hisilicon/Hi6220/Include/Hi6220.h > > An alternative pattern is an include directory named after the > SoC/Platform. > > Omap35xxPkg/Include/Omap3530/ > > You used > > Silicon/Socionext/SynQuacer/Include/Platform/ > > which I also don't mind. > > If you'd prefer it, I'd be happy with Platform/ and Silicon/. > > But we'd better settle on something before Pete changes too much based > on my feedback. > Yeah. I'll park this until Pete's stuff is merged. _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel
diff --git a/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c new file mode 100644 index 000000000000..b1bc93ce0381 --- /dev/null +++ b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c @@ -0,0 +1,204 @@ +/** @file + + This driver produces an EFI_RNG_PROTOCOL instance for the Broadcom 2836 RNG + + Copyright (C) 2019, 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/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/IoLib.h> +#include <Library/UefiBootServicesTableLib.h> + +#include <IndustryStandard/Bcm2836.h> +#include <IndustryStandard/Bcm2836Rng.h> + +#include <Protocol/Rng.h> + +#define RNG_WARMUP_COUNT 0x40000 +#define RNG_MAX_RETRIES 0x100 // arbitrary upper bound + +/** + 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 +Bcm2836RngGetInfo ( + 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; +} + +/** + 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 +Bcm2836RngGetRNG ( + IN EFI_RNG_PROTOCOL *This, + IN EFI_RNG_ALGORITHM *RNGAlgorithm, OPTIONAL + IN UINTN RNGValueLength, + OUT UINT8 *RNGValue + ) +{ + UINT32 Val; + UINT32 Num; + UINT32 Retries; + + 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; + } + + 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) && Num > 0) { + WriteUnaligned32 ((VOID *)RNGValue, MmioRead32 (RNG_DATA)); + RNGValue += sizeof (UINT32); + RNGValueLength -= sizeof (UINT32); + Num--; + } + + if (RNGValueLength > 0 && Num > 0) { + Val = MmioRead32 (RNG_DATA); + while (RNGValueLength--) { + *RNGValue++ = (UINT8)Val; + Val >>= 8; + } + } + } + return EFI_SUCCESS; +} + +STATIC EFI_RNG_PROTOCOL mBcm2836RngProtocol = { + Bcm2836RngGetInfo, + Bcm2836RngGetRNG +}; + +// +// Entry point of this driver. +// +EFI_STATUS +EFIAPI +Bcm2836RngEntryPoint ( + IN EFI_HANDLE ImageHandle, + IN EFI_SYSTEM_TABLE *SystemTable + ) +{ + EFI_STATUS Status; + + Status = gBS->InstallMultipleProtocolInterfaces (&ImageHandle, + &gEfiRngProtocolGuid, &mBcm2836RngProtocol, + NULL); + ASSERT_EFI_ERROR (Status); + + MmioWrite32 (RNG_STATUS, 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 new file mode 100644 index 000000000000..45e8825244f7 --- /dev/null +++ b/Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf @@ -0,0 +1,45 @@ +#/** @file +# +# Copyright (c) 2019 Linaro, Ltd. All rights reserved. +# +# 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 = 0x0001001B + BASE_NAME = RngDxe + FILE_GUID = 9743084e-c82a-4714-b2ba-f571f81cb021 + MODULE_TYPE = DXE_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = Bcm2836RngEntryPoint + +[Sources] + RngDxe.c + +[Packages] + MdePkg/MdePkg.dec + Silicon/Broadcom/Bcm283x/Bcm283x.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + IoLib + UefiBootServicesTableLib + UefiDriverEntryPoint + +[Protocols] + gEfiRngProtocolGuid ## PRODUCES + +[Guids] + gEfiRngAlgorithmRaw + +[Depex] + TRUE diff --git a/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h new file mode 100644 index 000000000000..8274e2fe8f77 --- /dev/null +++ b/Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h @@ -0,0 +1,26 @@ + /** @file + * + * Copyright (c) 2019 Linaro, Ltd. All rights reserved. + * + * 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. + * + **/ + +#ifndef __BCM2836_RNG_H__ +#define __BCM2836_RNG_H__ + +#define RNG_BASE_ADDRESS (BCM2836_SOC_REGISTERS + 0x00104000) + +#define RNG_CTRL (RNG_BASE_ADDRESS + 0x0) +#define RNG_STATUS (RNG_BASE_ADDRESS + 0x4) +#define RNG_DATA (RNG_BASE_ADDRESS + 0x8) + +#define RNG_CTRL_ENABLE 0x1 + +#endif /* __BCM2836_RNG_H__ */
Expose the SoC's RNG peripheral via the EFI_RNG_PROTOCOL. This is used by Linux to seed the KASLR routines. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> --- Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.c | 204 ++++++++++++++++++++ Silicon/Broadcom/Bcm283x/Drivers/RngDxe/RngDxe.inf | 45 +++++ Silicon/Broadcom/Bcm283x/Include/IndustryStandard/Bcm2836Rng.h | 26 +++ 3 files changed, 275 insertions(+) -- 2.20.1 _______________________________________________ edk2-devel mailing list edk2-devel@lists.01.org https://lists.01.org/mailman/listinfo/edk2-devel