From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-wm1-f68.google.com (mail-wm1-f68.google.com [209.85.128.68]) by mx.groups.io with SMTP id smtpd.web12.5472.1574858244631684979 for ; Wed, 27 Nov 2019 04:37:24 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@akeo-ie.20150623.gappssmtp.com header.s=20150623 header.b=wwP1k9Yu; spf=none, err=permanent DNS error (domain: akeo.ie, ip: 209.85.128.68, mailfrom: pete@akeo.ie) Received: by mail-wm1-f68.google.com with SMTP id p17so1408445wma.1 for ; Wed, 27 Nov 2019 04:37:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=akeo-ie.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=7Q51dqXaEjpglONNqI6d0oSt27IbmBnAgKF6HK/fujQ=; b=wwP1k9YuPfBsGJXNUsaCiX1wFxoCHjnPFxKH9ncqkrklHkHvuugRLUNx6oroceTGyn ITlh/JVeUFi6xbRXQSAjICI8cxk4i/iI9Iwpuqa+zWy0O6dsqQkhpAWGLPH0mw2lKXCk iQUaTcs4H5I2L026u8+kggGRX8TghrjckF6HlOy2IUnyO79YTo63Iiua1mJmwXbAChPR y0EbLwHqgDK9oJVKGdjJGfljy8kGGdnF821PrAxTjWFDLgMRp4H7/3Mmu0h31k5NM/9E MHZmzNgWYIBnJDdggTMqNFOyLzoZ4dJTonKnDBtlg32ZHP4/iJV9TS6n8Dyr44SJzTHG 0UEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=7Q51dqXaEjpglONNqI6d0oSt27IbmBnAgKF6HK/fujQ=; b=QXBEmvqeFcq8J6uFkcW8tsnSVXKCPSRb55S3pQn+khCFRB1MAwF8hqRQaD9KmcuxGP M5/FHds1CeXEkYLvu6cuxn4ruuHXjdqNy1ZPEID9MMWX7YgEaMdnacfYR2m810DOrrfA UmetF8SR+WffhBle9E7xV/E0EkRUYBjPl/sbRs4lZHeGOK1xVLYrsjkHBKb5ViadjQgE ItsK0hlF65jTfhqKAcBaALRrnJLQsrRvmErz/20WcdBkU+biVdpew9Rpw2P/0R8J5G7Q D4jaEAVSh++GTSnrTheavhXLikg5/sFX/x/uIlrDpdj8ZdzTZEPMVpqM2YK+XqQlUO8N weeg== X-Gm-Message-State: APjAAAWgX4i/2YknBGS42i4A1EYTflvIvpU2veavXd23+volsTMOPckn wlBvTwQeWSL2WGx5WrUj1Bx3ciUhk4c= X-Google-Smtp-Source: APXvYqz1J7YD1Tsqdb0jIS8tvWDVemDkimkA9YzUXJhSY09jX7WqivML5RuIjl603dNVtVqTlT60MQ== X-Received: by 2002:a1c:2e09:: with SMTP id u9mr4111508wmu.108.1574858242868; Wed, 27 Nov 2019 04:37:22 -0800 (PST) Return-Path: Received: from localhost.localdomain ([84.203.37.1]) by smtp.gmail.com with ESMTPSA id p9sm18847833wrs.55.2019.11.27.04.37.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 27 Nov 2019 04:37:22 -0800 (PST) From: "Pete Batard" To: devel@edk2.groups.io Cc: ard.biesheuvel@linaro.org, leif.lindholm@linaro.org, philmd@redhat.com, samer.el-haj-mahmoud@arm.com, andrey.warkentin@gmail.com Subject: [edk2-platforms][PATCH 2/5] Silicon/Bcm283x: Add FIFO mode for RNG Date: Wed, 27 Nov 2019 12:37:03 +0000 Message-Id: <20191127123706.4604-3-pete@akeo.ie> X-Mailer: git-send-email 2.21.0.windows.1 In-Reply-To: <20191127123706.4604-1-pete@akeo.ie> References: <20191127123706.4604-1-pete@akeo.ie> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit 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. Signed-off-by: Pete Batard --- 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 Copyright (C) 2019, Linaro Ltd. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -12,6 +13,8 @@ #include #include #include +#include +#include #include #include @@ -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