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

📄 longhaul.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  $Id: longhaul.c,v 1.83 2003/01/02 22:16:26 db Exp $ * *  (C) 2001  Dave Jones. <davej@suse.de> *  (C) 2002  Padraig Brady. <padraig@antefacto.com> * *  Licensed under the terms of the GNU GPL License version 2. *  Based upon datasheets & sample CPUs kindly provided by VIA. * *  VIA have currently 3 different versions of Longhaul. * *  +---------------------+----------+---------------------------------+ *  | Marketing name      | Codename | longhaul version / features.    | *  +---------------------+----------+---------------------------------+ *  |  Samuel/CyrixIII    |   C5A    | v1 : multipliers only           | *  |  Samuel2/C3         | C3E/C5B  | v1 : multiplier only            | *  |  Ezra               |   C5C    | v2 : multipliers & voltage      | *  |  Ezra-T             | C5M/C5N  | v3 : multipliers, voltage & FSB | *  +---------------------+----------+---------------------------------+ * *  BIG FAT DISCLAIMER: Work in progress code. Possibly *dangerous* */#include <linux/kernel.h>#include <linux/module.h> #include <linux/init.h>#include <linux/cpufreq.h>#include <linux/slab.h>#include <linux/string.h>#include <asm/msr.h>#include <asm/timex.h>#include <asm/io.h>#define DEBUG#ifdef DEBUG#define dprintk(msg...) printk(msg)#else#define dprintk(msg...) do { } while(0);#endifstatic int numscales=16, numvscales;static int minvid, maxvid;static int can_scale_voltage;static int can_scale_fsb;static int vrmrev;/* Module parameters */static int dont_scale_voltage;static int dont_scale_fsb;static int current_fsb;#define __hlt()     __asm__ __volatile__("hlt": : :"memory")/* * Clock ratio tables. * The eblcr ones specify the ratio read from the CPU. * The clock_ratio ones specify what to write to the CPU. *//* VIA C3 Samuel 1  & Samuel 2 (stepping 0)*/static int __initdata longhaul1_clock_ratio[16] = {	-1, /* 0000 -> RESERVED */	30, /* 0001 ->  3.0x */	40, /* 0010 ->  4.0x */	-1, /* 0011 -> RESERVED */	-1, /* 0100 -> RESERVED */	35, /* 0101 ->  3.5x */	45, /* 0110 ->  4.5x */	55, /* 0111 ->  5.5x */	60, /* 1000 ->  6.0x */	70, /* 1001 ->  7.0x */	80, /* 1010 ->  8.0x */	50, /* 1011 ->  5.0x */	65, /* 1100 ->  6.5x */	75, /* 1101 ->  7.5x */	-1, /* 1110 -> RESERVED */	-1, /* 1111 -> RESERVED */};static int __initdata samuel1_eblcr[16] = {	50, /* 0000 -> RESERVED */	30, /* 0001 ->  3.0x */	40, /* 0010 ->  4.0x */	-1, /* 0011 -> RESERVED */	55, /* 0100 ->  5.5x */	35, /* 0101 ->  3.5x */	45, /* 0110 ->  4.5x */	-1, /* 0111 -> RESERVED */	-1, /* 1000 -> RESERVED */	70, /* 1001 ->  7.0x */	80, /* 1010 ->  8.0x */	60, /* 1011 ->  6.0x */	-1, /* 1100 -> RESERVED */	75, /* 1101 ->  7.5x */	-1, /* 1110 -> RESERVED */	65, /* 1111 ->  6.5x */};/* VIA C3 Samuel2 Stepping 1->15 & VIA C3 Ezra */static int __initdata longhaul2_clock_ratio[16] = {	100, /* 0000 -> 10.0x */	30,  /* 0001 ->  3.0x */	40,  /* 0010 ->  4.0x */	90,  /* 0011 ->  9.0x */	95,  /* 0100 ->  9.5x */	35,  /* 0101 ->  3.5x */	45,  /* 0110 ->  4.5x */	55,  /* 0111 ->  5.5x */	60,  /* 1000 ->  6.0x */	70,  /* 1001 ->  7.0x */	80,  /* 1010 ->  8.0x */	50,  /* 1011 ->  5.0x */	65,  /* 1100 ->  6.5x */	75,  /* 1101 ->  7.5x */	85,  /* 1110 ->  8.5x */	120, /* 1111 -> 12.0x */};static int __initdata samuel2_eblcr[16] = {	50,  /* 0000 ->  5.0x */	30,  /* 0001 ->  3.0x */	40,  /* 0010 ->  4.0x */	100, /* 0011 -> 10.0x */	55,  /* 0100 ->  5.5x */	35,  /* 0101 ->  3.5x */	45,  /* 0110 ->  4.5x */	110, /* 0111 -> 11.0x */	90,  /* 1000 ->  9.0x */	70,  /* 1001 ->  7.0x */	80,  /* 1010 ->  8.0x */	60,  /* 1011 ->  6.0x */	120, /* 1100 -> 12.0x */	75,  /* 1101 ->  7.5x */	130, /* 1110 -> 13.0x */	65,  /* 1111 ->  6.5x */};static int __initdata ezra_eblcr[16] = {	50,  /* 0000 ->  5.0x */	30,  /* 0001 ->  3.0x */	40,  /* 0010 ->  4.0x */	100, /* 0011 -> 10.0x */	55,  /* 0100 ->  5.5x */	35,  /* 0101 ->  3.5x */	45,  /* 0110 ->  4.5x */	95,  /* 0111 ->  9.5x */	90,  /* 1000 ->  9.0x */	70,  /* 1001 ->  7.0x */	80,  /* 1010 ->  8.0x */	60,  /* 1011 ->  6.0x */	120, /* 1100 -> 12.0x */	75,  /* 1101 ->  7.5x */	85,  /* 1110 ->  8.5x */	65,  /* 1111 ->  6.5x */};/* VIA C5M. */static int __initdata longhaul3_clock_ratio[32] = {	100, /* 0000 -> 10.0x */	30,  /* 0001 ->  3.0x */	40,  /* 0010 ->  4.0x */	90,  /* 0011 ->  9.0x */	95,  /* 0100 ->  9.5x */	35,  /* 0101 ->  3.5x */	45,  /* 0110 ->  4.5x */	55,  /* 0111 ->  5.5x */	60,  /* 1000 ->  6.0x */	70,  /* 1001 ->  7.0x */	80,  /* 1010 ->  8.0x */	50,  /* 1011 ->  5.0x */	65,  /* 1100 ->  6.5x */	75,  /* 1101 ->  7.5x */	85,  /* 1110 ->  8.5x */	120, /* 1111 ->  12.0x */	-1,  /* 0000 -> RESERVED (10.0x) */	110, /* 0001 -> 11.0x */	120, /* 0010 -> 12.0x */	-1,  /* 0011 -> RESERVED (9.0x)*/	105, /* 0100 -> 10.5x */	115, /* 0101 -> 11.5x */	125, /* 0110 -> 12.5x */	135, /* 0111 -> 13.5x */	140, /* 1000 -> 14.0x */	150, /* 1001 -> 15.0x */	160, /* 1010 -> 16.0x */	130, /* 1011 -> 13.0x */	145, /* 1100 -> 14.5x */	155, /* 1101 -> 15.5x */	-1,  /* 1110 -> RESERVED (13.0x) */	-1,  /* 1111 -> RESERVED (12.0x) */};static int __initdata c5m_eblcr[32] = {	50,  /* 0000 ->  5.0x */	30,  /* 0001 ->  3.0x */	40,  /* 0010 ->  4.0x */	100, /* 0011 -> 10.0x */	55,  /* 0100 ->  5.5x */	35,  /* 0101 ->  3.5x */	45,  /* 0110 ->  4.5x */	95,  /* 0111 ->  9.5x */	90,  /* 1000 ->  9.0x */	70,  /* 1001 ->  7.0x */	80,  /* 1010 ->  8.0x */	60,  /* 1011 ->  6.0x */	120, /* 1100 -> 12.0x */	75,  /* 1101 ->  7.5x */	85,  /* 1110 ->  8.5x */	65,  /* 1111 ->  6.5x */	-1,  /* 0000 -> RESERVED (9.0x) */	110, /* 0001 -> 11.0x */	120, /* 0010 -> 12.0x */	-1,  /* 0011 -> RESERVED (10.0x)*/	135, /* 0100 -> 13.5x */	115, /* 0101 -> 11.5x */	125, /* 0110 -> 12.5x */	105, /* 0111 -> 10.5x */	130, /* 1000 -> 13.0x */	150, /* 1001 -> 15.0x */	160, /* 1010 -> 16.0x */	140, /* 1011 -> 14.0x */	-1,  /* 1100 -> RESERVED (12.0x) */	155, /* 1101 -> 15.5x */	-1,  /* 1110 -> RESERVED (13.0x) */	145, /* 1111 -> 14.5x */};/* fsb values as defined in CPU */static unsigned int eblcr_fsb_table[] = { 66, 133, 100, -1 };/* fsb values to favour low fsb speed (lower power) */static unsigned int power_fsb_table[] = { 66, 100, 133, -1 };/* fsb values to favour high fsb speed (for e.g. if lowering CPU    freq because of heat, but want to maintain highest performance possible) */static unsigned int perf_fsb_table[] = { 133, 100, 66, -1 };static unsigned int *fsb_search_table;/* Voltage scales. Div by 1000 to get actual voltage. */static int __initdata vrm85scales[32] = {	1250, 1200, 1150, 1100, 1050, 1800, 1750, 1700,	1650, 1600, 1550, 1500, 1450, 1400, 1350, 1300,	1275, 1225, 1175, 1125, 1075, 1825, 1775, 1725,	1675, 1625, 1575, 1525, 1475, 1425, 1375, 1325,};static int __initdata mobilevrmscales[32] = {	2000, 1950, 1900, 1850, 1800, 1750, 1700, 1650,	1600, 1550, 1500, 1450, 1500, 1350, 1300, -1,	1275, 1250, 1225, 1200, 1175, 1150, 1125, 1100,	1075, 1050, 1025, 1000, 975, 950, 925, -1,};/* Clock ratios multiplied by 10 */static int clock_ratio[32];static int eblcr_table[32];static int voltage_table[32];static int highest_speed, lowest_speed; /* kHz */static int longhaul; /* version. */static struct cpufreq_driver *longhaul_driver;static int longhaul_get_cpu_fsb (void){	unsigned long invalue=0,lo, hi;	if (current_fsb == 0) {		rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);		invalue = (lo & (1<<18|1<<19)) >>18;		return eblcr_fsb_table[invalue];	} else {		return current_fsb;	}}static int longhaul_get_cpu_mult (void){	unsigned long invalue=0,lo, hi;	rdmsr (MSR_IA32_EBL_CR_POWERON, lo, hi);	invalue = (lo & (1<<22|1<<23|1<<24|1<<25)) >>22;	if (longhaul==3) {		if (lo & (1<<27))			invalue+=16;	}	return eblcr_table[invalue];}/** * longhaul_set_cpu_frequency() * @clock_ratio_index : index of clock_ratio[] for new frequency * @newfsb: the new FSB * * Sets a new clock ratio, and -if applicable- a new Front Side Bus */static void longhaul_setstate (unsigned int clock_ratio_index, unsigned int newfsb){	unsigned long lo, hi;	unsigned int bits;	int revkey;	int vidindex, i;	struct cpufreq_freqs freqs;		if (!newfsb || (clock_ratio[clock_ratio_index] == -1))		return;	if ((!can_scale_fsb) && (newfsb != current_fsb))		return;	if (((clock_ratio[clock_ratio_index] * newfsb * 100) > highest_speed) ||	    ((clock_ratio[clock_ratio_index] * newfsb * 100) < lowest_speed))		return;	freqs.old = longhaul_get_cpu_mult() * longhaul_get_cpu_fsb() * 100;	freqs.new = clock_ratio[clock_ratio_index] * newfsb * 100;	freqs.cpu = 0; /* longhaul.c is UP only driver */		cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);	dprintk (KERN_INFO "longhaul: New FSB:%d Mult(x10):%d\n",				newfsb, clock_ratio[clock_ratio_index]);	bits = clock_ratio_index;	/* "bits" contains the bitpattern of the new multiplier.	   we now need to transform it to the desired format. */	switch (longhaul) {	case 1:		rdmsr (MSR_VIA_BCR2, lo, hi);		revkey = (lo & 0xf)<<4; /* Rev key. */		lo &= ~(1<<23|1<<24|1<<25|1<<26);		lo |= (1<<19);		/* Enable software clock multiplier */		lo |= (bits<<23);	/* desired multiplier */		lo |= revkey;		wrmsr (MSR_VIA_BCR2, lo, hi);		__hlt();		/* Disable software clock multiplier */		rdmsr (MSR_VIA_BCR2, lo, hi);		lo &= ~(1<<19);		lo |= revkey;		wrmsr (MSR_VIA_BCR2, lo, hi);		break;	case 2:		rdmsr (MSR_VIA_LONGHAUL, lo, hi);		revkey = (lo & 0xf)<<4;	/* Rev key. */		lo &= 0xfff0bf0f;	/* reset [19:16,14](bus ratio) and [7:4](rev key) to 0 */		lo |= (bits<<16);		lo |= (1<<8);	/* EnableSoftBusRatio */		lo |= revkey;		if (can_scale_voltage) {			if (can_scale_fsb==1) {				dprintk (KERN_INFO "longhaul: Voltage scaling + FSB scaling not done yet.\n");				goto bad_voltage;			} else {				/* PB: TODO fix this up */				vidindex = (((highest_speed-lowest_speed) / (newfsb/2)) -						((highest_speed-((clock_ratio[clock_ratio_index] * newfsb * 100)/1000)) / (newfsb/2)));			}			for (i=0;i<32;i++) {				dprintk (KERN_INFO "VID hunting. Looking for %d, found %d\n",						minvid+(vidindex*25), voltage_table[i]);				if (voltage_table[i]==(minvid + (vidindex * 25)))					break;			}			if (i==32)				goto bad_voltage;			dprintk (KERN_INFO "longhaul: Desired vid index=%d\n", i);#if 0			lo &= 0xfe0fffff;/* reset [24:20](voltage) to 0 */			lo |= (i<<20);   /* set voltage */			lo |= (1<<9);    /* EnableSoftVID */#endif		}bad_voltage:		wrmsr (MSR_VIA_LONGHAUL, lo, hi);		__hlt();		rdmsr (MSR_VIA_LONGHAUL, lo, hi);		lo &= ~(1<<8);		if (can_scale_voltage)			lo &= ~(1<<9);		lo |= revkey;		wrmsr (MSR_VIA_LONGHAUL, lo, hi);		break;	case 3:		rdmsr (MSR_VIA_LONGHAUL, lo, hi);		revkey = (lo & 0xf)<<4;	/* Rev key. */		lo &= 0xfff0bf0f;	/* reset longhaul[19:16,14] to 0 */		lo |= (bits<<16);		lo |= (1<<8);	/* EnableSoftBusRatio */		lo |= revkey;		/* Set FSB */		if (can_scale_fsb==1) {

⌨️ 快捷键说明

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