X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=IntelFrameworkModulePkg%2FUniversal%2FStatusCode%2FDxe%2FDataHubStatusCodeWorker.c;h=3cf5088fdfc561178f89e5a28f83dac885ece699;hb=2d78cc816ec151afa2efc018dc7345b432300afd;hp=0723af5d7cabbe4d3c11771d02ee5f7ab135f692;hpb=ad1a179818e9eba78cbdce2694ff87e9228c48fd;p=mirror_edk2.git diff --git a/IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c b/IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c index 0723af5d7c..3cf5088fdf 100644 --- a/IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c +++ b/IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c @@ -10,29 +10,20 @@ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. - Module Name: DataHubStatusCodeWorker.c - **/ -// -// Include common header file for this module. -// -#include "CommonHeader.h" #include "DxeStatusCode.h" // // Initialize FIFO to cache records. // -STATIC LIST_ENTRY mRecordsFifo = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsFifo); -STATIC LIST_ENTRY mRecordsBuffer = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsBuffer); -STATIC +UINT32 mLogDataHubStatus = 0; EFI_EVENT mLogDataHubEvent; // // Cache data hub protocol. // -STATIC EFI_DATA_HUB_PROTOCOL *mDataHubProtocol; @@ -45,8 +36,7 @@ EFI_DATA_HUB_PROTOCOL *mDataHubProtocol; @retval !NULL Point to buffer of record. **/ -STATIC -DATAHUB_STATUSCODE_RECORD * +DATA_HUB_STATUS_CODE_DATA_RECORD * AcquireRecordBuffer ( VOID ) @@ -62,9 +52,12 @@ AcquireRecordBuffer ( Node = GetFirstNode (&mRecordsBuffer); RemoveEntryList (Node); - Record = _CR (Node, DATAHUB_STATUSCODE_RECORD, Node); + Record = BASE_CR (Node, DATAHUB_STATUSCODE_RECORD, Node); } else { if (CurrentTpl > TPL_NOTIFY) { + // + // Memory management should work at <=TPL_NOTIFY + // gBS->RestoreTPL (CurrentTpl); return NULL; } @@ -86,7 +79,7 @@ AcquireRecordBuffer ( gBS->RestoreTPL (CurrentTpl); - return Record; + return (DATA_HUB_STATUS_CODE_DATA_RECORD *) (Record->Data); } @@ -98,33 +91,60 @@ AcquireRecordBuffer ( @return NULL the FIFO of record is empty. **/ -STATIC -DATAHUB_STATUSCODE_RECORD * +DATA_HUB_STATUS_CODE_DATA_RECORD * RetrieveRecord ( VOID ) { - DATAHUB_STATUSCODE_RECORD *Record = NULL; - LIST_ENTRY *Node; - EFI_TPL CurrentTpl; + DATA_HUB_STATUS_CODE_DATA_RECORD *RecordData = NULL; + DATAHUB_STATUSCODE_RECORD *Record; + LIST_ENTRY *Node; + EFI_TPL CurrentTpl; CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); if (!IsListEmpty (&mRecordsFifo)) { Node = GetFirstNode (&mRecordsFifo); Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, DATAHUB_STATUS_CODE_SIGNATURE); + ASSERT (NULL != Record); RemoveEntryList (&Record->Node); - InsertTailList (&mRecordsBuffer, &Record->Node); - Record->Signature = 0; + RecordData = (DATA_HUB_STATUS_CODE_DATA_RECORD *) Record->Data; } gBS->RestoreTPL (CurrentTpl); - return Record; + return RecordData; +} + +/** + Release Records to FIFO. + + @param RecordData Point to the record buffer allocated + from AcquireRecordBuffer. + +**/ +VOID +ReleaseRecord ( + DATA_HUB_STATUS_CODE_DATA_RECORD *RecordData + ) +{ + DATAHUB_STATUSCODE_RECORD *Record; + EFI_TPL CurrentTpl; + + Record = CR (RecordData, DATAHUB_STATUSCODE_RECORD, Data[0], DATAHUB_STATUS_CODE_SIGNATURE); + ASSERT (NULL != Record); + + CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL); + + InsertTailList (&mRecordsBuffer, &Record->Node); + Record->Signature = 0; + + gBS->RestoreTPL (CurrentTpl); } + /** Report status code into DataHub. @@ -145,7 +165,7 @@ RetrieveRecord ( @param CallerId This optional parameter may be used to identify the caller. This parameter allows the status code driver to apply different rules to different callers. - Type EFI_GUID is defined in InstallProtocolInterface() in the EFI 1.10 Specification. + Type EFI_GUID is defined in InstallProtocolInterface() in the UEFI 2.0 Specification. @param Data This optional parameter may be used to pass additional data @@ -164,11 +184,20 @@ DataHubStatusCodeReportWorker ( IN EFI_STATUS_CODE_DATA *Data OPTIONAL ) { - DATAHUB_STATUSCODE_RECORD *Record; - UINT32 ErrorLevel; - VA_LIST Marker; - CHAR8 *Format; - UINTN CharCount; + DATA_HUB_STATUS_CODE_DATA_RECORD *Record; + UINT32 ErrorLevel; + VA_LIST Marker; + CHAR8 *Format; + UINTN CharCount; + + + // + // Use atom operation to avoid the reentant of report. + // If current status is not zero, then the function is reentrancy. + // + if (1 == InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 0)) { + return EFI_DEVICE_ERROR; + } // // See whether in runtime phase or not. @@ -184,6 +213,7 @@ DataHubStatusCodeReportWorker ( // return EFI_OUT_OF_RESOURCES; } + // // Construct Data Hub Extended Data // @@ -198,7 +228,7 @@ DataHubStatusCodeReportWorker ( if (Data != NULL) { if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) { CharCount = UnicodeVSPrintAsciiFormat ( - (CHAR16 *) Record->ExtendData, + (CHAR16 *) (Record + 1), EFI_STATUS_CODE_DATA_MAX_SIZE, Format, Marker @@ -206,7 +236,7 @@ DataHubStatusCodeReportWorker ( // // Change record data type from DebugType to String Type. // - CopyGuid (&Record->Data.Type, &gEfiStatusCodeDataTypeStringGuid); + CopyGuid (&Record->Data.Type, &gEfiStatusCodeDataTypeDebugGuid); Record->Data.HeaderSize = Data->HeaderSize; Record->Data.Size = (UINT16) ((CharCount + 1) * sizeof (CHAR16)); } else { @@ -218,7 +248,7 @@ DataHubStatusCodeReportWorker ( if (Data->Size > EFI_STATUS_CODE_DATA_MAX_SIZE) { Record->Data.Size = EFI_STATUS_CODE_DATA_MAX_SIZE; } - CopyMem (Record->ExtendData, Data + 1, Record->Data.Size); + CopyMem ((VOID *) (Record + 1), Data + 1, Record->Data.Size); } } @@ -236,7 +266,6 @@ DataHubStatusCodeReportWorker ( @param Context Context of the event. **/ -STATIC VOID EFIAPI LogDataHubEventCallBack ( @@ -244,10 +273,18 @@ LogDataHubEventCallBack ( IN VOID *Context ) { - DATAHUB_STATUSCODE_RECORD *Record; + DATA_HUB_STATUS_CODE_DATA_RECORD *Record; UINT32 Size; UINT64 DataRecordClass; + // + // Use atom operation to avoid the reentant of report. + // If current status is not zero, then the function is reentrancy. + // + if (1 == InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 1)) { + return; + } + // // Log DataRecord in Data Hub. // Journal records fifo to find all record entry. @@ -260,7 +297,7 @@ LogDataHubEventCallBack ( // // Add in the size of the header we added. // - Size = sizeof (DATAHUB_STATUSCODE_RECORD) + (UINT32) Record->Data.Size; + Size = sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD) + (UINT32) Record->Data.Size; if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) { DataRecordClass = EFI_DATA_RECORD_CLASS_PROGRESS_CODE; @@ -284,14 +321,20 @@ LogDataHubEventCallBack ( mDataHubProtocol->LogData ( mDataHubProtocol, - &gEfiStatusCodeGuid, + &gEfiDataHubStatusCodeRecordGuid, &gEfiStatusCodeRuntimeProtocolGuid, DataRecordClass, Record, Size ); + ReleaseRecord (Record); } + + // + // Restore the nest status of report + // + InterlockedCompareExchange32 (&mLogDataHubStatus, 1, 0); }