Commit | Line | Data |
---|---|---|
2decb194 PA |
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[] = { | |
4ad33411 | 34 | { X86_FEATURE_DTHERM, CR_EAX, 0, 0x00000006, 0 }, |
2decb194 PA |
35 | { X86_FEATURE_IDA, CR_EAX, 1, 0x00000006, 0 }, |
36 | { X86_FEATURE_ARAT, CR_EAX, 2, 0x00000006, 0 }, | |
9792db61 FY |
37 | { X86_FEATURE_PLN, CR_EAX, 4, 0x00000006, 0 }, |
38 | { X86_FEATURE_PTS, CR_EAX, 6, 0x00000006, 0 }, | |
2decb194 PA |
39 | { X86_FEATURE_APERFMPERF, CR_ECX, 0, 0x00000006, 0 }, |
40 | { X86_FEATURE_EPB, CR_ECX, 3, 0x00000006, 0 }, | |
41 | { X86_FEATURE_XSAVEOPT, CR_EAX, 0, 0x0000000d, 1 }, | |
42 | { X86_FEATURE_CPB, CR_EDX, 9, 0x80000007, 0 }, | |
2f1e097e | 43 | { X86_FEATURE_HW_PSTATE, CR_EDX, 7, 0x80000007, 0 }, |
2decb194 PA |
44 | { X86_FEATURE_NPT, CR_EDX, 0, 0x8000000a, 0 }, |
45 | { X86_FEATURE_LBRV, CR_EDX, 1, 0x8000000a, 0 }, | |
46 | { X86_FEATURE_SVML, CR_EDX, 2, 0x8000000a, 0 }, | |
47 | { X86_FEATURE_NRIPS, CR_EDX, 3, 0x8000000a, 0 }, | |
aeb9c7d6 AP |
48 | { X86_FEATURE_TSCRATEMSR, CR_EDX, 4, 0x8000000a, 0 }, |
49 | { X86_FEATURE_VMCBCLEAN, CR_EDX, 5, 0x8000000a, 0 }, | |
50 | { X86_FEATURE_FLUSHBYASID, CR_EDX, 6, 0x8000000a, 0 }, | |
51 | { X86_FEATURE_DECODEASSISTS, CR_EDX, 7, 0x8000000a, 0 }, | |
52 | { X86_FEATURE_PAUSEFILTER, CR_EDX,10, 0x8000000a, 0 }, | |
53 | { X86_FEATURE_PFTHRESHOLD, CR_EDX,12, 0x8000000a, 0 }, | |
2decb194 PA |
54 | { 0, 0, 0, 0, 0 } |
55 | }; | |
56 | ||
57 | for (cb = cpuid_bits; cb->feature; cb++) { | |
58 | ||
59 | /* Verify that the level is valid */ | |
60 | max_level = cpuid_eax(cb->level & 0xffff0000); | |
61 | if (max_level < cb->level || | |
62 | max_level > (cb->level | 0xffff)) | |
63 | continue; | |
64 | ||
65 | cpuid_count(cb->level, cb->sub_leaf, ®s[CR_EAX], | |
66 | ®s[CR_EBX], ®s[CR_ECX], ®s[CR_EDX]); | |
67 | ||
68 | if (regs[cb->reg] & (1 << cb->bit)) | |
69 | set_cpu_cap(c, cb->feature); | |
70 | } | |
71 | } |