From: Andi Kleen This patch readds the early CPU detection to i386. This does some part of the CPUID checking for the boot cpu early because there is more and more code who wants to look at the information early at boot. This makes the AMD768 MPX workaround that was merged some time ago actually work and follows x86-64. In this case it is used to export a new macro cache_line_size(). This gives the cache line size of the L2 cache and can be used by slab to waste less memory (Manfred has patches for this) x86-64 already exports this macro. This is identical to the earlier patch, except that l2_cache_size() has been renamed to cache_line_size(). --- 25-akpm/arch/i386/kernel/cpu/common.c | 30 ++++++++++++++++++------------ 25-akpm/arch/i386/kernel/setup.c | 2 ++ 25-akpm/include/asm-i386/processor.h | 4 ++++ 3 files changed, 24 insertions(+), 12 deletions(-) diff -puN arch/i386/kernel/cpu/common.c~early-x86-cpu-detection arch/i386/kernel/cpu/common.c --- 25/arch/i386/kernel/cpu/common.c~early-x86-cpu-detection 2004-03-13 12:55:26.075192872 -0800 +++ 25-akpm/arch/i386/kernel/cpu/common.c 2004-03-13 12:55:26.081191960 -0800 @@ -196,7 +196,6 @@ int __init have_cpuid_p(void) void __init generic_identify(struct cpuinfo_x86 * c) { u32 tfms, xlvl; - int junk; if (have_cpuid_p()) { /* Get vendor name */ @@ -211,8 +210,8 @@ void __init generic_identify(struct cpui /* Intel-defined flags: level 0x00000001 */ if ( c->cpuid_level >= 0x00000001 ) { - u32 capability, excap; - cpuid(0x00000001, &tfms, &junk, &excap, &capability); + u32 capability, excap, misc; + cpuid(0x00000001, &tfms, &misc, &excap, &capability); c->x86_capability[0] = capability; c->x86_capability[4] = excap; c->x86 = (tfms >> 8) & 15; @@ -222,6 +221,9 @@ void __init generic_identify(struct cpui c->x86_model += ((tfms >> 16) & 0xF) << 4; } c->x86_mask = tfms & 15; + + if (c->x86_capability[0] & (1<<19)) + c->x86_clflush_size = ((misc >> 8) & 0xff) * 8; } else { /* Have CPUID level 0 only - unheard of */ c->x86 = 4; @@ -232,7 +234,7 @@ void __init generic_identify(struct cpui if ( (xlvl & 0xffff0000) == 0x80000000 ) { if ( xlvl >= 0x80000001 ) c->x86_capability[1] = cpuid_edx(0x80000001); - if ( xlvl >= 0x80000004 ) + if ( xlvl >= 0x80000004) get_model_name(c); /* Default name */ } } @@ -261,15 +263,8 @@ static int __init x86_serial_nr_setup(ch } __setup("serialnumber", x86_serial_nr_setup); - - -/* - * This does the hard work of actually picking apart the CPU stuff... - */ -void __init identify_cpu(struct cpuinfo_x86 *c) +void __init early_identify_cpu(struct cpuinfo_x86 *c) { - int i; - c->loops_per_jiffy = loops_per_jiffy; c->x86_cache_size = -1; c->x86_vendor = X86_VENDOR_UNKNOWN; @@ -277,6 +272,7 @@ void __init identify_cpu(struct cpuinfo_ c->x86_model = c->x86_mask = 0; /* So far unknown... */ c->x86_vendor_id[0] = '\0'; /* Unset */ c->x86_model_id[0] = '\0'; /* Unset */ + c->x86_clflush_size = 32; memset(&c->x86_capability, 0, sizeof c->x86_capability); if (!have_cpuid_p()) { @@ -289,6 +285,16 @@ void __init identify_cpu(struct cpuinfo_ } generic_identify(c); +} + +/* + * This does the hard work of actually picking apart the CPU stuff... + */ +void __init identify_cpu(struct cpuinfo_x86 *c) +{ + int i; + + early_identify_cpu(c); printk(KERN_DEBUG "CPU: After generic identify, caps: %08lx %08lx %08lx %08lx\n", c->x86_capability[0], diff -puN arch/i386/kernel/setup.c~early-x86-cpu-detection arch/i386/kernel/setup.c --- 25/arch/i386/kernel/setup.c~early-x86-cpu-detection 2004-03-13 12:55:26.077192568 -0800 +++ 25-akpm/arch/i386/kernel/setup.c 2004-03-13 12:55:26.083191656 -0800 @@ -1149,6 +1149,8 @@ void __init setup_arch(char **cmdline_p) dmi_scan_machine(); + early_identify_cpu(&boot_cpu_data); + #ifdef CONFIG_X86_GENERICARCH generic_apic_probe(*cmdline_p); #endif diff -puN include/asm-i386/processor.h~early-x86-cpu-detection include/asm-i386/processor.h --- 25/include/asm-i386/processor.h~early-x86-cpu-detection 2004-03-13 12:55:26.078192416 -0800 +++ 25-akpm/include/asm-i386/processor.h 2004-03-13 12:55:26.081191960 -0800 @@ -63,6 +63,7 @@ struct cpuinfo_x86 { int f00f_bug; int coma_bug; unsigned long loops_per_jiffy; + int x86_clflush_size; /* cache line size of L2 */ } __attribute__((__aligned__(SMP_CACHE_BYTES))); #define X86_VENDOR_INTEL 0 @@ -651,4 +652,7 @@ extern void select_idle_routine(const st #define ARCH_HAS_SCHED_WAKE_BALANCE #endif +#define cache_line_size() (boot_cpu_data.x86_clflush_size) +extern void early_identify_cpu(struct cpuinfo_x86 *c); + #endif /* __ASM_I386_PROCESSOR_H */ _