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

📄 cpu.c

📁 微内核软实时操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
	{ 1000, 1100 },	{  800, 1052 },	{  600,  988 }};/* Intel Pentium M processor 765 2.1 GHz */static const struct fq_info pentium_m_n765[] = {	{ 2100, 1340 },	{ 1800, 1276 },	{ 1600, 1228 },	{ 1400, 1180 },	{ 1200, 1132 },	{ 1000, 1084 },	{  800, 1036 },	{  600,  988 } };struct fqlist {	const char *brand_tag;	const struct fq_info *table;	u_int n;};static const struct fqlist pentium_m[] = {#define ENTRY(s, v)	{ s, v, sizeof(v) / sizeof((v)[0]) }	ENTRY(" 900", pentium_m_900),	ENTRY("1000", pentium_m_1000),	ENTRY("1100", pentium_m_1100),	ENTRY("1200", pentium_m_1200),	ENTRY("1300", pentium_m_1300),	ENTRY("1400", pentium_m_1400),	ENTRY("1500", pentium_m_1500),	ENTRY("1600", pentium_m_1600),	ENTRY("1700", pentium_m_1700),#undef ENTRY};static const struct fqlist pentium_m_dothan[] = {#define ENTRY(s, v)	{ s, v, sizeof(v) / sizeof((v)[0]) }	ENTRY("1.00", pentium_m_n723),	ENTRY("1.10", pentium_m_n733),	ENTRY("1.20", pentium_m_n753),	ENTRY("1.40", pentium_m_n738),#if 0	ENTRY("1.50", pentium_m_n758),#endif	ENTRY("1.50", pentium_m_n715),	ENTRY("1.60", pentium_m_n725),	ENTRY("1.70", pentium_m_n735),	ENTRY("1.80", pentium_m_n745),	ENTRY("2.00", pentium_m_n755),	ENTRY("2.10", pentium_m_n765),#undef ENTRY};struct est_cpu {	const char *brand_prefix;	const char *brand_suffix;	const struct fqlist *list;	int n;};static const struct est_cpu est_cpus[] = {	{		"Intel(R) Pentium(R) M processor ", "MHz",		pentium_m,		(sizeof(pentium_m) / sizeof(pentium_m[0]))	},	{		"Intel(R) Pentium(R) M processor ", "GHz",		pentium_m_dothan,		(sizeof(pentium_m_dothan) / sizeof(pentium_m_dothan[0]))	},};#define NESTCPUS	  (sizeof(est_cpus) / sizeof(est_cpus[0]))#define MSRVALUE(mhz, mv)	((((mhz) / 100) << 8) | (((mv) - 700) / 16))#define MSR2MHZ(msr)		((((int) (msr) >> 8) & 0xff) * 100)#define MSR2MV(msr)		(((int) (msr) & 0xff) * 16 + 700)static const struct fqlist *est_fqlist;static struct cpu_info cpu_info;static struct cpu_stat cpu_stat;#ifdef CONFIG_DVS_EMULATIONstatic int bochs;#endif/* * Get cpu id */static void cpuid(u_int eax, u_int *p){	__asm__ __volatile__(		"cpuid\n\t"		"movl %%eax, 0(%2)\n\t"		"movl %%ebx, 4(%2)\n\t"		"movl %%ecx, 8(%2)\n\t"		"movl %%edx, 12(%2)\n\t"		: "=a" (eax)		: "0" (eax), "S" (p)		: "bx", "cx", "dx");}/* * Set CPU performance * * @level: percent of cpu speed */int cpu_setperf(int level){	int i, fq;	u_int msr_lo, msr_hi;	int max_mhz;	ASSERT(cpu_info.clock_ctrl);	max_mhz = est_fqlist->table[0].mhz;	fq = max_mhz * level / 100;		for (i = est_fqlist->n - 1; i > 0; i--)		if (est_fqlist->table[i].mhz >= fq)			break;	if (est_fqlist->table[i].mhz == cpu_stat.speed)		return 0;	cpu_stat.speed = est_fqlist->table[i].mhz;	cpu_stat.power = est_fqlist->table[i].mv;	cpu_dbg("setperf: %dMHz %dmV\n", cpu_stat.speed, cpu_stat.power);#ifdef CONFIG_DVS_EMULATION	if (bochs)		return 0;#endif	rdmsr(MSR_PERF_CTL, msr_lo, msr_hi);	msr_lo = (msr_lo & ~0xffff) |		MSRVALUE(est_fqlist->table[i].mhz, est_fqlist->table[i].mv);	wrmsr(MSR_PERF_CTL, msr_lo, msr_hi);	return 0;}/* * Get CPU performance */int cpu_getperf(void){	int max_mhz;	int level;		ASSERT(cpu_info.clock_ctrl);	max_mhz = est_fqlist->table[0].mhz;	ASSERT(max_mhz);	level = cpu_stat.speed * 100 / max_mhz;	return level;}/* * Initialize CPU performance * Return false on error. */int cpu_initperf(void){	int i, j, n, mhz, mv;	const struct est_cpu *cpu;	u_int msr_lo, msr_hi;	char *tag, *brand_str;	const struct fqlist *fql;	if (!cpu_info.clock_ctrl)		return -1;#ifdef CONFIG_DVS_EMULATION	if (bochs) {		msr_lo = 0x1031;		cpu = &est_cpus[0];		est_fqlist = &cpu->list[7];	} else		rdmsr(MSR_PERF_STATUS, msr_lo, msr_hi);#else	rdmsr(MSR_PERF_STATUS, msr_lo, msr_hi);#endif	mhz = MSR2MHZ(msr_lo);	mv = MSR2MV(msr_lo);	printk("Enhanced SpeedStep %d MHz (%d mV)\n", mhz, mv);#ifdef CONFIG_DVS_EMULATION	if (!bochs) {#endif	/*	 * Look for a CPU matching brand_str.	 */	brand_str = cpu_info.name;	for (i = 0; est_fqlist == NULL && i < NESTCPUS; i++) {		cpu = &est_cpus[i];		n = strnlen(cpu->brand_prefix, 48);		if (strncmp(cpu->brand_prefix, brand_str, n) != 0)			continue;		tag = brand_str + n;		for (j = 0; j < cpu->n; j++) {			fql = &cpu->list[j];			n = strnlen(fql->brand_tag, 48);			if (!strncmp(fql->brand_tag, tag, n) &&			    !strncmp(cpu->brand_suffix, tag + n, 48)) {				est_fqlist = fql;				break;			}		}	}	if (est_fqlist == NULL) {		printk("Unknown EST cpu, no changes possible\n");		cpu_info.clock_ctrl = 0;		return -1;	}	/*	 * Check that the current operating point is in our list.	 */	for (i = est_fqlist->n - 1; i >= 0; i--)		if (est_fqlist->table[i].mhz == mhz)			break;	if (i < 0) {		printk(" (not in table)\n");		cpu_info.clock_ctrl = 0;		return -1;	}#ifdef CONFIG_DVS_EMULATION	}#endif	/*	 * Store current state	 */	cpu_info.speed = est_fqlist->table[0].mhz;	cpu_info.power = est_fqlist->table[0].mv;	cpu_stat.speed = mhz;	cpu_stat.power = mv;	/*	 * OK, tell the user the available frequencies.	 */	printk("Speeds: ");	for (i = 0; i < est_fqlist->n; i++)		printk("%d%s", est_fqlist->table[i].mhz,		    i < est_fqlist->n - 1 ? ", " : " MHz\n");	return 0;}static int cpu_ioctl(device_t dev, int cmd, u_long arg){	switch (cmd) {	case CPUIOC_GET_INFO:		if (umem_copyout(&cpu_info, (void *)arg, sizeof(cpu_info)))			return EFAULT;		break;	case CPUIOC_GET_STAT:		if (umem_copyout(&cpu_stat, (void *)arg, sizeof(cpu_stat)))			return EFAULT;		break;	default:		return EINVAL;	}	return 0;}/* * Initialize CPU addon feature * * FIXME: i486 does not support cpuid instruction */static int cpu_init(void){	u_int regs[4];	char brand_str[49];	char *p, *q;	/* Create device object */	cpu_dev = device_create(&cpu_io, "cpu");	ASSERT(cpu_dev);#ifdef CONFIG_DVS_EMULATION	bochs = 0;	if (inb(0xe9) == 0xe9) {		/*		 * Detect Bochs. Fake the cpuid value.		 */		bochs = 1;		cpu_info.id = 0x6d6;		cpu_info.clock_ctrl = 1;		strncpy(cpu_info.name,			"Intel(R) Pentium(R) M processor 1600MHz", 50);		printk("CPU brand: %s\n", cpu_info.name);		return 0;	}#endif	/*	 * Check enhanced speed step capability	 */	cpuid(1, regs);	cpu_info.id = regs[0];	cpu_dbg("cpu id=%x\n", regs[0]);	if ((regs[2] & 0x80) == 0) {		cpu_info.clock_ctrl = 0;		return 0;	}	cpu_info.clock_ctrl = 1;	/*	 * Get CPU brand string	 */	cpuid(0x80000002, regs);	memcpy(brand_str, regs, sizeof(regs));	cpuid(0x80000003, regs);	memcpy(brand_str + 16, regs, sizeof(regs));	cpuid(0x80000004, regs);	memcpy(brand_str + 32, regs, sizeof(regs));	/* Store string with lef-align */	q = &cpu_info.name[0];	p = brand_str;	while (*p == ' ')		p++;	while (*p)		*q++ = *p++;	*q = '\0';	printk("CPU brand: %s\n", cpu_info.name);	return 0;}

⌨️ 快捷键说明

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