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