[PATCH v2] arm/beagle: Added TRNG based getentropy implementation

dev.madaari at gmail.com dev.madaari at gmail.com
Fri Mar 16 14:51:05 UTC 2018


From: Udit agarwal <dev.madaari at gmail.com>

---
 bsps/arm/include/libcpu/am335x.h                 |  33 ++++++
 c/src/lib/libbsp/arm/beagle/Makefile.am          |   4 +-
 c/src/lib/libbsp/arm/beagle/dev/bbb_getentropy.c | 130 +++++++++++++++++++++++
 3 files changed, 166 insertions(+), 1 deletion(-)
 create mode 100644 c/src/lib/libbsp/arm/beagle/dev/bbb_getentropy.c

diff --git a/bsps/arm/include/libcpu/am335x.h b/bsps/arm/include/libcpu/am335x.h
index 367e97c..a6fb8b8 100644
--- a/bsps/arm/include/libcpu/am335x.h
+++ b/bsps/arm/include/libcpu/am335x.h
@@ -14,11 +14,17 @@
  * Modified by Ben Gras <beng at shrike-systems.com> to add lots
  * of beagleboard/beaglebone definitions, delete lpc32xx specific
  * ones, and merge with some other header files.
+ *
+ * Modified by Udit agarwal <dev.madaari at gmail.com> to add true random
+ * number generating module definitions and TRNG register structure.
  */
 
 #if !defined(_AM335X_H_)
 #define _AM335X_H_
 
+/* For TRNG register definition */
+#include <stdint.h>
+
 /* Interrupt controller memory map */
 #define OMAP3_DM37XX_INTR_BASE 0x48200000 /* INTCPS physical address */
 
@@ -701,4 +707,31 @@
 #define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L4_GCLK (0x00000020u)
 #define AM335X_I2C_INT_STOP_CONDITION AM335X_I2C_IRQSTATUS_BF
 
+/* TRNG Registers */
+/* TRNG base address */
+#define TRNG_BASE 0x48310000
+/* Mask bits for trng clock status */
+#define AM335X_CLK_TRNG_BIT_MASK (0x30000)
+/* Mask bits for output ready flag */
+#define TRNG_STATUS_RDY (1u <<  0)
+/* Mask bits for FRO related error */
+#define TRNG_STATUS_ERR (1u <<  1)
+/* Mask bits for clock status */
+#define TRNG_STATUS_CLK (1u << 31)
+/* enable module */
+#define AM335X_TRNG_ENABLE (1 << 10)
+
+/* TRNG module clock register */
+#define CM_PER_TRNG_CLKCTRL (AM335X_CM_PER_ADDR | (9 << 4))
+
+/* TRNG register structure */
+typedef struct {
+  uint64_t output;     /* 00 */
+  uint32_t status;     /* 08 */
+  uint32_t irq_en;     /* 0c */
+  uint32_t status_clr; /* 10 */
+  uint32_t control;    /* 14 */
+  uint32_t config;     /* 18 */
+} am335x_trng_register;
+
 #endif
diff --git a/c/src/lib/libbsp/arm/beagle/Makefile.am b/c/src/lib/libbsp/arm/beagle/Makefile.am
index 8251660..c483dc4 100644
--- a/c/src/lib/libbsp/arm/beagle/Makefile.am
+++ b/c/src/lib/libbsp/arm/beagle/Makefile.am
@@ -40,7 +40,6 @@ libbsp_a_LIBADD =
 
 # Shared
 libbsp_a_SOURCES += ../../shared/bootcard.c
-libbsp_a_SOURCES += ../../shared/getentropy-cpucounter.c
 libbsp_a_SOURCES += ../../shared/src/bsp-fdt.c
 libbsp_a_SOURCES += ../../shared/bspclean.c
 libbsp_a_SOURCES += ../../shared/bspgetworkarea.c
@@ -88,6 +87,9 @@ libbsp_a_SOURCES += gpio/bbb-gpio.c
 #pwm
 libbsp_a_SOURCES += pwm/pwm.c
 
+#getentropy
+libbsp_a_SOURCES += dev/bbb_getentropy.c
+
 #RTC
 libbsp_a_SOURCES += rtc.c
 libbsp_a_SOURCES += ../../shared/tod.c
