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.mada...@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.mada...@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 <b...@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.mada...@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.maude...@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 <j...@rtems.org> wrote: > > > > > > > > > > > > On Mar 13, 2018 1:31 AM, "Sebastian Huber" <sebastian.huber@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.mada...@gmail.com <mailto:dev.mada...@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 <b...@shrike-systems.com <mailto: > b...@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.mada...@gmail.com <mailto: > dev.mada...@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@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.hu...@embedded-brains.de > > PGP : Public key available on request. > > > > Diese Nachricht ist keine geschäftliche Mitteilung im Sinne des EHUG. > > > > > > _______________________________________________ > > devel mailing list > > devel@rtems.org > > http://lists.rtems.org/mailman/listinfo/devel > > > > > > > > > > -- > -------------------------------------------- > embedded brains GmbH > Christian Mauderer > Dornierstr. 4 > D-82178 Puchheim > Germany > email: christian.maude...@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. >
From ae0c79ae4850503259c64387dea69346e7d7b1d4 Mon Sep 17 00:00:00 2001 From: Udit agarwal <dev.mada...@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
From ea885f9681c14f324917469b295e7489f56c10e7 Mon Sep 17 00:00:00 2001 From: Udit agarwal <dev.mada...@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 <b...@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.mada...@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
_______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel