xref: /linux/arch/powerpc/platforms/microwatt/rng.c (revision 4afc78eae10cd74c5a0b70822b9754d1d094c5d6)
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>
14c25769fdSPaul Mackerras 
15c25769fdSPaul Mackerras #define DARN_ERR 0xFFFFFFFFFFFFFFFFul
16c25769fdSPaul Mackerras 
17*4afc78eaSMichael Ellerman static int microwatt_get_random_darn(unsigned long *v)
18c25769fdSPaul Mackerras {
19c25769fdSPaul Mackerras 	unsigned long val;
20c25769fdSPaul Mackerras 
21c25769fdSPaul Mackerras 	/* Using DARN with L=1 - 64-bit conditioned random number */
22c25769fdSPaul Mackerras 	asm volatile(PPC_DARN(%0, 1) : "=r"(val));
23c25769fdSPaul Mackerras 
24c25769fdSPaul Mackerras 	if (val == DARN_ERR)
25c25769fdSPaul Mackerras 		return 0;
26c25769fdSPaul Mackerras 
27c25769fdSPaul Mackerras 	*v = val;
28c25769fdSPaul Mackerras 
29c25769fdSPaul Mackerras 	return 1;
30c25769fdSPaul Mackerras }
31c25769fdSPaul Mackerras 
32c25769fdSPaul Mackerras static __init int rng_init(void)
33c25769fdSPaul Mackerras {
34c25769fdSPaul Mackerras 	unsigned long val;
35c25769fdSPaul Mackerras 	int i;
36c25769fdSPaul Mackerras 
37c25769fdSPaul Mackerras 	for (i = 0; i < 10; i++) {
38c25769fdSPaul Mackerras 		if (microwatt_get_random_darn(&val)) {
39c25769fdSPaul Mackerras 			ppc_md.get_random_seed = microwatt_get_random_darn;
40c25769fdSPaul Mackerras 			return 0;
41c25769fdSPaul Mackerras 		}
42c25769fdSPaul Mackerras 	}
43c25769fdSPaul Mackerras 
44c25769fdSPaul Mackerras 	pr_warn("Unable to use DARN for get_random_seed()\n");
45c25769fdSPaul Mackerras 
46c25769fdSPaul Mackerras 	return -EIO;
47c25769fdSPaul Mackerras }
48c25769fdSPaul Mackerras machine_subsys_initcall(, rng_init);
49