|
|
|
@ -444,35 +444,49 @@ int sec_reset(void) |
|
|
|
|
#ifndef CONFIG_SPL_BUILD |
|
|
|
|
static int instantiate_rng(uint8_t sec_idx) |
|
|
|
|
{ |
|
|
|
|
struct result op; |
|
|
|
|
u32 *desc; |
|
|
|
|
u32 rdsta_val; |
|
|
|
|
int ret = 0; |
|
|
|
|
int ret = 0, sh_idx, size; |
|
|
|
|
ccsr_sec_t __iomem *sec = (ccsr_sec_t __iomem *)SEC_ADDR(sec_idx); |
|
|
|
|
struct rng4tst __iomem *rng = |
|
|
|
|
(struct rng4tst __iomem *)&sec->rng; |
|
|
|
|
|
|
|
|
|
memset(&op, 0, sizeof(struct result)); |
|
|
|
|
|
|
|
|
|
desc = memalign(ARCH_DMA_MINALIGN, sizeof(uint32_t) * 6); |
|
|
|
|
if (!desc) { |
|
|
|
|
printf("cannot allocate RNG init descriptor memory\n"); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
inline_cnstr_jobdesc_rng_instantiation(desc); |
|
|
|
|
int size = roundup(sizeof(uint32_t) * 6, ARCH_DMA_MINALIGN); |
|
|
|
|
flush_dcache_range((unsigned long)desc, |
|
|
|
|
(unsigned long)desc + size); |
|
|
|
|
for (sh_idx = 0; sh_idx < RNG4_MAX_HANDLES; sh_idx++) { |
|
|
|
|
/*
|
|
|
|
|
* If the corresponding bit is set, this state handle |
|
|
|
|
* was initialized by somebody else, so it's left alone. |
|
|
|
|
*/ |
|
|
|
|
rdsta_val = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK; |
|
|
|
|
if (rdsta_val & (1 << sh_idx)) |
|
|
|
|
continue; |
|
|
|
|
|
|
|
|
|
inline_cnstr_jobdesc_rng_instantiation(desc, sh_idx); |
|
|
|
|
size = roundup(sizeof(uint32_t) * 6, ARCH_DMA_MINALIGN); |
|
|
|
|
flush_dcache_range((unsigned long)desc, |
|
|
|
|
(unsigned long)desc + size); |
|
|
|
|
|
|
|
|
|
ret = run_descriptor_jr_idx(desc, sec_idx); |
|
|
|
|
ret = run_descriptor_jr_idx(desc, sec_idx); |
|
|
|
|
|
|
|
|
|
if (ret) |
|
|
|
|
printf("RNG: Instantiation failed with error %x\n", ret); |
|
|
|
|
if (ret) |
|
|
|
|
printf("RNG: Instantiation failed with error 0x%x\n", |
|
|
|
|
ret); |
|
|
|
|
|
|
|
|
|
rdsta_val = sec_in32(&rng->rdsta); |
|
|
|
|
if (op.status || !(rdsta_val & RNG_STATE0_HANDLE_INSTANTIATED)) |
|
|
|
|
return -1; |
|
|
|
|
rdsta_val = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK; |
|
|
|
|
if (!(rdsta_val & (1 << sh_idx))) { |
|
|
|
|
free(desc); |
|
|
|
|
return -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
memset(desc, 0, sizeof(uint32_t) * 6); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
free(desc); |
|
|
|
|
|
|
|
|
|
return ret; |
|
|
|
|
} |
|
|
|
@ -524,14 +538,11 @@ static int rng_init(uint8_t sec_idx) |
|
|
|
|
ccsr_sec_t __iomem *sec = (ccsr_sec_t __iomem *)SEC_ADDR(sec_idx); |
|
|
|
|
struct rng4tst __iomem *rng = |
|
|
|
|
(struct rng4tst __iomem *)&sec->rng; |
|
|
|
|
|
|
|
|
|
u32 rdsta = sec_in32(&rng->rdsta); |
|
|
|
|
|
|
|
|
|
/* Check if RNG state 0 handler is already instantiated */ |
|
|
|
|
if (rdsta & RNG_STATE0_HANDLE_INSTANTIATED) |
|
|
|
|
return 0; |
|
|
|
|
u32 inst_handles; |
|
|
|
|
|
|
|
|
|
do { |
|
|
|
|
inst_handles = sec_in32(&rng->rdsta) & RNG_STATE_HANDLE_MASK; |
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* If either of the SH's were instantiated by somebody else |
|
|
|
|
* then it is assumed that the entropy |
|
|
|
@ -540,8 +551,10 @@ static int rng_init(uint8_t sec_idx) |
|
|
|
|
* Also, if a handle was instantiated, do not change |
|
|
|
|
* the TRNG parameters. |
|
|
|
|
*/ |
|
|
|
|
kick_trng(ent_delay, sec_idx); |
|
|
|
|
ent_delay += 400; |
|
|
|
|
if (!inst_handles) { |
|
|
|
|
kick_trng(ent_delay, sec_idx); |
|
|
|
|
ent_delay += 400; |
|
|
|
|
} |
|
|
|
|
/*
|
|
|
|
|
* if instantiate_rng(...) fails, the loop will rerun |
|
|
|
|
* and the kick_trng(...) function will modfiy the |
|
|
|
|