From c80b8fdf24dbdcbad435f59d83a07a4ad12602b0 Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Thu, 24 Aug 2023 15:35:50 +0300 Subject: [PATCH] arch/risc-v/src/mpfs/mpfs_ddr.c: Add a simple prng for memory training code Implement the previously empty mpfs_ddr_rand with adapted "seiran128" code from https://github.com/andanteyk/prng-seiran This implements a non-secure prng, which is minimal in size. The DDR training doesn't need cryptographically secure prng, and linking in the NuttX crypto would increase the code size significantly for bootloaders. Signed-off-by: Jukka Laitinen --- arch/risc-v/src/mpfs/mpfs_ddr.c | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) diff --git a/arch/risc-v/src/mpfs/mpfs_ddr.c b/arch/risc-v/src/mpfs/mpfs_ddr.c index db50ccb920..0ed14b4ac3 100644 --- a/arch/risc-v/src/mpfs/mpfs_ddr.c +++ b/arch/risc-v/src/mpfs/mpfs_ddr.c @@ -306,6 +306,14 @@ static const uint8_t refclk_offsets[][5] = #endif +/* State of the seiran128 PRNG, with initial seed */ + +static uint64_t prng_state[2] = + { + 0x6c64f673ed93b6cc, + 0x97c703d5f6c9d72b + }; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -2131,19 +2139,29 @@ static int mpfs_write_calibration_using_mtc(struct mpfs_ddr_priv_s *priv) * Name: mpfs_ddr_rand * * Description: - * This should return a random value. + * This is adapted from seiran128 + * (https://github.com/andanteyk/prng-seiran) * * Returned Value: - * Always zero at the moment. - * - * Assumptions/Limitations: - * This doesn't return random values at the moment. + * Non-cryptographically secure pseudo random number * ****************************************************************************/ +static inline uint64_t rotl(uint64_t x, int k) +{ + return (x << k) | (x >> (-k & 0x3f)); +} + static int mpfs_ddr_rand(void) { - return 0; + uint64_t s0 = prng_state[0]; + uint64_t s1 = prng_state[1]; + uint64_t result = rotl((s0 + s1) * 9, 29) + s0; + + prng_state[0] = s0 ^ rotl(s1, 29); + prng_state[1] = s0 ^ (s1 << 9); + + return (int)result; } /****************************************************************************