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

📄 speedstep.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
		{  66, 0x0 },		{ 100, 0x2 },		{ 133, 0x1 },		{   0, 0xff}	};	u32     msr_lo, msr_tmp;	int     i = 0, j = 0;	struct  cpuinfo_x86 *c = cpu_data;	/* read MSR 0x2a - we only need the low 32 bits */	rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_tmp);	dprintk(KERN_DEBUG "cpufreq: P3 - MSR_IA32_EBL_CR_POWERON: 0x%x 0x%x\n", msr_lo, msr_tmp);	msr_tmp = msr_lo;	/* decode the FSB */	msr_tmp &= 0x00c0000;	msr_tmp >>= 18;	while (msr_tmp != msr_decode_fsb[i].bitmap) {		if (msr_decode_fsb[i].bitmap == 0xff)			return -EINVAL;		i++;	}	/* decode the multiplier */	if ((c->x86_model == 0x08) && (c->x86_mask == 0x01))                 /* different on early Coppermine PIII */		msr_lo &= 0x03c00000;	else		msr_lo &= 0x0bc00000;	msr_lo >>= 22;	while (msr_lo != msr_decode_mult[j].bitmap) {		if (msr_decode_mult[j].bitmap == 0xff)			return -EINVAL;		j++;	}	return (msr_decode_mult[j].ratio * msr_decode_fsb[i].value * 100);}/** * pentium4_get_frequency - get the core frequency for P4-Ms * *   Should return the core frequency (in kHz) for P4-Ms.  */static unsigned int pentium4_get_frequency(void){	u32 msr_lo, msr_hi;	rdmsr(0x2c, msr_lo, msr_hi);	dprintk(KERN_DEBUG "cpufreq: P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi);	/* First 12 bits seem to change a lot (0x511, 0x410 and 0x30f seen 	 * yet). Next 12 bits always seem to be 0x300. If this is not true 	 * on this CPU, complain. Last 8 bits are frequency (in 100MHz).	 */	if (msr_hi || ((msr_lo & 0x00FFF000) != 0x300000)) {		printk(KERN_DEBUG "cpufreq: P4 - MSR_EBC_FREQUENCY_ID: 0x%x 0x%x\n", msr_lo, msr_hi);		printk(KERN_INFO "cpufreq: problem in initialization. Please contact Dominik Brodowski\n");		printk(KERN_INFO "cpufreq: <linux@brodo.de> and attach this dmesg. Thanks in advance\n");		return 0;	}	msr_lo >>= 24;	return (msr_lo * 100000);}/**  * speedstep_detect_processor - detect Intel SpeedStep-capable processors. * *   Returns the SPEEDSTEP_PROCESSOR_-number for the detected processor,  * or zero on failure. */static unsigned int speedstep_detect_processor (void){	struct cpuinfo_x86 *c = cpu_data;	u32                     ebx;	if ((c->x86_vendor != X86_VENDOR_INTEL) || 	    ((c->x86 != 6) && (c->x86 != 0xF)))		return 0;	if (c->x86 == 0xF) {		/* Intel Pentium 4 Mobile P4-M */		if (c->x86_model != 2)			return 0;		if ((c->x86_mask != 4) && (c->x86_mask != 7))			return 0;		ebx = cpuid_ebx(0x00000001);		ebx &= 0x000000FF;		if ((ebx != 0x0e) && (ebx != 0x0f))			return 0;		return SPEEDSTEP_PROCESSOR_P4M;	}	switch (c->x86_model) {	case 0x0B: /* Intel PIII [Tualatin] */		/* cpuid_ebx(1) is 0x04 for desktop PIII, 		                   0x06 for mobile PIII-M */		ebx = cpuid_ebx(0x00000001);		ebx &= 0x000000FF;		if (ebx != 0x06)			return 0;		/* So far all PIII-M processors support SpeedStep. See		 * Intel's 24540633.pdf of August 2002 		 */		return SPEEDSTEP_PROCESSOR_PIII_T;	case 0x08: /* Intel PIII [Coppermine] */ 	        {			u32     msr_lo, msr_hi;			/* all mobile PIII Coppermines have FSB 100 MHz			 * ==> sort out a few desktop PIIIs. */			rdmsr(MSR_IA32_EBL_CR_POWERON, msr_lo, msr_hi);			dprintk(KERN_DEBUG "cpufreq: Coppermine: MSR_IA32_EBL_Cr_POWERON is 0x%x, 0x%x\n", msr_lo, msr_hi);			msr_lo &= 0x00c0000;			if (msr_lo != 0x0080000)				return 0;			if (speedstep_coppermine)				return SPEEDSTEP_PROCESSOR_PIII_C;			printk(KERN_INFO "cpufreq: in case this is a SpeedStep-capable Intel Pentium III Coppermine\n");			printk(KERN_INFO "cpufreq: processor, please pass the boot option or module parameter\n");			printk(KERN_INFO "cpufreq: `speedstep_coppermine=1` to the kernel. Thanks!\n");			return 0;		}	default:		return 0;	}}/********************************************************************* *                        HIGH LEVEL FUNCTIONS                       * *********************************************************************//** * speedstep_detect_speeds - detects low and high CPU frequencies. * *   Detects the low and high CPU frequencies in kHz. Returns 0 on * success or -EINVAL / -EIO on problems.  */static int speedstep_detect_speeds (void){	unsigned long   flags;	unsigned int    state;	int             i, result;	/* Disable irqs for entire detection process */	local_irq_save(flags);	for (i=0; i<2; i++) {		/* read the current state */		result = speedstep_get_state(&state);		if (result)			return result;		/* save the correct value, and switch to other */		if (state == SPEEDSTEP_LOW) {			switch (speedstep_processor) {			case SPEEDSTEP_PROCESSOR_PIII_C:			case SPEEDSTEP_PROCESSOR_PIII_T:				speedstep_low_freq = pentium3_get_frequency();				break;			case SPEEDSTEP_PROCESSOR_P4M:				speedstep_low_freq = pentium4_get_frequency();			}			speedstep_set_state(SPEEDSTEP_HIGH, 0);		} else {			switch (speedstep_processor) {			case SPEEDSTEP_PROCESSOR_PIII_C:			case SPEEDSTEP_PROCESSOR_PIII_T:				speedstep_high_freq = pentium3_get_frequency();				break;			case SPEEDSTEP_PROCESSOR_P4M:				speedstep_high_freq = pentium4_get_frequency();			}			speedstep_set_state(SPEEDSTEP_LOW, 0);		}	}	local_irq_restore(flags);	if (!speedstep_low_freq || !speedstep_high_freq || 	    (speedstep_low_freq == speedstep_high_freq))		return -EIO;	return 0;}/** * speedstep_setpolicy - set a new CPUFreq policy * @policy: new policy * * Sets a new CPUFreq policy. */static int speedstep_setpolicy (struct cpufreq_policy *policy){	unsigned int    newstate = 0;	if (cpufreq_frequency_table_setpolicy(policy, &speedstep_freqs[0], &newstate))		return -EINVAL;	speedstep_set_state(newstate, 1);	return 0;}/** * speedstep_verify - verifies a new CPUFreq policy * @freq: new policy * * Limit must be within speedstep_low_freq and speedstep_high_freq, with * at least one border included. */static int speedstep_verify (struct cpufreq_policy *policy){	return cpufreq_frequency_table_verify(policy, &speedstep_freqs[0]);}#ifndef MODULE/** * speedstep_setup  speedstep command line parameter parsing * * speedstep command line parameter.  Use: *  speedstep_coppermine=1 * if the CPU in your notebook is a SpeedStep-capable Intel * Pentium III Coppermine. These processors cannot be detected * automatically, as Intel continues to consider the detection  * alogrithm as proprietary material. */static int __init speedstep_setup(char *str){	speedstep_coppermine = simple_strtoul(str, &str, 0);	return 1;}__setup("speedstep_coppermine=", speedstep_setup);#endif/** * speedstep_init - initializes the SpeedStep CPUFreq driver * *   Initializes the SpeedStep support. Returns -ENODEV on unsupported * devices, -EINVAL on problems during initiatization, and zero on * success. */static int __init speedstep_init(void){	int                     result;	unsigned int            speed;	struct cpufreq_driver   *driver;	/* detect chipset */	speedstep_chipset = speedstep_detect_chipset(); 	/* detect chipset */	if (speedstep_chipset)		speedstep_processor = speedstep_detect_processor();	if ((!speedstep_chipset) || (!speedstep_processor)) {		printk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) for this %s not (yet) available.\n", speedstep_chipset ? "processor" : "chipset");		return -ENODEV;	}	dprintk(KERN_INFO "cpufreq: Intel(R) SpeedStep(TM) support $Revision: 1.64 $\n");	dprintk(KERN_DEBUG "cpufreq: chipset 0x%x - processor 0x%x\n", 	       speedstep_chipset, speedstep_processor);	/* activate speedstep support */	result = speedstep_activate();	if (result)		return result;	/* detect low and high frequency */	result = speedstep_detect_speeds();	if (result)		return result;	/* get current speed setting */	result = speedstep_get_state(&speed);	if (result)		return result;	speed = (speed == SPEEDSTEP_LOW) ? speedstep_low_freq : speedstep_high_freq;	dprintk(KERN_INFO "cpufreq: currently at %s speed setting - %i MHz\n", 	       (speed == speedstep_low_freq) ? "low" : "high",	       (speed / 1000));	/* initialization of main "cpufreq" code*/	driver = kmalloc(sizeof(struct cpufreq_driver) + 			 NR_CPUS * sizeof(struct cpufreq_policy), GFP_KERNEL);	if (!driver)		return -ENOMEM;	driver->policy = (struct cpufreq_policy *) (driver + 1);	driver->policy[0].cpu    = 0;	result = cpufreq_frequency_table_cpuinfo(&driver->policy[0], &speedstep_freqs[0]);	if (result) {		kfree(driver);		return result;	}#ifdef CONFIG_CPU_FREQ_24_API	driver->cpu_cur_freq[0] = speed;#endif	driver->verify      = &speedstep_verify;	driver->setpolicy   = &speedstep_setpolicy;	driver->policy[0].cpuinfo.transition_latency = CPUFREQ_ETERNAL;	driver->policy[0].policy = (speed == speedstep_low_freq) ? 	    CPUFREQ_POLICY_POWERSAVE : CPUFREQ_POLICY_PERFORMANCE;	speedstep_driver = driver;	result = cpufreq_register(driver);	if (result) {		speedstep_driver = NULL;		kfree(driver);	}	return result;}/** * speedstep_exit - unregisters SpeedStep support * *   Unregisters SpeedStep support. */static void __exit speedstep_exit(void){	if (speedstep_driver) {		cpufreq_unregister();		kfree(speedstep_driver);	}}MODULE_AUTHOR ("Dave Jones <davej@suse.de>, Dominik Brodowski <linux@brodo.de>");MODULE_DESCRIPTION ("Speedstep driver for Intel mobile processors.");MODULE_LICENSE ("GPL");module_init(speedstep_init);module_exit(speedstep_exit);MODULE_PARM (speedstep_coppermine, "i");

⌨️ 快捷键说明

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