Skip to content

Commit d00a734

Browse files
RichardSWheatleyjhedberg
authored andcommitted
drivers: entropy: add puf-trng entropy driver
add puf-trng entropy driver to apollo510 Signed-off-by: Richard Wheatley <[email protected]>
1 parent b70e761 commit d00a734

File tree

8 files changed

+153
-0
lines changed

8 files changed

+153
-0
lines changed

boards/ambiq/apollo510_evb/apollo510_evb.dts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
zephyr,console = &uart0;
1616
zephyr,shell-uart = &uart0;
1717
zephyr,uart-pipe = &uart0;
18+
zephyr,entropy = &trng;
1819
ambiq,xo32m = &xo32m_xtal;
1920
ambiq,xo32k = &xo32k_xtal;
2021
ambiq,extrefclk = &extrefclk;
@@ -90,6 +91,10 @@
9091
};
9192
};
9293

94+
&trng {
95+
status = "okay";
96+
};
97+
9398
&xo32m_xtal {
9499
clock-frequency = <DT_FREQ_M(48)>;
95100
};

drivers/entropy/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ endif()
1212
zephyr_library_sources_ifdef(CONFIG_USERSPACE entropy_handlers.c)
1313

1414
# zephyr-keep-sorted-start
15+
zephyr_library_sources_ifdef(CONFIG_ENTROPY_AMBIQ_PUF_TRNG entropy_ambiq_puf_trng.c)
1516
zephyr_library_sources_ifdef(CONFIG_ENTROPY_BRCM_IPROC_RNG200 entropy_iproc_rng200.c)
1617
zephyr_library_sources_ifdef(CONFIG_ENTROPY_BT_HCI entropy_bt_hci.c)
1718
zephyr_library_sources_ifdef(CONFIG_ENTROPY_CC13XX_CC26XX_RNG entropy_cc13xx_cc26xx.c)

drivers/entropy/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ config ENTROPY_INIT_PRIORITY
2121
Entropy driver device initialization priority.
2222

2323
# zephyr-keep-sorted-start
24+
source "drivers/entropy/Kconfig.ambiq"
2425
source "drivers/entropy/Kconfig.b91"
2526
source "drivers/entropy/Kconfig.bt_hci"
2627
source "drivers/entropy/Kconfig.cc13xx_cc26xx"

