📄 setup.c
字号:
static void __init winchip2_unprotect_mcr(void){ u32 lo, hi; u32 key; rdmsr(MSR_IDT_MCR_CTRL, lo, hi); lo&=~0x1C0; /* blank bits 8-6 */ key = (lo>>17) & 7; lo |= key<<6; /* replace with unlock key */ wrmsr(MSR_IDT_MCR_CTRL, lo, hi);}static void __init winchip2_protect_mcr(void){ u32 lo, hi; rdmsr(MSR_IDT_MCR_CTRL, lo, hi); lo&=~0x1C0; /* blank bits 8-6 */ wrmsr(MSR_IDT_MCR_CTRL, lo, hi);} #endifstatic void __init init_centaur(struct cpuinfo_x86 *c){ enum { ECX8=1<<1, EIERRINT=1<<2, DPM=1<<3, DMCE=1<<4, DSTPCLK=1<<5, ELINEAR=1<<6, DSMC=1<<7, DTLOCK=1<<8, EDCTLB=1<<8, EMMX=1<<9, DPDC=1<<11, EBRPRED=1<<12, DIC=1<<13, DDC=1<<14, DNA=1<<15, ERETSTK=1<<16, E2MMX=1<<19, EAMD3D=1<<20, }; char *name; u32 fcr_set=0; u32 fcr_clr=0; u32 lo,hi,newlo; u32 aa,bb,cc,dd; /* Bit 31 in normal CPUID used for nonstandard 3DNow ID; 3DNow is IDd by bit 31 in extended CPUID (1*32+31) anyway */ clear_bit(0*32+31, &c->x86_capability); switch (c->x86) { case 5: switch(c->x86_model) { case 4: name="C6"; fcr_set=ECX8|DSMC|EDCTLB|EMMX|ERETSTK; fcr_clr=DPDC; printk(KERN_NOTICE "Disabling bugged TSC.\n"); clear_bit(X86_FEATURE_TSC, &c->x86_capability);#ifdef CONFIG_X86_OOSTORE winchip_create_optimal_mcr(); /* Enable write combining on non-stack, non-string write combining on string, all types weak write ordering The C6 original lacks weak read order Note 0x120 is write only on Winchip 1 */ wrmsr(MSR_IDT_MCR_CTRL, 0x01F0001F, 0);#endif break; case 8: switch(c->x86_mask) { default: name="2"; break; case 7 ... 9: name="2A"; break; case 10 ... 15: name="2B"; break; } fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D; fcr_clr=DPDC;#ifdef CONFIG_X86_OOSTORE winchip2_unprotect_mcr(); winchip2_create_optimal_mcr(); rdmsr(MSR_IDT_MCR_CTRL, lo, hi); /* Enable write combining on non-stack, non-string write combining on string, all types weak write ordering */ lo|=31; wrmsr(MSR_IDT_MCR_CTRL, lo, hi); winchip2_protect_mcr();#endif break; case 9: name="3"; fcr_set=ECX8|DSMC|DTLOCK|EMMX|EBRPRED|ERETSTK|E2MMX|EAMD3D; fcr_clr=DPDC;#ifdef CONFIG_X86_OOSTORE winchip2_unprotect_mcr(); winchip2_create_optimal_mcr(); rdmsr(MSR_IDT_MCR_CTRL, lo, hi); /* Enable write combining on non-stack, non-string write combining on string, all types weak write ordering */ lo|=31; wrmsr(MSR_IDT_MCR_CTRL, lo, hi); winchip2_protect_mcr();#endif break; case 10: name="4"; /* no info on the WC4 yet */ break; default: name="??"; } rdmsr(MSR_IDT_FCR1, lo, hi); newlo=(lo|fcr_set) & (~fcr_clr); if (newlo!=lo) { printk(KERN_INFO "Centaur FCR was 0x%X now 0x%X\n", lo, newlo ); wrmsr(MSR_IDT_FCR1, newlo, hi ); } else { printk(KERN_INFO "Centaur FCR is 0x%X\n",lo); } /* Emulate MTRRs using Centaur's MCR. */ set_bit(X86_FEATURE_CENTAUR_MCR, &c->x86_capability); /* Report CX8 */ set_bit(X86_FEATURE_CX8, &c->x86_capability); /* Set 3DNow! on Winchip 2 and above. */ if (c->x86_model >=8) set_bit(X86_FEATURE_3DNOW, &c->x86_capability); /* See if we can find out some more. */ if ( cpuid_eax(0x80000000) >= 0x80000005 ) { /* Yes, we can. */ cpuid(0x80000005,&aa,&bb,&cc,&dd); /* Add L1 data and code cache sizes. */ c->x86_cache_size = (cc>>24)+(dd>>24); } sprintf( c->x86_model_id, "WinChip %s", name ); break; case 6: switch (c->x86_model) { case 6 ... 8: /* Cyrix III family */ rdmsr (MSR_VIA_FCR, lo, hi); lo |= (1<<1 | 1<<7); /* Report CX8 & enable PGE */ wrmsr (MSR_VIA_FCR, lo, hi); set_bit(X86_FEATURE_CX8, &c->x86_capability); set_bit(X86_FEATURE_3DNOW, &c->x86_capability); get_model_name(c); display_cacheinfo(c); break; } break; }}static void __init init_transmeta(struct cpuinfo_x86 *c){ unsigned int cap_mask, uk, max, dummy; unsigned int cms_rev1, cms_rev2; unsigned int cpu_rev, cpu_freq, cpu_flags; char cpu_info[65]; get_model_name(c); /* Same as AMD/Cyrix */ display_cacheinfo(c); /* Print CMS and CPU revision */ max = cpuid_eax(0x80860000); if ( max >= 0x80860001 ) { cpuid(0x80860001, &dummy, &cpu_rev, &cpu_freq, &cpu_flags); printk(KERN_INFO "CPU: Processor revision %u.%u.%u.%u, %u MHz\n", (cpu_rev >> 24) & 0xff, (cpu_rev >> 16) & 0xff, (cpu_rev >> 8) & 0xff, cpu_rev & 0xff, cpu_freq); } if ( max >= 0x80860002 ) { cpuid(0x80860002, &dummy, &cms_rev1, &cms_rev2, &dummy); printk(KERN_INFO "CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n", (cms_rev1 >> 24) & 0xff, (cms_rev1 >> 16) & 0xff, (cms_rev1 >> 8) & 0xff, cms_rev1 & 0xff, cms_rev2); } if ( max >= 0x80860006 ) { cpuid(0x80860003, (void *)&cpu_info[0], (void *)&cpu_info[4], (void *)&cpu_info[8], (void *)&cpu_info[12]); cpuid(0x80860004, (void *)&cpu_info[16], (void *)&cpu_info[20], (void *)&cpu_info[24], (void *)&cpu_info[28]); cpuid(0x80860005, (void *)&cpu_info[32], (void *)&cpu_info[36], (void *)&cpu_info[40], (void *)&cpu_info[44]); cpuid(0x80860006, (void *)&cpu_info[48], (void *)&cpu_info[52], (void *)&cpu_info[56], (void *)&cpu_info[60]); cpu_info[64] = '\0'; printk(KERN_INFO "CPU: %s\n", cpu_info); } /* Unhide possibly hidden capability flags */ rdmsr(0x80860004, cap_mask, uk); wrmsr(0x80860004, ~0, uk); c->x86_capability[0] = cpuid_edx(0x00000001); wrmsr(0x80860004, cap_mask, uk);}static void __init init_rise(struct cpuinfo_x86 *c){ printk("CPU: Rise iDragon"); if (c->x86_model > 2) printk(" II"); printk("\n"); /* Unhide possibly hidden capability flags The mp6 iDragon family don't have MSRs. We switch on extra features with this cpuid weirdness: */ __asm__ ( "movl $0x6363452a, %%eax\n\t" "movl $0x3231206c, %%ecx\n\t" "movl $0x2a32313a, %%edx\n\t" "cpuid\n\t" "movl $0x63634523, %%eax\n\t" "movl $0x32315f6c, %%ecx\n\t" "movl $0x2333313a, %%edx\n\t" "cpuid\n\t" : : : "eax", "ebx", "ecx", "edx" ); set_bit(X86_FEATURE_CX8, &c->x86_capability);}extern void trap_init_f00f_bug(void);static void __init init_intel(struct cpuinfo_x86 *c){#ifndef CONFIG_M686 static int f00f_workaround_enabled = 0;#endif char *p = NULL; unsigned int l1i = 0, l1d = 0, l2 = 0, l3 = 0; /* Cache sizes */#ifndef CONFIG_M686 /* * All current models of Pentium and Pentium with MMX technology CPUs * have the F0 0F bug, which lets nonpriviledged users lock up the system. * Note that the workaround only should be initialized once... */ c->f00f_bug = 0; if ( c->x86 == 5 ) { c->f00f_bug = 1; if ( !f00f_workaround_enabled ) { trap_init_f00f_bug(); printk(KERN_NOTICE "Intel Pentium with F0 0F bug - workaround enabled.\n"); f00f_workaround_enabled = 1; } }#endif if (c->cpuid_level > 1) { /* supports eax=2 call */ int i, j, n; int regs[4]; unsigned char *dp = (unsigned char *)regs; /* Number of times to iterate */ n = cpuid_eax(2) & 0xFF; for ( i = 0 ; i < n ; i++ ) { cpuid(2, ®s[0], ®s[1], ®s[2], ®s[3]); /* 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; /* Black magic... */ switch ( dh ) { case 0: switch ( dl ) { case 6: /* L1 I cache */ l1i += 8; break; case 8: /* L1 I cache */ l1i += 16; break; case 10: /* L1 D cache */ l1d += 8; break; case 12: /* L1 D cache */ l1d += 16; break; default:; /* TLB, or unknown */ } break; case 2: if ( dl ) { /* L3 cache */ cs = (dl-1) << 9; l3 += cs; } break; case 4: if ( c->x86 > 6 && dl ) { /* P4 family */ /* L3 cache */ cs = 128 << (dl-1); l3 += cs; break; } /* else same as 8 - fall through */ 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: if ( dl >= 8 ) { /* L2 cache */ cs = 64<<(dl-8); l2 += cs; } else { /* L0 I cache, count as L1 */ cs = dl ? (16 << (dl-1)) : 12; l1i += cs; } break; default: /* TLB, or something else we don't know about */ break; } } } if ( l1i || l1d ) printk(KERN_INFO "CPU: L1 I cache: %dK, L1 D cache: %dK\n", l1i, l1d); if ( l2 ) printk(KERN_INFO "CPU: L2 cache: %dK\n", l2); if ( l3 ) printk(KERN_INFO "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 */ if ( c->x86 == 6 && c->x86_model < 3 && c->x86_mask < 3 ) clear_bit(X86_FEATURE_SEP, &c->x86_capability); /* Names for the Pentium II/Celeron processors detectable only by also checking the cache size. Dixon is NOT a Celeron. */ if (c->x86 == 6) { switch (c->x86_model) { case 5: if (l2 == 0) p = "Celeron (Covington)"; if (l2 == 256) p = "Mobile Pentium II (Dixon)"; break; case 6: if (l2 == 128) p = "Celeron (Mendocino)"; break; case 8: if (l2 == 128) p = "Celeron (Coppermine)"; break; } } if ( p ) strcpy(c->x86_model_id, p); #ifdef CONFIG_SMP if (test_bit(X86_FEATURE_HT, &c->x86_capability) && !disable_x86_ht) { extern int phys_proc_id[NR_CPUS]; u32 eax, ebx, ecx, edx; int index_lsb, index_msb, tmp; int initial_apic_id; int cpu = smp_processor_id(); cpuid(1, &eax, &ebx, &ecx, &edx); smp_num_siblings = (ebx & 0xff0000) >> 16; if (smp_num_siblings == 1) { printk(KERN_INFO "CPU: Hyper-Threading is disabled\n"); } else if (smp_num_siblings > 1 ) { index_lsb = 0; index_msb = 31; /* * At this point we only support two siblings per * processor package. */#define NR_SIBLINGS 2 if (smp_num_siblings != NR_SIBLINGS) { printk(KERN_WARNING "CPU: Unsupported number of the siblings %d", smp_num_siblings); smp_num_siblings = 1; goto too_many_siblings; } tmp = smp_num_siblings; while ((tmp & 1) == 0) { tmp >>=1 ; index_lsb++; } tmp = smp_num_siblings; while ((tmp & 0x80000000 ) == 0) { tmp <<=1 ; index_msb--; } if (index_lsb != index_msb ) index_msb++; initial_apic_id = ebx >> 24 & 0xff; phys_proc_id[cpu] = initial_apic_id >> index_msb; printk(KERN_INFO "C
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -