Skip to content

Commit 8d07f6b

Browse files
tswaehnkartben
authored andcommitted
drivers: entropy: sy1xx add support for trng
Add entropy support for the sensry soc sy1xx, based on trng. Signed-off-by: Sven Ginka <[email protected]>
1 parent 9be79bc commit 8d07f6b

File tree

5 files changed

+186
-0
lines changed

5 files changed

+186
-0
lines changed

drivers/entropy/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,5 +36,6 @@ zephyr_library_sources_ifdef(CONFIG_ENTROPY_PSA_CRYPTO_RNG entropy_psa_crypto.c
3636
zephyr_library_sources_ifdef(CONFIG_ENTROPY_NPCX_DRBG entropy_npcx_drbg.c)
3737
zephyr_library_sources_ifdef(CONFIG_ENTROPY_MAX32_TRNG entropy_max32.c)
3838
zephyr_library_sources_ifdef(CONFIG_ENTROPY_RENESAS_RA entropy_renesas_ra.c)
39+
zephyr_library_sources_ifdef(CONFIG_ENTROPY_SY1XX_TRNG entropy_sy1xx_trng.c)
3940

4041
zephyr_library_link_libraries_ifdef(CONFIG_BUILD_WITH_TFM tfm_api)

drivers/entropy/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ source "drivers/entropy/Kconfig.psa_crypto"
3939
source "drivers/entropy/Kconfig.npcx"
4040
source "drivers/entropy/Kconfig.max32"
4141
source "drivers/entropy/Kconfig.renesas_ra"
42+
source "drivers/entropy/Kconfig.sy1xx"
4243

4344
config ENTROPY_HAS_DRIVER
4445
bool

drivers/entropy/Kconfig.sy1xx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# Copyright (c) 2025 sensry.io
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config ENTROPY_SY1XX_TRNG
5+
bool "Sensry sy1xx soc family true random number generator (TRNG) driver"
6+
default y
7+
depends on DT_HAS_SENSRY_SY1XX_TRNG_ENABLED
8+
select ENTROPY_HAS_DRIVER

drivers/entropy/entropy_sy1xx_trng.c

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/*
2+
* Copyright (c) 2025 sensry.io
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT sensry_sy1xx_trng
8+
9+
#include <zephyr/logging/log.h>
10+
LOG_MODULE_REGISTER(sy1xx_entropy, CONFIG_ENTROPY_LOG_LEVEL);
11+
12+
#include <zephyr/device.h>
13+
#include <zephyr/drivers/entropy.h>
14+
#include <errno.h>
15+
#include <zephyr/init.h>
16+
#include <zephyr/kernel.h>
17+
18+
#define SY1XX_TRNG_VAL_OFFS 0x00
19+
#define SY1XX_TRNG_FIFO_COUNT_OFFS 0x04
20+
#define SY1XX_TRNG_STATUS_OFFS 0x08
21+
#define SY1XX_TRNG_ERROR_OFFS 0x0c
22+
23+
#define SY1XX_TRNG_FIFO_SIZE 64
24+
25+
/* time needed to fill fifo when empty */
26+
#define SY1XX_TRNG_FIFO_REFILL_TIME_USEC 80
27+
#define SY1XX_TRNG_FIFO_REFILL_MAX_RETRIES 5
28+
29+
struct sy1xx_trng_config {
30+
uint32_t base_addr;
31+
};
32+
33+
struct sy1xx_trng_data {
34+
struct k_mutex mutex;
35+
};
36+
37+
static int sy1xx_trng_driver_init(const struct device *dev)
38+
{
39+
const struct sy1xx_trng_config *const cfg = dev->config;
40+
struct sy1xx_trng_data *const data = dev->data;
41+
42+
k_mutex_init(&data->mutex);
43+
44+
/* trng comes up fully initialized, so only check if all is fine */
45+
if (0 != sys_read32(cfg->base_addr + SY1XX_TRNG_ERROR_OFFS)) {
46+
LOG_ERR("failure mode active, internal init failed");
47+
return -EINVAL;
48+
}
49+
50+
if (SY1XX_TRNG_FIFO_SIZE != sys_read32(cfg->base_addr + SY1XX_TRNG_FIFO_COUNT_OFFS)) {
51+
LOG_ERR("fifo not fully loaded");
52+
return -EINVAL;
53+
}
54+
55+
return 0;
56+
}
57+
58+
static int sy1xx_trng_driver_get_entropy(const struct device *dev, uint8_t *buffer, uint16_t length)
59+
{
60+
const struct sy1xx_trng_config *const cfg = dev->config;
61+
struct sy1xx_trng_data *const data = dev->data;
62+
uint32_t retries_left;
63+
uint32_t random_word;
64+
65+
uint32_t word_count = DIV_ROUND_UP(length, 4);
66+
67+
for (uint32_t i = 0; i < word_count; i++) {
68+
retries_left = SY1XX_TRNG_FIFO_REFILL_MAX_RETRIES;
69+
70+
k_mutex_lock(&data->mutex, K_FOREVER);
71+
while (true) {
72+
/* make sure fifo has at least one random word */
73+
if (sys_read32(cfg->base_addr + SY1XX_TRNG_FIFO_COUNT_OFFS) > 0) {
74+
/* get new random word */
75+
random_word = sys_read32(cfg->base_addr + SY1XX_TRNG_VAL_OFFS);
76+
break;
77+
}
78+
79+
/* currently no random values available, thus wait */
80+
retries_left--;
81+
if (!retries_left) {
82+
/* number of retries exhausted, give up */
83+
k_mutex_unlock(&data->mutex);
84+
return -ETIMEDOUT;
85+
}
86+
k_sleep(K_USEC(SY1XX_TRNG_FIFO_REFILL_TIME_USEC));
87+
};
88+
k_mutex_unlock(&data->mutex);
89+
90+
memcpy(&buffer[i * 4], &random_word, MIN(length, 4));
91+
length -= 4;
92+
}
93+
94+
/* always error check, to make sure that we received valid readings */
95+
if (0 != sys_read32(cfg->base_addr + SY1XX_TRNG_ERROR_OFFS)) {
96+
LOG_ERR("failure mode active, reading of values failed");
97+
return -EINVAL;
98+
}
99+
100+
return 0;
101+
}
102+
103+
static int sy1xx_trng_driver_get_entropy_isr(const struct device *dev, uint8_t *buffer,
104+
uint16_t length, uint32_t flags)
105+
{
106+
107+
const struct sy1xx_trng_config *const cfg = dev->config;
108+
unsigned int key;
109+
uint32_t random_word;
110+
int ret;
111+
112+
uint32_t word_count = DIV_ROUND_UP(length, 4);
113+
114+
for (uint32_t i = 0; i < word_count; i++) {
115+
116+
do {
117+
key = irq_lock();
118+
/* make sure fifo has at least one random word */
119+
if (sys_read32(cfg->base_addr + SY1XX_TRNG_FIFO_COUNT_OFFS) > 0) {
120+
/* get new random word */
121+
random_word = sys_read32(cfg->base_addr + SY1XX_TRNG_VAL_OFFS);
122+
ret = 0;
123+
} else {
124+
ret = -EAGAIN;
125+
}
126+
irq_unlock(key);
127+
128+
if (ret && !(flags & ENTROPY_BUSYWAIT)) {
129+
/* no waiting allowed */
130+
return ret;
131+
}
132+
133+
} while (ret);
134+
135+
memcpy(&buffer[i * 4], &random_word, MIN(length, 4));
136+
length -= 4;
137+
}
138+
139+
/* always error check, to make sure that we received valid readings */
140+
if (0 != sys_read32(cfg->base_addr + SY1XX_TRNG_ERROR_OFFS)) {
141+
LOG_ERR("failure mode active, reading of values failed");
142+
return -EINVAL;
143+
}
144+
145+
return 0;
146+
}
147+
148+
static DEVICE_API(entropy,
149+
sy1xx_entropy_api) = {.get_entropy = sy1xx_trng_driver_get_entropy,
150+
.get_entropy_isr = sy1xx_trng_driver_get_entropy_isr};
151+
152+
#define SY1XX_TRNG_INIT(n) \
153+
\
154+
static const struct sy1xx_trng_config sy1xx_trng##n##_cfg = { \
155+
.base_addr = (uint32_t)DT_INST_REG_ADDR(n), \
156+
}; \
157+
\
158+
static struct sy1xx_trng_data sy1xx_trng##n##_data = {}; \
159+
\
160+
DEVICE_DT_INST_DEFINE(n, sy1xx_trng_driver_init, NULL, &sy1xx_trng##n##_data, \
161+
&sy1xx_trng##n##_cfg, PRE_KERNEL_1, CONFIG_ENTROPY_INIT_PRIORITY, \
162+
&sy1xx_entropy_api);
163+
164+
DT_INST_FOREACH_STATUS_OKAY(SY1XX_TRNG_INIT)
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# Copyright (c) 2025 sensry.io
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
description: Sensry SY1XX TRNG node
5+
6+
compatible: "sensry,sy1xx-trng"
7+
8+
include: base.yaml
9+
10+
properties:
11+
reg:
12+
required: true

0 commit comments

Comments
 (0)