blob: e52e994db58de16c95fe454949bef6a40f72a58b [file] [log] [blame]
#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");
}