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

📄 init.c

📁 开源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	/* VIA/Cyrix/Centaur Processors with CPUID */	case 'C':		if ( cpu_id.vend_id[1] == 'e' ) {	/* CentaurHauls */			l1_cache = cpu_id.cache_info[3] + cpu_id.cache_info[7];			l2_cache = cpu_id.cache_info[11];			switch(cpu_id.type){			case 5:				cprint(LINE_CPU, 0, "Centaur 5x86");				off = 12;				break;			case 6: // VIA C3				switch(cpu_id.model){					default:						if (cpu_id.step < 8) {							cprint(LINE_CPU, 0, "VIA C3 Samuel2");							off = 14;						} else {							cprint(LINE_CPU, 0, "VIA C3 Eden");							off = 11;						}						break;					case 10:						cprint(LINE_CPU, 0, "VIA C7 (C5J)");						l1_cache = 64;						l2_cache = 128;						off = 16;						break;					case 13:						cprint(LINE_CPU, 0, "VIA C7 (C5R)");						l1_cache = 64;						l2_cache = 128;						off = 12;						break;					case 15:						cprint(LINE_CPU, 0, "VIA Isaiah (CN)");						l1_cache = 64;						l2_cache = 1024;						off = 15;						break;				}			}		} else {				/* CyrixInstead */			switch(cpu_id.type) {			case 5:				switch(cpu_id.model) {				case 0:					cprint(LINE_CPU, 0, "Cyrix 6x86MX/MII");					off = 16;					break;				case 4:					cprint(LINE_CPU, 0, "Cyrix GXm");					off = 9;					break;				}				return;			case 6: // VIA C3				switch(cpu_id.model) {				case 6:					cprint(LINE_CPU, 0, "Cyrix III");					off = 9;					break;				case 7:					if (cpu_id.step < 8) {						cprint(LINE_CPU, 0, "VIA C3 Samuel2");						off = 14;					} else {						cprint(LINE_CPU, 0, "VIA C3 Ezra-T");						off = 13;					}					break;				case 8:					cprint(LINE_CPU, 0, "VIA C3 Ezra-T");					off = 13;					break;				case 9:					cprint(LINE_CPU, 0, "VIA C3 Nehemiah");					off = 15;					break;				}				// L1 = L2 = 64 KB from Cyrix III to Nehemiah				l1_cache = 64;				l2_cache = 64;				break;			}		}		break;	/* Unknown processor */	default:		off = 3;		/* Make a guess at the family */		switch(cpu_id.type) {		case 5:			cprint(LINE_CPU, 0, "586");			return;		case 6:			cprint(LINE_CPU, 0, "686");			return;		}	}	/* We are here only if the CPU type supports the rdtsc instruction */	/* Print CPU speed */	if ((speed = cpuspeed()) > 0) {		if (speed < 1000000-50) {			speed += 50; /* for rounding */			cprint(LINE_CPU, off, "    . MHz");			dprint(LINE_CPU, off+1, speed/1000, 3, 1);			dprint(LINE_CPU, off+5, (speed/100)%10, 1, 0);		} else {			speed += 500; /* for rounding */			cprint(LINE_CPU, off, "      MHz");			dprint(LINE_CPU, off, speed/1000, 5, 0);		}		extclock = speed;	}	/* Print out L1 cache info */	/* To measure L1 cache speed we use a block size that is 1/4th */	/* of the total L1 cache size since half of it is for instructions */	if (l1_cache) {		cprint(LINE_CPU+1, 0, "L1 Cache:     K  ");		dprint(LINE_CPU+1, 11, l1_cache, 3, 0);		if ((speed=memspeed((ulong)mapping(0x100), (l1_cache / 4) * 1024, 200, MS_COPY))) {			cprint(LINE_CPU+1, 16, "       MB/s");			dprint(LINE_CPU+1, 16, speed, 6, 0);		}	}	/* Print out L2 cache info */	/* We measure the L2 cache speed by using a block size that is */	/* the size of the L1 cache.  We have to fudge if the L1 */	/* cache is bigger than the L2 */	if (l2_cache) {		cprint(LINE_CPU+2, 0, "L2 Cache:     K  ");		dprint(LINE_CPU+2, 10, l2_cache, 4, 0);		dprint(LINE_CPU+2, 10, l2_cache, 4, 0);		if (l2_cache < l1_cache) {			i = l1_cache / 4 + l2_cache / 4;		} else {			i = l1_cache;		}		if ((speed=memspeed((ulong)mapping(0x100), i*1024, 200, MS_COPY))) {			cprint(LINE_CPU+2, 16, "       MB/s");			dprint(LINE_CPU+2, 16, speed, 6, 0);		}	}	/* Print out L3 cache info */	/* We measure the L3 cache speed by using a block size that is */	/* the size of the L2 cache. */	if (l3_cache) {		cprint(LINE_CPU+3, 0, "L3 Cache:     K  ");		dprint(LINE_CPU+3, 10, l3_cache, 4, 0);		dprint(LINE_CPU+3, 10, l3_cache, 4, 0);		i = l2_cache*2;		if ((speed=memspeed((ulong)mapping(0x100), i*1024, 150, MS_COPY))) {			cprint(LINE_CPU+3, 16, "       MB/s");			dprint(LINE_CPU+3, 16, speed, 6, 0);		}	}	/* Determine memory speed.  To find the memory speed we use */	/* A block size that is 5x the sum of the L1, L2 & L3 caches */	i = (l3_cache + l2_cache + l1_cache) * 5;			/* Make sure that we have enough memory to do the test */	if ((1 + (i * 2)) > (v->plim_upper << 2)) {		i = ((v->plim_upper <<2) - 1) / 2;	}	if((speed = memspeed((ulong)mapping(0x100), i*1024, 50, MS_COPY))) {		cprint(LINE_CPU+4, 16, "       MB/s");		dprint(LINE_CPU+4, 16, speed, 6, 0);	}	/* Record the starting time */	asm __volatile__ ("rdtsc":"=a" (v->startl),"=d" (v->starth));	v->snapl = v->startl;	v->snaph = v->starth;	v->rdtsc = 1;	if (l1_cache == 0) { l1_cache = 66; }	if (l2_cache == 0) { l1_cache = 666; }}/* Find cache-able memory size */static void cacheable(void){	ulong speed, pspeed;	ulong paddr, mem_top, cached;	mem_top = v->pmap[v->msegs - 1].end;	cached = v->test_pages;	pspeed = 0;	for (paddr=0x200; paddr <= mem_top - 64; paddr+=0x400) {		int i;		int found;		/* See if the paddr is at a testable location */		found = 0;		for(i = 0; i < v->msegs; i++) {			if ((v->pmap[i].start >= paddr)  &&				(v->pmap[i].end <= (paddr + 32))) {				found = 1;				break;			}		}		if (!found) {			continue;		}		/* Map the range and perform the test */		map_page(paddr);		speed = memspeed((ulong)mapping(paddr), 32*4096, 1, MS_READ);		if (pspeed) {			if (speed < pspeed) {				cached -= 32;			}			pspeed = (ulong)((float)speed * 0.7);		}	}	aprint(LINE_INFO, COL_CACHE_TOP, cached);	/* Ensure the default set of pages are mapped */	map_page(0);	map_page(0x80000);}/* #define TICKS 5 * 11832 (count = 6376)*//* #define TICKS (65536 - 12752) *//* #define TICKS (65536 - 8271) */#define TICKS	59659			/* Program counter to 50 ms = 59659 clks *//* Returns CPU clock in khz */static int cpuspeed(void){	int loops;	/* Setup timer */	outb((inb(0x61) & ~0x02) | 0x01, 0x61);	outb(0xb0, 0x43);	outb(TICKS & 0xff, 0x42);	outb(TICKS >> 8, 0x42);	asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high));	loops = 0;	do {		loops++;	} while ((inb(0x61) & 0x20) == 0);	asm __volatile__ (		"rdtsc\n\t" \		"subl st_low,%%eax\n\t" \		"sbbl st_high,%%edx\n\t" \		:"=a" (end_low), "=d" (end_high)	);	/* Make sure we have a credible result */	if (loops < 4 || end_low < 50000) {		return(-1);	}	if(tsc_invariable){ end_low = correct_tsc(end_low);	}	v->clks_msec = end_low/50;		return(v->clks_msec);}/* Measure cache/memory speed by copying a block of memory. *//* Returned value is kbytes/second */ulong memspeed(ulong src, ulong len, int iter, int type){	ulong dst;	ulong wlen;	int i;	dst = src + len;	wlen = len / 4;  /* Length is bytes */	/* Calibrate the overhead with a zero word copy */	asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high));	for (i=0; i<iter; i++) {		asm __volatile__ (			"movl %0,%%esi\n\t" \       		 	"movl %1,%%edi\n\t" \       		 	"movl %2,%%ecx\n\t" \       		 	"cld\n\t" \       		 	"rep\n\t" \       		 	"movsl\n\t" \				:: "g" (src), "g" (dst), "g" (0)			: "esi", "edi", "ecx"		);	}	asm __volatile__ ("rdtsc":"=a" (cal_low),"=d" (cal_high));	/* Compute the overhead time */	asm __volatile__ (		"subl %2,%0\n\t"		"sbbl %3,%1"		:"=a" (cal_low), "=d" (cal_high)		:"g" (st_low), "g" (st_high),		"0" (cal_low), "1" (cal_high)	);	/* Now measure the speed */	switch (type) {	case MS_COPY:		/* Do the first copy to prime the cache */		asm __volatile__ (			"movl %0,%%esi\n\t" \			"movl %1,%%edi\n\t" \       		 	"movl %2,%%ecx\n\t" \       		 	"cld\n\t" \       		 	"rep\n\t" \       		 	"movsl\n\t" \			:: "g" (src), "g" (dst), "g" (wlen)			: "esi", "edi", "ecx"		);		asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high));		for (i=0; i<iter; i++) {		        asm __volatile__ (				"movl %0,%%esi\n\t" \				"movl %1,%%edi\n\t" \       			 	"movl %2,%%ecx\n\t" \       			 	"cld\n\t" \       			 	"rep\n\t" \       			 	"movsl\n\t" \				:: "g" (src), "g" (dst), "g" (wlen)				: "esi", "edi", "ecx"			);		}		asm __volatile__ ("rdtsc":"=a" (end_low),"=d" (end_high));		break;	case MS_WRITE:		asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high));		for (i=0; i<iter; i++) {			asm __volatile__ (       			 	"movl %0,%%ecx\n\t" \				"movl %1,%%edi\n\t" \       			 	"movl %2,%%eax\n\t" \                                "rep\n\t" \                                "stosl\n\t"                                :: "g" (wlen), "g" (dst), "g" (0)				: "edi", "ecx", "eax"                        );		}		asm __volatile__ ("rdtsc":"=a" (end_low),"=d" (end_high));		break;	case MS_READ:		asm __volatile__ (			"movl %0,%%esi\n\t" \			"movl %1,%%ecx\n\t" \       	 		"cld\n\t" \       	 		"L1:\n\t" \			"lodsl\n\t" \       	 		"loop L1\n\t" \			:: "g" (src), "g" (wlen)			: "esi", "ecx"		);		asm __volatile__ ("rdtsc":"=a" (st_low),"=d" (st_high));		for (i=0; i<iter; i++) {		        asm __volatile__ (				"movl %0,%%esi\n\t" \				"movl %1,%%ecx\n\t" \       		 		"cld\n\t" \       		 		"L2:\n\t" \				"lodsl\n\t" \       		 		"loop L2\n\t" \				:: "g" (src), "g" (wlen)				: "esi", "ecx"			);		}		asm __volatile__ ("rdtsc":"=a" (end_low),"=d" (end_high));		break;	}	/* Compute the elapsed time */	asm __volatile__ (		"subl %2,%0\n\t"		"sbbl %3,%1"		:"=a" (end_low), "=d" (end_high)		:"g" (st_low), "g" (st_high),		"0" (end_low), "1" (end_high)	);	/* Subtract the overhead time */	asm __volatile__ (		"subl %2,%0\n\t"		"sbbl %3,%1"		:"=a" (end_low), "=d" (end_high)		:"g" (cal_low), "g" (cal_high),		"0" (end_low), "1" (end_high)	);	/* Make sure that the result fits in 32 bits */	if (end_high) {		return(0);	}	/* If this was a copy adjust the time */	if (type == MS_COPY) {		end_low /= 2;	}	/* Convert to clocks/KB */	end_low /= len;	end_low *= 1024;	end_low /= iter;	if (end_low == 0) {		return(0);	}	if(tsc_invariable){ end_low = correct_tsc(end_low);	}			/* Convert to kbytes/sec */	return((v->clks_msec)/end_low);}ulong correct_tsc(ulong el_org){		float coef_now, coef_max;	int msr_lo, msr_hi, is_xe;		rdmsr(0x198, msr_lo, msr_hi);	is_xe = (msr_lo >> 31) & 0x1;				if(is_xe){		rdmsr(0x198, msr_lo, msr_hi);		coef_max = ((msr_hi >> 8) & 0x1F);			if ((msr_hi >> 14) & 0x1) { coef_max = coef_max + 0.5f; }	} else {		rdmsr(0x17, msr_lo, msr_hi);		coef_max = ((msr_lo >> 8) & 0x1F);		if ((msr_lo >> 14) & 0x1) { coef_max = coef_max + 0.5f; }	}		if((cpu_id.feature_flag >> 7) & 1) {		rdmsr(0x198, msr_lo, msr_hi);		coef_now = ((msr_lo >> 8) & 0x1F);		if ((msr_lo >> 14) & 0x1) { coef_now = coef_now + 0.5f; }	} else {		rdmsr(0x2A, msr_lo, msr_hi);		coef_now = (msr_lo >> 22) & 0x1F;	}			if(coef_max && coef_now) { el_org = (ulong)(el_org * coef_now / coef_max); }		return el_org;}

⌨️ 快捷键说明

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