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

acassis 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 60abe4744fa arch/mips/jz4780: Add hardware Random Number Generator 
(RNG) support
60abe4744fa is described below

commit 60abe4744fa8d5bf7b751dec0cc5647a301f8ab9
Author: Lwazi Dube <[email protected]>
AuthorDate: Fri Aug 7 01:37:08 2026 -0400

    arch/mips/jz4780: Add hardware Random Number Generator (RNG) support
    
    Add support for the hardware Random Number Generator (RNG) module found
    on the Ingenic JZ4780 SoC.
    
    Changes include:
    - Update jz4780 chip.h with power management controllor base
      address JZPMC_BASE and register offsets for the RNG registers.
    - A new file jz4780_rng.c to provide character driver interfaces
      for `/dev/random` and `/dev/urandom` utilizing the hardware
      RNG block.
    
    Signed-off-by: Lwazi Dube <[email protected]>
---
 arch/mips/include/jz4780/chip.h   |  28 +++--
 arch/mips/src/jz4780/Kconfig      |   6 +
 arch/mips/src/jz4780/Make.defs    |   4 +
 arch/mips/src/jz4780/jz4780_rng.c | 233 ++++++++++++++++++++++++++++++++++++++
 4 files changed, 260 insertions(+), 11 deletions(-)

diff --git a/arch/mips/include/jz4780/chip.h b/arch/mips/include/jz4780/chip.h
index ec1908fba6c..6a15381b786 100644
--- a/arch/mips/include/jz4780/chip.h
+++ b/arch/mips/include/jz4780/chip.h
@@ -33,10 +33,10 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-#define CKPCR               0xB0003040
+#define CKPCR               0xb0003040
 #define CKPCR_CK32CTL_RTCLK (3 << 1)
 
-#define JZINTC_BASE         0xB0001000
+#define JZINTC_BASE         0xb0001000
 
 #define ICMSR0              (JZINTC_BASE + 0x08)
 #define ICMCR0              (JZINTC_BASE + 0x0C)
@@ -45,7 +45,7 @@
 #define ICMCR1              (JZINTC_BASE + 0x2C)
 #define ICPR1               (JZINTC_BASE + 0x30)
 
-#define JZTMR_BASE          0xB0002000
+#define JZTMR_BASE          0xb0002000
 
 #define WD_TDR              (JZTMR_BASE + 0x00) // u16: Watchdog Timer Data
 #define WD_TCER             (JZTMR_BASE + 0x04) // u8 : Watchdog Counter Enable
@@ -87,37 +87,43 @@
 #define TCSR(n)             (JZTMR_BASE + 0x4C + (n)*0x10)
 #define TDFR(n)             (JZTMR_BASE + 0x40 + (n)*0x10)
 
-#define CLKGR0_REG          0xb0000020
+#define JZPMC_BASE          0xb0000000
+
+#define CLKGR0_REG          (JZPMC_BASE + 0x20)
 #  define CLKGR0_OTG0       (1 << 2)
 #  define CLKGR0_UHC        (1 << 24)
 #  define CLKGR0_LCD        (1 << 28)
 #  define CLKGR0_TVE        (1 << 27)
 
-#define OPCR_REG            0xb0000024
+#define OPCR_REG            (JZPMC_BASE + 0x24)
 #  define OPCR_SPENDN1      (1 << 6)
 
-#define CLKGR1_REG          0xb0000028
+#define CLKGR1_REG          (JZPMC_BASE + 0x28)
 #  define CLKGR1_HDMI       (1 << 9)
 
-#define USBPCR_REG          0xb000003c
+#define USBPCR_REG          (JZPMC_BASE + 0x3c)
 #  define USBPCR_POR        (1 << 22)
 
-#define USBPCR1_REG         0xb0000048
+#define USBPCR1_REG         (JZPMC_BASE + 0x48)
 #  define REFCLK_DIV_MSK    0xfcffffff  /* clears bits 25:24 */
 #  define REFCLK_DIV_48MHZ  0x02000000  /* bits 25:24 */
 #  define WORD_IF_16BIT     0x000c0000  /* bits 19:18 */
 
-#define LP1CDR_REG          0xb0000054
+#define LP1CDR_REG          (JZPMC_BASE + 0x54)
 #  define LPCDR_VAL         0x15
 #  define LPCS_VPLL         0X80000000
 #  define CE_LCD            (1 << 28)
 #  define LCD_BUSY          (1 << 27)
 
-#define HDMICDR_REG         0xb000008c
+#define HDMICDR_REG         (JZPMC_BASE + 0x8c)
 
-#define SRBC_REG            0xb00000c4
+#define SRBC_REG            (JZPMC_BASE + 0xc4)
 #  define SRBC_UHC_SR       (1 << 14)
 
+#define ERNG_REG            (JZPMC_BASE + 0xd8)
+#  define ENABLE_RNG        (1 << 0)
+#define RNG_REG             (JZPMC_BASE + 0xdc)
+
 #define TICKS_PER_MS        (48000/16)
 
 #define CHIP_JZ4780         1
diff --git a/arch/mips/src/jz4780/Kconfig b/arch/mips/src/jz4780/Kconfig
index a363c1f16cc..9d0616ad150 100644
--- a/arch/mips/src/jz4780/Kconfig
+++ b/arch/mips/src/jz4780/Kconfig
@@ -7,6 +7,12 @@ if ARCH_CHIP_JZ4780
 comment "JZ4780 Configuration Options"
 
 menu "JZ4780 Peripheral Support"
+
+config JZ4780_RNG
+       bool "Random Number Generator (RNG)"
+       default y
+       select ARCH_HAVE_RNG
+
 config JZ4780_LCD
        bool "LCD controller"
        default n
