[PATCH] Added Getentropy() support to beagle BSP

Udit agarwal dev.madaari at gmail.com
Thu Mar 15 04:56:45 UTC 2018


Hi,
Below is the updated patch along with the one for atsam. Please have a look.
Moreover, in error case(FRO unwanted shutdown), Error bit of status
register turns zero, indicating that FRO is no longer running.Untill now, i
haven't came across any situation where this bit turns 0. In the NETBSD
<http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/arch/arm/omap/am335x_trng.c>
and in linux kernel
<https://github.com/torvalds/linux/blob/68fed41e0ff6c0332520a0d70ac05be2a7d9130e/drivers/char/hw_random/omap-rng.c>
(line 241 ) implementation of am335x_trng, it seems they aren't checking
for this bit. Instead they are only using RNG_STATUS_RDY as an indication
of successful random data generation.

*Patch: atsam*

>From ae0c79ae4850503259c64387dea69346e7d7b1d4 Mon Sep 17 00:00:00 2001
From: Udit agarwal <dev.madaari at gmail.com>
Date: Thu, 15 Mar 2018 09:43:13 +0530
Subject: [PATCH] Fixed mutual exclusion of critical section

---
 c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c
b/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c
index 11e24dc..b26b6a8 100644
--- a/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c
+++ b/c/src/lib/libbsp/arm/atsam/startup/getentropy-trng.c
@@ -17,6 +17,8 @@
 #include <string.h>
 #include <rtems/sysinit.h>

