This is an automated email from the ASF dual-hosted git repository.

xiaoxiang781216 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new 52e84e0c0a4 arch/arm/rp23xx: Add hardware TRNG driver for /dev/random.
52e84e0c0a4 is described below

commit 52e84e0c0a4be5dfad8c16577bea4f30f27aeaa2
Author: Marco Casaroli <[email protected]>
AuthorDate: Fri Jul 24 22:06:29 2026 +0200

    arch/arm/rp23xx: Add hardware TRNG driver for /dev/random.
    
    Add a driver for the rp2350 hardware true random number generator.
    
    Enabling CONFIG_RP23XX_RNG selects ARCH_HAVE_RNG and builds the driver,
    which registers /dev/random (and /dev/urandom when CONFIG_DEV_URANDOM
    selects the architecture source, DEV_URANDOM_ARCH).  Each read enables
    the entropy source, waits for a valid 192-bit entropy holding register
    (EHR) sample, reads the six 32-bit EHR words, and repeats until the
    request is satisfied.
    
    Document the TRNG on the rp23xx platform page.
    
    Assisted-by: Claude Opus 4.8 (1M context) <[email protected]>
    Signed-off-by: Marco Casaroli <[email protected]>
---
 .codespellrc                                 |   1 +
 Documentation/platforms/arm/rp23xx/index.rst |  19 +++
 arch/arm/src/rp23xx/CMakeLists.txt           |   4 +
 arch/arm/src/rp23xx/Kconfig                  |   9 ++
 arch/arm/src/rp23xx/Make.defs                |   4 +
 arch/arm/src/rp23xx/rp23xx_rng.c             | 185 +++++++++++++++++++++++++++
 6 files changed, 222 insertions(+)

diff --git a/.codespellrc b/.codespellrc
index d22ff556a14..14770824d32 100644
--- a/.codespellrc
+++ b/.codespellrc
@@ -26,6 +26,7 @@ ignore-words-list =
   BU,
   DAA,
   dout,
+  ehr,
   emac,
   eeeprom,
   extint,
diff --git a/Documentation/platforms/arm/rp23xx/index.rst 
b/Documentation/platforms/arm/rp23xx/index.rst
index 779c8f4e1be..d91ad4cade5 100644
--- a/Documentation/platforms/arm/rp23xx/index.rst
+++ b/Documentation/platforms/arm/rp23xx/index.rst
@@ -41,6 +41,7 @@ Flash ROM Boot   Working       Does not require boot2 from 
pico-sdk
                                If picotool is available a nuttx.uf2 file will 
be created
 SRAM Boot        Working       Requires external SWD debugger
 PSRAM            Working       Three modes of heap allocation described below
+TRNG             Working       Hardware RNG at /dev/random and /dev/urandom
 ==============   ============  =====
 
 Installation
@@ -203,6 +204,24 @@ GPIO 0 and 1 pins must be connected to the device such as 
USB-serial converter.
 The `usbnsh` configuration provides the console access by USB CDC/ACM serial
 device.  The console is available by using a terminal software on the USB host.
 
+TRNG
+====
+
+The rp2350 has a hardware true random number generator (TRNG).  Enabling
+``RP23XX_RNG`` builds the driver and selects ``ARCH_HAVE_RNG``, which in turn
+makes ``DEV_RANDOM`` available.
+
+With ``DEV_RANDOM`` enabled the driver registers ``/dev/random``.  Enabling
+``DEV_URANDOM`` additionally registers ``/dev/urandom``; when a hardware RNG is
+present the architecture source (``DEV_URANDOM_ARCH``) is selected by default,
+so ``/dev/urandom`` is served from the same TRNG rather than a software PRNG.
+
+Each read collects entropy from the TRNG's 192-bit entropy holding register
+(EHR): the source is enabled, the driver waits for ``TRNG_VALID``, reads the
+six 32-bit EHR words, and repeats until the request is satisfied.  For 
example::
+
+    nsh> dd if=/dev/random of=/dev/console bs=16 count=1
+
 Supported Boards
 ================
 
diff --git a/arch/arm/src/rp23xx/CMakeLists.txt 
b/arch/arm/src/rp23xx/CMakeLists.txt
index b67f08039aa..77449ea491d 100644
--- a/arch/arm/src/rp23xx/CMakeLists.txt
+++ b/arch/arm/src/rp23xx/CMakeLists.txt
@@ -60,6 +60,10 @@ if(CONFIG_RP23XX_I2C)
   list(APPEND SRCS rp23xx_i2c.c)
 endif()
 
+if(CONFIG_RP23XX_RNG)
+  list(APPEND SRCS rp23xx_rng.c)
+endif()
+
 if(CONFIG_RP23XX_I2C_SLAVE)
   list(APPEND SRCS rp23xx_i2c_slave.c)
 endif()
diff --git a/arch/arm/src/rp23xx/Kconfig b/arch/arm/src/rp23xx/Kconfig
index cbeba7bbaa7..05907356d4c 100644
--- a/arch/arm/src/rp23xx/Kconfig
+++ b/arch/arm/src/rp23xx/Kconfig
@@ -740,6 +740,15 @@ endif # SPISD Configuration
 #  ADC Configuration
 #####################################################################
 
+config RP23XX_RNG
+       bool "Enable hardware TRNG (/dev/random)"
+       default n
+       select ARCH_HAVE_RNG
+       ---help---
+               Enable the RP2350 hardware true random number generator.  
Provides
+               /dev/random (and /dev/urandom when CONFIG_DEV_URANDOM selects 
the
+               architecture source) via the TRNG entropy register (EHR).
+
 config RP23XX_ADC
        bool "Enable ADC Support"
        default n