diff --git a/c/src/lib/libbsp/arm/beagle/dev/bbb_getentropy.c b/c/src/lib/libbsp/arm/beagle/dev/bbb_getentropy.c
new file mode 100644
index 0000000..b3ea681
--- /dev/null
+++ b/c/src/lib/libbsp/arm/beagle/dev/bbb_getentropy.c
@@ -0,0 +1,130 @@
+/**
+* @file
+*
+* @ingroup arm_beagle
+*
+* @brief Getentropy implementation on BeagleBone Black BSP
+*/
+
+/*
+* Copyright (c) 2018 Udit agarwal <dev.madaari at gmail.com>
+* All rights reserved.
+*
+* Redistribution and use in source and binary forms, with or without
+* modification, are permitted provided that the following conditions
+* are met:
+* 1. Redistributions of source code must retain the above copyright
+*    notice, this list of conditions and the following disclaimer.
+* 2. Redistributions in binary form must reproduce the above copyright
+*    notice, this list of conditions and the following disclaimer in the
+*    documentation and/or other materials provided with the distribution.
+*
+* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+* ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+* SUCH DAMAGE.
+*/
+
+#include <libcpu/am335x.h>
+#include <unistd.h>
+#include <string.h>
+#include <rtems/sysinit.h>
+#include <rtems/thread.h>
+#include <stdint.h>
+
+/* max refill 34 * 256 cycles */
+#define AM335X_TRNG_MAX_REFILL (34 << 16)
+/* min refill 33 * 64 cycles */
+#define AM335X_TRNG_MIN_REFILL (33 << 0)
+/* startup 33 * 256 cycles */
+#define AM335X_TRNG_STARTUP_CYCLES (33 << 16)
+
+static rtems_mutex am335x_trng_mutex =
+    RTEMS_MUTEX_INITIALIZER("am335x_trng");
+
+/* maximun and minimum refill cycle sets the number of samples to be taken
+ * from FRO to generate random number */
+static void am335x_trng_enable(volatile am335x_trng_register *trng)
+{
+  trng->control = trng->config = 0;
+  trng->config |= AM335X_TRNG_MIN_REFILL | AM335X_TRNG_MAX_REFILL ;
+  trng->control |= AM335X_TRNG_STARTUP_CYCLES | AM335X_TRNG_ENABLE ;
+}
+
+static void am335x_trng_clock_enable(void)
+{
+  volatile am335x_trng_register  *trng = (am335x_trng_register*) TRNG_BASE;
+  *(volatile uint8_t *) CM_PER_TRNG_CLKCTRL = 2;
+  while(
+    *(volatile uint32_t *) CM_PER_TRNG_CLKCTRL &
+    AM335X_CLK_TRNG_BIT_MASK
+  ) {
+    /* wait */
+  }
+  am335x_trng_enable(trng);
+}
+
+static uint64_t trng_getranddata(volatile am335x_trng_register *trng)
+{
+  uint64_t output = trng->output;
+  return output;
+}
+
+int getentropy(void *ptr, size_t n)
+{
+  volatile am335x_trng_register  *trng =
+      (am335x_trng_register*) TRNG_BASE;
+
+  /* for mutual exclusion synchronization between multiple
+   * access to TRNG register in different contexts */
+  rtems_mutex_lock(&am335x_trng_mutex);
+
+  while ( n > 0 )
+  {
+    uint64_t random;
+    size_t copy;
+
+    /* wait untill TRNG becomes ready with next set of random data */
+    while ( ( trng->status & TRNG_STATUS_RDY ) == 0 )
+    {
+      /* wait */
+    }
+
+    random = trng_getranddata(trng);
+
+    /* clear the status flag after reading to generate new random
+     * value */
+    trng->status_clr = TRNG_STATUS_RDY;
+
+    /* checking for error by masking all bits other then error bit in
+     * status register */
+    if ( ((trng->status & TRNG_STATUS_ERR) >> 1) == 1 )
+    {
+      copy = sizeof(random);
+      if ( n < copy )
+      {
+        copy = n;
+      }
+      memcpy(ptr, &random, copy);
+      n -= copy;
+      ptr = (char*)ptr + copy;
+    }
+
+  }
+
+  rtems_mutex_unlock(&am335x_trng_mutex);
+  return 0;
+}
+
+RTEMS_SYSINIT_ITEM(
+  am335x_trng_clock_enable,
+  RTEMS_SYSINIT_DEVICE_DRIVERS,
+  RTEMS_SYSINIT_ORDER_LAST
+);
-- 
1.9.1



More information about the devel mailing list