+static rtems_mutex atsam_trng_reg =
RTEMS_MUTEX_INITIALIZER("atsam_trng_reg");
+
 static void atsam_trng_enable(void)
 {
     PMC_EnablePeripheral(ID_TRNG);
@@ -29,9 +31,12 @@ int getentropy(void *ptr, size_t n)
         uint32_t random;
         size_t copy;

+        rtems_mutex_lock(&atsam_trng_reg);
         while ((TRNG_GetStatus() & TRNG_ISR_DATRDY) == 0) {
             /* wait */
         }
+
+        rtems_mutex_unlock(&atsam_trng_reg);
         random = TRNG_GetRandData();

         /*
@@ -51,6 +56,7 @@ int getentropy(void *ptr, size_t n)
         ptr += copy;
     }

+    rtems_mutex_destroy(&atsam_trng_reg);
     return 0;
 }

-- 
1.9.1

*Patch BBB*

>From ea885f9681c14f324917469b295e7489f56c10e7 Mon Sep 17 00:00:00 2001
From: Udit agarwal <dev.madaari at gmail.com>
Date: Thu, 15 Mar 2018 09:24:35 +0530
Subject: [PATCH] Added getentropy support to beagle BSP

---
 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 | 126
+++++++++++++++++++++++
 3 files changed, 162 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..6170ef3 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 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 Register */
+
+/* RNG base address */
+#define RNG_BASE 0x48310000
+/* RNG clock control */
+#define CM_PER_RNG_CLKCTRL (AM335X_CM_PER_ADDR | (9 << 4))
+/* rng module clock status bits */
+#define AM335X_CLK_RNG_BIT_MASK (0x30000)
+/* Offset from RNG base for output ready flag */
+#define RNG_STATUS_RDY (1u <<  0)
+/* Offset from RNG base for FRO related error */
+#define RNG_STATUS_ERR (1u <<  1)
+/* Offset from RNG base for clock status */
+#define RNG_STATUS_CLK (1u << 31)
+/* enable module */
+#define AM335X_RNG_ENABLE (1 << 10)
+
+/* 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..5445331
--- /dev/null
+++ b/c/src/lib/libbsp/arm/beagle/dev/bbb_getentropy.c
@@ -0,0 +1,126 @@
+/**
+* @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_RNG_MAX_REFILL (34 << 16)
+/* min refill 33 * 64 cycles */
+#define AM335X_RNG_MIN_REFILL (33 << 0)
+/* startup 33 * 256 cycles */
+#define AM335X_RNG_STARTUP_CYCLES (33 << 16)
+
+static rtems_mutex am335x_trng_reg =
RTEMS_MUTEX_INITIALIZER("am335x_trng_reg");
+/* maximun and minimum refill cycle sets the number of samples to be taken
+   from FRO to generate random number */
+static void am335x_rng_enable(volatile am335x_trng_register *rng)
+{
+    rng->control = rng->config = 0;
+    rng->config |= AM335X_RNG_MIN_REFILL | AM335X_RNG_MAX_REFILL ;
+    rng->control |= AM335X_RNG_STARTUP_CYCLES | AM335X_RNG_ENABLE ;
+}
+
+static void am335x_rng_clock_enable(void)
+{
+    volatile am335x_trng_register  *rng = (am335x_trng_register*) RNG_BASE;
+    *(volatile uint8_t *) CM_PER_RNG_CLKCTRL = 2;
+    while(
+      *(volatile uint32_t *) CM_PER_RNG_CLKCTRL &
+      AM335X_CLK_RNG_BIT_MASK
+    ) {
+        /* wait */
+    }
+    am335x_rng_enable(rng);
+}
+
+static uint64_t trng_getranddata(volatile am335x_trng_register *rng)
+{
+    uint64_t output = rng->output;
+    return output;
+}
+
+int getentropy(void *ptr, size_t n)
+{
+    volatile am335x_trng_register  *rng = (am335x_trng_register*) RNG_BASE;
+    while (n > 0)
+    {
+        uint64_t random;
+        size_t copy;
+
+        /* for mutual exclusion synchronization between multiple
+           access to TRNG register in different contexts */
+        rtems_mutex_lock(&am335x_trng_reg);
+
+        /* wait untill RNG becomes ready with next set of random data */
+        while( ( rng->status & RNG_STATUS_RDY ) == 0 )
+        {
+            /* wait */
+        }
+
+        rtems_mutex_unlock(&am335x_trng_reg);
+        random = trng_getranddata(rng);
+
+        /* clear the status flag after reading to generate new random
+           value */
+        rng->status_clr = RNG_STATUS_RDY;
+
+        /* checking for error by masking all bits other then error bit in
+           status register */
+        if( ((rng->status & RNG_STATUS_ERR)>>1) == 1)
+        {
+            copy = sizeof(random);
+            if ( n < copy )
+            {
+                copy = n;
+            }
+            memcpy(ptr, &random, copy);
+            n -= copy;
+            ptr = (char*)ptr + copy;
+        }
+    }
+
+    rtems_mutex_destroy(&am335x_trng_reg);
+    return 0;
+}
+
+RTEMS_SYSINIT_ITEM(
+    am335x_rng_clock_enable,
+    RTEMS_SYSINIT_DEVICE_DRIVERS,
+    RTEMS_SYSINIT_ORDER_LAST
+);
-- 
1.9.1



On Wed, Mar 14, 2018 at 11:02 AM, Christian Mauderer <
christian.mauderer at embedded-brains.de> wrote:

>
> Am Mittwoch, 14. März 2018 schrieb Udit agarwal:
> > Hi,
> > @Joel This seems to be SoC specific.
> >
> >
> > So, here is the implementation with mutex, Do let me know if this is
> okay. I'll then do it for atsam also.
>
> Atsam should be an extra patch.
>
> >
> > int getentropy(void *ptr, size_t n)
> > {
> >     volatile am335x_trng_register  *rng = (am335x_trng_register*)
> RNG_BASE;
> >     rtems_mutex lock_trng_reg = RTEMS_MUTEX_INITIALIZER("lock_
> trng_reg");
>
> If you create a local variable every thread will have it's own mutex. So
> they still can access the critical section in parallel. Use a global one in
> this case.
>
> >
> >     while (n > 0)
> >     {
> >         uint64_t random;
> >         size_t copy;
> >
> >         /* for mutual exclusion synchronization between multiple
> >            access to TRNG register in different contexts */
> >         rtems_mutex_lock(&lock_trng_reg);
> >
> >         /* wait untill RNG becomes ready with next set of random data */
> >         while( ( rng->status & RNG_STATUS_RDY ) == 0 )
> >         {
> >             /* wait */
> >         }
> >
> >         random = trng_getranddata(rng);
> >         /* clear the status flag after reading to generate new random
> >            value */
> >         rng->status_clr = RNG_STATUS_RDY;
> >         rtems_mutex_unlock(&lock_trng_reg);
> >
> >         /* checking for error by masking all bits other then error bit in
> >            status register */
> >         if( ((rng->status & RNG_STATUS_ERR)>>1) == 1)
> >         {
> >             copy = sizeof(random);
> >             if ( n < copy )
> >             {
> >                 copy = n;
> >             }
> >             memcpy(ptr, &random, copy);
> >             n -= copy;
> >             ptr = (char*)ptr + copy;
> >         }
>
> Just noted that one: What Value is returned in the error case? Can the
> error even happen? I think that there is a special function that should be
> called in that case.
>
> >     }
> >
> >     rtems_mutex_destroy(&lock_trng_reg);
> >     return 0;
> > }
> >
> >
> >
> >
> > On Wed, Mar 14, 2018 at 2:15 AM, Joel Sherrill <joel at rtems.org> wrote:
> >
> >
> >
> >
> >
> > On Mar 13, 2018 1:31 AM, "Sebastian Huber" <sebastian.huber at embedded-
> brains.de> wrote:
> >
> >
> >
> > On 12/03/18 20:02, Udit agarwal wrote:
> >
> > So, It looks like here's the final patch, do let me know if its ready to
> be pushed. Also, it would be really helpful if someone else also tests this
> patch before pushing(Although i have done that once).
> >
> > Thanks,
> > Udit agarwal
> >
> >
> > From 454a8ff3e0ea3393818859874705a54b098c6081 Mon Sep 17 00:00:00 2001
> >
> > From: Udit agarwal <dev.madaari at gmail.com <mailto:dev.madaari at gmail.com>
> >
> >
> > Date: Tue, 13 Mar 2018 00:20:28 +0530
> > Subject: [PATCH] Added Getentropy() support to beagle BSP
> >
> > ---
> >  bsps/arm/include/libcpu/am335x.h                   |  37 ++++++-
> >  c/src/lib/libbsp/arm/beagle/Makefile.am            |   4 +-
> >  .../libbsp/arm/beagle/getentropy/bbb_getentropy.c  | 116
> +++++++++++++++++++++
> >  3 files changed, 155 insertions(+), 2 deletions(-)
> >  create mode 100644 c/src/lib/libbsp/arm/beagle/
> getentropy/bbb_getentropy.c
> >
> > diff --git a/bsps/arm/include/libcpu/am335x.h b/bsps/arm/include/libcpu/
> am335x.h
> > index 367e97c..cedd637 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 <mailto:
> 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 <mailto:
> dev.madaari at gmail.com>> to add 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,33 @@
> >  #define AM335X_CM_PER_OCPWP_L3_CLKSTCTRL_CLKACTIVITY_OCPWP_L4_GCLK
> (0x00000020u)
> >  #define AM335X_I2C_INT_STOP_CONDITION AM335X_I2C_IRQSTATUS_BF
> >
> > -#endif
> > +/* TRNG Register */
> > +
> > +/* RNG base address */
> > +#define RNG_BASE 0x48310000
> > +/* RNG clock control */
> > +#define CM_PER_RNG_CLKCTRL (AM335X_CM_PER_ADDR | (9 << 4))
> > +/* rng module clock status bits */
> > +#define AM335X_CLK_RNG_BIT_MASK (0x30000)
> > +/* Offset from RNG base for output ready flag */
> > +#define RNG_STATUS_RDY (1u <<  0)
> > +/* Offset from RNG base for FRO related error */
> > +#define RNG_STATUS_ERR (1u <<  1)
> > +/* Offset from RNG base for clock status */
> > +#define RNG_STATUS_CLK (1u << 31)
> > +/* enable module */
> > +#define AM335X_RNG_ENABLE (1 << 10)
> > +
> > +/* TRNG register structure */
> > +struct bbb_trng_register
> > +{
> > +    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 */
> > +};
> > +typedef struct bbb_trng_register bbb_trng_register;
> >
> >
> > The bbb (Beagle Bone Black) is a particular board and the AM335X is a
> SoC family. This should be something like this
> >
> > typedef struct {
> >  ...
> > } am335x_trng;
> >
> >
> >
> > +
> > +#endif
> > \ No newline at end of file
> >
> >
> >
> > Git thinks that files should have a newline at the end of the file.
> >
> >
> >
> > diff --git a/c/src/lib/libbsp/arm/beagle/Makefile.am
> b/c/src/lib/libbsp/arm/beagle/Makefile.am
> > index 8251660..5d5ade3 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 += getentropy/bbb_getentropy.c
> > +
> >
> >
> >
> > With the new BSP source structure
> >
> > https://devel.rtems.org/ticket/3285
> >
> > this new file could be also placed at
> >
> > bsps/arm/beagle/dev/getentropy.c
> >
> >
> >
> > Is this specific to the Beagle or the SoC? Or a combination? Earlier you
> said the structure was SoC specific?
> >
> >
> > [...]
> >
> > +int getentropy(void *ptr, size_t n)
> > +{
> > +    volatile bbb_trng_register  *rng = (bbb_trng_register*) RNG_BASE;
> > +    am335x_rng_enable(rng);
> > +    while (n > 0)
> > +    {
> > +        uint64_t random;
> > +        size_t copy;
> > +
> > +        /* wait untill RNG becomes ready with next set of random data */
> > +        while( ( rng->status & RNG_STATUS_RDY ) == 0 )
> > +        {
> > +            /* wait */
> > +        }
> >
> >
> > What happens if you call this function in parallel on different
> processors?
> >
> >
> > +
> > +        random = trng_getranddata(rng);
> > +
> > +        /* Checking for error by masking all bits other then error bit
> in
> > +           status register */
> > +        if( ((rng->status & RNG_STATUS_ERR)>>1) == 1)
> > +        {
> > +            /* clear the status flag after reading to generate new
> random
> > +               value */
> > +            rng->status_clr = RNG_STATUS_RDY;
> > +            copy = sizeof(random);
> > +            if ( n < copy )
> > +            {
> > +                copy = n;
> > +            }
> > +            memcpy(ptr, &random, copy);
> > +            n -= copy;
> > +            ptr = (char*)ptr + copy;
> > +        }
> > +    }
> > +
> > +    return 0;
> > +}
> > +
> > +RTEMS_SYSINIT_ITEM(
> > +    am335x_rng_clock_enable,
> > +    RTEMS_SYSINIT_DEVICE_DRIVERS,
> > +    RTEMS_SYSINIT_ORDER_LAST
> > +);
> > \ No newline at end of file
> > --
> > 1.9.1
> >
> >
> >
> >
> >
> > _______________________________________________
> > devel mailing list
> > devel at rtems.org
> > http://lists.rtems.org/mailman/listinfo/devel
> >
> >
> > --
> > Sebastian Huber, embedded brains GmbH
> >
> > Address : Dornierstr. 4, D-82178 Puchheim, Germany
> > Phone   : +49 89 189 47 41-16
> > Fax     : +49 89 189 47 41-09
> > E-Mail  : sebastian.huber at embedded-brains.de
> > PGP     : Public key available on request.
> >
> > Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
> >
> >
> > _______________________________________________
> > devel mailing list
> > devel at rtems.org
> > http://lists.rtems.org/mailman/listinfo/devel
> >
> >
> >
> >
>
> --
> --------------------------------------------
> embedded brains GmbH
> Christian Mauderer
> Dornierstr. 4
> D-82178 Puchheim
> Germany
> email: christian.mauderer at embedded-brains.de
> Phone: +49-89-18 94 741 - 18
> Fax:   +49-89-18 94 741 - 08
> PGP: Public key available on request.
>
> Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20180315/972f015a/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Fixed-mutual-exclusion-of-critical-section.patch
Type: text/x-patch
Size: 1241 bytes
Desc: not available
URL: <http://lists.rtems.org/pipermail/devel/attachments/20180315/972f015a/attachment-0002.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: 0001-Added-getentropy-support-to-beagle-BSP.patch
Type: text/x-patch
Size: 7177 bytes
Desc: not available
URL: <http://lists.rtems.org/pipermail/devel/attachments/20180315/972f015a/attachment-0003.bin>


More information about the devel mailing list