summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicolas Boichat <drinkcat@chromium.org>2018-07-09 15:59:24 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-07-10 23:45:51 -0700
commit6e8bc42dbd8710b99cdba92c40a1aec1eabcb0d6 (patch)
treeea379ac88bf4ef2ef866bc37c3a896bfd3cd1a8b
parente0abbbb5f8bd54ac7586df334979e7cd57df7802 (diff)
downloadchrome-ec-6e8bc42dbd8710b99cdba92c40a1aec1eabcb0d6.tar.gz
stm32h7: Add support for TRNG
STM32H7 contains a True Random Number Generator. Add support for that. We source rng_clk from HSI48 oscillator (confusingly misspelled hsi8_clk in RM), and fine-tune number of tries to make sure we wait long enough for a random number, no matter the CPU speed (64 or 400 MHz). We also add a console command to test the random number generator (disabled by default). BRANCH=none BUG=b:111190988 TEST=reboot; clock pll; rand => works. TEST=reboot; rand => works. Change-Id: I45624ff4df30b6a332226245e02e3e435b9b15bf Signed-off-by: Nicolas Boichat <drinkcat@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/1128785 Reviewed-by: Randall Spangler <rspangler@chromium.org>
-rw-r--r--chip/stm32/registers.h12
-rw-r--r--chip/stm32/trng.c38
-rw-r--r--include/config.h1
3 files changed, 50 insertions, 1 deletions
diff --git a/chip/stm32/registers.h b/chip/stm32/registers.h
index 37a49da00a..2028aa9325 100644
--- a/chip/stm32/registers.h
+++ b/chip/stm32/registers.h
@@ -411,6 +411,7 @@
#define STM32_PWR_BASE 0x58024800
#define STM32_RCC_BASE 0x58024400
+#define STM32_RNG_BASE 0x48021800
#define STM32_RTC_BASE 0x58004000
#define STM32_SYSCFG_BASE 0x58000400
@@ -1411,6 +1412,9 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define STM32_RCC_AHB3ENR REG32(STM32_RCC_BASE + 0x0D4)
#define STM32_RCC_AHB1ENR REG32(STM32_RCC_BASE + 0x0D8)
#define STM32_RCC_AHB2ENR REG32(STM32_RCC_BASE + 0x0DC)
+#define STM32_RCC_AHB2ENR_RNGEN (1 << 6)
+#define STM32_RCC_AHB2ENR_HASHEN (1 << 5)
+#define STM32_RCC_AHB2ENR_CRYPTEN (1 << 4)
#define STM32_RCC_AHB4ENR REG32(STM32_RCC_BASE + 0x0E0)
#define STM32_RCC_AHB4ENR_GPIOMASK 0x3ff
#define STM32_RCC_APB3ENR REG32(STM32_RCC_BASE + 0x0E4)
@@ -1435,6 +1439,8 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define STM32_RCC_CR_HSIRDY (1 << 2)
#define STM32_RCC_CR_CSION (1 << 7)
#define STM32_RCC_CR_CSIRDY (1 << 8)
+#define STM32_RCC_CR_HSI48ON (1 << 12)
+#define STM32_RCC_CR_HSI48RDY (1 << 13)
#define STM32_RCC_CR_PLL1ON (1 << 24)
#define STM32_RCC_CR_PLL1RDY (1 << 25)
#define STM32_RCC_CR_PLL2ON (1 << 26)
@@ -1516,6 +1522,11 @@ typedef volatile struct timer_ctlr timer_ctlr_t;
#define STM32_RCC_D2CCIP2_USART16SEL_CSI (4 << 3)
#define STM32_RCC_D2CCIP2_USART16SEL_LSE (5 << 3)
#define STM32_RCC_D2CCIP2_USART16SEL_MASK (7 << 3)
+#define STM32_RCC_D2CCIP2_RNGSEL_HSI48 (0 << 8)
+#define STM32_RCC_D2CCIP2_RNGSEL_PLL1Q (1 << 8)
+#define STM32_RCC_D2CCIP2_RNGSEL_LSE (2 << 8)
+#define STM32_RCC_D2CCIP2_RNGSEL_LSI (3 << 8)
+#define STM32_RCC_D2CCIP2_RNGSEL_MASK (3 << 8)
#define STM32_RCC_D2CCIP2_LPTIM1SEL_PCLK (0 << 28)
#define STM32_RCC_D2CCIP2_LPTIM1SEL_PLL2 (1 << 28)
#define STM32_RCC_D2CCIP2_LPTIM1SEL_PLL3 (2 << 28)
@@ -3049,6 +3060,7 @@ enum dmamux1_request {
#define STM32_RNG_CR REG32(STM32_RNG_BASE + 0x0)
#define STM32_RNG_CR_RNGEN (1<<2)
#define STM32_RNG_CR_IE (1<<3)
+#define STM32_RNG_CR_CED (1<<5)
#define STM32_RNG_SR REG32(STM32_RNG_BASE + 0x4)
#define STM32_RNG_SR_DRDY (1<<0)
#define STM32_RNG_DR REG32(STM32_RNG_BASE + 0x8)
diff --git a/chip/stm32/trng.c b/chip/stm32/trng.c
index e19f93d688..7799c03f93 100644
--- a/chip/stm32/trng.c
+++ b/chip/stm32/trng.c
@@ -6,6 +6,7 @@
/* Hardware Random Number Generator */
#include "common.h"
+#include "console.h"
#include "panic.h"
#include "registers.h"
#include "task.h"
@@ -14,7 +15,7 @@
uint32_t rand(void)
{
- int tries = 40;
+ int tries = 300;
/* Wait for a valid random number */
while (!(STM32_RNG_SR & STM32_RNG_SR_DRDY) && --tries)
;
@@ -46,6 +47,7 @@ void rand_bytes(void *buffer, size_t len)
void init_trng(void)
{
+#ifdef CHIP_FAMILY_STM32L4
/* Enable the 48Mhz internal RC oscillator */
STM32_RCC_CRRCR |= STM32_RCC_CRRCR_HSI48ON;
/* no timeout: we watchdog if the oscillator doesn't start */
@@ -55,7 +57,20 @@ void init_trng(void)
/* Clock the TRNG using the HSI48 */
STM32_RCC_CCIPR = (STM32_RCC_CCIPR & ~STM32_RCC_CCIPR_CLK48SEL_MASK)
| (0 << STM32_RCC_CCIPR_CLK48SEL_SHIFT);
+#elif defined(CHIP_FAMILY_STM32H7)
+ /* Enable the 48Mhz internal RC oscillator */
+ STM32_RCC_CR |= STM32_RCC_CR_HSI48ON;
+ /* no timeout: we watchdog if the oscillator doesn't start */
+ while (!(STM32_RCC_CR & STM32_RCC_CR_HSI48RDY))
+ ;
+ /* Clock the TRNG using the HSI48 */
+ STM32_RCC_D2CCIP2R =
+ (STM32_RCC_D2CCIP2R & ~STM32_RCC_D2CCIP2_RNGSEL_MASK)
+ | STM32_RCC_D2CCIP2_RNGSEL_HSI48;
+#else
+#error "Please add support for CONFIG_RNG on this chip family."
+#endif
/* Enable the RNG logic */
STM32_RCC_AHB2ENR |= STM32_RCC_AHB2ENR_RNGEN;
/* Start the random number generation */
@@ -66,5 +81,26 @@ void exit_trng(void)
{
STM32_RNG_CR &= ~STM32_RNG_CR_RNGEN;
STM32_RCC_AHB2ENR &= ~STM32_RCC_AHB2ENR_RNGEN;
+#ifdef CHIP_FAMILY_STM32L4
STM32_RCC_CRRCR &= ~STM32_RCC_CRRCR_HSI48ON;
+#elif defined(CHIP_FAMILY_STM32H7)
+ STM32_RCC_CR &= ~STM32_RCC_CR_HSI48ON;
+#endif
+}
+
+#ifdef CONFIG_CMD_RAND
+static int command_rand(int argc, char **argv)
+{
+ uint8_t data[32];
+
+ init_trng();
+ rand_bytes(data, sizeof(data));
+ exit_trng();
+
+ ccprintf("rand %.*h\n", sizeof(data), data);
+
+ return EC_SUCCESS;
}
+DECLARE_CONSOLE_COMMAND(rand, command_rand,
+ NULL, "Output random bytes to console.");
+#endif
diff --git a/include/config.h b/include/config.h
index bc84b4ee3f..7a0eadd75b 100644
--- a/include/config.h
+++ b/include/config.h
@@ -920,6 +920,7 @@
#define CONFIG_CMD_PWR_AVG
#define CONFIG_CMD_POWER_AP
#undef CONFIG_CMD_PPC_DUMP
+#undef CONFIG_CMD_RAND
#define CONFIG_CMD_REGULATOR
#undef CONFIG_CMD_RTC
#undef CONFIG_CMD_RTC_ALARM