diff options
Diffstat (limited to 'arch/i386/kernel/cpu/amd.c')
-rw-r--r-- | arch/i386/kernel/cpu/amd.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/arch/i386/kernel/cpu/amd.c b/arch/i386/kernel/cpu/amd.c index 41cfea57232b..2d47db482972 100644 --- a/arch/i386/kernel/cpu/amd.c +++ b/arch/i386/kernel/cpu/amd.c | |||
@@ -22,6 +22,37 @@ | |||
22 | extern void vide(void); | 22 | extern void vide(void); |
23 | __asm__(".align 4\nvide: ret"); | 23 | __asm__(".align 4\nvide: ret"); |
24 | 24 | ||
25 | #define ENABLE_C1E_MASK 0x18000000 | ||
26 | #define CPUID_PROCESSOR_SIGNATURE 1 | ||
27 | #define CPUID_XFAM 0x0ff00000 | ||
28 | #define CPUID_XFAM_K8 0x00000000 | ||
29 | #define CPUID_XFAM_10H 0x00100000 | ||
30 | #define CPUID_XFAM_11H 0x00200000 | ||
31 | #define CPUID_XMOD 0x000f0000 | ||
32 | #define CPUID_XMOD_REV_F 0x00040000 | ||
33 | |||
34 | /* AMD systems with C1E don't have a working lAPIC timer. Check for that. */ | ||
35 | static __cpuinit int amd_apic_timer_broken(void) | ||
36 | { | ||
37 | u32 lo, hi; | ||
38 | u32 eax = cpuid_eax(CPUID_PROCESSOR_SIGNATURE); | ||
39 | switch (eax & CPUID_XFAM) { | ||
40 | case CPUID_XFAM_K8: | ||
41 | if ((eax & CPUID_XMOD) < CPUID_XMOD_REV_F) | ||
42 | break; | ||
43 | case CPUID_XFAM_10H: | ||
44 | case CPUID_XFAM_11H: | ||
45 | rdmsr(MSR_K8_ENABLE_C1E, lo, hi); | ||
46 | if (lo & ENABLE_C1E_MASK) | ||
47 | return 1; | ||
48 | break; | ||
49 | default: | ||
50 | /* err on the side of caution */ | ||
51 | return 1; | ||
52 | } | ||
53 | return 0; | ||
54 | } | ||
55 | |||
25 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) | 56 | static void __cpuinit init_amd(struct cpuinfo_x86 *c) |
26 | { | 57 | { |
27 | u32 l, h; | 58 | u32 l, h; |
@@ -241,6 +272,9 @@ static void __cpuinit init_amd(struct cpuinfo_x86 *c) | |||
241 | 272 | ||
242 | if (cpuid_eax(0x80000000) >= 0x80000006) | 273 | if (cpuid_eax(0x80000000) >= 0x80000006) |
243 | num_cache_leaves = 3; | 274 | num_cache_leaves = 3; |
275 | |||
276 | if (amd_apic_timer_broken()) | ||
277 | set_bit(X86_FEATURE_LAPIC_TIMER_BROKEN, c->x86_capability); | ||
244 | } | 278 | } |
245 | 279 | ||
246 | static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) | 280 | static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) |