getentropy() implementation on BBB

Udit agarwal dev.madaari at gmail.com
Mon Mar 5 13:51:40 UTC 2018


Hi,
I tried implementing getentropy on BBB, below is the patch. Please have a
look.
I followed these(1
<https://e2e.ti.com/support/arm/sitara_arm/f/791/t/355064> & 2
<http://ftp.netbsd.org/pub/NetBSD/NetBSD-current/src/sys/arch/arm/omap/am335x_trng.c>)
links for code reference. and this
<https://docs.google.com/spreadsheets/d/1VpghMlLtrWQIrcvCsRg3ueRZkX0eGSQkFnzjfsqrd8A/view#gid=0>
for register reference. Moreover, what further configuration in RTEMS is
needed to execute and test this code along with getentropy() sample
testcode?


+ /*
+  * Copyright (c) 2018 embedded brains GmbH.  All rights reserved.
+  *
+  *  embedded brains GmbH
+  *  Dornierstr. 4
+  *  82178 Puchheim
+  *  Germany
+  *  <rtems at embedded-brains.de>
+  *
+  * The license and distribution terms for this file may be
+  * found in the file LICENSE in this distribution or at
+  * http://www.rtems.org/license/LICENSE.
+  */
+
+ #include <libcpu/am335x.h>
+ #include <unistd.h>
+ #include <string.h>
+ #include <rtems/sysinit.h>
+
+ #define RNG_BASE    0x48310000
+ #define CM_PER_RNG_CLKCTRL    0x44e00090
+ #define RNG_STATUS_RDY    (1u <<  0)  // output ready for reading
+ #define RNG_STATUS_ERR    (1u <<  1)  // FRO shutdown alarm
+ #define RNG_STATUS_CLK    (1u << 31)  // module functional clock active
(no irq)
+
+ typedef volatile struct rng *rng_ref_t;
+
+ struct rng {
+ /*00*/    uint64_t output;    //r-
+ /*08*/    uint32_t status;    //r-
+ /*0c*/    uint32_t irq_en;    //rw
+ /*10*/    uint32_t status_clr;    //-c
+ /*14*/    uint32_t control;    //rw
+ /*18*/    uint32_t config;    //rw
+ };
+
+ static void TRNG_Enable(rng_ref_t rng){
+     rng->config = 0
+     | 34 << 16  // max refill 34 * 256 cycles
+     | 33 <<  0;  // min refill 33 * 64 cycles
+     rng->control = 0
+     | 33 << 16  // startup 33 * 256 cycles
+     |  1 << 10;  // enable module
+ }
+
+ static void beagle_trng_clock_enable(void)
+ {
+     // enable module clock
+     *(volatile uint8_t *) CM_PER_RNG_CLKCTRL = 2;
+     while( *(volatile uint32_t *) CM_PER_RNG_CLKCTRL & 0x30000 ) {}
+ }
+
+ static uint64_t TRNG_GetRandData(){
+     uint64_t output = rng->output;
+     return output;
+ }
+
+ int getentropy(void *ptr, size_t n)
+ {
+     rng_ref_t const rng = (rng_ref_t) RNG_BASE;
+     TRNG_Enable(rng);
+     while (n > 0) {
+         uint64_t random;
+         size_t copy;
+
+         while( ( rng->status & RNG_STATUS_RDY ) == 0 ); //wait
+
+         random = TRNG_GetRandData(rng);
+
+         /*
+          * Read TRNG status one more time to avoid race condition.
+          * Otherwise we can read (and clear) an old ready status but get
+          * a new value. The ready status for this value wouldn't be
+          * reset.
+          */
+         rng->status_clr = RNG_STATUS_RDY;
+
+         copy = sizeof(random);
+         if (n < copy ) {
+             copy = n;
+         }
+         memcpy(ptr, &random, copy);
+         n -= copy;
+         ptr += copy;
+     }
+
+     return 0;
+ }
+
+ RTEMS_SYSINIT_ITEM(
+   beagle_trng_clock_enable,
+   RTEMS_SYSINIT_DEVICE_DRIVERS,
+   RTEMS_SYSINIT_ORDER_LAST
+ );

Regards,
Udit agarwal
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20180305/a4224415/attachment.html>


More information about the devel mailing list