aboutsummaryrefslogtreecommitdiffstats
path: root/arch/i386
diff options
context:
space:
mode:
Diffstat (limited to 'arch/i386')
-rw-r--r--arch/i386/kernel/apic.c32
-rw-r--r--arch/i386/kernel/cpu/amd.c34
2 files changed, 37 insertions, 29 deletions
diff --git a/arch/i386/kernel/apic.c b/arch/i386/kernel/apic.c
index e88415282a6f..93aa911646ad 100644
--- a/arch/i386/kernel/apic.c
+++ b/arch/i386/kernel/apic.c
@@ -272,32 +272,6 @@ static void __devinit setup_APIC_timer(void)
272} 272}
273 273
274/* 274/*
275 * Detect systems with known broken BIOS implementations
276 */
277static int __init lapic_check_broken_bios(struct dmi_system_id *d)
278{
279 printk(KERN_NOTICE "%s detected: disabling lapic timer.\n",
280 d->ident);
281 local_apic_timer_disabled = 1;
282 return 0;
283}
284
285static struct dmi_system_id __initdata broken_bios_dmi_table[] = {
286 {
287 /*
288 * BIOS exports only C1 state, but uses deeper power
289 * modes behind the kernels back.
290 */
291 .callback = lapic_check_broken_bios,
292 .ident = "HP nx6325",
293 .matches = {
294 DMI_MATCH(DMI_PRODUCT_NAME, "HP Compaq nx6325"),
295 },
296 },
297 {}
298};
299
300/*
301 * In this functions we calibrate APIC bus clocks to the external timer. 275 * In this functions we calibrate APIC bus clocks to the external timer.
302 * 276 *
303 * We want to do the calibration only once since we want to have local timer 277 * We want to do the calibration only once since we want to have local timer
@@ -372,12 +346,12 @@ void __init setup_boot_APIC_clock(void)
372 long delta, deltapm; 346 long delta, deltapm;
373 int pm_referenced = 0; 347 int pm_referenced = 0;
374 348
375 /* Detect know broken systems */ 349 if (boot_cpu_has(X86_FEATURE_LAPIC_TIMER_BROKEN))
376 dmi_check_system(broken_bios_dmi_table); 350 local_apic_timer_disabled = 1;
377 351
378 /* 352 /*
379 * The local apic timer can be disabled via the kernel 353 * The local apic timer can be disabled via the kernel
380 * commandline or from the dmi quirk above. Register the lapic 354 * commandline or from the test above. Register the lapic
381 * timer as a dummy clock event source on SMP systems, so the 355 * timer as a dummy clock event source on SMP systems, so the
382 * broadcast mechanism is used. On UP systems simply ignore it. 356 * broadcast mechanism is used. On UP systems simply ignore it.
383 */ 357 */
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 @@
22extern void vide(void); 22extern 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. */
35static __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
25static void __cpuinit init_amd(struct cpuinfo_x86 *c) 56static 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
246static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size) 280static unsigned int __cpuinit amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)