diff --git a/CODEOWNERS b/CODEOWNERS index 05511e5d28c..3c682da6dcb 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -142,6 +142,7 @@ /drivers/eeprom/ @henrikbrixandersen /drivers/eeprom/eeprom_stm32.c @KwonTae-young /drivers/entropy/*rv32m1* @MaureenHelm +/drivers/entropy/*gecko* @chrta /drivers/espi/ @albertofloyd @franciscomunoz @scottwcpg /drivers/ps2/ @albertofloyd @franciscomunoz @scottwcpg /drivers/kscan/ @albertofloyd @franciscomunoz @scottwcpg diff --git a/boards/arm/efm32pg_stk3402a/doc/index.rst b/boards/arm/efm32pg_stk3402a/doc/index.rst index 18c00c61cec..5d91d7d615c 100644 --- a/boards/arm/efm32pg_stk3402a/doc/index.rst +++ b/boards/arm/efm32pg_stk3402a/doc/index.rst @@ -61,6 +61,8 @@ The efm32pg_stk3402a board configuration supports the following hardware feature +-----------+------------+-------------------------------------+ | WATCHDOG | on-chip | watchdog | +-----------+------------+-------------------------------------+ +| TRNG | on-chip | true random number generator | ++-----------+------------+-------------------------------------+ The default configuration can be found in the defconfig file: diff --git a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi index ab2e1f15a61..f68921fe49e 100644 --- a/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi +++ b/boards/arm/efm32pg_stk3402a/efm32pg_stk3402a_common.dtsi @@ -113,3 +113,7 @@ }; }; + +&trng0 { + status = "okay"; +}; diff --git a/boards/arm/efr32mg_sltb004a/doc/index.rst b/boards/arm/efr32mg_sltb004a/doc/index.rst index 7d2bce192d8..c5cdc14c34b 100644 --- a/boards/arm/efr32mg_sltb004a/doc/index.rst +++ b/boards/arm/efr32mg_sltb004a/doc/index.rst @@ -79,6 +79,8 @@ The efr32mg_sltb004a board configuration supports the following hardware feature +-----------+------------+-------------------------------------+ | WATCHDOG | on-chip | watchdog | +-----------+------------+-------------------------------------+ +| TRNG | on-chip | true random number generator | ++-----------+------------+-------------------------------------+ The default configuration can be found in the defconfig file: ``boards/arm/efr32mg_sltb004a/efr32mg_sltb004a_defconfig``. diff --git a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts index 3880e51a21b..5501026a142 100644 --- a/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts +++ b/boards/arm/efr32mg_sltb004a/efr32mg_sltb004a.dts @@ -146,3 +146,7 @@ }; }; + +&trng0 { + status = "okay"; +}; diff --git a/drivers/entropy/CMakeLists.txt b/drivers/entropy/CMakeLists.txt index 7299431d2fa..c4e0f11ff90 100644 --- a/drivers/entropy/CMakeLists.txt +++ b/drivers/entropy/CMakeLists.txt @@ -13,3 +13,4 @@ zephyr_library_sources_ifdef(CONFIG_ENTROPY_LITEX_RNG entropy_litex.c) zephyr_library_sources_ifdef(CONFIG_FAKE_ENTROPY_NATIVE_POSIX fake_entropy_native_posix.c) zephyr_library_sources_ifdef(CONFIG_USERSPACE entropy_handlers.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_RV32M1_TRNG entropy_rv32m1_trng.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_GECKO_TRNG entropy_gecko_trng.c) diff --git a/drivers/entropy/Kconfig b/drivers/entropy/Kconfig index 3d3f6f4bba7..900cc619d94 100644 --- a/drivers/entropy/Kconfig +++ b/drivers/entropy/Kconfig @@ -19,6 +19,7 @@ source "drivers/entropy/Kconfig.sam" source "drivers/entropy/Kconfig.native_posix" source "drivers/entropy/Kconfig.rv32m1" source "drivers/entropy/Kconfig.litex" +source "drivers/entropy/Kconfig.gecko" config ENTROPY_HAS_DRIVER bool diff --git a/drivers/entropy/Kconfig.gecko b/drivers/entropy/Kconfig.gecko new file mode 100644 index 00000000000..0037d09dece --- /dev/null +++ b/drivers/entropy/Kconfig.gecko @@ -0,0 +1,14 @@ +# gecko entropy generator driver configuration + +# Copyright (c) 2020 Lemonbeat GmbH +# SPDX-License-Identifier: Apache-2.0 + +config ENTROPY_GECKO_TRNG + bool "GECKO TRNG driver" + depends on SOC_GECKO_TRNG + select ENTROPY_HAS_DRIVER + select HAS_DTS_ENTROPY + default y + help + This option enables the true random number generator + driver based on the TRNG. diff --git a/drivers/entropy/entropy_gecko_trng.c b/drivers/entropy/entropy_gecko_trng.c new file mode 100644 index 00000000000..a710ac97c38 --- /dev/null +++ b/drivers/entropy/entropy_gecko_trng.c @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2020 Lemonbeat GmbH + * + * SPDX-License-Identifier: Apache-2.0 + */ + + #include + #include + #include "soc.h" + #include "em_cmu.h" + +static void entropy_gecko_trng_read(u8_t *output, size_t len) +{ + u32_t tmp; + u32_t *data = (u32_t *) output; + + /* Read known good available data. */ + while (len >= 4) { + *data++ = TRNG0->FIFO; + len -= 4; + } + if (len > 0) { + /* Handle the case where len is not a multiple of 4 + * and FIFO data is available. + */ + tmp = TRNG0->FIFO; + memcpy(data, (const u8_t *) &tmp, len); + } +} + +static int entropy_gecko_trng_get_entropy(struct device *dev, u8_t *buffer, + u16_t length) +{ + size_t count = 0; + size_t available; + + ARG_UNUSED(dev); + + while (length) { + available = TRNG0->FIFOLEVEL * 4; + if (available == 0) { + return -EINVAL; + } + + count = SL_MIN(length, available); + entropy_gecko_trng_read(buffer, count); + buffer += count; + length -= count; + } + + return 0; +} + +static int entropy_gecko_trng_init(struct device *device) +{ + /* Enable the TRNG0 clock. */ + CMU_ClockEnable(cmuClock_TRNG0, true); + + /* Enable TRNG0. */ + TRNG0->CONTROL = TRNG_CONTROL_ENABLE; + return 0; +} + +static struct entropy_driver_api entropy_gecko_trng_api_funcs = { + .get_entropy = entropy_gecko_trng_get_entropy +}; + +DEVICE_AND_API_INIT(entropy_gecko_trng, CONFIG_ENTROPY_NAME, + entropy_gecko_trng_init, NULL, NULL, + PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEVICE, + &entropy_gecko_trng_api_funcs); diff --git a/dts/arm/silabs/efm32_jg_pg_12b.dtsi b/dts/arm/silabs/efm32_jg_pg_12b.dtsi index 03bbd6338aa..765092cacb6 100644 --- a/dts/arm/silabs/efm32_jg_pg_12b.dtsi +++ b/dts/arm/silabs/efm32_jg_pg_12b.dtsi @@ -218,6 +218,14 @@ interrupts = <3 0>; status = "disabled"; }; + + trng0: trng@4001d000 { + compatible = "silabs,gecko-trng"; + reg = <0x4001d000 0x400>; + interrupts = <49 0>; + label = "TRNG0"; + status = "disabled"; + }; }; }; }; diff --git a/dts/arm/silabs/efr32mg.dtsi b/dts/arm/silabs/efr32mg.dtsi index 2285e8a9bf8..8629de31c24 100644 --- a/dts/arm/silabs/efr32mg.dtsi +++ b/dts/arm/silabs/efr32mg.dtsi @@ -210,6 +210,14 @@ interrupts = <3 0>; status = "disabled"; }; + + trng0: trng@4001d000 { + compatible = "silabs,gecko-trng"; + reg = <0x4001d000 0x400>; + interrupts = <49 0>; + label = "TRNG0"; + status = "disabled"; + }; }; }; diff --git a/dts/bindings/rng/silabs,gecko-trng.yaml b/dts/bindings/rng/silabs,gecko-trng.yaml new file mode 100644 index 00000000000..f89d4bf6060 --- /dev/null +++ b/dts/bindings/rng/silabs,gecko-trng.yaml @@ -0,0 +1,21 @@ +# Copyright (c) 2020, Lemonbeat GmbH +# SPDX-License-Identifier: Apache-2.0 + +description: | + GECKO TRNG (True Random Number Generator). + + The TRNG module is a non-deterministic randomnumber generator based on a full hardware solution. + +compatible: "silabs,gecko-trng" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + label: + required: true diff --git a/soc/arm/silabs_exx32/Kconfig b/soc/arm/silabs_exx32/Kconfig index abeea71b39b..65ba2985ce8 100644 --- a/soc/arm/silabs_exx32/Kconfig +++ b/soc/arm/silabs_exx32/Kconfig @@ -97,6 +97,11 @@ config SOC_GECKO_WDOG help Set if the Watchdog Timer (WDOG) HAL module is used. +config SOC_GECKO_TRNG + bool + help + Set if the SoC has a True Random Number Generator (TRNG) module. + config SOC_GECKO_EMU_DCDC bool "Enable SoC DC/DC regulator" select SOC_GECKO_EMU diff --git a/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series b/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series index b4f052ecf52..ba50bd58061 100644 --- a/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32jg12b/Kconfig.series @@ -18,5 +18,6 @@ config SOC_SERIES_EFM32JG12B select SOC_GECKO_CMU select SOC_GECKO_EMU select SOC_GECKO_GPIO + select SOC_GECKO_TRNG help Enable support for EFM32 JadeGecko MCU series diff --git a/soc/arm/silabs_exx32/efm32jg12b/dts_fixup.h b/soc/arm/silabs_exx32/efm32jg12b/dts_fixup.h index 9f371934619..ef51e360505 100644 --- a/soc/arm/silabs_exx32/efm32jg12b/dts_fixup.h +++ b/soc/arm/silabs_exx32/efm32jg12b/dts_fixup.h @@ -31,5 +31,6 @@ #define DT_WDT_0_NAME DT_INST_0_SILABS_GECKO_WDOG_LABEL #define DT_WDT_1_NAME DT_INST_1_SILABS_GECKO_WDOG_LABEL +#define CONFIG_ENTROPY_NAME DT_SILABS_GECKO_TRNG_4001D000_LABEL /* End of SoC Level DTS fixup file */ diff --git a/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series b/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series index 286ea4c8c86..d1e9a86b9bd 100644 --- a/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series +++ b/soc/arm/silabs_exx32/efm32pg12b/Kconfig.series @@ -20,5 +20,6 @@ config SOC_SERIES_EFM32PG12B select SOC_GECKO_CMU select SOC_GECKO_EMU select SOC_GECKO_GPIO + select SOC_GECKO_TRNG help Enable support for EFM32 PearlGecko MCU series diff --git a/soc/arm/silabs_exx32/efm32pg12b/dts_fixup.h b/soc/arm/silabs_exx32/efm32pg12b/dts_fixup.h index 8873b8e1a31..9aeb530c276 100644 --- a/soc/arm/silabs_exx32/efm32pg12b/dts_fixup.h +++ b/soc/arm/silabs_exx32/efm32pg12b/dts_fixup.h @@ -31,5 +31,6 @@ #define DT_WDT_0_NAME DT_INST_0_SILABS_GECKO_WDOG_LABEL #define DT_WDT_1_NAME DT_INST_1_SILABS_GECKO_WDOG_LABEL +#define CONFIG_ENTROPY_NAME DT_SILABS_GECKO_TRNG_4001D000_LABEL /* End of SoC Level DTS fixup file */ diff --git a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series index 29162f27dac..be9aab29f74 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series +++ b/soc/arm/silabs_exx32/efr32mg12p/Kconfig.series @@ -21,5 +21,6 @@ config SOC_SERIES_EFR32MG12P select SOC_GECKO_CMU select SOC_GECKO_EMU select SOC_GECKO_GPIO + select SOC_GECKO_TRNG help Enable support for EFR32 Mighty Gecko MCU series diff --git a/soc/arm/silabs_exx32/efr32mg12p/dts_fixup.h b/soc/arm/silabs_exx32/efr32mg12p/dts_fixup.h index 9969f6c7521..95371cde668 100644 --- a/soc/arm/silabs_exx32/efr32mg12p/dts_fixup.h +++ b/soc/arm/silabs_exx32/efr32mg12p/dts_fixup.h @@ -32,5 +32,6 @@ #define DT_WDT_0_NAME DT_INST_0_SILABS_GECKO_WDOG_LABEL #define DT_WDT_1_NAME DT_INST_1_SILABS_GECKO_WDOG_LABEL +#define CONFIG_ENTROPY_NAME DT_SILABS_GECKO_TRNG_4001D000_LABEL /* End of SoC Level DTS fixup file */