#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);
在最终用串口去写