天天看點

記憶體檢測失敗,蜂鳴器報警

問題描述:記憶體檢測失敗,蜂鳴器報警

基本思路

記憶體檢測失敗,蜂鳴器報警

記憶體檢測

記憶體檢測在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階段處理。

繼續閱讀