drivers/entropy/Kconfig.ambiq

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# PUF entropy generator driver configuration
2+
3+
# Copyright (c) 2025, Ambiq Micro, Inc.
4+
# SPDX-License-Identifier: Apache-2.0
5+
6+
config ENTROPY_AMBIQ_PUF_TRNG
7+
bool "Ambiq TRNG driver"
8+
default y
9+
depends on SOC_AMBIQ_HAS_PUF
10+
depends on DT_HAS_AMBIQ_PUF_TRNG_ENABLED
11+
select ENTROPY_HAS_DRIVER
12+
help
13+
This option enables the true random number generator
14+
driver based on the OTP/PUF TRNG.
Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
/*
2+
* Copyright (c) 2025 Ambiq Micro, Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#define DT_DRV_COMPAT ambiq_puf_trng
8+
9+
#include <string.h>
10+
#include "soc.h"
11+
#include <zephyr/logging/log.h>
12+
#include <zephyr/drivers/entropy.h>
13+
14+
LOG_MODULE_REGISTER(ambiq_puf_trng_entropy, CONFIG_ENTROPY_LOG_LEVEL);
15+
16+
/*
17+
* Select the correct TRNG memory base address.
18+
*
19+
* The TRNG is implemented in the OTP memory
20+
* and the TRNG address is memory mapped to the OTP.
21+
*
22+
*/
23+
#define TRNG_BASE DT_INST_REG_ADDR(0)
24+
25+
/* Max Fail Count for errors */
26+
#define MAX_FAIL_COUNT 5
27+
28+
static inline uint32_t get_trng_u32(void)
29+
{
30+
return AM_REGVAL(TRNG_BASE);
31+
}
32+
33+
static int entropy_ambiq_get_trng(const struct device *dev, uint8_t *buffer, uint16_t length)
34+
{
35+
ARG_UNUSED(dev);
36+
37+
/* Validate input parameters */
38+
if (length == 0 || buffer == NULL) {
39+
return -EINVAL;
40+
}
41+
42+
uint8_t *byte_buffer = buffer;
43+
uint8_t fail_cnt = 0;
44+
45+
/*
46+
* While the passed in length is greater than zero
47+
* grab data from RNG and save to output.
48+
*/
49+
while ((length > 0) && (fail_cnt < MAX_FAIL_COUNT)) {
50+
uint32_t word = get_trng_u32();
51+
52+
/* This is a failure mode where the RNG doesn't have enough randomness */
53+
if (word == 0xdeaddead) {
54+
fail_cnt++;
55+
continue;
56+
}
57+
58+
size_t copy_length = MIN(sizeof(uint32_t), length);
59+
/*
60+
* If the length is less than 4 bytes, we only copy the
61+
* requested number of bytes.
62+
*/
63+
memcpy(byte_buffer, &word, copy_length);
64+
byte_buffer += copy_length;
65+
length -= copy_length;
66+
}
67+
68+
if (fail_cnt >= MAX_FAIL_COUNT) {
69+
return -EIO;
70+
}
71+
72+
return 0;
73+
}
74+
75+
static int entropy_ambiq_trng_init(const struct device *dev)
76+
{
77+
uint32_t status;
78+
bool peripheral_enabled = false;
79+
80+
/* Check and Power on OTP if it is not already on. */
81+
status = am_hal_pwrctrl_periph_enabled(AM_HAL_PWRCTRL_PERIPH_OTP, &peripheral_enabled);
82+
if (status != AM_HAL_STATUS_SUCCESS) {
83+
LOG_ERR("Failed to check OTP peripheral status, error: 0x%x", status);
84+
return -EBUSY;
85+
}
86+
87+
if (!peripheral_enabled) {
88+
status = am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_OTP);
89+
if (status != AM_HAL_STATUS_SUCCESS) {
90+
LOG_ERR("Failed to enable OTP peripheral, error: 0x%x", status);
91+
return -EBUSY;
92+
}
93+
}
94+
95+
return 0;
96+
}
97+
98+
static DEVICE_API(entropy, entropy_ambiq_api_funcs) = {
99+
.get_entropy = entropy_ambiq_get_trng,
100+
};
101+
102+
DEVICE_DT_INST_DEFINE(0, entropy_ambiq_trng_init, NULL, NULL, NULL, PRE_KERNEL_1,
103+
CONFIG_ENTROPY_INIT_PRIORITY, &entropy_ambiq_api_funcs);

dts/arm/ambiq/ambiq_apollo510.dtsi

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,12 @@
137137
soc {
138138
compatible = "ambiq,apollo510", "ambiq,apollo5x", "simple-bus";
139139

140+
trng: trng@40014aa0 {
141+
compatible = "ambiq,puf-trng";
142+
reg = <0x40014aa0 0x4>;
143+
status = "disabled";
144+
};
145+
140146
stimer0: stimer@STIMER_BASE_NAME {
141147
compatible = "ambiq,stimer";
142148
reg = <STIMER_REG_BASE STIMER_REG_SIZE>;

dts/bindings/rng/ambiq,puf-trng.yaml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright (c) 2025, Ambiq
2+
# Author: Richard S Wheatley
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
description: |
6+
PUF TRNG (True Random Number Generator).
7+
8+
This module is a non-deterministic random number generator based on a full hardware solution.
9+
10+
compatible: "ambiq,puf-trng"
11+
12+
include: base.yaml
13+
14+
properties:
15+
reg:
16+
required: true

soc/ambiq/apollo5x/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ config SOC_SERIES_APOLLO5X
2020
select SOC_EARLY_INIT_HOOK
2121
select REQUIRES_FULL_LIBC
2222

23+
config SOC_AMBIQ_HAS_PUF
24+
bool "Ambiq PUF support"
25+
default y
26+
help
27+
This option enables the Ambiq PUF support.
28+
It is required for the true random number generator.
29+
2330
config SOC_AMBIQ_DCACHE_SIZE
2431
int
2532
default 65536 if SOC_APOLLO510

0 commit comments

Comments
 (0)