diff --git a/arch/arm/src/rp23xx/Make.defs b/arch/arm/src/rp23xx/Make.defs
index 00421248049..36100cd47f7 100644
--- a/arch/arm/src/rp23xx/Make.defs
+++ b/arch/arm/src/rp23xx/Make.defs
@@ -64,6 +64,10 @@ ifeq ($(CONFIG_RP23XX_I2C),y)
 CHIP_CSRCS += rp23xx_i2c.c
 endif
 
+ifeq ($(CONFIG_RP23XX_RNG),y)
+CHIP_CSRCS += rp23xx_rng.c
+endif
+
 ifeq ($(CONFIG_RP23XX_I2C_SLAVE),y)
 CHIP_CSRCS += rp23xx_i2c_slave.c
 endif
diff --git a/arch/arm/src/rp23xx/rp23xx_rng.c b/arch/arm/src/rp23xx/rp23xx_rng.c
new file mode 100644
index 00000000000..e2c7bca54f0
--- /dev/null
+++ b/arch/arm/src/rp23xx/rp23xx_rng.c
@@ -0,0 +1,185 @@
+/****************************************************************************
+ * arch/arm/src/rp23xx/rp23xx_rng.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/types.h>
+#include <stdint.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#include <nuttx/fs/fs.h>
+#include <nuttx/mutex.h>
+#include <nuttx/drivers/drivers.h>
+
+#include "arm_internal.h"
+#include "hardware/rp23xx_trng.h"
+
+#if defined(CONFIG_DEV_RANDOM) || defined(CONFIG_DEV_URANDOM_ARCH)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* The TRNG delivers entropy 192 bits (six 32-bit EHR words) at a time. */
+
+#define RP23XX_TRNG_EHR_WORDS  6
+#define RP23XX_TRNG_EHR_BYTES  (RP23XX_TRNG_EHR_WORDS * sizeof(uint32_t))
+
+/* TRNG_VALID.EHR_VALID: the EHR holds a fresh 192-bit sample. */
+
+#define RP23XX_TRNG_EHR_VALID  (1 << 0)
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static ssize_t rp23xx_rng_read(struct file *filep, char *buffer,
+                               size_t buflen);
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static mutex_t g_rng_lock = NXMUTEX_INITIALIZER;
+
+static const struct file_operations g_rngops =
+{
+  NULL,             /* open */
+  NULL,             /* close */
+  rp23xx_rng_read,  /* read */
+  NULL,             /* write */
+  NULL,             /* seek */
+  NULL,             /* ioctl */
+};
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: rp23xx_rng_read
+ *
+ * Description:
+ *   Fill 'buffer' with 'buflen' bytes of hardware entropy.  Enables the ring
+ *   -oscillator source, then repeatedly waits for a valid 192-bit EHR and
+ *   copies it out until the request is satisfied.
+ *
+ ****************************************************************************/
+
+static ssize_t rp23xx_rng_read(struct file *filep, char *buffer,
+                               size_t buflen)
+{
+  size_t nread = 0;
+  int ret;
+
+  ret = nxmutex_lock(&g_rng_lock);
+  if (ret < 0)
+    {
+      return ret;
+    }
+
+  /* Enable the entropy source. */
+
+  putreg32(1, RP23XX_TRNG_RND_SOURCE_ENABLE);
+
+  while (nread < buflen)
+    {
+      uint32_t ehr[RP23XX_TRNG_EHR_WORDS];
+      size_t chunk;
+      int i;
+
+      /* Wait for the next 192-bit sample to become valid. */
+
+      while ((getreg32(RP23XX_TRNG_TRNG_VALID) & RP23XX_TRNG_EHR_VALID) == 0)
+        {
+        }
+
+      for (i = 0; i < RP23XX_TRNG_EHR_WORDS; i++)
+        {
+          ehr[i] = getreg32(RP23XX_TRNG_EHR_DATA(i));
+        }
+
+      /* Acknowledge the sample so the engine collects the next one. */
+
+      putreg32(0xffffffff, RP23XX_TRNG_RNG_ICR);
+
+      chunk = buflen - nread;
+      if (chunk > RP23XX_TRNG_EHR_BYTES)
+        {
+          chunk = RP23XX_TRNG_EHR_BYTES;
+        }
+
+      memcpy(buffer + nread, ehr, chunk);
+      nread += chunk;
+    }
+
+  /* Leave the source disabled to save power. */
+
+  putreg32(0, RP23XX_TRNG_RND_SOURCE_ENABLE);
+
+  nxmutex_unlock(&g_rng_lock);
+  return (ssize_t)nread;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: devrandom_register
+ *
+ * Description:
+ *   Register /dev/random, backed by the RP2350 hardware TRNG.  Called
+ *   automatically from drivers_initialize() when CONFIG_DEV_RANDOM is set.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEV_RANDOM
+void devrandom_register(void)
+{
+  register_driver("/dev/random", &g_rngops, 0444, NULL);
+}
+#endif
+
+/****************************************************************************
+ * Name: devurandom_register
+ *
+ * Description:
+ *   Register /dev/urandom, backed by the same hardware TRNG.  Called from
+ *   drivers_initialize() when CONFIG_DEV_URANDOM selects the arch source.
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEV_URANDOM_ARCH
+void devurandom_register(void)
+{
+  register_driver("/dev/urandom", &g_rngops, 0444, NULL);
+}
+#endif
+
+#endif /* CONFIG_DEV_RANDOM || CONFIG_DEV_URANDOM_ARCH */

Reply via email to