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

📄 mca.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
 *	None */voidia64_mca_ucmc_handler(void){	/* Get the MCA processor log */	ia64_log_get(SAL_INFO_TYPE_MCA, SAL_SUB_INFO_TYPE_PROCESSOR, (prfunc_t)printk);	/* Get the MCA platform log */	ia64_log_get(SAL_INFO_TYPE_MCA, SAL_SUB_INFO_TYPE_PLATFORM, (prfunc_t)printk);	ia64_log_print(SAL_INFO_TYPE_MCA, SAL_SUB_INFO_TYPE_PROCESSOR, (prfunc_t)printk);	/* 	 * Do some error handling - Platform-specific mca handler is called at this point	 */	mca_handler_platform() ;	/* Clear the SAL MCA logs */	ia64_log_clear(SAL_INFO_TYPE_MCA, SAL_SUB_INFO_TYPE_PROCESSOR, 1, printk);	ia64_log_clear(SAL_INFO_TYPE_MCA, SAL_SUB_INFO_TYPE_PLATFORM, 1, printk);	/* Wakeup all the processors which are spinning in the rendezvous	 * loop.	 */	ia64_mca_wakeup_all();	ia64_return_to_sal_check();}/*  * ia64_mca_cmc_int_handler *	This is correctable machine check interrupt handler. *	Right now the logs are extracted and displayed in a well-defined *	format.  * Inputs *	None * Outputs *	None */voidia64_mca_cmc_int_handler(int cmc_irq, void *arg, struct pt_regs *ptregs){		/* Get the CMC processor log */	ia64_log_get(SAL_INFO_TYPE_CMC, SAL_SUB_INFO_TYPE_PROCESSOR, (prfunc_t)printk);	/* Get the CMC platform log */	ia64_log_get(SAL_INFO_TYPE_CMC, SAL_SUB_INFO_TYPE_PLATFORM, (prfunc_t)printk);	ia64_log_print(SAL_INFO_TYPE_CMC, SAL_SUB_INFO_TYPE_PROCESSOR, (prfunc_t)printk);	cmci_handler_platform(cmc_irq, arg, ptregs);	/* Clear the CMC SAL logs now that they have been saved in the OS buffer */	ia64_sal_clear_state_info(SAL_INFO_TYPE_CMC, SAL_SUB_INFO_TYPE_PROCESSOR);	ia64_sal_clear_state_info(SAL_INFO_TYPE_CMC, SAL_SUB_INFO_TYPE_PLATFORM);}/* * IA64_MCA log support */#define IA64_MAX_LOGS		2	/* Double-buffering for nested MCAs */#define IA64_MAX_LOG_TYPES	3	/* MCA, CMC, INIT */#define IA64_MAX_LOG_SUBTYPES	2	/* Processor, Platform */typedef struct ia64_state_log_s {	spinlock_t	isl_lock;	int		isl_index;	ia64_psilog_t	isl_log[IA64_MAX_LOGS];	/* need space to store header + error log */} ia64_state_log_t;static ia64_state_log_t	ia64_state_log[IA64_MAX_LOG_TYPES][IA64_MAX_LOG_SUBTYPES];#define IA64_LOG_LOCK_INIT(it, sit)	spin_lock_init(&ia64_state_log[it][sit].isl_lock)#define IA64_LOG_LOCK(it, sit)	 	spin_lock_irqsave(&ia64_state_log[it][sit].isl_lock, s)#define IA64_LOG_UNLOCK(it, sit) 	spin_unlock_irqrestore(&ia64_state_log[it][sit].isl_lock,\							       s)#define IA64_LOG_NEXT_INDEX(it, sit)	ia64_state_log[it][sit].isl_index#define IA64_LOG_CURR_INDEX(it, sit) 	1 - ia64_state_log[it][sit].isl_index#define IA64_LOG_INDEX_INC(it, sit)	\	ia64_state_log[it][sit].isl_index = 1 - ia64_state_log[it][sit].isl_index#define IA64_LOG_INDEX_DEC(it, sit)	\	ia64_state_log[it][sit].isl_index = 1 - ia64_state_log[it][sit].isl_index#define IA64_LOG_NEXT_BUFFER(it, sit) 	(void *)(&(ia64_state_log[it][sit].isl_log[IA64_LOG_NEXT_INDEX(it,sit)]))#define IA64_LOG_CURR_BUFFER(it, sit) 	(void *)(&(ia64_state_log[it][sit].isl_log[IA64_LOG_CURR_INDEX(it,sit)]))/* * C portion of the OS INIT handler * * Called from ia64_<monarch/slave>_init_handler * * Inputs: pointer to pt_regs where processor info was saved. * * Returns:  *   0 if SAL must warm boot the System *   1 if SAL must retrun to interrupted context using PAL_MC_RESUME * */voidia64_init_handler (struct pt_regs *regs){	sal_log_processor_info_t *proc_ptr;	ia64_psilog_t *plog_ptr;	printk("Entered OS INIT handler\n");	/* Get the INIT processor log */	ia64_log_get(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PROCESSOR, (prfunc_t)printk);	/* Get the INIT platform log */	ia64_log_get(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PLATFORM, (prfunc_t)printk);#ifdef IA64_DUMP_ALL_PROC_INFO 	ia64_log_print(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PROCESSOR, (prfunc_t)printk);#endif 	/* 	 * get pointer to min state save area	 *	 */	plog_ptr=(ia64_psilog_t *)IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_INIT,						       SAL_SUB_INFO_TYPE_PROCESSOR);	proc_ptr = &plog_ptr->devlog.proclog;		ia64_process_min_state_save(&proc_ptr->slpi_min_state_area,regs);	init_handler_platform(regs);              /* call platform specific routines */	/* Clear the INIT SAL logs now that they have been saved in the OS buffer */	ia64_sal_clear_state_info(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PROCESSOR);	ia64_sal_clear_state_info(SAL_INFO_TYPE_INIT, SAL_SUB_INFO_TYPE_PLATFORM);}/* * ia64_log_init * 	Reset the OS ia64 log buffer * Inputs 	:	info_type 	(SAL_INFO_TYPE_{MCA,INIT,CMC}) *			sub_info_type	(SAL_SUB_INFO_TYPE_{PROCESSOR,PLATFORM}) * Outputs	: 	None */voidia64_log_init(int sal_info_type, int sal_sub_info_type){	IA64_LOG_LOCK_INIT(sal_info_type, sal_sub_info_type);	IA64_LOG_NEXT_INDEX(sal_info_type, sal_sub_info_type) = 0;	memset(IA64_LOG_NEXT_BUFFER(sal_info_type, sal_sub_info_type), 0, 	       sizeof(ia64_psilog_t) * IA64_MAX_LOGS);}/*  * ia64_log_get * 	Get the current MCA log from SAL and copy it into the OS log buffer. * Inputs 	:	info_type 	(SAL_INFO_TYPE_{MCA,INIT,CMC}) *			sub_info_type	(SAL_SUB_INFO_TYPE_{PROCESSOR,PLATFORM}) * Outputs	: 	None * */voidia64_log_get(int sal_info_type, int sal_sub_info_type, prfunc_t prfunc){	sal_log_header_t	*log_buffer;	int			s,total_len=0;	IA64_LOG_LOCK(sal_info_type, sal_sub_info_type);	/* Get the process state information */	log_buffer = IA64_LOG_NEXT_BUFFER(sal_info_type, sal_sub_info_type);	if (!(total_len=ia64_sal_get_state_info(sal_info_type, sal_sub_info_type ,(u64 *)log_buffer)))		prfunc("ia64_mca_log_get : Getting processor log failed\n");	IA64_MCA_DEBUG("ia64_log_get: retrieved %d bytes of error information\n",total_len);	IA64_LOG_INDEX_INC(sal_info_type, sal_sub_info_type);	IA64_LOG_UNLOCK(sal_info_type, sal_sub_info_type);}/*  * ia64_log_clear * 	Clear the current MCA log from SAL and dpending on the clear_os_buffer flags *	clear the OS log buffer also * Inputs 	:	info_type 	(SAL_INFO_TYPE_{MCA,INIT,CMC}) *			sub_info_type	(SAL_SUB_INFO_TYPE_{PROCESSOR,PLATFORM}) *			clear_os_buffer  *			prfunc		(print function) * Outputs	: 	None * */voidia64_log_clear(int sal_info_type, int sal_sub_info_type, int clear_os_buffer, prfunc_t prfunc){	if (ia64_sal_clear_state_info(sal_info_type, sal_sub_info_type))		prfunc("ia64_mca_log_get : Clearing processor log failed\n");	if (clear_os_buffer) {		sal_log_header_t	*log_buffer;		int			s;		IA64_LOG_LOCK(sal_info_type, sal_sub_info_type);		/* Get the process state information */		log_buffer = IA64_LOG_CURR_BUFFER(sal_info_type, sal_sub_info_type);		memset(log_buffer, 0, sizeof(ia64_psilog_t));		IA64_LOG_INDEX_DEC(sal_info_type, sal_sub_info_type);			IA64_LOG_UNLOCK(sal_info_type, sal_sub_info_type);	}}/* * ia64_log_processor_regs_print *	Print the contents of the saved processor register(s) in the format *		<reg_prefix>[<index>] <value> *		 * Inputs	:	regs 		(Register save buffer) *			reg_num 	(# of registers) *			reg_class	(application/banked/control/bank1_general) *			reg_prefix	(ar/br/cr/b1_gr) * Outputs	: 	None * */voidia64_log_processor_regs_print(u64 	*regs, 			      int 	reg_num,			      char 	*reg_class,			      char 	*reg_prefix,			      prfunc_t	prfunc){	int i;	prfunc("+%s Registers\n", reg_class);	for (i = 0; i < reg_num; i++)		prfunc("+ %s[%d] 0x%lx\n", reg_prefix, i, regs[i]);}static char *pal_mesi_state[] = {	"Invalid",	"Shared",	"Exclusive",	"Modified",	"Reserved1",	"Reserved2",	"Reserved3",	"Reserved4"};static char *pal_cache_op[] = {	"Unknown",	"Move in",	"Cast out",	"Coherency check",	"Internal",	"Instruction fetch",	"Implicit Writeback",	"Reserved"};/* * ia64_log_cache_check_info_print *	Display the machine check information related to cache error(s). * Inputs	:	i		(Multiple errors are logged, i - index of logged error) *			info		(Machine check info logged by the PAL and later  *					 captured by the SAL) *			target_addr	(Address which caused the cache error) * Outputs	: 	None */void ia64_log_cache_check_info_print(int 			i, 				pal_cache_check_info_t 	info,				u64			target_addr,				prfunc_t		prfunc){	prfunc("+ Cache check info[%d]\n+", i);	prfunc("  Level: L%d",info.level);	if (info.mv)		prfunc(" ,Mesi: %s",pal_mesi_state[info.mesi]);	prfunc(" ,Index: %d,", info.index);	if (info.ic)		prfunc(" ,Cache: Instruction");	if (info.dc)		prfunc(" ,Cache: Data");	if (info.tl)		prfunc(" ,Line: Tag");	if (info.dl)		prfunc(" ,Line: Data");	prfunc(" ,Operation: %s,", pal_cache_op[info.op]);	if (info.wv)		prfunc(" ,Way: %d,", info.way);	if (info.tv)		prfunc(" ,Target Addr: 0x%lx", target_addr);	if (info.mc)		prfunc(" ,MC: Corrected");	prfunc("\n");}/* * ia64_log_tlb_check_info_print *	Display the machine check information related to tlb error(s). * Inputs	:	i		(Multiple errors are logged, i - index of logged error) *			info		(Machine check info logged by the PAL and later  *					 captured by the SAL) * Outputs	: 	None */voidia64_log_tlb_check_info_print(int 			i,			      pal_tlb_check_info_t	info,			      prfunc_t			prfunc){	prfunc("+ TLB Check Info [%d]\n+", i);	if (info.itc)		prfunc("  Failure: Instruction Translation Cache");	if (info.dtc)		prfunc("  Failure: Data Translation Cache");	if (info.itr) {		prfunc("  Failure: Instruction Translation Register");		prfunc(" ,Slot: %d", info.tr_slot);	}	if (info.dtr) {		prfunc("  Failure: Data Translation Register");		prfunc(" ,Slot: %d", info.tr_slot);	}	if (info.mc)		prfunc(" ,MC: Corrected");	prfunc("\n");}/* * ia64_log_bus_check_info_print *	Display the machine check information related to bus error(s). * Inputs	:	i		(Multiple errors are logged, i - index of logged error) *			info		(Machine check info logged by the PAL and later  *					 captured by the SAL) *			req_addr	(Address of the requestor of the transaction) *			resp_addr	(Address of the responder of the transaction) *			target_addr	(Address where the data was to be delivered to  or *					 obtained from) * Outputs	: 	None */voidia64_log_bus_check_info_print(int 			i,			      pal_bus_check_info_t	info,			      u64			req_addr,			      u64			resp_addr,			      u64			targ_addr,			      prfunc_t			prfunc){	prfunc("+ BUS Check Info [%d]\n+", i);	prfunc(" Status Info: %d", info.bsi);	prfunc(" ,Severity: %d", info.sev);	prfunc(" ,Transaction Type: %d", info.type);	prfunc(" ,Transaction Size: %d", info.size);	if (info.cc)		prfunc(" ,Cache-cache-transfer");	if (info.ib)		prfunc(" ,Error: Internal");	if (info.eb)		prfunc(" ,Error: External");	if (info.mc)		prfunc(" ,MC: Corrected");	if (info.tv)		prfunc(" ,Target Address: 0x%lx", targ_addr);	if (info.rq)		prfunc(" ,Requestor Address: 0x%lx", req_addr);	if (info.tv)		prfunc(" ,Responder Address: 0x%lx", resp_addr);	prfunc("\n");}/* * ia64_log_processor_info_print *	Display the processor-specific information logged by PAL as a part *	of MCA or INIT or CMC. * Inputs 	:	lh	(Pointer of the sal log header which specifies the format *				 of SAL state info as specified by the SAL spec). * Outputs	: 	None */voidia64_log_processor_info_print(sal_log_header_t *lh, prfunc_t prfunc){	sal_log_processor_info_t	*slpi;	int				i;	if (!lh)		return;	if (lh->slh_log_type != SAL_SUB_INFO_TYPE_PROCESSOR)		return;	slpi = (sal_log_processor_info_t *)((char *)lh+sizeof(sal_log_header_t));  /* point to proc info */	if (!slpi) {		prfunc("No Processor Error Log found\n");		return;	}	/* Print branch register contents if valid */	if (slpi->slpi_valid.slpi_br) 		ia64_log_processor_regs_print(slpi->slpi_br, 8, "Branch", "br", prfunc);	/* Print control register contents if valid */	if (slpi->slpi_valid.slpi_cr) 		ia64_log_processor_regs_print(slpi->slpi_cr, 128, "Control", "cr", prfunc);	/* Print application register contents if valid */	if (slpi->slpi_valid.slpi_ar) 		ia64_log_processor_regs_print(slpi->slpi_br, 128, "Application", "ar", prfunc);	/* Print region register contents if valid */	if (slpi->slpi_valid.slpi_rr) 		ia64_log_processor_regs_print(slpi->slpi_rr, 8, "Region", "rr", prfunc);	/* Print floating-point register contents if valid */	if (slpi->slpi_valid.slpi_fr) 		ia64_log_processor_regs_print(slpi->slpi_fr, 128, "Floating-point", "fr", 					      prfunc);	/* Print the cache check information if any*/	for (i = 0 ; i < MAX_CACHE_ERRORS; i++)		ia64_log_cache_check_info_print(i, 					slpi->slpi_cache_check_info[i].slpi_cache_check,					slpi->slpi_cache_check_info[i].slpi_target_address,						prfunc);	/* Print the tlb check information if any*/	for (i = 0 ; i < MAX_TLB_ERRORS; i++)		ia64_log_tlb_check_info_print(i,slpi->slpi_tlb_check_info[i], prfunc);	/* Print the bus check information if any*/	for (i = 0 ; i < MAX_BUS_ERRORS; i++)		ia64_log_bus_check_info_print(i, 					slpi->slpi_bus_check_info[i].slpi_bus_check,					slpi->slpi_bus_check_info[i].slpi_requestor_addr,					slpi->slpi_bus_check_info[i].slpi_responder_addr,					slpi->slpi_bus_check_info[i].slpi_target_addr,					      prfunc);}/* * ia64_log_print * 	Display the contents of the OS error log information * Inputs 	:	info_type 	(SAL_INFO_TYPE_{MCA,INIT,CMC}) *			sub_info_type	(SAL_SUB_INFO_TYPE_{PROCESSOR,PLATFORM}) * Outputs	: 	None */voidia64_log_print(int sal_info_type, int sal_sub_info_type, prfunc_t prfunc){	char 	*info_type, *sub_info_type;	switch(sal_info_type) {	case SAL_INFO_TYPE_MCA:		info_type = "MCA";		break;	case SAL_INFO_TYPE_INIT:		info_type = "INIT";		break;	case SAL_INFO_TYPE_CMC:		info_type = "CMC";		break;	default:		info_type = "UNKNOWN";		break;	}	switch(sal_sub_info_type) {	case SAL_SUB_INFO_TYPE_PROCESSOR:		sub_info_type = "PROCESSOR";		break;	case SAL_SUB_INFO_TYPE_PLATFORM:		sub_info_type = "PLATFORM";		break;	default:		sub_info_type = "UNKNOWN";		break;	}	prfunc("+BEGIN HARDWARE ERROR STATE [%s %s]\n", info_type, sub_info_type);	if (sal_sub_info_type == SAL_SUB_INFO_TYPE_PROCESSOR)		ia64_log_processor_info_print(				      IA64_LOG_CURR_BUFFER(sal_info_type, sal_sub_info_type),				      prfunc);	else		log_print_platform(IA64_LOG_CURR_BUFFER(sal_info_type, sal_sub_info_type),prfunc);	prfunc("+END HARDWARE ERROR STATE [%s %s]\n", info_type, sub_info_type);}

⌨️ 快捷键说明

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