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 + * <rt...@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
_______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel