THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
- Module Name: DataHubStatusCodeWorker.c\r
-\r
**/\r
-//\r
-// Include common header file for this module.\r
-//\r
-#include "CommonHeader.h"\r
\r
#include "DxeStatusCode.h"\r
\r
STATIC\r
LIST_ENTRY mRecordsBuffer = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsBuffer);\r
STATIC\r
+UINT32 mLogDataHubStatus = 0;\r
+STATIC\r
EFI_EVENT mLogDataHubEvent;\r
//\r
// Cache data hub protocol.\r
\r
**/\r
STATIC\r
-DATAHUB_STATUSCODE_RECORD *\r
+DATA_HUB_STATUS_CODE_DATA_RECORD *\r
AcquireRecordBuffer (\r
VOID\r
)\r
Record = _CR (Node, DATAHUB_STATUSCODE_RECORD, Node);\r
} else {\r
if (CurrentTpl > TPL_NOTIFY) {\r
+ //\r
+ // Memory management should work at <=TPL_NOTIFY\r
+ // \r
gBS->RestoreTPL (CurrentTpl);\r
return NULL;\r
}\r
\r
gBS->RestoreTPL (CurrentTpl);\r
\r
- return Record;\r
+ return (DATA_HUB_STATUS_CODE_DATA_RECORD *) (Record->Data);\r
}\r
\r
\r
\r
**/\r
STATIC\r
-DATAHUB_STATUSCODE_RECORD *\r
+DATA_HUB_STATUS_CODE_DATA_RECORD *\r
RetrieveRecord (\r
VOID\r
)\r
{\r
- DATAHUB_STATUSCODE_RECORD *Record = NULL;\r
- LIST_ENTRY *Node;\r
- EFI_TPL CurrentTpl;\r
+ DATA_HUB_STATUS_CODE_DATA_RECORD *RecordData = NULL;\r
+ DATAHUB_STATUSCODE_RECORD *Record;\r
+ LIST_ENTRY *Node;\r
+ EFI_TPL CurrentTpl;\r
\r
CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
\r
if (!IsListEmpty (&mRecordsFifo)) {\r
Node = GetFirstNode (&mRecordsFifo);\r
Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, DATAHUB_STATUS_CODE_SIGNATURE);\r
+ ASSERT (NULL != Record);\r
\r
RemoveEntryList (&Record->Node);\r
- InsertTailList (&mRecordsBuffer, &Record->Node);\r
- Record->Signature = 0;\r
+ RecordData = (DATA_HUB_STATUS_CODE_DATA_RECORD *) Record->Data;\r
}\r
\r
gBS->RestoreTPL (CurrentTpl);\r
\r
- return Record;\r
+ return RecordData;\r
+}\r
+\r
+/**\r
+ Release Records to FIFO.\r
+ \r
+ @param RecordData Point to the record buffer allocated\r
+ from AcquireRecordBuffer.\r
+\r
+**/\r
+STATIC\r
+VOID\r
+ReleaseRecord (\r
+ DATA_HUB_STATUS_CODE_DATA_RECORD *RecordData\r
+ )\r
+{\r
+ DATAHUB_STATUSCODE_RECORD *Record;\r
+ EFI_TPL CurrentTpl;\r
+\r
+ Record = CR (RecordData, DATAHUB_STATUSCODE_RECORD, Data[0], DATAHUB_STATUS_CODE_SIGNATURE);\r
+ ASSERT (NULL != Record);\r
+\r
+ CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);\r
+\r
+ InsertTailList (&mRecordsBuffer, &Record->Node);\r
+ Record->Signature = 0;\r
+\r
+ gBS->RestoreTPL (CurrentTpl);\r
}\r
\r
\r
+\r
/**\r
Report status code into DataHub.\r
\r
IN EFI_STATUS_CODE_DATA *Data OPTIONAL\r
)\r
{\r
- DATAHUB_STATUSCODE_RECORD *Record;\r
- UINT32 ErrorLevel;\r
- VA_LIST Marker;\r
- CHAR8 *Format;\r
- UINTN CharCount;\r
+ DATA_HUB_STATUS_CODE_DATA_RECORD *Record;\r
+ UINT32 ErrorLevel;\r
+ VA_LIST Marker;\r
+ CHAR8 *Format;\r
+ UINTN CharCount;\r
+\r
+\r
+ //\r
+ // Use atom operation to avoid the reentant of report.\r
+ // If current status is not zero, then the function is reentrancy.\r
+ //\r
+ if (1 == InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 0)) {\r
+ return EFI_DEVICE_ERROR;\r
+ }\r
\r
//\r
// See whether in runtime phase or not.\r
//\r
return EFI_OUT_OF_RESOURCES;\r
}\r
+\r
//\r
// Construct Data Hub Extended Data\r
//\r
if (Data != NULL) {\r
if (ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel, &Marker, &Format)) {\r
CharCount = UnicodeVSPrintAsciiFormat (\r
- (CHAR16 *) Record->ExtendData,\r
+ (CHAR16 *) (Record + 1),\r
EFI_STATUS_CODE_DATA_MAX_SIZE,\r
Format,\r
Marker\r
//\r
// Change record data type from DebugType to String Type.\r
//\r
- CopyGuid (&Record->Data.Type, &gEfiStatusCodeDataTypeStringGuid);\r
+ CopyGuid (&Record->Data.Type, &gEfiStatusCodeDataTypeDebugGuid);\r
Record->Data.HeaderSize = Data->HeaderSize;\r
Record->Data.Size = (UINT16) ((CharCount + 1) * sizeof (CHAR16));\r
} else {\r
if (Data->Size > EFI_STATUS_CODE_DATA_MAX_SIZE) {\r
Record->Data.Size = EFI_STATUS_CODE_DATA_MAX_SIZE;\r
}\r
- CopyMem (Record->ExtendData, Data + 1, Record->Data.Size);\r
+ CopyMem ((VOID *) (Record + 1), Data + 1, Record->Data.Size);\r
}\r
}\r
\r
IN VOID *Context\r
)\r
{\r
- DATAHUB_STATUSCODE_RECORD *Record;\r
+ DATA_HUB_STATUS_CODE_DATA_RECORD *Record;\r
UINT32 Size;\r
UINT64 DataRecordClass;\r
\r
+ //\r
+ // Use atom operation to avoid the reentant of report.\r
+ // If current status is not zero, then the function is reentrancy.\r
+ //\r
+ if (1 == InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 1)) {\r
+ return;\r
+ }\r
+\r
//\r
// Log DataRecord in Data Hub.\r
// Journal records fifo to find all record entry.\r
//\r
// Add in the size of the header we added.\r
//\r
- Size = sizeof (DATAHUB_STATUSCODE_RECORD) + (UINT32) Record->Data.Size;\r
+ Size = sizeof (DATA_HUB_STATUS_CODE_DATA_RECORD) + (UINT32) Record->Data.Size;\r
\r
if ((Record->CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_PROGRESS_CODE) {\r
DataRecordClass = EFI_DATA_RECORD_CLASS_PROGRESS_CODE;\r
\r
mDataHubProtocol->LogData (\r
mDataHubProtocol,\r
- &gEfiStatusCodeGuid,\r
+ &gEfiDataHubStatusCodeRecordGuid,\r
&gEfiStatusCodeRuntimeProtocolGuid,\r
DataRecordClass,\r
Record,\r
Size\r
);\r
\r
+ ReleaseRecord (Record);\r
}\r
+\r
+ //\r
+ // Restore the nest status of report\r
+ //\r
+ InterlockedCompareExchange32 (&mLogDataHubStatus, 1, 0);\r
}\r
\r
\r