drivers: entropy: add puf-trng entropy driver

add puf-trng entropy driver to apollo510

Signed-off-by: Richard Wheatley <richard.wheatley@ambiq.com>
This commit is contained in:
Richard Wheatley
2025-07-18 10:55:52 -05:00
committed by Johan Hedberg
parent b70e761d42
commit d00a734c0c
8 changed files with 153 additions and 0 deletions

View File

@@ -15,6 +15,7 @@
zephyr,console = &uart0;
zephyr,shell-uart = &uart0;
zephyr,uart-pipe = &uart0;
zephyr,entropy = &trng;
ambiq,xo32m = &xo32m_xtal;
ambiq,xo32k = &xo32k_xtal;
ambiq,extrefclk = &extrefclk;
@@ -90,6 +91,10 @@
};
};
&trng {
status = "okay";
};
&xo32m_xtal {
clock-frequency = <DT_FREQ_M(48)>;
};

View File

@@ -12,6 +12,7 @@ endif()
zephyr_library_sources_ifdef(CONFIG_USERSPACE entropy_handlers.c)
# zephyr-keep-sorted-start
zephyr_library_sources_ifdef(CONFIG_ENTROPY_AMBIQ_PUF_TRNG entropy_ambiq_puf_trng.c)
zephyr_library_sources_ifdef(CONFIG_ENTROPY_BRCM_IPROC_RNG200 entropy_iproc_rng200.c)
zephyr_library_sources_ifdef(CONFIG_ENTROPY_BT_HCI entropy_bt_hci.c)
zephyr_library_sources_ifdef(CONFIG_ENTROPY_CC13XX_CC26XX_RNG entropy_cc13xx_cc26xx.c)

View File

@@ -21,6 +21,7 @@ config ENTROPY_INIT_PRIORITY
Entropy driver device initialization priority.
# zephyr-keep-sorted-start
source "drivers/entropy/Kconfig.ambiq"
source "drivers/entropy/Kconfig.b91"
source "drivers/entropy/Kconfig.bt_hci"
source "drivers/entropy/Kconfig.cc13xx_cc26xx"

View File

@@ -0,0 +1,14 @@
# PUF entropy generator driver configuration
# Copyright (c) 2025, Ambiq Micro, Inc.
# SPDX-License-Identifier: Apache-2.0
config ENTROPY_AMBIQ_PUF_TRNG
bool "Ambiq TRNG driver"
default y
depends on SOC_AMBIQ_HAS_PUF
depends on DT_HAS_AMBIQ_PUF_TRNG_ENABLED
select ENTROPY_HAS_DRIVER
help
This option enables the true random number generator
driver based on the OTP/PUF TRNG.

View File

@@ -0,0 +1,103 @@
/*
* Copyright (c) 2025 Ambiq Micro, Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/
#define DT_DRV_COMPAT ambiq_puf_trng
#include <string.h>
#include "soc.h"
#include <zephyr/logging/log.h>
#include <zephyr/drivers/entropy.h>
LOG_MODULE_REGISTER(ambiq_puf_trng_entropy, CONFIG_ENTROPY_LOG_LEVEL);
/*
* Select the correct TRNG memory base address.
*
* The TRNG is implemented in the OTP memory
* and the TRNG address is memory mapped to the OTP.
*
*/
#define TRNG_BASE DT_INST_REG_ADDR(0)
/* Max Fail Count for errors */
#define MAX_FAIL_COUNT 5
static inline uint32_t get_trng_u32(void)
{
return AM_REGVAL(TRNG_BASE);
}
static int entropy_ambiq_get_trng(const struct device *dev, uint8_t *buffer, uint16_t length)
{
ARG_UNUSED(dev);
/* Validate input parameters */
if (length == 0 || buffer == NULL) {
return -EINVAL;
}
uint8_t *byte_buffer = buffer;
uint8_t fail_cnt = 0;
/*
* While the passed in length is greater than zero
* grab data from RNG and save to output.
*/
while ((length > 0) && (fail_cnt < MAX_FAIL_COUNT)) {
uint32_t word = get_trng_u32();
/* This is a failure mode where the RNG doesn't have enough randomness */
if (word == 0xdeaddead) {
fail_cnt++;
continue;
}
size_t copy_length = MIN(sizeof(uint32_t), length);
/*
* If the length is less than 4 bytes, we only copy the
* requested number of bytes.
*/
memcpy(byte_buffer, &word, copy_length);
byte_buffer += copy_length;
length -= copy_length;
}
if (fail_cnt >= MAX_FAIL_COUNT) {
return -EIO;
}
return 0;
}
static int entropy_ambiq_trng_init(const struct device *dev)
{
uint32_t status;
bool peripheral_enabled = false;
/* Check and Power on OTP if it is not already on. */
status = am_hal_pwrctrl_periph_enabled(AM_HAL_PWRCTRL_PERIPH_OTP, &peripheral_enabled);
if (status != AM_HAL_STATUS_SUCCESS) {
LOG_ERR("Failed to check OTP peripheral status, error: 0x%x", status);
return -EBUSY;
}
if (!peripheral_enabled) {
status = am_hal_pwrctrl_periph_enable(AM_HAL_PWRCTRL_PERIPH_OTP);
if (status != AM_HAL_STATUS_SUCCESS) {
LOG_ERR("Failed to enable OTP peripheral, error: 0x%x", status);
return -EBUSY;
}
}
return 0;
}
static DEVICE_API(entropy, entropy_ambiq_api_funcs) = {
.get_entropy = entropy_ambiq_get_trng,
};
DEVICE_DT_INST_DEFINE(0, entropy_ambiq_trng_init, NULL, NULL, NULL, PRE_KERNEL_1,
CONFIG_ENTROPY_INIT_PRIORITY, &entropy_ambiq_api_funcs);

View File

@@ -137,6 +137,12 @@
soc {
compatible = "ambiq,apollo510", "ambiq,apollo5x", "simple-bus";
trng: trng@40014aa0 {
compatible = "ambiq,puf-trng";
reg = <0x40014aa0 0x4>;
status = "disabled";
};
stimer0: stimer@STIMER_BASE_NAME {
compatible = "ambiq,stimer";
reg = <STIMER_REG_BASE STIMER_REG_SIZE>;

View File

@@ -0,0 +1,16 @@
# Copyright (c) 2025, Ambiq
# Author: Richard S Wheatley
# SPDX-License-Identifier: Apache-2.0
description: |
PUF TRNG (True Random Number Generator).
This module is a non-deterministic random number generator based on a full hardware solution.
compatible: "ambiq,puf-trng"
include: base.yaml
properties:
reg:
required: true

View File

@@ -20,6 +20,13 @@ config SOC_SERIES_APOLLO5X
select SOC_EARLY_INIT_HOOK
select REQUIRES_FULL_LIBC
config SOC_AMBIQ_HAS_PUF
bool "Ambiq PUF support"
default y
help
This option enables the Ambiq PUF support.
It is required for the true random number generator.
config SOC_AMBIQ_DCACHE_SIZE
int
default 65536 if SOC_APOLLO510