天天看点

Intel MACHINE-CHECK 特性的初始化伪代码实现

如果要使用MCA,首先要初始化芯片来激活 machine-check exception和 error-reporting机制

下面给出的伪代码中展示了如何完成MCA的初始化动作。本代码首先检测MCA和exception是否被芯片支持;然后使能 machine-check exception和 error-reporting的bank寄存器。

在主板上电以后, IA32_MCi_STATUS寄存器中的数据并不保证是正确的直到软件将它初始化为全0

伪代码如下:

/*获得CPUID, 并检查芯片是否支持MCA和MCE*/
if(CPUID[14]){
	支持MCA;
} 

if(CPUID[7]){
	支持MCE;
}


if(CPU支持MCE){
	if(CPU支持MCA){
		if(1 == IA32_MCG_CAP.MCG_CTL_P) /*芯片上有IA32_MCG_CTL寄存器*/{
			IA32_MCG_CTL = FFFFFFFFFFFFFFFFH; /*使能所有的MCA特性*/
		}
		
		if(1 == IA32_MCG_CAP.MCG_LMCE_P 
		&& 1 == IA32_FEATURE_CONTROL.LOCK 
		&& 1 == IA32_FEATURE_CONTROL.LMCE_ON){ /*芯片中有IA32_MCG_EXT_CTL寄存器,且平台支持LMCE特性*/
			IA32_MCG_EXT_CTL = IA32_MCG_EXT_CTL | 01H; /*使能LMCE特性,以便精准单播MCE到被影响的CPU*/
		}
		
		/*确定支持的error-reporting banks数量*/
		COUNT = IA32_MCG_CAP.Count;
		MAX_BANK_NUMBER = COUNT - 1;
		
		if(P6处理器家族, 且 EXTMODEL:MODEL <= 1AH){
			/*除了第0个bank,使能所有的bank来记录错误*/
			for(i=1; i <= MAX_BANK_NUMBER; i++){ /*从1到MAX_BANK_NUMBER*/
				IA32_MCi_CTL = 0FFFFFFFFFFFFFFFFH;
			}
		}else {
			/*使能所有的bank来记录错误*/
			for(i=0; i <= MAX_BANK_NUMBER; i++){ /*从0到MAX_BANK_NUMBER*/
				IA32_MCi_CTL = 0FFFFFFFFFFFFFFFFH;
			}
		}
		
		/*在power reset的时候,BIOS清除所有的错误状态记录*/
		if(BIOS发现在power reset){
			for(i=0; i <= MAX_BANK_NUMBER; i++){ /*从0到MAX_BANK_NUMBER*/
				IA32_MCi_STATUS = 0x0;
			}			
		}else{			
			for(i=0; i <= MAX_BANK_NUMBER; i++){ /*从0到MAX_BANK_NUMBER*/
				记录STATUS中已有的错误; /*既可BIOS做,也可以由OS做*/
				IA32_MCi_STATUS = 0x0; /*只能OS做*/
			}				
		}
	}
	
	在IDT的18号向量中,设定 Machine Check Exception (#MC) 的处理函数
	CR4.MCE = 1; /*设定CR4的16bit, 使能Machine-Check Exceptions*/
}
           

相关文章 Intel MCE UCR ERRORS(三) UCR的错误分类