如果要使用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的錯誤分類