diff --git a/arch/mips/src/jz4780/Make.defs b/arch/mips/src/jz4780/Make.defs
index 7b434dd545e..58b1f21f9e4 100644
--- a/arch/mips/src/jz4780/Make.defs
+++ b/arch/mips/src/jz4780/Make.defs
@@ -52,6 +52,10 @@ CHIP_CSRCS  = jz4780_lowinit.c jz4780_exception.c 
jz4780_decodeirq.c
 CHIP_CSRCS += jz4780_irq.c jz4780_timerisr.c jz4780_gpio.c
 CHIP_CSRCS += jz4780_cache.c
 
+ifeq ($(CONFIG_JZ4780_RNG),y)
+CHIP_CSRCS += jz4780_rng.c
+endif
+
 ifeq ($(CONFIG_USBHOST),y)
 CHIP_CSRCS += jz_usbhost.c
 
diff --git a/arch/mips/src/jz4780/jz4780_rng.c 
b/arch/mips/src/jz4780/jz4780_rng.c
new file mode 100644
index 00000000000..e8e6a807660
--- /dev/null
+++ b/arch/mips/src/jz4780/jz4780_rng.c
@@ -0,0 +1,233 @@
+/****************************************************************************
+ * arch/mips/src/jz4780/jz4780_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 <stdint.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/param.h>
+
+#include <nuttx/debug.h>
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <nuttx/fs/fs.h>
+#include <nuttx/mutex.h>
+#include <nuttx/drivers/drivers.h>
+
+#include "mips_internal.h"
+
+#if defined(CONFIG_DEV_RANDOM) || defined(CONFIG_DEV_URANDOM_ARCH)
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#define ENTROPY_DELAY 10
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int jz_rng_initialize(void);
+static ssize_t jz_rng_read(struct file *filep, char *buffer, size_t);
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+struct rng_dev_s
+{
+  mutex_t rd_lock;
+};
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+static struct rng_dev_s g_rngdev =
+{
+  .rd_lock = NXMUTEX_INITIALIZER,
+};
+
+static const struct file_operations g_rngops =
+{
+  NULL,            /* open */
+  NULL,            /* close */
+  jz_rng_read,     /* read */
+};
+
+/****************************************************************************
+ * Private functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: jz_rng_initialize
+ *
+ * Description:
+ *   Enable the random number generator
+ *
+ * Returned Value:
+ *   OK on success; negated errno on failure.
+ *
+ ****************************************************************************/
+
+static int jz_rng_initialize(void)
+{
+  uint32_t retval;
+  struct rng_dev_s *priv = (struct rng_dev_s *)&g_rngdev;
+
+  if (nxmutex_lock(&priv->rd_lock) != OK)
+    {
+      return -EBUSY;
+    }
+
+  /* Enable RNG if it is disabled */
+
+  if ((getreg32(ERNG_REG) & ENABLE_RNG) == 0)
+    {
+      putreg32(ENABLE_RNG, ERNG_REG);
+    }
+
+  up_mdelay(1);
+
+  retval = (getreg32(ERNG_REG) & ENABLE_RNG) ? OK : -EIO;
+
+  if (retval != OK)
+    {
+      _err("Failed to initialize RNG\n");
+    }
+
+  nxmutex_unlock(&priv->rd_lock);
+  return retval;
+}
+
+/****************************************************************************
+ * Name: jz_rng_read
+ *
+ * Description:
+ *   This is the standard, NuttX character driver read method
+ *
+ * Input Parameters:
+ *   filep - The VFS file instance
+ *   buffer - Buffer in which to return the random samples
+ *   buflen - The length of the buffer
+ *
+ * Returned Value:
+ *
+ ****************************************************************************/
+
+static ssize_t jz_rng_read(struct file *filep, char *buffer, size_t buflen)
+{
+  struct rng_dev_s *priv = (struct rng_dev_s *)&g_rngdev;
+  ssize_t bytes_left = buflen;
+  uint8_t *rd_buf = (uint8_t *)buffer;
+  uint32_t last_word;
+
+  if (nxmutex_lock(&priv->rd_lock) != OK)
+    {
+      return -EBUSY;
+    }
+
+  last_word = getreg32(RNG_REG);
+  while (bytes_left > 0)
+    {
+      up_mdelay(ENTROPY_DELAY);
+      uint32_t word = getreg32(RNG_REG);
+      if (word == last_word)
+        {
+          /* Try again if the same number is repeated */
+
+          continue;
+        }
+
+      last_word = word;
+
+      uint32_t count = MIN(sizeof(word), bytes_left);
+
+      memcpy(rd_buf, &word, count);
+      rd_buf += count;
+      bytes_left -= count;
+    }
+
+  nxmutex_unlock(&priv->rd_lock);
+  return buflen;
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: devrandom_register
+ *
+ * Description:
+ *   Initialize the RNG hardware and register the /dev/random driver.
+ *   Must be called BEFORE devurandom_register.
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEV_RANDOM
+void devrandom_register(void)
+{
+  if (jz_rng_initialize() == OK)
+    {
+      register_driver("/dev/random", &g_rngops, 0444, NULL);
+    }
+}
+#endif
+
+/****************************************************************************
+ * Name: devurandom_register
+ *
+ * Description:
+ *   Register /dev/urandom
+ *
+ * Input Parameters:
+ *   None
+ *
+ * Returned Value:
+ *   None
+ *
+ ****************************************************************************/
+
+#ifdef CONFIG_DEV_URANDOM_ARCH
+void devurandom_register(void)
+{
+  if (jz_rng_initialize() == OK)
+    {
+      register_driver("/dev/urandom", &g_rngops, 0444, NULL);
+    }
+}
+#endif
+
+#endif /* CONFIG_DEV_RANDOM || CONFIG_DEV_URANDOM_ARCH */

Reply via email to