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

📄 setup.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
	/* we test for DEVID by checking whether CCR3 is writable */	local_irq_save(flags);	ccr3 = getCx86(CX86_CCR3);	setCx86(CX86_CCR3, ccr3 ^ 0x80);	getCx86(0xc0);   /* dummy to change bus */	if (getCx86(CX86_CCR3) == ccr3) {       /* no DEVID regs. */		ccr2 = getCx86(CX86_CCR2);		setCx86(CX86_CCR2, ccr2 ^ 0x04);		getCx86(0xc0);  /* dummy */		if (getCx86(CX86_CCR2) == ccr2) /* old Cx486SLC/DLC */			*dir0 = 0xfd;		else {                          /* Cx486S A step */			setCx86(CX86_CCR2, ccr2);			*dir0 = 0xfe;		}	}	else {		setCx86(CX86_CCR3, ccr3);  /* restore CCR3 */		/* read DIR0 and DIR1 CPU registers */		*dir0 = getCx86(CX86_DIR0);		*dir1 = getCx86(CX86_DIR1);	}	local_irq_restore(flags);}/* * Cx86_dir0_msb is a HACK needed by check_cx686_cpuid/slop in bugs.h in * order to identify the Cyrix CPU model after we're out of setup.c * * Actually since bugs.h doesn't even reference this perhaps someone should * fix the documentation ??? */static unsigned char Cx86_dir0_msb __initdata = 0;static char Cx86_model[][9] __initdata = {	"Cx486", "Cx486", "5x86 ", "6x86", "MediaGX ", "6x86MX ",	"M II ", "Unknown"};static char Cx486_name[][5] __initdata = {	"SLC", "DLC", "SLC2", "DLC2", "SRx", "DRx",	"SRx2", "DRx2"};static char Cx486S_name[][4] __initdata = {	"S", "S2", "Se", "S2e"};static char Cx486D_name[][4] __initdata = {	"DX", "DX2", "?", "?", "?", "DX4"};static char Cx86_cb[] __initdata = "?.5x Core/Bus Clock";static char cyrix_model_mult1[] __initdata = "12??43";static char cyrix_model_mult2[] __initdata = "12233445";/* * Reset the slow-loop (SLOP) bit on the 686(L) which is set by some old * BIOSes for compatability with DOS games.  This makes the udelay loop * work correctly, and improves performance. * * FIXME: our newer udelay uses the tsc. We dont need to frob with SLOP */extern void calibrate_delay(void) __init;static void __init check_cx686_slop(struct cpuinfo_x86 *c){	unsigned long flags;		if (Cx86_dir0_msb == 3) {		unsigned char ccr3, ccr5;		local_irq_save(flags);		ccr3 = getCx86(CX86_CCR3);		setCx86(CX86_CCR3, (ccr3 & 0x0f) | 0x10); /* enable MAPEN  */		ccr5 = getCx86(CX86_CCR5);		if (ccr5 & 2)			setCx86(CX86_CCR5, ccr5 & 0xfd);  /* reset SLOP */		setCx86(CX86_CCR3, ccr3);                 /* disable MAPEN */		local_irq_restore(flags);		if (ccr5 & 2) { /* possible wrong calibration done */			printk(KERN_INFO "Recalibrating delay loop with SLOP bit reset\n");			calibrate_delay();			c->loops_per_jiffy = loops_per_jiffy;		}	}}static void __init init_cyrix(struct cpuinfo_x86 *c){	unsigned char dir0, dir0_msn, dir0_lsn, dir1 = 0;	char *buf = c->x86_model_id;	const char *p = NULL;	/* 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);	/* Cyrix used bit 24 in extended (AMD) CPUID for Cyrix MMX extensions */	if ( test_bit(1*32+24, &c->x86_capability) ) {		clear_bit(1*32+24, &c->x86_capability);		set_bit(X86_FEATURE_CXMMX, &c->x86_capability);	}	do_cyrix_devid(&dir0, &dir1);	check_cx686_slop(c);	Cx86_dir0_msb = dir0_msn = dir0 >> 4; /* identifies CPU "family"   */	dir0_lsn = dir0 & 0xf;                /* model or clock multiplier */	/* common case step number/rev -- exceptions handled below */	c->x86_model = (dir1 >> 4) + 1;	c->x86_mask = dir1 & 0xf;	/* Now cook; the original recipe is by Channing Corn, from Cyrix.	 * We do the same thing for each generation: we work out	 * the model, multiplier and stepping.  Black magic included,	 * to make the silicon step/rev numbers match the printed ones.	 */	 	switch (dir0_msn) {		unsigned char tmp;	case 0: /* Cx486SLC/DLC/SRx/DRx */		p = Cx486_name[dir0_lsn & 7];		break;	case 1: /* Cx486S/DX/DX2/DX4 */		p = (dir0_lsn & 8) ? Cx486D_name[dir0_lsn & 5]			: Cx486S_name[dir0_lsn & 3];		break;	case 2: /* 5x86 */		Cx86_cb[2] = cyrix_model_mult1[dir0_lsn & 5];		p = Cx86_cb+2;		break;	case 3: /* 6x86/6x86L */		Cx86_cb[1] = ' ';		Cx86_cb[2] = cyrix_model_mult1[dir0_lsn & 5];		if (dir1 > 0x21) { /* 686L */			Cx86_cb[0] = 'L';			p = Cx86_cb;			(c->x86_model)++;		} else             /* 686 */			p = Cx86_cb+1;		/* Emulate MTRRs using Cyrix's ARRs. */		set_bit(X86_FEATURE_CYRIX_ARR, &c->x86_capability);		/* 6x86's contain this bug */		c->coma_bug = 1;		break;	case 4: /* MediaGX/GXm */#ifdef CONFIG_PCI		/* It isnt really a PCI quirk directly, but the cure is the		   same. The MediaGX has deep magic SMM stuff that handles the		   SB emulation. It thows away the fifo on disable_dma() which		   is wrong and ruins the audio.                    		   Bug2: VSA1 has a wrap bug so that using maximum sized DMA 		   causes bad things. According to NatSemi VSA2 has another		   bug to do with 'hlt'. I've not seen any boards using VSA2		   and X doesn't seem to support it either so who cares 8).		   VSA1 we work around however.		*/		printk(KERN_INFO "Working around Cyrix MediaGX virtual DMA bugs.\n");		isa_dma_bridge_buggy = 2;#endif				c->x86_cache_size=16;	/* Yep 16K integrated cache thats it */		/* GXm supports extended cpuid levels 'ala' AMD */		if (c->cpuid_level == 2) {			get_model_name(c);  /* get CPU marketing name */			/*	 		 *	The 5510/5520 companion chips have a funky PIT			 *	that breaks the TSC synchronizing, so turn it off			 */			if(pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, NULL) ||			   pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, NULL))				clear_bit(X86_FEATURE_TSC, c->x86_capability);			return;		}		else {  /* MediaGX */			Cx86_cb[2] = (dir0_lsn & 1) ? '3' : '4';			p = Cx86_cb+2;			c->x86_model = (dir1 & 0x20) ? 1 : 2;			if(pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5510, NULL) ||			   pci_find_device(PCI_VENDOR_ID_CYRIX, PCI_DEVICE_ID_CYRIX_5520, NULL))				clear_bit(X86_FEATURE_TSC, &c->x86_capability);		}		break;        case 5: /* 6x86MX/M II */		if (dir1 > 7)		{			dir0_msn++;  /* M II */			/* Enable MMX extensions (App note 108) */			setCx86(CX86_CCR7, getCx86(CX86_CCR7)|1);		}		else		{			c->coma_bug = 1;      /* 6x86MX, it has the bug. */		}		tmp = (!(dir0_lsn & 7) || dir0_lsn & 1) ? 2 : 0;		Cx86_cb[tmp] = cyrix_model_mult2[dir0_lsn & 7];		p = Cx86_cb+tmp;        	if (((dir1 & 0x0f) > 4) || ((dir1 & 0xf0) == 0x20))			(c->x86_model)++;		/* Emulate MTRRs using Cyrix's ARRs. */		set_bit(X86_FEATURE_CYRIX_ARR, &c->x86_capability);		break;	case 0xf:  /* Cyrix 486 without DEVID registers */		switch (dir0_lsn) {		case 0xd:  /* either a 486SLC or DLC w/o DEVID */			dir0_msn = 0;			p = Cx486_name[(c->hard_math) ? 1 : 0];			break;		case 0xe:  /* a 486S A step */			dir0_msn = 0;			p = Cx486S_name[0];			break;		}		break;	default:  /* unknown (shouldn't happen, we know everyone ;-) */		dir0_msn = 7;		break;	}	strcpy(buf, Cx86_model[dir0_msn & 7]);	if (p) strcat(buf, p);	return;}#ifdef CONFIG_X86_OOSTOREstatic u32 __init power2(u32 x){	u32 s=1;	while(s<=x)		s<<=1;	return s>>=1;}/* *	Set up an actual MCR */ static void __init winchip_mcr_insert(int reg, u32 base, u32 size, int key){	u32 lo, hi;		hi = base & ~0xFFF;	lo = ~(size-1);		/* Size is a power of 2 so this makes a mask */	lo &= ~0xFFF;		/* Remove the ctrl value bits */	lo |= key;		/* Attribute we wish to set */	wrmsr(reg+MSR_IDT_MCR0, lo, hi);	mtrr_centaur_report_mcr(reg, lo, hi);	/* Tell the mtrr driver */}/* *	Figure what we can cover with MCR's * *	Shortcut: We know you can't put 4Gig of RAM on a winchip */static u32 __init ramtop(void)		/* 16388 */{	int i;	u32 top = 0;	u32 clip = 0xFFFFFFFFUL;		for (i = 0; i < e820.nr_map; i++) {		unsigned long start, end;		if (e820.map[i].addr > 0xFFFFFFFFUL)			continue;		/*		 *	Don't MCR over reserved space. Ignore the ISA hole		 *	we frob around that catastrophy already		 */		 					if (e820.map[i].type == E820_RESERVED)		{			if(e820.map[i].addr >= 0x100000UL && e820.map[i].addr < clip)				clip = e820.map[i].addr;			continue;		}		start = e820.map[i].addr;		end = e820.map[i].addr + e820.map[i].size;		if (start >= end)			continue;		if (end > top)			top = end;	}	/* Everything below 'top' should be RAM except for the ISA hole.	   Because of the limited MCR's we want to map NV/ACPI into our	   MCR range for gunk in RAM 	   	   Clip might cause us to MCR insufficient RAM but that is an	   acceptable failure mode and should only bite obscure boxes with	   a VESA hole at 15Mb	   	   The second case Clip sometimes kicks in is when the EBDA is marked	   as reserved. Again we fail safe with reasonable results	*/		if(top>clip)		top=clip;			return top;}/* *	Compute a set of MCR's to give maximum coverage */static int __init winchip_mcr_compute(int nr, int key){	u32 mem = ramtop();	u32 root = power2(mem);	u32 base = root;	u32 top = root;	u32 floor = 0;	int ct = 0;		while(ct<nr)	{		u32 fspace = 0;		/*		 *	Find the largest block we will fill going upwards		 */		u32 high = power2(mem-top);			/*		 *	Find the largest block we will fill going downwards		 */		u32 low = base/2;		/*		 *	Don't fill below 1Mb going downwards as there		 *	is an ISA hole in the way.		 */				 		if(base <= 1024*1024)			low = 0;					/*		 *	See how much space we could cover by filling below		 *	the ISA hole		 */		 		if(floor == 0)			fspace = 512*1024;		else if(floor ==512*1024)			fspace = 128*1024;		/* And forget ROM space */				/*		 *	Now install the largest coverage we get		 */		 		if(fspace > high && fspace > low)		{			winchip_mcr_insert(ct, floor, fspace, key);			floor += fspace;		}		else if(high > low)		{			winchip_mcr_insert(ct, top, high, key);			top += high;		}		else if(low > 0)		{			base -= low;			winchip_mcr_insert(ct, base, low, key);		}		else break;		ct++;	}	/*	 *	We loaded ct values. We now need to set the mask. The caller	 *	must do this bit.	 */	 	return ct;}static void __init winchip_create_optimal_mcr(void){	int i;	/*	 *	Allocate up to 6 mcrs to mark as much of ram as possible	 *	as write combining and weak write ordered.	 *	 *	To experiment with: Linux never uses stack operations for 	 *	mmio spaces so we could globally enable stack operation wc	 *	 *	Load the registers with type 31 - full write combining, all	 *	writes weakly ordered.	 */	int used = winchip_mcr_compute(6, 31);	/*	 *	Wipe unused MCRs	 */	 	for(i=used;i<8;i++)		wrmsr(MSR_IDT_MCR0+i, 0, 0);}static void __init winchip2_create_optimal_mcr(void){	u32 lo, hi;	int i;	/*	 *	Allocate up to 6 mcrs to mark as much of ram as possible	 *	as write combining, weak store ordered.	 *	 *	Load the registers with type 25	 *		8	-	weak write ordering	 *		16	-	weak read ordering	 *		1	-	write combining	 */	int used = winchip_mcr_compute(6, 25);		/*	 *	Mark the registers we are using.	 */	 	rdmsr(MSR_IDT_MCR_CTRL, lo, hi);	for(i=0;i<used;i++)		lo|=1<<(9+i);	wrmsr(MSR_IDT_MCR_CTRL, lo, hi);		/*	 *	Wipe unused MCRs	 */	 	for(i=used;i<8;i++)		wrmsr(MSR_IDT_MCR0+i, 0, 0);}/* *	Handle the MCR key on the Winchip 2. */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,

⌨️ 快捷键说明

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