問題描述:記憶體檢測失敗,蜂鳴器報警
基本思路
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicWZwpmLwIWZ2YDMlVjZ5UTN0YmMhJ2YhRDMzMjNmljMyEmNidzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpeg)
記憶體檢測
記憶體檢測在PEI階段,
EFI_STATUS
DramInitWrapper (
IN CONST EFI_PEI_SERVICES **PeiServices,
IN WRAPPER_PARAM *WapperParam
)
{
EFI_STATUS Status;
Status = EFI_SUCCESS;
DEBUG((EFI_D_ERROR, "miabeep %a,Line:%d,BootMode:%d\n",__FUNCTION__,__LINE__,WapperParam->BootMode));
if (WapperParam->BootMode == BOOT_ON_S3_RESUME) {
Status = (WapperParam->EfiAisaDram)->DramS3Init((EFI_PEI_SERVICES **)PeiServices, (WapperParam->EfiAisaDram));
} else {
Status = (WapperParam->EfiAisaDram)->DramNormalInit((EFI_PEI_SERVICES **)PeiServices, (WapperParam->EfiAisaDram));
if (EFI_ERROR( Status)) {
//ERROR_CODE(PEI_MEMORY_NOT_DETECTED, EFI_ERROR_MAJOR);
DEBUG((EFI_D_ERROR, "miabeep %a,Line:%d\n",__FUNCTION__,__LINE__));
REPORT_STATUS_CODE(EFI_ERROR_CODE, 0x10); //記憶體檢測失敗,送出狀态碼
CpuDeadLoop ();
}
}
return Status;
}
register status code 原理
隻有當Report Status Code 協定被安裝時,Register Status Code 回調方法。
Status = gBS->LocateProtocol (
&gEfiRscHandlerProtocolGuid,
NULL,
(VOID **) &mBeepRscHandlerProtocol
);
ASSERT_EFI_ERROR (Status);
mBeepRscHandlerProtocol->Register (BeepStatusCodeReportWorker, TPL_HIGH_LEVEL);
Status = gBS->CreateEventEx (
EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
UnregisterBeepBootTimeHandlers,
NULL,
&gEfiEventExitBootServicesGuid,
&mBeepExitBootServicesEvent
);
先注冊BeepStatusCodeReportWorker 回調函數,當記憶體檢測失敗,送出錯誤狀态碼,BeepStatusCodeReportWorker 回調函數對獲得的狀态類型及狀态碼進行處理,比對Map Table裡的記憶體錯誤類型,比對成功觸發蜂鳴器報警功能。
蜂鳴器報警
EFI_STATUS
TurnOnSpeaker (
VOID
)
{
DEBUG((EFI_D_ERROR, "miabeep %a,Line:%d\n",__FUNCTION__,__LINE__));
UINT8 Data;
//
//Write control port
//
Data = IoRead8 (0x61);
Data |= 0x03;
IoWrite8(0x61,Data);
return EFI_SUCCESS;
}
EFI_STATUS
TurnOffSpeaker (
VOID
)
{
DEBUG((EFI_D_ERROR, "miabeep %a,Line:%d\n",__FUNCTION__,__LINE__));
UINT8 Data;
//
//Write control port
//
Data = IoRead8 (0x61);
Data &= 0xFC;
IoWrite8(0x61,Data);
return EFI_SUCCESS;
}
EFI_STATUS
OutputBeep (
IN UINTN NumberOfBeep,
IN UINTN BeepDuration,
IN UINTN TimeInterval
)
{
DEBUG((EFI_D_ERROR, "miabeep %a,Line:%d\n",__FUNCTION__,__LINE__));
UINTN Num;
for (Num = 0; Num < NumberOfBeep; Num++) {
TurnOnSpeaker ();
MicroSecondDelay(BeepDuration);
TurnOffSpeaker ();
MicroSecondDelay(TimeInterval);
}
return EFI_SUCCESS;
}
蜂鳴器的條件是, 0x61寄存器中倒數第二位置1
蜂鳴器不響原因
1.當記憶體失敗的時候REPORT_STATUS XX—這個確定代碼有跑到
2. 當REPORT_STATUS XX的時候確定BeepStatusCodeReportWorker同時進來
3. 當BeepStatusCodeReportWorker進來的時候確定map table有對應的entry
4. 測試蜂鳴器功能可用
思考
CRS 注冊,送出,接收功能可以處理多種報警事件,如
STATUS_CODE_TO_DATA_MAP mBeepErrorMap[] = {
//
// PEI
//
// Regular boot
{ PEI_MEMORY_NOT_DETECTED, 1 },
{ PEI_MEMORY_INSTALLED_TWICE, 1 },
{ PEI_DXEIPL_NOT_FOUND, 3 },
{ PEI_DXE_CORE_NOT_FOUND, 3 },
{ PEI_RESET_NOT_AVAILABLE, 7 },
// Recovery
{ PEI_RECOVERY_FAILED, 4 },
// S3 Resume
{ PEI_S3_RESUME_FAILED, 4 },
//
// DXE
//
{ DXE_ARCH_PROTOCOL_NOT_AVAILABLE, 4 },
{ DXE_NO_CON_OUT, 5 },
{ DXE_NO_CON_IN, 5 },
{ DXE_INVALID_PASSWORD, 1 },
{ DXE_FLASH_UPDATE_FAILED, 6 },
{ DXE_RESET_NOT_AVAILABLE, 7 },
{0,0}
};
報警功能也可以為setup界面顯示,post界面提示,或其它操作。不僅限于PEI階段的值交給runtime階段處理。