diff -ur stock/linux-2.4.0-test11-pre5/arch/i386/Makefile linux-2.4.0-test11-pre5-reportintel/arch/i386/Makefile --- stock/linux-2.4.0-test11-pre5/arch/i386/Makefile Wed Nov 15 11:24:19 2000 +++ linux-2.4.0-test11-pre5-reportintel/arch/i386/Makefile Thu Nov 16 13:06:43 2000 @@ -54,6 +54,10 @@ CFLAGS += -march=i686 endif +ifdef CONFIG_MPENTIUM4 +CFLAGS += -march=i686 +endif + ifdef CONFIG_MK6 CFLAGS += $(shell if $(CC) -march=k6 -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-march=k6"; else echo "-march=i586"; fi) endif diff -ur stock/linux-2.4.0-test11-pre5/arch/i386/config.in linux-2.4.0-test11-pre5-reportintel/arch/i386/config.in --- stock/linux-2.4.0-test11-pre5/arch/i386/config.in Wed Nov 15 11:24:19 2000 +++ linux-2.4.0-test11-pre5-reportintel/arch/i386/config.in Thu Nov 16 13:02:10 2000 @@ -34,6 +34,7 @@ Pentium-MMX CONFIG_M586MMX \ Pentium-Pro/Celeron/Pentium-II CONFIG_M686 \ Pentium-III CONFIG_M686FXSR \ + Pentium-4 CONFIG_MPENTIUM4 \ K6/K6-II/K6-III CONFIG_MK6 \ Athlon/K7 CONFIG_MK7 \ Crusoe CONFIG_MCRUSOE \ @@ -85,6 +86,15 @@ fi if [ "$CONFIG_M686FXSR" = "y" ]; then define_int CONFIG_X86_L1_CACHE_SHIFT 5 + define_bool CONFIG_X86_TSC y + define_bool CONFIG_X86_GOOD_APIC y + define_bool CONFIG_X86_PGE y + define_bool CONFIG_X86_USE_PPRO_CHECKSUM y + define_bool CONFIG_X86_FXSR y + define_bool CONFIG_X86_XMM y +fi +if [ "$CONFIG_MPENTIUM4" = "y" ]; then + define_int CONFIG_X86_L1_CACHE_SHIFT 7 define_bool CONFIG_X86_TSC y define_bool CONFIG_X86_GOOD_APIC y define_bool CONFIG_X86_PGE y diff -ur stock/linux-2.4.0-test11-pre5/arch/i386/kernel/mpparse.c linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/mpparse.c --- stock/linux-2.4.0-test11-pre5/arch/i386/kernel/mpparse.c Wed Nov 15 11:24:19 2000 +++ linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/mpparse.c Thu Nov 16 12:59:39 2000 @@ -97,6 +97,8 @@ return("Pentium(tm) Pro"); case 0x0F: + if (model == 0x00) + return("Pentium 4(tm)"); if (model == 0x0F) return("Special controller"); } diff -ur stock/linux-2.4.0-test11-pre5/arch/i386/kernel/setup.c linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/setup.c --- stock/linux-2.4.0-test11-pre5/arch/i386/kernel/setup.c Wed Nov 15 11:24:19 2000 +++ linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/setup.c Thu Nov 16 13:12:46 2000 @@ -1485,6 +1485,7 @@ #endif extern void mcheck_init(struct cpuinfo_x86 *c); char *p = NULL; + unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */ #ifndef CONFIG_M686 /* @@ -1506,43 +1507,80 @@ if (c->cpuid_level > 1) { /* supports eax=2 call */ - int edx = cpuid_edx(2); + int i, j, n; + int regs[4]; + unsigned char *dp = (unsigned char *)regs; - /* We need only the LSB */ - edx &= 0xff; + /* Number of times to iterate */ + n = cpuid_eax(2) & 0xFF; - switch (edx) { - case 0x40: - c->x86_cache_size = 0; - break; - - case 0x41: /* 4-way 128 */ - c->x86_cache_size = 128; - break; - - case 0x42: /* 4-way 256 */ - case 0x82: /* 8-way 256 */ - c->x86_cache_size = 256; - break; - - case 0x43: /* 4-way 512 */ - c->x86_cache_size = 512; - break; - - case 0x44: /* 4-way 1024 */ - case 0x84: /* 8-way 1024 */ - c->x86_cache_size = 1024; - break; + for ( i = 0 ; i < n ; i++ ) { + cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); - case 0x45: /* 4-way 2048 */ - case 0x85: /* 8-way 2048 */ - c->x86_cache_size = 2048; - break; - - default: - c->x86_cache_size = 0; - break; + /* If bit 31 is set, this is an unknown format */ + for ( j = 0 ; j < 3 ; j++ ) { + if ( regs[j] < 0 ) regs[j] = 0; + } + + /* Byte 0 is level count, not a descriptor */ + for ( j = 1 ; j < 16 ; j++ ) { + unsigned char des = dp[j]; + unsigned char dl, dh; + unsigned int cs; + + dh = des >> 4; + dl = des & 0x0F; + + switch ( dh ) + { + case 2: + if ( dl ) { + /* L3 cache */ + cs = (dl-1) << 9; + l3 += cs; + } + break; + case 4: + case 8: + if ( dl ) { + /* L2 cache */ + cs = 128 << (dl-1); + l2 += cs; + } + break; + case 6: + if (dl > 5) { + /* L1 D cache */ + cs = 8<<(dl-6); + l1d += cs; + } + break; + case 7: + /* L1 I cache */ + cs = dl ? (16 << (dl-1)) : 12; + l1i += cs; + break; + default: + /* TLB, or something else we don't know about */ + break; + } + } } + if ( l1i || l1d ) + printk("CPU: L1 I cache: %dK, L1 D cache: %dK\n", + l1i, l1d); + if ( l2 ) + printk("CPU: L2 cache: %dK\n", l2); + if ( l3 ) + printk("CPU: L3 cache: %dK\n", l3); + + /* + * This assumes the L3 cache is shared; it typically lives in + * the northbridge. The L1 caches are included by the L2 + * cache, and so should not be included for the purpose of + * SMP switching weights. + */ + c->x86_cache_size = l2 ? l2 : (l1i+l1d); } /* SEP CPUID bug: Pentium Pro reports SEP but doesn't have it */ @@ -1555,19 +1593,19 @@ if (c->x86 == 6) { switch (c->x86_model) { case 5: - if (c->x86_cache_size == 0) + if (l2 == 0) p = "Celeron (Covington)"; - if (c->x86_cache_size == 256) + if (l2 == 256) p = "Mobile Pentium II (Dixon)"; break; case 6: - if (c->x86_cache_size == 128) + if (l2 == 128) p = "Celeron (Mendocino)"; break; case 8: - if (c->x86_cache_size == 128) + if (l2 == 128) p = "Celeron (Coppermine)"; break; } @@ -2028,7 +2066,7 @@ /* Intel-defined */ "fpu", "vme", "de", "pse", "tsc", "msr", "pae", "mce", "cx8", "apic", NULL, "sep", "mtrr", "pge", "mca", "cmov", - "pat", "pse36", "pn", "clflsh", NULL, "dtes", NULL, "mmx", + "pat", "pse36", "pn", "clflsh", NULL, "dtes", "acpi", "mmx", "fxsr", "sse", "sse2", "selfsnoop", NULL, "acc", "ia64", NULL, /* AMD-defined */ diff -ur stock/linux-2.4.0-test11-pre5/arch/i386/kernel/smpboot.c linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/smpboot.c --- stock/linux-2.4.0-test11-pre5/arch/i386/kernel/smpboot.c Sun Oct 1 20:35:15 2000 +++ linux-2.4.0-test11-pre5-reportintel/arch/i386/kernel/smpboot.c Thu Nov 16 12:57:32 2000 @@ -455,7 +455,7 @@ cpu_init(); smp_callin(); while (!atomic_read(&smp_commenced)) - /* nothing */ ; + rep_nop(); /* * low-memory mappings have been cleared, flush them from * the local TLBs too. diff -ur stock/linux-2.4.0-test11-pre5/include/asm-i386/processor.h linux-2.4.0-test11-pre5-reportintel/include/asm-i386/processor.h --- stock/linux-2.4.0-test11-pre5/include/asm-i386/processor.h Wed Nov 15 11:24:21 2000 +++ linux-2.4.0-test11-pre5-reportintel/include/asm-i386/processor.h Thu Nov 16 13:05:01 2000 @@ -473,4 +473,10 @@ #define MICROCODE_IOCFREE _IO('6',0) /* because it is for P6 */ +/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ +extern inline void rep_nop(void) +{ + __asm__ __volatile__("rep;nop"); +} + #endif /* __ASM_I386_PROCESSOR_H */ diff -ur stock/linux-2.4.0-test11-pre5/init/main.c linux-2.4.0-test11-pre5-reportintel/init/main.c --- stock/linux-2.4.0-test11-pre5/init/main.c Thu Oct 26 13:49:15 2000 +++ linux-2.4.0-test11-pre5-reportintel/init/main.c Thu Nov 16 12:58:14 2000 @@ -333,7 +333,7 @@ /* wait for "start of" clock tick */ ticks = jiffies; while (ticks == jiffies) - /* nothing */; + rep_nop(); /* Go .. */ ticks = jiffies; __delay(loops_per_sec); @@ -349,7 +349,8 @@ while ( lps_precision-- && (loopbit >>= 1) ) { loops_per_sec |= loopbit; ticks = jiffies; - while (ticks == jiffies); + while (ticks == jiffies) + rep_nop(); ticks = jiffies; __delay(loops_per_sec); if (jiffies != ticks) /* longer than 1 tick */