Branch data Line data Source code
1 : : // SPDX-License-Identifier: GPL-2.0
2 : : #include <linux/sched.h>
3 : : #include <linux/sched/clock.h>
4 : :
5 : : #include <asm/cpufeature.h>
6 : :
7 : : #include "cpu.h"
8 : :
9 : : #define MSR_ZHAOXIN_FCR57 0x00001257
10 : :
11 : : #define ACE_PRESENT (1 << 6)
12 : : #define ACE_ENABLED (1 << 7)
13 : : #define ACE_FCR (1 << 7) /* MSR_ZHAOXIN_FCR */
14 : :
15 : : #define RNG_PRESENT (1 << 2)
16 : : #define RNG_ENABLED (1 << 3)
17 : : #define RNG_ENABLE (1 << 8) /* MSR_ZHAOXIN_RNG */
18 : :
19 : 0 : static void init_zhaoxin_cap(struct cpuinfo_x86 *c)
20 : : {
21 : 0 : u32 lo, hi;
22 : :
23 : : /* Test for Extended Feature Flags presence */
24 [ # # ]: 0 : if (cpuid_eax(0xC0000000) >= 0xC0000001) {
25 : 0 : u32 tmp = cpuid_edx(0xC0000001);
26 : :
27 : : /* Enable ACE unit, if present and disabled */
28 [ # # ]: 0 : if ((tmp & (ACE_PRESENT | ACE_ENABLED)) == ACE_PRESENT) {
29 : 0 : rdmsr(MSR_ZHAOXIN_FCR57, lo, hi);
30 : : /* Enable ACE unit */
31 : 0 : lo |= ACE_FCR;
32 : 0 : wrmsr(MSR_ZHAOXIN_FCR57, lo, hi);
33 : 0 : pr_info("CPU: Enabled ACE h/w crypto\n");
34 : : }
35 : :
36 : : /* Enable RNG unit, if present and disabled */
37 [ # # ]: 0 : if ((tmp & (RNG_PRESENT | RNG_ENABLED)) == RNG_PRESENT) {
38 : 0 : rdmsr(MSR_ZHAOXIN_FCR57, lo, hi);
39 : : /* Enable RNG unit */
40 : 0 : lo |= RNG_ENABLE;
41 : 0 : wrmsr(MSR_ZHAOXIN_FCR57, lo, hi);
42 : 0 : pr_info("CPU: Enabled h/w RNG\n");
43 : : }
44 : :
45 : : /*
46 : : * Store Extended Feature Flags as word 5 of the CPU
47 : : * capability bit array
48 : : */
49 : 0 : c->x86_capability[CPUID_C000_0001_EDX] = cpuid_edx(0xC0000001);
50 : : }
51 : :
52 [ # # ]: 0 : if (c->x86 >= 0x6)
53 : 0 : set_cpu_cap(c, X86_FEATURE_REP_GOOD);
54 : 0 : }
55 : :
56 : 0 : static void early_init_zhaoxin(struct cpuinfo_x86 *c)
57 : : {
58 [ # # ]: 0 : if (c->x86 >= 0x6)
59 : 0 : set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
60 : : #ifdef CONFIG_X86_64
61 : 0 : set_cpu_cap(c, X86_FEATURE_SYSENTER32);
62 : : #endif
63 [ # # ]: 0 : if (c->x86_power & (1 << 8)) {
64 : 0 : set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
65 : 0 : set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
66 : : }
67 : :
68 [ # # ]: 0 : if (c->cpuid_level >= 0x00000001) {
69 : 0 : u32 eax, ebx, ecx, edx;
70 : :
71 : 0 : cpuid(0x00000001, &eax, &ebx, &ecx, &edx);
72 : : /*
73 : : * If HTT (EDX[28]) is set EBX[16:23] contain the number of
74 : : * apicids which are reserved per package. Store the resulting
75 : : * shift value for the package management code.
76 : : */
77 [ # # ]: 0 : if (edx & (1U << 28))
78 [ # # ]: 0 : c->x86_coreid_bits = get_count_order((ebx >> 16) & 0xff);
79 : : }
80 : :
81 : 0 : }
82 : :
83 : 0 : static void init_zhaoxin(struct cpuinfo_x86 *c)
84 : : {
85 : 0 : early_init_zhaoxin(c);
86 : 0 : init_intel_cacheinfo(c);
87 : 0 : detect_num_cpu_cores(c);
88 : : #ifdef CONFIG_X86_32
89 : : detect_ht(c);
90 : : #endif
91 : :
92 [ # # ]: 0 : if (c->cpuid_level > 9) {
93 : 0 : unsigned int eax = cpuid_eax(10);
94 : :
95 : : /*
96 : : * Check for version and the number of counters
97 : : * Version(eax[7:0]) can't be 0;
98 : : * Counters(eax[15:8]) should be greater than 1;
99 : : */
100 [ # # # # ]: 0 : if ((eax & 0xff) && (((eax >> 8) & 0xff) > 1))
101 : 0 : set_cpu_cap(c, X86_FEATURE_ARCH_PERFMON);
102 : : }
103 : :
104 [ # # ]: 0 : if (c->x86 >= 0x6)
105 : 0 : init_zhaoxin_cap(c);
106 : : #ifdef CONFIG_X86_64
107 : 0 : set_cpu_cap(c, X86_FEATURE_LFENCE_RDTSC);
108 : : #endif
109 : :
110 : 0 : init_ia32_feat_ctl(c);
111 : 0 : }
112 : :
113 : : #ifdef CONFIG_X86_32
114 : : static unsigned int
115 : : zhaoxin_size_cache(struct cpuinfo_x86 *c, unsigned int size)
116 : : {
117 : : return size;
118 : : }
119 : : #endif
120 : :
121 : : static const struct cpu_dev zhaoxin_cpu_dev = {
122 : : .c_vendor = "zhaoxin",
123 : : .c_ident = { " Shanghai " },
124 : : .c_early_init = early_init_zhaoxin,
125 : : .c_init = init_zhaoxin,
126 : : #ifdef CONFIG_X86_32
127 : : .legacy_cache_size = zhaoxin_size_cache,
128 : : #endif
129 : : .c_x86_vendor = X86_VENDOR_ZHAOXIN,
130 : : };
131 : :
132 : : cpu_dev_register(zhaoxin_cpu_dev);
|