当前位置: 代码迷 >> 综合 >> UEFI debugprint 实现
  详细解决方案

UEFI debugprint 实现

热度:63   发布时间:2023-12-14 22:23:29.0

 

 

#define _DEBUG(Expression)   DebugPrint Expression

edk2\MdeModulePkg\Library\PeiDxeDebugLibReportStatusCode\DebugLib.c

VOID
EFIAPI
DebugPrint (IN  UINTN        ErrorLevel,IN  CONST CHAR8  *Format,...)

函数的前半部分完成对参数的解析, 即... , 我 们觉的%s%d  , 即*Format 

Format 对... 进行格式化

在函数的最后,会call 

  //
  // Send the DebugInfo record
  //
  REPORT_STATUS_CODE_EX (
    EFI_DEBUG_CODE,
    (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_DC_UNSPECIFIED),
    0,
    NULL,
    &gEfiStatusCodeDataTypeDebugGuid,
    DebugInfo,
    TotalSize
    );

 

 

它的实现为:

#define REPORT_STATUS_CODE_EX(Type,Value,Instance,CallerId,ExtendedDataGuid,ExtendedData,ExtendedDataSize)  \(ReportProgressCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE)             ?  \ReportStatusCodeEx(Type,Value,Instance,CallerId,ExtendedDataGuid,ExtendedData,ExtendedDataSize)        :  \(ReportErrorCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)                   ?  \ReportStatusCodeEx(Type,Value,Instance,CallerId,ExtendedDataGuid,ExtendedData,ExtendedDataSize)        :  \(ReportDebugCodeEnabled() && ((Type) & EFI_STATUS_CODE_TYPE_MASK) == EFI_DEBUG_CODE)                   ?  \ReportStatusCodeEx(Type,Value,Instance,CallerId,ExtendedDataGuid,ExtendedData,ExtendedDataSize)        :  \EFI_UNSUPPORTED

最终就是call ReportStatusCodeEx

ReportStatusCodeEx 在smm, dxe, pei 里面都有不同的实现

//
// Declaration of status code protocol.
//
EFI_STATUS_CODE_PROTOCOL  mEfiStatusCodeProtocol  = {ReportDispatcher
};//
// Report operation nest status.
// If it is set, then the report operation has nested.
//
UINT32  mStatusCodeNestStatus = 0;/**Entry point of DXE Status Code Driver.This function is the entry point of this DXE Status Code Driver.It installs Status Code Runtime Protocol, and registers event for EVT_SIGNAL_VIRTUAL_ADDRESS_CHANGE.@param  ImageHandle       The firmware allocated handle for the EFI image.@param  SystemTable       A pointer to the EFI System Table.@retval EFI_SUCCESS       The entry point is executed successfully.**/
EFI_STATUS
EFIAPI
StatusCodeRuntimeDxeEntry (IN EFI_HANDLE         ImageHandle,IN EFI_SYSTEM_TABLE   *SystemTable)
{EFI_STATUS  Status;//// Dispatch initialization request to supported devices//InitializationDispatcherWorker ();//// Install Status Code Runtime Protocol implementation as defined in PI Specification.//Status = gBS->InstallMultipleProtocolInterfaces (&mHandle,&gEfiStatusCodeRuntimeProtocolGuid,&mEfiStatusCodeProtocol,NULL);ASSERT_EFI_ERROR (Status);Status = gBS->CreateEventEx (EVT_NOTIFY_SIGNAL,TPL_NOTIFY,VirtualAddressChangeCallBack,NULL,&gEfiEventVirtualAddressChangeGuid,&mVirtualAddressChangeEvent);ASSERT_EFI_ERROR (Status);return EFI_SUCCESS;
}

 

EFI_STATUS
EFIAPI
ReportDispatcher (IN EFI_STATUS_CODE_TYPE     CodeType,IN EFI_STATUS_CODE_VALUE    Value,IN UINT32                   Instance,IN EFI_GUID                 *CallerId  OPTIONAL,IN EFI_STATUS_CODE_DATA     *Data      OPTIONAL)
{//// Use atom operation to avoid the reentant of report.// If current status is not zero, then the function is reentrancy.//if (InterlockedCompareExchange32 (&mStatusCodeNestStatus, 0, 1) == 1) {return EFI_DEVICE_ERROR;}if (FeaturePcdGet (PcdStatusCodeUseSerial)) {SerialStatusCodeReportWorker (CodeType,Value,Instance,CallerId,Data);}if (FeaturePcdGet (PcdStatusCodeUseMemory)) {RtMemoryStatusCodeReportWorker (CodeType,Value,Instance);}if (FeaturePcdGet (PcdStatusCodeUseDataHub)) {DataHubStatusCodeReportWorker (CodeType,Value,Instance,CallerId,Data);}if (FeaturePcdGet (PcdStatusCodeUseOEM)) {//// Call OEM hook status code library API to report status code to OEM device//OemHookStatusCodeReport (CodeType,Value,Instance,CallerId,Data);}//// Restore the nest status of report//InterlockedCompareExchange32 (&mStatusCodeNestStatus, 1, 0);return EFI_SUCCESS;
}

  }

  //
  // Call SerialPort Lib function to do print.
  //
  SerialPortWrite ((UINT8 *) Buffer, CharCount);

 

在最终用串口去写