1c25769fdSPaul Mackerras // SPDX-License-Identifier: GPL-2.0-or-later 2c25769fdSPaul Mackerras /* 3c25769fdSPaul Mackerras * Derived from arch/powerpc/platforms/powernv/rng.c, which is: 4c25769fdSPaul Mackerras * Copyright 2013, Michael Ellerman, IBM Corporation. 5c25769fdSPaul Mackerras */ 6c25769fdSPaul Mackerras 7c25769fdSPaul Mackerras #define pr_fmt(fmt) "microwatt-rng: " fmt 8c25769fdSPaul Mackerras 9c25769fdSPaul Mackerras #include <linux/kernel.h> 10c25769fdSPaul Mackerras #include <linux/smp.h> 11c25769fdSPaul Mackerras #include <asm/archrandom.h> 12c25769fdSPaul Mackerras #include <asm/cputable.h> 13c25769fdSPaul Mackerras #include <asm/machdep.h> 14*20a9689bSJason A. Donenfeld #include "microwatt.h" 15c25769fdSPaul Mackerras 16c25769fdSPaul Mackerras #define DARN_ERR 0xFFFFFFFFFFFFFFFFul 17c25769fdSPaul Mackerras 184afc78eaSMichael Ellerman static int microwatt_get_random_darn(unsigned long *v) 19c25769fdSPaul Mackerras { 20c25769fdSPaul Mackerras unsigned long val; 21c25769fdSPaul Mackerras 22c25769fdSPaul Mackerras /* Using DARN with L=1 - 64-bit conditioned random number */ 23c25769fdSPaul Mackerras asm volatile(PPC_DARN(%0, 1) : "=r"(val)); 24c25769fdSPaul Mackerras 25c25769fdSPaul Mackerras if (val == DARN_ERR) 26c25769fdSPaul Mackerras return 0; 27c25769fdSPaul Mackerras 28c25769fdSPaul Mackerras *v = val; 29c25769fdSPaul Mackerras 30c25769fdSPaul Mackerras return 1; 31c25769fdSPaul Mackerras } 32c25769fdSPaul Mackerras 33*20a9689bSJason A. Donenfeld void __init microwatt_rng_init(void) 34c25769fdSPaul Mackerras { 35c25769fdSPaul Mackerras unsigned long val; 36c25769fdSPaul Mackerras int i; 37c25769fdSPaul Mackerras 38c25769fdSPaul Mackerras for (i = 0; i < 10; i++) { 39c25769fdSPaul Mackerras if (microwatt_get_random_darn(&val)) { 40c25769fdSPaul Mackerras ppc_md.get_random_seed = microwatt_get_random_darn; 41*20a9689bSJason A. Donenfeld return; 42c25769fdSPaul Mackerras } 43c25769fdSPaul Mackerras } 44c25769fdSPaul Mackerras } 45