int mbytes = num_physpages >> (20-PAGE_SHIFT);
int r;
+#ifdef CONFIG_SMP
+ unsigned long long value;
+
+ /* Disable TLB flush filter by setting HWCR.FFDIS on K8
+ * bit 6 of msr C001_0015
+ *
+ * Errata 63 for SH-B3 steppings
+ * Errata 122 for all steppings (F+ have it disabled by default)
+ */
+ if (c->x86 == 15) {
+ rdmsrl(MSR_K7_HWCR, value);
+ value |= 1 << 6;
+ wrmsrl(MSR_K7_HWCR, value);
+ }
+#endif
+
/*
* FIXME: We should handle the K5 here. Set up the write
* range and also turn on MSR 83 bits 4 and 31 (write alloc,
set_bit(X86_FEATURE_K6_MTRR, c->x86_capability);
break;
}
- break;
+ if (c->x86_model == 10) {
+ /* AMD Geode LX is model 10 */
+ /* placeholder for any needed mods */
+ break;
+ }
+ break;
case 6: /* An Athlon/Duron */
/* Bit 15 of Athlon specific MSR 15, needs to be 0
set_bit(X86_FEATURE_K7, c->x86_capability);
break;
}
+ if (c->x86 >= 6)
+ set_bit(X86_FEATURE_FXSAVE_LEAK, c->x86_capability);
display_cacheinfo(c);
- detect_ht(c);
+
+ if (cpuid_eax(0x80000000) >= 0x80000008) {
+ c->x86_max_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
+ }
+
+ if (cpuid_eax(0x80000000) >= 0x80000007) {
+ c->x86_power = cpuid_edx(0x80000007);
+ if (c->x86_power & (1<<8))
+ set_bit(X86_FEATURE_CONSTANT_TSC, c->x86_capability);
+ }
#ifdef CONFIG_X86_HT
- /* AMD dual core looks like HT but isn't really. Hide it from the
- scheduler. This works around problems with the domain scheduler.
- Also probably gives slightly better scheduling and disables
- SMT nice which is harmful on dual core.
- TBD tune the domain scheduler for dual core. */
- if (cpu_has(c, X86_FEATURE_CMP_LEGACY))
- smp_num_siblings = 1;
+ /*
+ * On a AMD dual core setup the lower bits of the APIC id
+ * distingush the cores. Assumes number of cores is a power
+ * of two.
+ */
+ if (c->x86_max_cores > 1) {
+ int cpu = smp_processor_id();
+ unsigned bits = 0;
+ while ((1 << bits) < c->x86_max_cores)
+ bits++;
+ cpu_core_id[cpu] = phys_proc_id[cpu] & ((1<<bits)-1);
+ phys_proc_id[cpu] >>= bits;
+ printk(KERN_INFO "CPU %d(%d) -> Core %d\n",
+ cpu, c->x86_max_cores, cpu_core_id[cpu]);
+ }
#endif
- if (cpuid_eax(0x80000000) >= 0x80000008) {
- c->x86_num_cores = (cpuid_ecx(0x80000008) & 0xff) + 1;
- if (c->x86_num_cores & (c->x86_num_cores - 1))
- c->x86_num_cores = 1;
- }
}
static unsigned int amd_size_cache(struct cpuinfo_x86 * c, unsigned int size)
}
//early_arch_initcall(amd_init_cpu);
+
+static int __init amd_exit_cpu(void)
+{
+ cpu_devs[X86_VENDOR_AMD] = NULL;
+ return 0;
+}
+
+late_initcall(amd_exit_cpu);