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

📄 common.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
#include <linux/init.h>#include <linux/string.h>#include <linux/delay.h>#include <linux/smp.h>#include <linux/module.h>#include <linux/percpu.h>#include <asm/semaphore.h>#include <asm/processor.h>#include <asm/i387.h>#include <asm/msr.h>#include <asm/io.h>#include <asm/mmu_context.h>#ifdef CONFIG_X86_LOCAL_APIC#include <asm/mpspec.h>#include <asm/apic.h>#include <mach_apic.h>#endif#include "cpu.h"DEFINE_PER_CPU(struct desc_struct, cpu_gdt_table[GDT_ENTRIES]);EXPORT_PER_CPU_SYMBOL(cpu_gdt_table);DEFINE_PER_CPU(unsigned char, cpu_16bit_stack[CPU_16BIT_STACK_SIZE]);EXPORT_PER_CPU_SYMBOL(cpu_16bit_stack);static int cachesize_override __devinitdata = -1;static int disable_x86_fxsr __devinitdata = 0;static int disable_x86_serial_nr __devinitdata = 1;struct cpu_dev * cpu_devs[X86_VENDOR_NUM] = {};extern int disable_pse;static void default_init(struct cpuinfo_x86 * c){	/* Not much we can do here... */	/* Check if at least it has cpuid */	if (c->cpuid_level == -1) {		/* No cpuid. It must be an ancient CPU */		if (c->x86 == 4)			strcpy(c->x86_model_id, "486");		else if (c->x86 == 3)			strcpy(c->x86_model_id, "386");	}}static struct cpu_dev default_cpu = {	.c_init	= default_init,};static struct cpu_dev * this_cpu = &default_cpu;static int __init cachesize_setup(char *str){	get_option (&str, &cachesize_override);	return 1;}__setup("cachesize=", cachesize_setup);int __devinit get_model_name(struct cpuinfo_x86 *c){	unsigned int *v;	char *p, *q;	if (cpuid_eax(0x80000000) < 0x80000004)		return 0;	v = (unsigned int *) c->x86_model_id;	cpuid(0x80000002, &v[0], &v[1], &v[2], &v[3]);	cpuid(0x80000003, &v[4], &v[5], &v[6], &v[7]);	cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);	c->x86_model_id[48] = 0;	/* Intel chips right-justify this string for some dumb reason;	   undo that brain damage */	p = q = &c->x86_model_id[0];	while ( *p == ' ' )	     p++;	if ( p != q ) {	     while ( *p )		  *q++ = *p++;	     while ( q <= &c->x86_model_id[48] )		  *q++ = '\0';	/* Zero-pad the rest */	}	return 1;}void __devinit display_cacheinfo(struct cpuinfo_x86 *c){	unsigned int n, dummy, ecx, edx, l2size;	n = cpuid_eax(0x80000000);	if (n >= 0x80000005) {		cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);		printk(KERN_INFO "CPU: L1 I Cache: %dK (%d bytes/line), D cache %dK (%d bytes/line)\n",			edx>>24, edx&0xFF, ecx>>24, ecx&0xFF);		c->x86_cache_size=(ecx>>24)+(edx>>24);		}	if (n < 0x80000006)	/* Some chips just has a large L1. */		return;	ecx = cpuid_ecx(0x80000006);	l2size = ecx >> 16;		/* do processor-specific cache resizing */	if (this_cpu->c_size_cache)		l2size = this_cpu->c_size_cache(c,l2size);	/* Allow user to override all this if necessary. */	if (cachesize_override != -1)		l2size = cachesize_override;	if ( l2size == 0 )		return;		/* Again, no L2 cache is possible */	c->x86_cache_size = l2size;	printk(KERN_INFO "CPU: L2 Cache: %dK (%d bytes/line)\n",	       l2size, ecx & 0xFF);}/* 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 *//* Look up CPU names by table lookup. */static char __devinit *table_lookup_model(struct cpuinfo_x86 *c){	struct cpu_model_info *info;	if ( c->x86_model >= 16 )		return NULL;	/* Range check */	if (!this_cpu)		return NULL;	info = this_cpu->c_models;	while (info && info->family) {		if (info->family == c->x86)			return info->model_names[c->x86_model];		info++;	}	return NULL;		/* Not found */}static void __devinit get_cpu_vendor(struct cpuinfo_x86 *c, int early){	char *v = c->x86_vendor_id;	int i;	for (i = 0; i < X86_VENDOR_NUM; i++) {		if (cpu_devs[i]) {			if (!strcmp(v,cpu_devs[i]->c_ident[0]) ||			    (cpu_devs[i]->c_ident[1] && 			     !strcmp(v,cpu_devs[i]->c_ident[1]))) {				c->x86_vendor = i;				if (!early)					this_cpu = cpu_devs[i];				break;			}		}	}}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 __devinit have_cpuid_p(void){	return flag_is_changeable_p(X86_EFLAGS_ID);}/* Do minimum CPU detection early.   Fields really needed: vendor, cpuid_level, family, model, mask, cache alignment.   The others are not touched to avoid unwanted side effects.   WARNING: this function is only called on the BP.  Don't add code here   that is supposed to run on all CPUs. */static void __init early_cpu_detect(void){	struct cpuinfo_x86 *c = &boot_cpu_data;	c->x86_cache_alignment = 32;	if (!have_cpuid_p())		return;	/* Get vendor name */	cpuid(0x00000000, &c->cpuid_level,	      (int *)&c->x86_vendor_id[0],	      (int *)&c->x86_vendor_id[8],	      (int *)&c->x86_vendor_id[4]);	get_cpu_vendor(c, 1);	c->x86 = 4;	if (c->cpuid_level >= 0x00000001) {		u32 junk, tfms, cap0, misc;		cpuid(0x00000001, &tfms, &misc, &junk, &cap0);		c->x86 = (tfms >> 8) & 15;		c->x86_model = (tfms >> 4) & 15;		if (c->x86 == 0xf)			c->x86 += (tfms >> 20) & 0xff;		if (c->x86 >= 0x6)			c->x86_model += ((tfms >> 16) & 0xF) << 4;		c->x86_mask = tfms & 15;		if (cap0 & (1<<19))			c->x86_cache_alignment = ((misc >> 8) & 0xff) * 8;	}}void __devinit generic_identify(struct cpuinfo_x86 * c){	u32 tfms, xlvl;	int junk;	if (have_cpuid_p()) {		/* Get vendor name */		cpuid(0x00000000, &c->cpuid_level,		      (int *)&c->x86_vendor_id[0],		      (int *)&c->x86_vendor_id[8],		      (int *)&c->x86_vendor_id[4]);				get_cpu_vendor(c, 0);		/* Initialize the standard set of capabilities */		/* Note that the vendor-specific code below might override */			/* Intel-defined flags: level 0x00000001 */		if ( c->cpuid_level >= 0x00000001 ) {			u32 capability, excap;			cpuid(0x00000001, &tfms, &junk, &excap, &capability);			c->x86_capability[0] = capability;			c->x86_capability[4] = excap;			c->x86 = (tfms >> 8) & 15;			c->x86_model = (tfms >> 4) & 15;			if (c->x86 == 0xf) {				c->x86 += (tfms >> 20) & 0xff;				c->x86_model += ((tfms >> 16) & 0xF) << 4;			} 			c->x86_mask = tfms & 15;		} else {			/* Have CPUID level 0 only - unheard of */			c->x86 = 4;		}		/* AMD-defined flags: level 0x80000001 */		xlvl = cpuid_eax(0x80000000);		if ( (xlvl & 0xffff0000) == 0x80000000 ) {			if ( xlvl >= 0x80000001 ) {				c->x86_capability[1] = cpuid_edx(0x80000001);				c->x86_capability[6] = cpuid_ecx(0x80000001);			}			if ( xlvl >= 0x80000004 )				get_model_name(c); /* Default name */		}	}	early_intel_workaround(c);#ifdef CONFIG_X86_HT	phys_proc_id[smp_processor_id()] = (cpuid_ebx(1) >> 24) & 0xff;#endif}static void __devinit squash_the_stupid_serial_number(struct cpuinfo_x86 *c){	if (cpu_has(c, X86_FEATURE_PN) && 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);/* * This does the hard work of actually picking apart the CPU stuff... */void __devinit identify_cpu(struct cpuinfo_x86 *c)

⌨️ 快捷键说明

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