From 4e5cad0acf0f0f89fcb7b7b7d37d8f2b5c697885 Mon Sep 17 00:00:00 2001 From: Dave Jones <davej@codemonkey.org.uk> Date: Mon, 7 Oct 2002 19:24:58 -0700 Subject: [PATCH] [PATCH] intel cache parsing update. - Recognise and decode trace cache - Add several missing elements to descriptor table - Xeon errata workaround - updated names for P4's --- arch/i386/kernel/cpu/intel.c | 51 ++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/arch/i386/kernel/cpu/intel.c b/arch/i386/kernel/cpu/intel.c index 43a9feed397f..281c31bfe971 100644 --- a/arch/i386/kernel/cpu/intel.c +++ b/arch/i386/kernel/cpu/intel.c @@ -95,6 +95,7 @@ __setup("noht", P4_disable_ht); #define LVL_1_DATA 2 #define LVL_2 3 #define LVL_3 4 +#define LVL_TRACE 5 struct _cache_table { @@ -114,6 +115,8 @@ static struct _cache_table cache_table[] __initdata = { 0x23, LVL_3, 1024 }, { 0x25, LVL_3, 2048 }, { 0x29, LVL_3, 4096 }, + { 0x39, LVL_2, 128 }, + { 0x3C, LVL_2, 256 }, { 0x41, LVL_2, 128 }, { 0x42, LVL_2, 256 }, { 0x43, LVL_2, 512 }, @@ -122,20 +125,44 @@ static struct _cache_table cache_table[] __initdata = { 0x66, LVL_1_DATA, 8 }, { 0x67, LVL_1_DATA, 16 }, { 0x68, LVL_1_DATA, 32 }, + { 0x70, LVL_TRACE, 12 }, + { 0x71, LVL_TRACE, 16 }, + { 0x72, LVL_TRACE, 32 }, { 0x79, LVL_2, 128 }, { 0x7A, LVL_2, 256 }, { 0x7B, LVL_2, 512 }, { 0x7C, LVL_2, 1024 }, { 0x82, LVL_2, 256 }, + { 0x83, LVL_2, 512 }, { 0x84, LVL_2, 1024 }, { 0x85, LVL_2, 2048 }, { 0x00, 0, 0} }; +/* + * P4 Xeon errata 037 workaround. + * Hardware prefetcher may cause stale data to be loaded into the cache. + */ +static void __init Intel_errata_workarounds(struct cpuinfo_x86 *c) +{ + unsigned long lo, hi; + + if ((c->x86 == 15) && (c->x86_model == 1) && (c->x86_mask == 1)) { + rdmsr (MSR_IA32_MISC_ENABLE, lo, hi); + if ((lo & (1<<9)) == 0) { + printk (KERN_INFO "CPU: C0 stepping P4 Xeon detected.\n"); + printk (KERN_INFO "CPU: Disabling hardware prefetching (Errata 037)\n"); + lo |= (1<<9); /* Disable hw prefetching */ + wrmsr (MSR_IA32_MISC_ENABLE, lo, hi); + } + } +} + + static void __init init_intel(struct cpuinfo_x86 *c) { char *p = NULL; - unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ + unsigned int trace = 0, l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ #ifdef CONFIG_X86_F00F_BUG /* @@ -196,6 +223,9 @@ static void __init init_intel(struct cpuinfo_x86 *c) case LVL_3: l3 += cache_table[k].size; break; + case LVL_TRACE: + trace += cache_table[k].size; + break; } break; @@ -205,9 +235,13 @@ static void __init init_intel(struct cpuinfo_x86 *c) } } } - if ( l1i || l1d ) - printk(KERN_INFO "CPU: L1 I cache: %dK, L1 D cache: %dK\n", - l1i, l1d); + + if ( trace ) + printk (KERN_INFO "CPU: Trace cache: %dK uops", trace); + else if ( l1i ) + printk (KERN_INFO "CPU: L1 I cache: %dK", l1i); + if ( l1d ) + printk(", L1 D cache: %dK\n", l1d); if ( l2 ) printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); if ( l3 ) @@ -312,8 +346,12 @@ static void __init init_intel(struct cpuinfo_x86 *c) /* Disable the PN if appropriate */ squash_the_stupid_serial_number(c); + + /* Work around errata */ + Intel_errata_workarounds(c); } + static unsigned int intel_size_cache(struct cpuinfo_x86 * c, unsigned int size) { /* Intel PIII Tualatin. This comes in two flavours. @@ -370,7 +408,10 @@ static struct cpu_dev intel_cpu_dev __initdata = { }, { X86_VENDOR_INTEL, 15, { - [1] "Pentium 4 (Unknown)", + [0] "Pentium 4 (Unknown)", + [1] "Pentium 4 (Willamette)", + [2] "Pentium 4 (Northwood)", + [4] "Pentium 4 (Foster)", [5] "Pentium 4 (Foster)", } }, -- 2.30.9