天天看點

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的錯誤分類