Merge tag 'imx-drm-next-2020-10-30' of git://git.pengutronix.de/git/pza/linux into...
[linux-2.6-microblaze.git] / arch / arm64 / include / asm / archrandom.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_ARCHRANDOM_H
3 #define _ASM_ARCHRANDOM_H
4
5 #ifdef CONFIG_ARCH_RANDOM
6
7 #include <linux/bug.h>
8 #include <linux/kernel.h>
9 #include <asm/cpufeature.h>
10
11 static inline bool __arm64_rndr(unsigned long *v)
12 {
13         bool ok;
14
15         /*
16          * Reads of RNDR set PSTATE.NZCV to 0b0000 on success,
17          * and set PSTATE.NZCV to 0b0100 otherwise.
18          */
19         asm volatile(
20                 __mrs_s("%0", SYS_RNDR_EL0) "\n"
21         "       cset %w1, ne\n"
22         : "=r" (*v), "=r" (ok)
23         :
24         : "cc");
25
26         return ok;
27 }
28
29 static inline bool __must_check arch_get_random_long(unsigned long *v)
30 {
31         return false;
32 }
33
34 static inline bool __must_check arch_get_random_int(unsigned int *v)
35 {
36         return false;
37 }
38
39 static inline bool __must_check arch_get_random_seed_long(unsigned long *v)
40 {
41         /*
42          * Only support the generic interface after we have detected
43          * the system wide capability, avoiding complexity with the
44          * cpufeature code and with potential scheduling between CPUs
45          * with and without the feature.
46          */
47         if (!cpus_have_const_cap(ARM64_HAS_RNG))
48                 return false;
49
50         return __arm64_rndr(v);
51 }
52
53
54 static inline bool __must_check arch_get_random_seed_int(unsigned int *v)
55 {
56         unsigned long val;
57         bool ok = arch_get_random_seed_long(&val);
58
59         *v = val;
60         return ok;
61 }
62
63 static inline bool __init __early_cpu_has_rndr(void)
64 {
65         /* Open code as we run prior to the first call to cpufeature. */
66         unsigned long ftr = read_sysreg_s(SYS_ID_AA64ISAR0_EL1);
67         return (ftr >> ID_AA64ISAR0_RNDR_SHIFT) & 0xf;
68 }
69
70 static inline bool __init __must_check
71 arch_get_random_seed_long_early(unsigned long *v)
72 {
73         WARN_ON(system_state != SYSTEM_BOOTING);
74
75         if (!__early_cpu_has_rndr())
76                 return false;
77
78         return __arm64_rndr(v);
79 }
80 #define arch_get_random_seed_long_early arch_get_random_seed_long_early
81
82 #endif /* CONFIG_ARCH_RANDOM */
83 #endif /* _ASM_ARCHRANDOM_H */