diff --git a/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.dts b/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.dts index 8dd66453b9c1f..0d4780b907d89 100644 --- a/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.dts +++ b/boards/sifli/sf32lb52_devkit_lcd/sf32lb52_devkit_lcd.dts @@ -24,6 +24,7 @@ zephyr,code-partition = &code; zephyr,console = &usart1; zephyr,shell-uart = &usart1; + zephyr,entropy = &trng; }; buttons { @@ -153,3 +154,7 @@ temp_sensor: &tsen { status = "okay"; }; + +&trng { + status = "okay"; +}; diff --git a/drivers/entropy/CMakeLists.txt b/drivers/entropy/CMakeLists.txt index 91d26519a8e90..334c39a9e5d55 100644 --- a/drivers/entropy/CMakeLists.txt +++ b/drivers/entropy/CMakeLists.txt @@ -37,6 +37,7 @@ zephyr_library_sources_ifdef(CONFIG_ENTROPY_PSA_CRYPTO_RNG entropy_psa_crypto.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_RENESAS_RA entropy_renesas_ra.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_RV32M1_TRNG entropy_rv32m1_trng.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_SAM_RNG entropy_sam.c) +zephyr_library_sources_ifdef(CONFIG_ENTROPY_SF32LB entropy_sf32lb.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_SILABS_SIWX91X entropy_silabs_siwx91x.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_SMARTBOND_TRNG entropy_smartbond.c) zephyr_library_sources_ifdef(CONFIG_ENTROPY_STM32_RNG entropy_stm32.c) diff --git a/drivers/entropy/Kconfig b/drivers/entropy/Kconfig index 021c47dc29198..c5178f9f6a667 100644 --- a/drivers/entropy/Kconfig +++ b/drivers/entropy/Kconfig @@ -43,6 +43,7 @@ source "drivers/entropy/Kconfig.psa_crypto" source "drivers/entropy/Kconfig.renesas_ra" source "drivers/entropy/Kconfig.rv32m1" source "drivers/entropy/Kconfig.sam" +source "drivers/entropy/Kconfig.sf32lb" source "drivers/entropy/Kconfig.siwx91x" source "drivers/entropy/Kconfig.smartbond" source "drivers/entropy/Kconfig.stm32" diff --git a/drivers/entropy/Kconfig.sf32lb b/drivers/entropy/Kconfig.sf32lb new file mode 100644 index 0000000000000..72bab709662b3 --- /dev/null +++ b/drivers/entropy/Kconfig.sf32lb @@ -0,0 +1,10 @@ +# Copyright (c) 2025, Qingsong Gou +# SPDX-License-Identifier: Apache-2.0 + +config ENTROPY_SF32LB + bool "SF32LB Entropy driver" + default y + depends on DT_HAS_SIFLI_SF32LB_TRNG_ENABLED + select ENTROPY_HAS_DRIVER + help + Enable driver for SF32LB True Random Number Generator (TRNG). diff --git a/drivers/entropy/entropy_sf32lb.c b/drivers/entropy/entropy_sf32lb.c new file mode 100644 index 0000000000000..4bc9369643ea3 --- /dev/null +++ b/drivers/entropy/entropy_sf32lb.c @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2025 Qingsong Gou + * SPDX-License-Identifier: Apache-2.0 + */ +#define DT_DRV_COMPAT sifli_sf32lb_trng + +#include +#include +#include +#include +#include + +#include + +LOG_MODULE_REGISTER(entropy_sf32lb, CONFIG_ENTROPY_LOG_LEVEL); + +#define TRNG_CTRL offsetof(TRNG_TypeDef, CTRL) +#define TRNG_STAT offsetof(TRNG_TypeDef, STAT) +#define TRNG_RAND offsetof(TRNG_TypeDef, RAND_NUM0) + +#define TRNG_RAND_NUM_MAX (8U) + +#define TRNG_RAND_MASK (TRNG_RAND_NUM_MAX - 1U) + +struct entropy_sf32lb_config { + uintptr_t base; + struct sf32lb_clock_dt_spec clock; +}; + +static int entropy_sf32lb_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t length) +{ + const struct entropy_sf32lb_config *config = dev->config; + uint32_t buf[TRNG_RAND_NUM_MAX]; + uint16_t bytes; + + while (length) { + sys_set_bit(config->base + TRNG_CTRL, TRNG_CTRL_GEN_SEED_START_Pos); + while (!sys_test_bit(config->base + TRNG_STAT, TRNG_STAT_SEED_VALID_Pos)) { + } + + /* Generate random data */ + sys_set_bit(config->base + TRNG_CTRL, TRNG_CTRL_GEN_RAND_NUM_START_Pos); + while (!sys_test_bit(config->base + TRNG_STAT, TRNG_STAT_RAND_NUM_VALID_Pos)) { + } + + for (uint8_t i = 0U; i < TRNG_RAND_NUM_MAX; i++) { + buf[i] = sys_read32(config->base + TRNG_RAND + (i * 4U)); + } + + bytes = MIN(length, sizeof(buf)); + + memcpy(buffer, buf, bytes); + + length -= bytes; + buffer += bytes; + } + + return 0; +} + +static DEVICE_API(entropy, entropy_sf32lb_api) = { + .get_entropy = entropy_sf32lb_get_entropy, +}; + +static int entropy_sf32lb_init(const struct device *dev) +{ + const struct entropy_sf32lb_config *config = dev->config; + + if (!sf32lb_clock_is_ready_dt(&config->clock)) { + return -ENODEV; + } + + return sf32lb_clock_control_on_dt(&config->clock); +} + +#define ENTROPY_SF32LB_DEFINE(n) \ + static const struct entropy_sf32lb_config entropy_sf32lb_config_##n = { \ + .base = DT_INST_REG_ADDR(n), \ + .clock = SF32LB_CLOCK_DT_INST_SPEC_GET(n), \ + }; \ + \ + DEVICE_DT_INST_DEFINE(n, entropy_sf32lb_init, NULL, NULL, \ + &entropy_sf32lb_config_##n, PRE_KERNEL_1, \ + CONFIG_ENTROPY_INIT_PRIORITY, &entropy_sf32lb_api); + +DT_INST_FOREACH_STATUS_OKAY(ENTROPY_SF32LB_DEFINE) diff --git a/dts/arm/sifli/sf32lb52x.dtsi b/dts/arm/sifli/sf32lb52x.dtsi index fb12fbb34c815..7e51b63117cd1 100644 --- a/dts/arm/sifli/sf32lb52x.dtsi +++ b/dts/arm/sifli/sf32lb52x.dtsi @@ -105,6 +105,14 @@ status = "disabled"; }; + trng: trng@5000f000 { + compatible = "sifli,sf32lb-trng"; + reg = <0x5000f000 0x1000>; + clocks = <&rcc_clk SF32LB52X_CLOCK_TRNG>; + interrupts = <69 0>; + status = "disabled"; + }; + mpi1: memory-controller@50041000 { /* * configure compatible depending on memory type, choices: diff --git a/dts/bindings/rng/sifli,sf32lb-trng.yaml b/dts/bindings/rng/sifli,sf32lb-trng.yaml new file mode 100644 index 0000000000000..22b43df4f713c --- /dev/null +++ b/dts/bindings/rng/sifli,sf32lb-trng.yaml @@ -0,0 +1,18 @@ +# Copyright (c) 2025, Qingsong Gou +# SPDX-License-Identifier: Apache-2.0 + +description: Sifli SF32LB TRNG (True Random Number Generator). + +compatible: "sifli,sf32lb-trng" + +include: base.yaml + +properties: + reg: + required: true + + interrupts: + required: true + + clocks: + required: true