ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/marvell/uboot/drivers/geu/asr_rng.c b/marvell/uboot/drivers/geu/asr_rng.c
new file mode 100644
index 0000000..e52e994
--- /dev/null
+++ b/marvell/uboot/drivers/geu/asr_rng.c
@@ -0,0 +1,122 @@
+#include <common.h>

+#include <config.h>

+#include <ubi_uboot.h>

+#include <asm/arch/cpu.h>

+#include <kgdb.h>

+#include <asm/processor.h>

+#include <asm/io.h>

+#include <malloc.h>

+#include "asr_geu.h"

+#include "asr_rng.h"

+

+static struct random_data random_data = {

+    .random_base = GEU_BASE,

+    .random_num_saved = 0

+};

+

+#define random_read(x)	readl(random_data.random_base + x)

+#define random_write(x, y) writel(y, (random_data.random_base + x))

+

+static void geu_rng_enable(void)

+{

+	uint32_t val;

+	uint32_t seed = read_timer();   //TODO

+

+	val = random_read(GEU_PRNG_CTRL_REG);

+	if (!(val & GEU_PRNG_EN)) {

+		val |= GEU_PRNG_EN;

+		random_write(GEU_PRNG_CTRL_REG, val);

+		udelay(1000); /* means a reset happens */

+	}

+	random_write(GEU_HW_RANDOM_NUM_SEED, seed & 0xFF);

+}

+

+static uint32_t geu_get_random_data(void)

+{

+	uint32_t val = 0;

+	uint32_t timeout = 100, mytime;

+	int ret = 0;

+

+	uint32_t start = get_timer(0);

+	

+	do {

+		val = random_read(GEU_HW_RANDOM_NUM_GEN);

+		mytime = get_timer(start);

+

+		if (mytime >= timeout) {

+			// porintf("fail to generate rng seed, time out!");

+			panic("fail to generate rng seed, time out!\n");

+		}

+	}while(val ==0 || val == random_data.random_num_saved);

+

+exit:

+	random_data.random_num_saved = val;

+

+	return val;

+}

+

+uint32_t crypto_rng_read(void *buf, size_t len)

+{

+	uint32_t *rngbuf = buf;

+	uint32_t val = 0;

+

+	assert(buf);

+

+	asr_geu_get();

+	geu_enable_clk();

+	geu_rng_enable();

+

+	while (len) {

+		val = geu_get_random_data();

+		if (len > sizeof(uint32_t)) {

+			len = len - sizeof(uint32_t);

+			memcpy(rngbuf, &val, sizeof(uint32_t));

+			rngbuf++;

+		} else {

+			memcpy(rngbuf, &val, len);

+			len = 0;

+		}

+	}

+	geu_disable_clk();

+	asr_geu_put();

+

+	return 0;

+}

+

+uint8_t hw_get_random_byte(void)

+{

+	uint8_t data = 0;

+

+	if (crypto_rng_read(&data, 1))

+		panic("rng read failed\n");

+

+	return data;

+}

+

+uint32_t hw_get_random_32(void)

+{

+	uint32_t data = 0;

+

+	if (crypto_rng_read(&data, 4))

+		panic("rng read failed\n");

+

+	return data;

+}

+

+void geu_random_test(void)

+{

+    uint8_t buf[32] = {0};

+    uint32_t size = sizeof(buf);

+

+    if (crypto_rng_read(buf, size)) {

+        printf("geu rng test failed");

+        return;

+    }

+

+    for (uint32_t i = 0; i < size; i++) {

+        printf("%.2x ", buf[i]);

+        if ((i + 1) == 0)

+            printf("\n");

+    }

+    printf("\n");

+}
\ No newline at end of file