⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setup.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
		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, &regs[0], &regs[1], &regs[2], &regs[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)) {		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  "CPU: Physical Processor ID: %d\n",                               phys_proc_id[cpu]);		}	}too_many_siblings:#endif}void __init get_cpu_vendor(struct cpuinfo_x86 *c){	char *v = c->x86_vendor_id;	if (!strcmp(v, "GenuineIntel"))		c->x86_vendor = X86_VENDOR_INTEL;	else if (!strcmp(v, "AuthenticAMD"))		c->x86_vendor = X86_VENDOR_AMD;	else if (!strcmp(v, "CyrixInstead"))		c->x86_vendor = X86_VENDOR_CYRIX;	else if (!strcmp(v, "UMC UMC UMC "))		c->x86_vendor = X86_VENDOR_UMC;	else if (!strcmp(v, "CentaurHauls"))		c->x86_vendor = X86_VENDOR_CENTAUR;	else if (!strcmp(v, "NexGenDriven"))		c->x86_vendor = X86_VENDOR_NEXGEN;	else if (!strcmp(v, "RiseRiseRise"))		c->x86_vendor = X86_VENDOR_RISE;	else if (!strcmp(v, "GenuineTMx86") ||		 !strcmp(v, "TransmetaCPU"))		c->x86_vendor = X86_VENDOR_TRANSMETA;	else		c->x86_vendor = X86_VENDOR_UNKNOWN;}struct cpu_model_info {	int vendor;	int family;	char *model_names[16];};/* Naming convention should be: <Name> [(<Codename>)] *//* This table only is used unless init_<vendor>() below doesn't set it; *//* in particular, if CPUID levels 0x80000002..4 are supported, this isn't used */static struct cpu_model_info cpu_models[] __initdata = {	{ X86_VENDOR_INTEL,	4,	  { "486 DX-25/33", "486 DX-50", "486 SX", "486 DX/2", "486 SL", 	    "486 SX/2", NULL, "486 DX/2-WB", "486 DX/4", "486 DX/4-WB", NULL, 	    NULL, NULL, NULL, NULL, NULL }},	{ X86_VENDOR_INTEL,	5,	  { "Pentium 60/66 A-step", "Pentium 60/66", "Pentium 75 - 200",	    "OverDrive PODP5V83", "Pentium MMX", NULL, NULL,	    "Mobile Pentium 75 - 200", "Mobile Pentium MMX", NULL, NULL, NULL,	    NULL, NULL, NULL, NULL }},	{ X86_VENDOR_INTEL,	6,	  { "Pentium Pro A-step", "Pentium Pro", NULL, "Pentium II (Klamath)", 	    NULL, "Pentium II (Deschutes)", "Mobile Pentium II",	    "Pentium III (Katmai)", "Pentium III (Coppermine)", NULL,	    "Pentium III (Cascades)", NULL, NULL, NULL, NULL }},	{ X86_VENDOR_AMD,	4,	  { NULL, NULL, NULL, "486 DX/2", NULL, NULL, NULL, "486 DX/2-WB",	    "486 DX/4", "486 DX/4-WB", NULL, NULL, NULL, NULL, "Am5x86-WT",	    "Am5x86-WB" }},	{ X86_VENDOR_AMD,	5, /* Is this this really necessary?? */	  { "K5/SSA5", "K5",	    "K5", "K5", NULL, NULL,	    "K6", "K6", "K6-2",	    "K6-3", NULL, NULL, NULL, NULL, NULL, NULL }},	{ X86_VENDOR_AMD,	6, /* Is this this really necessary?? */	  { "Athlon", "Athlon",	    "Athlon", NULL, "Athlon", NULL,	    NULL, NULL, NULL,	    NULL, NULL, NULL, NULL, NULL, NULL, NULL }},	{ X86_VENDOR_UMC,	4,	  { NULL, "U5D", "U5S", NULL, NULL, NULL, NULL, NULL, NULL, NULL,	    NULL, NULL, NULL, NULL, NULL, NULL }},	{ X86_VENDOR_NEXGEN,	5,	  { "Nx586", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,	    NULL, NULL, NULL, NULL, NULL, NULL, NULL }},	{ X86_VENDOR_RISE,	5,	  { "iDragon", NULL, "iDragon", NULL, NULL, NULL, NULL,	    NULL, "iDragon II", "iDragon II", NULL, NULL, NULL, NULL, NULL, NULL }},};/* Look up CPU names by table lookup. */static char __init *table_lookup_model(struct cpuinfo_x86 *c){	struct cpu_model_info *info = cpu_models;	int i;	if ( c->x86_model >= 16 )		return NULL;	/* Range check */	for ( i = 0 ; i < sizeof(cpu_models)/sizeof(struct cpu_model_info) ; i++ ) {		if ( info->vendor == c->x86_vendor &&		     info->family == c->x86 ) {			return info->model_names[c->x86_model];		}		info++;	}	return NULL;		/* Not found */}/* *	Detect a NexGen CPU running without BIOS hypercode new enough *	to have CPUID. (Thanks to Herbert Oppmann) */ static int __init deep_magic_nexgen_probe(void){	int ret;		__asm__ __volatile__ (		"	movw	$0x5555, %%ax\n"		"	xorw	%%dx,%%dx\n"		"	movw	$2, %%cx\n"		"	divw	%%cx\n"		"	movl	$0, %%eax\n"		"	jnz	1f\n"		"	movl	$1, %%eax\n"		"1:\n" 		: "=a" (ret) : : "cx", "dx" );	return  ret;}static void __init squash_the_stupid_serial_number(struct cpuinfo_x86 *c){	if( test_bit(X86_FEATURE_PN, &c->x86_capability) &&	    disable_x86_serial_nr ) {		/* Disable processor serial number */		unsigned long lo,hi;		rdmsr(MSR_IA32_BBL_CR_CTL,lo,hi);		lo |= 0x200000;		wrmsr(MSR_IA32_BBL_CR_CTL,lo,hi);		printk(KERN_NOTICE "CPU serial number disabled.\n");		clear_bit(X86_FEATURE_PN, &c->x86_capability);		/* Disabling the serial number may affect the cpuid level */		c->cpuid_level = cpuid_eax(0);	}}static int __init x86_serial_nr_setup(char *s){	disable_x86_serial_nr = 0;	return 1;}__setup("serialnumber", x86_serial_nr_setup);static int __init x86_fxsr_setup(char * s){	disable_x86_fxsr = 1;	return 1;}__setup("nofxsr", x86_fxsr_setup);/* Standard macro to see if a specific flag is changeable */static inline int flag_is_changeable_p(u32 flag){	u32 f1, f2;	asm("pushfl\n\t"	    "pushfl\n\t"	    "popl %0\n\t"	    "movl %0,%1\n\t"	    "xorl %2,%0\n\t"	    "pushl %0\n\t"	    "popfl\n\t"	    "pushfl\n\t"	    "popl %0\n\t"	    "popfl\n\t"	    : "=&r" (f1), "=&r" (f2)	    : "ir" (flag));	return ((f1^f2) & flag) != 0;}/* Probe for the CPUID instruction */static int __init have_cpuid_p(void){	return flag_is_changeable_p(X86_EFLAGS_ID);}/* * Cyrix CPUs without cpuid or with cpuid not yet enabled can be detected * by the fact that they preserve the flags across the division of 5/2. * PII and PPro exhibit this behavior too, but they have cpuid available. */ /* * Perform the Cyrix 5/2 test. A Cyrix won't change * the flags, while other 486 chips will. */static inline int test_cyrix_52div(void){	unsigned int test;	__asm__ __volatile__(	     "sahf\n\t"		/* clear flags (%eax = 0x0005) */	     "div %b2\n\t"	/* divide 5 by 2 */	     "lahf"		/* store flags into %ah */	     : "=a" (test)	     : "0" (5), "q" (2)	     : "cc");	/* AH is 0x02 on Cyrix after the divide.. */	return (unsigned char) (test >> 8) == 0x02;}/* Try to detect a CPU with disabled CPUID, and if so, enable.  This routine   may also be used to detect non-CPUID processors and fill in some of   the information manually. */static int __init id_and_try_enable_cpuid(struct cpuinfo_x86 *c){	/* First of all, decide if this is a 486 or higher */	/* It's a 486 if we can modify the AC flag */	if ( flag_is_changeable_p(X86_EFLAGS_AC) )		c->x86 = 4;	else		c->x86 = 3;	/* Detect Cyrix with disabled CPUID */	if ( c->x86 == 4 && test_cyrix_52div() ) {		unsigned char dir0, dir1;				strcpy(c->x86_vendor_id, "CyrixInstead");	        c->x86_vendor = X86_VENDOR_CYRIX;	        	        /* Actually enable cpuid on the older cyrix */	    	    	/* Retrieve CPU revisions */	    			do_cyrix_devid(&dir0, &dir1);		dir0>>=4;						/* Check it is an affected model */		   	        if (dir0 == 5 || dir0 == 3)   	        {			uns

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -