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

📄 bluesmoke.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
字号:
/*  * Machine check handler. * K8 parts Copyright 2002 Andi Kleen, SuSE Labs. * Rest from unknown author(s).  */#include <linux/init.h>#include <linux/types.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/string.h>#include <linux/ctype.h>#include <asm/processor.h> #include <asm/msr.h>#include <asm/kdebug.h>#include <linux/pci.h>#include <linux/timer.h>static int mce_disabled __initdata = 1;/* *	Machine Check Handler For PII/PIII/K7 */static int banks;static unsigned long ignored_banks, disabled_banks =  (1UL << 4); static void generic_machine_check(struct pt_regs * regs, long error_code){	int recover=1;	u32 alow, ahigh, high, low;	u32 mcgstl, mcgsth;	int i;		rdmsr(MSR_IA32_MCG_STATUS, mcgstl, mcgsth);	if(mcgstl&(1<<0))	/* Recoverable ? */		recover=0;	printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x\n", smp_processor_id(), mcgsth, mcgstl);		if (regs && (mcgstl & 2))		printk(KERN_EMERG "RIP <%02lx>:%016lx RSP %016lx\n", 		       regs->cs, regs->rip, regs->rsp); 	for(i=0;i<banks;i++)	{		if ((1UL<<i) & ignored_banks) 			continue; 		rdmsr(MSR_IA32_MC0_STATUS+i*4,low, high);		if(high&(1<<31))		{			if(high&(1<<29))				recover|=1;			if(high&(1<<25))				recover|=2;			printk(KERN_EMERG "Bank %d: %08x%08x", i, high, low);			high&=~(1<<31);			if(high&(1<<27))			{				rdmsr(MSR_IA32_MC0_MISC+i*4, alow, ahigh);				printk("[%08x%08x]", alow, ahigh);			}			if(high&(1<<26))			{				rdmsr(MSR_IA32_MC0_ADDR+i*4, alow, ahigh);				printk(" at %08x%08x", 					ahigh, alow);			}			printk("\n");			/* Clear it */			wrmsr(MSR_IA32_MC0_STATUS+i*4, 0UL, 0UL);			/* Serialize */			wmb();		}	}	if(recover&2)		panic("CPU context corrupt");	if(recover&1)		panic("Unable to continue");	printk(KERN_EMERG "Attempting to continue.\n");	mcgstl&=~(1<<2);	wrmsr(MSR_IA32_MCG_STATUS,mcgstl, mcgsth);}static void unexpected_machine_check(struct pt_regs *regs, long error_code){ 	printk("unexpected machine check %lx\n", error_code); } /* *	Call the installed machine check handler for this CPU setup. */  static void (*machine_check_vector)(struct pt_regs *, long error_code) = unexpected_machine_check;void do_machine_check(struct pt_regs * regs, long error_code){	notify_die(DIE_NMI, "machine check", regs, error_code);	machine_check_vector(regs, error_code);}/*  *	K8 machine check. */static struct pci_dev *find_k8_nb(void){ 	struct pci_dev *dev;	int cpu = smp_processor_id(); 	pci_for_each_dev(dev) {		if (dev->bus->number==0 && PCI_FUNC(dev->devfn)==3 &&		    PCI_SLOT(dev->devfn) == (24+cpu))			return dev;	}	return NULL;}static void k8_machine_check(struct pt_regs * regs, long error_code){ 	u64 status, nbstatus;	struct pci_dev *nb;	rdmsrl(MSR_IA32_MCG_STATUS, status); 	if ((status & (1<<2)) == 0) 		return; 	if (status & 1)		printk(KERN_EMERG "MCG_STATUS: unrecoverable\n"); 	rdmsrl(MSR_IA32_MC0_STATUS+4*4, nbstatus); 	if ((nbstatus & (1UL<<63)) == 0)		goto others; 		printk(KERN_EMERG "Northbridge Machine Check %s %016lx %lx\n", 	       regs ? "exception" : "timer",	       (unsigned long)nbstatus, error_code); 	if (nbstatus & (1UL<<62))		printk(KERN_EMERG "Lost at least one NB error condition\n"); 		if (nbstatus & (1UL<<61))		printk(KERN_EMERG "Uncorrectable condition\n"); 	if (nbstatus & (1UL<57))		printk(KERN_EMERG "Unrecoverable condition\n"); 			nb = find_k8_nb(); 	if (nb != NULL) { 		u32 statuslow, statushigh;		pci_read_config_dword(nb, 0x48, &statuslow);		pci_read_config_dword(nb, 0x4c, &statushigh);		printk(KERN_EMERG "Northbridge status %08x%08x\n",		       statushigh,statuslow); 		if (statuslow & 0x10) 			printk(KERN_EMERG "GART error %d\n", statuslow & 0xf); 		if (statushigh & (1<<31))			printk(KERN_EMERG "Lost an northbridge error\n"); 		if (statushigh & (1<<25))			printk(KERN_EMERG "NB status: unrecoverable\n"); 		if (statushigh & (1<<26)) { 			u32 addrhigh, addrlow; 			pci_read_config_dword(nb, 0x54, &addrhigh); 			pci_read_config_dword(nb, 0x50, &addrlow); 			printk(KERN_EMERG "NB error address %08x%08x\n", addrhigh,addrlow); 		}		statushigh &= ~(1<<31); 		pci_write_config_dword(nb, 0x4c, statushigh); 			} 	if (nbstatus & (1UL<<58)) { 		u64 adr;		rdmsrl(MSR_IA32_MC0_ADDR+4*4, adr);		printk(KERN_EMERG "Address: %016lx\n", (unsigned long)adr);	}		wrmsrl(MSR_IA32_MC0_STATUS+4*4, 0); 	wrmsrl(MSR_IA32_MCG_STATUS, 0);       	if (regs && (status & (1<<1)))		printk(KERN_EMERG "MCE at EIP %lx ESP %lx\n", regs->rip, regs->rsp);  others:	generic_machine_check(regs, error_code); } static struct timer_list mcheck_timer;int mcheck_interval = 30*HZ; static void mcheck_timer_handler(unsigned long data){	k8_machine_check(NULL,0);	BUG_ON(timer_pending(&mcheck_timer));	mcheck_timer.expires = jiffies + mcheck_interval;	add_timer(&mcheck_timer);}#ifdef CONFIG_SMP /* SMP needs a process context trampoline because smp_call_function cannot be    called from interrupt context */static void mcheck_timer_dist(void *data){ 	/* preempt disabled on preemptive kernel */		if (!data) 		smp_call_function((void (*)(void *))mcheck_timer_handler,(void*)1,0,0);	mcheck_timer_handler(0); 	} static void mcheck_timer_trampoline(unsigned long data){ 	static struct tq_struct mcheck_task = { 		routine: mcheck_timer_dist	}; 	schedule_task(&mcheck_task); } #define mcheck_timer_handler mcheck_timer_trampoline#endif static int nok8 __initdata; static void __init k8_mcheck_init(struct cpuinfo_x86 *c){	u64 cap;	int i;	struct pci_dev *nb; 	if (!test_bit(X86_FEATURE_MCE, &c->x86_capability) || 	    !test_bit(X86_FEATURE_MCA, &c->x86_capability))		return; 	rdmsrl(MSR_IA32_MCG_CAP, cap); 	banks = cap&0xff; 	machine_check_vector = k8_machine_check; 	for (i = 0; i < banks; i++) { 		u64 val = ((1UL<<i) & disabled_banks) ? 0 : ~0UL; 		wrmsrl(MSR_IA32_MC0_CTL+4*i, val);		wrmsrl(MSR_IA32_MC0_STATUS+4*i,0); 	}	nb = find_k8_nb(); 	if (nb != NULL) {		u32 reg;		pci_read_config_dword(nb, 0x40, &reg); 		pci_write_config_dword(nb, 0x40, reg|(1<<11)|(1<<10)|(1<<9)|(1<<8)); 		printk(KERN_INFO "Machine Check Reporting for K8 Northbridge %d enabled\n",		       nb->devfn);		ignored_banks |= (1UL<<4); 	} 	set_in_cr4(X86_CR4_MCE);	   		if (mcheck_interval) { 		init_timer(&mcheck_timer); 		mcheck_timer.function = (void (*)(unsigned long))mcheck_timer_handler; 		mcheck_timer.expires = jiffies + mcheck_interval; 		add_timer(&mcheck_timer); 	} 		printk(KERN_INFO "Machine Check Reporting enabled for CPU#%d\n", smp_processor_id()); } /* *	Set up machine check reporting for Intel processors */static void __init generic_mcheck_init(struct cpuinfo_x86 *c){	u32 l, h;	int i;	static int done;		/*	 *	Check for MCE support	 */	if( !test_bit(X86_FEATURE_MCE, &c->x86_capability) )		return;			/*	 *	Check for PPro style MCA	 */	 			if( !test_bit(X86_FEATURE_MCA, &c->x86_capability) )		return;			/* Ok machine check is available */		machine_check_vector = generic_machine_check;	wmb();		if(done==0)		printk(KERN_INFO "Intel machine check architecture supported.\n");	rdmsr(MSR_IA32_MCG_CAP, l, h);	if(l&(1<<8))		wrmsr(MSR_IA32_MCG_CTL, 0xffffffff, 0xffffffff);	banks = l&0xff;	for(i=0;i<banks;i++)	{		u32 val = ((1UL<<i) & disabled_banks) ? 0 : ~0;		wrmsr(MSR_IA32_MC0_CTL+4*i, val, val);		wrmsr(MSR_IA32_MC0_STATUS+4*i, 0x0, 0x0);	}	set_in_cr4(X86_CR4_MCE);	printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", smp_processor_id());	done=1;}/* *	This has to be run for each processor */void __init mcheck_init(struct cpuinfo_x86 *c){	if(mce_disabled==1)		return;			switch(c->x86_vendor) {	case X86_VENDOR_AMD:		if (c->x86 == 15 && !nok8) {			k8_mcheck_init(c); 			break;		}		/* FALL THROUGH */	default:	case X86_VENDOR_INTEL:		generic_mcheck_init(c);		break;	}}static int __init mcheck_disable(char *str){	mce_disabled = 1;	return 0;}/* mce=off disable machine check   mcenok8 disable k8 specific features   mce=disable<NUMBER> disable bank NUMBER   mce=enable<NUMBER> enable bank number   mce=NUMBER mcheck timer interval number seconds.    Can be also comma separated in a single mce= */static int __init mcheck_enable(char *str){	char *p;	while ((p = strsep(&str,",")) != NULL) { 		if (isdigit(*p))			mcheck_interval = simple_strtol(p,NULL,0) * HZ; 		else if (!strcmp(p,"off"))			mce_disabled = 1; 		else if (!strncmp(p,"enable",6))			disabled_banks &= ~(1<<simple_strtol(p+6,NULL,0));		else if (!strncmp(p,"disable",7))			disabled_banks |= ~(1<<simple_strtol(p+7,NULL,0));		else if (!strcmp(p,"nok8"))			nok8 = 1;		else			return -1;				}	return 0;}__setup("nomce", mcheck_disable);__setup("mce", mcheck_enable);

⌨️ 快捷键说明

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