+ //\r
+ // 4. Fill in the FPDT record according to different Performance Identifier.\r
+ //\r
+ switch (PerfId) {\r
+ case MODULE_START_ID:\r
+ case MODULE_END_ID:\r
+ GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);\r
+ StringPtr = ModuleName;\r
+ //\r
+ // Cache the offset of start image start record and use to update the start image end record if needed.\r
+ //\r
+ if (PerfId == MODULE_START_ID && Attribute == PerfEntry) {\r
+ mCachedLength = mSmmBootPerformanceTable->Header.Length;\r
+ }\r
+ if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {\r
+ FpdtRecordPtr.GuidEvent->Header.Type = FPDT_GUID_EVENT_TYPE;\r
+ FpdtRecordPtr.GuidEvent->Header.Length = sizeof (FPDT_GUID_EVENT_RECORD);\r
+ FpdtRecordPtr.GuidEvent->Header.Revision = FPDT_RECORD_REVISION_1;\r
+ FpdtRecordPtr.GuidEvent->ProgressID = PerfId;\r
+ FpdtRecordPtr.GuidEvent->Timestamp = TimeStamp;\r
+ CopyMem (&FpdtRecordPtr.GuidEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidEvent->Guid));\r
+ if (CallerIdentifier == NULL && PerfId == MODULE_END_ID && mCachedLength != 0) {\r
+ CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8*)mSmmBootPerformanceTable + mCachedLength);\r
+ CopyMem (&FpdtRecordPtr.GuidEvent->Guid, &CachedFpdtRecordPtr.GuidEvent->Guid, sizeof (FpdtRecordPtr.GuidEvent->Guid));\r
+ mCachedLength = 0;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case MODULE_LOADIMAGE_START_ID:\r
+ case MODULE_LOADIMAGE_END_ID:\r
+ GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);\r
+ StringPtr = ModuleName;\r
+ if (PerfId == MODULE_LOADIMAGE_START_ID) {\r
+ mLoadImageCount++;\r
+ //\r
+ // Cache the offset of load image start record and use to be updated by the load image end record if needed.\r
+ //\r
+ if (CallerIdentifier == NULL && Attribute == PerfEntry) {\r
+ mCachedLength = mSmmBootPerformanceTable->Header.Length;\r
+ }\r
+ }\r
+ if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {\r
+ FpdtRecordPtr.GuidQwordEvent->Header.Type = FPDT_GUID_QWORD_EVENT_TYPE;\r
+ FpdtRecordPtr.GuidQwordEvent->Header.Length = sizeof (FPDT_GUID_QWORD_EVENT_RECORD);\r
+ FpdtRecordPtr.GuidQwordEvent->Header.Revision = FPDT_RECORD_REVISION_1;\r
+ FpdtRecordPtr.GuidQwordEvent->ProgressID = PerfId;\r
+ FpdtRecordPtr.GuidQwordEvent->Timestamp = TimeStamp;\r
+ FpdtRecordPtr.GuidQwordEvent->Qword = mLoadImageCount;\r
+ CopyMem (&FpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.GuidQwordEvent->Guid));\r
+ if (PerfId == MODULE_LOADIMAGE_END_ID && mCachedLength != 0) {\r
+ CachedFpdtRecordPtr.RecordHeader = (EFI_ACPI_5_0_FPDT_PERFORMANCE_RECORD_HEADER *)((UINT8*)mSmmBootPerformanceTable + mCachedLength);\r
+ CopyMem (&CachedFpdtRecordPtr.GuidQwordEvent->Guid, &ModuleGuid, sizeof (CachedFpdtRecordPtr.GuidQwordEvent->Guid));\r
+ mCachedLength = 0;\r
+ }\r
+ }\r
+ break;\r
+\r
+ case PERF_EVENTSIGNAL_START_ID:\r
+ case PERF_EVENTSIGNAL_END_ID:\r
+ case PERF_CALLBACK_START_ID:\r
+ case PERF_CALLBACK_END_ID:\r
+ if (String == NULL || Guid == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ StringPtr = String;\r
+ if (AsciiStrLen (String) == 0) {\r
+ StringPtr = "unknown name";\r
+ }\r
+ if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {\r
+ FpdtRecordPtr.DualGuidStringEvent->Header.Type = FPDT_DUAL_GUID_STRING_EVENT_TYPE;\r
+ FpdtRecordPtr.DualGuidStringEvent->Header.Length = sizeof (FPDT_DUAL_GUID_STRING_EVENT_RECORD);\r
+ FpdtRecordPtr.DualGuidStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;\r
+ FpdtRecordPtr.DualGuidStringEvent->ProgressID = PerfId;\r
+ FpdtRecordPtr.DualGuidStringEvent->Timestamp = TimeStamp;\r
+ CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid1, CallerIdentifier, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid1));\r
+ CopyMem (&FpdtRecordPtr.DualGuidStringEvent->Guid2, Guid, sizeof (FpdtRecordPtr.DualGuidStringEvent->Guid2));\r
+ CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DualGuidStringEvent->String, StringPtr, &FpdtRecordPtr.DualGuidStringEvent->Header.Length);\r
+ }\r
+ break;\r
+\r
+ case PERF_EVENT_ID:\r
+ case PERF_FUNCTION_START_ID:\r
+ case PERF_FUNCTION_END_ID:\r
+ case PERF_INMODULE_START_ID:\r
+ case PERF_INMODULE_END_ID:\r
+ case PERF_CROSSMODULE_START_ID:\r
+ case PERF_CROSSMODULE_END_ID:\r
+ GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);\r
+ if (String != NULL) {\r
+ StringPtr = String;\r
+ } else {\r
+ StringPtr = ModuleName;\r
+ }\r
+ if (AsciiStrLen (StringPtr) == 0) {\r
+ StringPtr = "unknown name";\r
+ }\r
+ if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {\r
+ FpdtRecordPtr.DynamicStringEvent->Header.Type = FPDT_DYNAMIC_STRING_EVENT_TYPE;\r
+ FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);\r
+ FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;\r
+ FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId;\r
+ FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp;\r
+ CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));\r
+ CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length);\r
+ }\r
+ break;\r
+\r
+ default:\r
+ if (Attribute != PerfEntry) {\r
+ GetModuleInfoFromHandle ((EFI_HANDLE *)CallerIdentifier, ModuleName, sizeof (ModuleName), &ModuleGuid);\r
+ if (String != NULL) {\r
+ StringPtr = String;\r
+ } else {\r
+ StringPtr = ModuleName;\r
+ }\r
+ if (AsciiStrLen (StringPtr) == 0) {\r
+ StringPtr = "unknown name";\r
+ }\r
+ if (!PcdGetBool (PcdEdkiiFpdtStringRecordEnableOnly)) {\r
+ FpdtRecordPtr.DynamicStringEvent->Header.Type = FPDT_DYNAMIC_STRING_EVENT_TYPE;\r
+ FpdtRecordPtr.DynamicStringEvent->Header.Length = sizeof (FPDT_DYNAMIC_STRING_EVENT_RECORD);\r
+ FpdtRecordPtr.DynamicStringEvent->Header.Revision = FPDT_RECORD_REVISION_1;\r
+ FpdtRecordPtr.DynamicStringEvent->ProgressID = PerfId;\r
+ FpdtRecordPtr.DynamicStringEvent->Timestamp = TimeStamp;\r
+ CopyMem (&FpdtRecordPtr.DynamicStringEvent->Guid, &ModuleGuid, sizeof (FpdtRecordPtr.DynamicStringEvent->Guid));\r
+ CopyStringIntoPerfRecordAndUpdateLength (FpdtRecordPtr.DynamicStringEvent->String, StringPtr, &FpdtRecordPtr.DynamicStringEvent->Header.Length);\r
+ }\r
+ } else {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ break;\r