diff options
Diffstat (limited to 'arch/x86/kernel/cpu/addon_cpuid_features.c')
-rw-r--r-- | arch/x86/kernel/cpu/addon_cpuid_features.c | 150 |
1 files changed, 0 insertions, 150 deletions
diff --git a/arch/x86/kernel/cpu/addon_cpuid_features.c b/arch/x86/kernel/cpu/addon_cpuid_features.c deleted file mode 100644 index 41eebcd90fc..00000000000 --- a/arch/x86/kernel/cpu/addon_cpuid_features.c +++ /dev/null | |||
@@ -1,150 +0,0 @@ | |||
1 | /* | ||
2 | * Routines to indentify additional cpu features that are scattered in | ||
3 | * cpuid space. | ||
4 | */ | ||
5 | #include <linux/cpu.h> | ||
6 | |||
7 | #include <asm/pat.h> | ||
8 | #include <asm/processor.h> | ||
9 | |||
10 | #include <asm/apic.h> | ||
11 | |||
12 | struct cpuid_bit { | ||
13 | u16 feature; | ||
14 | u8 reg; | ||
15 | u8 bit; | ||
16 | u32 level; | ||
17 | u32 sub_leaf; | ||
18 | }; | ||
19 | |||
20 | enum cpuid_regs { | ||
21 | CR_EAX = 0, | ||
22 | CR_ECX, | ||
23 | CR_EDX, | ||
24 | CR_EBX | ||
25 | }; | ||
26 | |||
27 | void __cpuinit init_scattered_cpuid_features(struct cpuinfo_x86 *c) | ||
28 | { | ||
29 | u32 max_level; | ||
30 | u32 regs[4]; | ||
31 | const struct cpuid_bit *cb; | ||
32 | |||
33 | static const struct cpuid_bit __cpuinitconst cpuid_bits[] = { | ||
34 | { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, | ||
35 | { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, | ||
36 | { X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006, 0 }, | ||
37 | { X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 }, | ||
38 | { X86_FEATURE_XSAVEOPT, CR_EAX, 0, 0x0000000d, 1 }, | ||
39 | { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 }, | ||
40 | { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a, 0 }, | ||
41 | { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 }, | ||
42 | { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 }, | ||
43 | { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a, 0 }, | ||
44 | { 0, 0, 0, 0, 0 } | ||
45 | }; | ||
46 | |||
47 | for (cb = cpuid_bits; cb->feature; cb++) { | ||
48 | |||
49 | /* Verify that the level is valid */ | ||
50 | max_level = cpuid_eax(cb->level & 0xffff0000); | ||
51 | if (max_level < cb->level || | ||
52 | max_level > (cb->level | 0xffff)) | ||
53 | continue; | ||
54 | |||
55 | cpuid_count(cb->level, cb->sub_leaf, ®s[CR_EAX], | ||
56 | ®s[CR_EBX], ®s[CR_ECX], ®s[CR_EDX]); | ||
57 | |||
58 | if (regs[cb->reg] & (1 << cb->bit)) | ||
59 | set_cpu_cap(c, cb->feature); | ||
60 | } | ||
61 | } | ||
62 | |||
63 | /* leaf 0xb SMT level */ | ||
64 | #define SMT_LEVEL 0 | ||
65 | |||
66 | /* leaf 0xb sub-leaf types */ | ||
67 | #define INVALID_TYPE 0 | ||
68 | #define SMT_TYPE 1 | ||
69 | #define CORE_TYPE 2 | ||
70 | |||
71 | #define LEAFB_SUBTYPE(ecx) (((ecx) >> 8) & 0xff) | ||
72 | #define BITS_SHIFT_NEXT_LEVEL(eax) ((eax) & 0x1f) | ||
73 | #define LEVEL_MAX_SIBLINGS(ebx) ((ebx) & 0xffff) | ||
74 | |||
75 | /* | ||
76 | * Check for extended topology enumeration cpuid leaf 0xb and if it | ||
77 | * exists, use it for populating initial_apicid and cpu topology | ||
78 | * detection. | ||
79 | */ | ||
80 | void __cpuinit detect_extended_topology(struct cpuinfo_x86 *c) | ||
81 | { | ||
82 | #ifdef CONFIG_SMP | ||
83 | unsigned int eax, ebx, ecx, edx, sub_index; | ||
84 | unsigned int ht_mask_width, core_plus_mask_width; | ||
85 | unsigned int core_select_mask, core_level_siblings; | ||
86 | static bool printed; | ||
87 | |||
88 | if (c->cpuid_level < 0xb) | ||
89 | return; | ||
90 | |||
91 | cpuid_count(0xb, SMT_LEVEL, &eax, &ebx, &ecx, &edx); | ||
92 | |||
93 | /* | ||
94 | * check if the cpuid leaf 0xb is actually implemented. | ||
95 | */ | ||
96 | if (ebx == 0 || (LEAFB_SUBTYPE(ecx) != SMT_TYPE)) | ||
97 | return; | ||
98 | |||
99 | set_cpu_cap(c, X86_FEATURE_XTOPOLOGY); | ||
100 | |||
101 | /* | ||
102 | * initial apic id, which also represents 32-bit extended x2apic id. | ||
103 | */ | ||
104 | c->initial_apicid = edx; | ||
105 | |||
106 | /* | ||
107 | * Populate HT related information from sub-leaf level 0. | ||
108 | */ | ||
109 | core_level_siblings = smp_num_siblings = LEVEL_MAX_SIBLINGS(ebx); | ||
110 | core_plus_mask_width = ht_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); | ||
111 | |||
112 | sub_index = 1; | ||
113 | do { | ||
114 | cpuid_count(0xb, sub_index, &eax, &ebx, &ecx, &edx); | ||
115 | |||
116 | /* | ||
117 | * Check for the Core type in the implemented sub leaves. | ||
118 | */ | ||
119 | if (LEAFB_SUBTYPE(ecx) == CORE_TYPE) { | ||
120 | core_level_siblings = LEVEL_MAX_SIBLINGS(ebx); | ||
121 | core_plus_mask_width = BITS_SHIFT_NEXT_LEVEL(eax); | ||
122 | break; | ||
123 | } | ||
124 | |||
125 | sub_index++; | ||
126 | } while (LEAFB_SUBTYPE(ecx) != INVALID_TYPE); | ||
127 | |||
128 | core_select_mask = (~(-1 << core_plus_mask_width)) >> ht_mask_width; | ||
129 | |||
130 | c->cpu_core_id = apic->phys_pkg_id(c->initial_apicid, ht_mask_width) | ||
131 | & core_select_mask; | ||
132 | c->phys_proc_id = apic->phys_pkg_id(c->initial_apicid, core_plus_mask_width); | ||
133 | /* | ||
134 | * Reinit the apicid, now that we have extended initial_apicid. | ||
135 | */ | ||
136 | c->apicid = apic->phys_pkg_id(c->initial_apicid, 0); | ||
137 | |||
138 | c->x86_max_cores = (core_level_siblings / smp_num_siblings); | ||
139 | |||
140 | if (!printed) { | ||
141 | printk(KERN_INFO "CPU: Physical Processor ID: %d\n", | ||
142 | c->phys_proc_id); | ||
143 | if (c->x86_max_cores > 1) | ||
144 | printk(KERN_INFO "CPU: Processor Core ID: %d\n", | ||
145 | c->cpu_core_id); | ||
146 | printed = 1; | ||
147 | } | ||
148 | return; | ||
149 | #endif | ||
150 | } | ||