19#include <Protocol/VariablePolicy.h>
36#include <Library/VariablePolicyHelperLib.h>
39#define SMM_BOOT_RECORD_COMM_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + sizeof(SMM_BOOT_RECORD_COMMUNICATE))
43BOOLEAN mLockBoxReady =
FALSE;
47UINTN mFirmwarePerformanceTableTemplateKey = 0;
48BOOLEAN mDxeCoreReportStatusCodeEnable =
FALSE;
86 EFI_ACPI_5_0_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER,
88 EFI_ACPI_5_0_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER
102 EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT,
104 EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT
138 EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND,
140 EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND
163 UINTN ChecksumOffset;
170 Buffer[ChecksumOffset] = 0;
198 if (mLockBoxReady && (mAcpiS3PerformanceTable !=
NULL)) {
206 if (!mLockBoxReady) {
207 Status =
gBS->LocateProtocol (&gEfiLockBoxProtocolGuid,
NULL, &Interface);
208 if (!EFI_ERROR (Status)) {
212 mLockBoxReady =
TRUE;
216 if (mAcpiS3PerformanceTable ==
NULL) {
217 Status =
gBS->LocateProtocol (&gEfiVariableArchProtocolGuid,
NULL, &Interface);
218 if (!EFI_ERROR (Status)) {
222 ZeroMem (&PerformanceVariable,
sizeof (PerformanceVariable));
223 Size =
sizeof (PerformanceVariable);
224 Status =
gRT->GetVariable (
225 EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
226 &gEfiFirmwarePerformanceGuid,
231 if (!EFI_ERROR (Status)) {
232 Status =
gBS->AllocatePages (
238 if (!EFI_ERROR (Status)) {
243 if (mAcpiS3PerformanceTable ==
NULL) {
253 DEBUG ((DEBUG_INFO,
"FPDT: ACPI S3 Performance Table address = 0x%x\n", mAcpiS3PerformanceTable));
254 if (mAcpiS3PerformanceTable !=
NULL) {
255 CopyMem (mAcpiS3PerformanceTable, &mS3PerformanceTableTemplate,
sizeof (mS3PerformanceTableTemplate));
260 if (mLockBoxReady && (mAcpiS3PerformanceTable !=
NULL)) {
267 &gFirmwarePerformanceS3PointerGuid,
268 &S3PerformanceTablePointer,
288 UINTN BootPerformanceDataSize;
296 Status =
gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid,
NULL, (VOID **)&AcpiTableProtocol);
297 if (EFI_ERROR (Status)) {
304 Status =
gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid,
NULL, (VOID **)&VariablePolicyProtocol);
305 if (EFI_ERROR (Status)) {
309 if (mReceivedAcpiBootPerformanceTable !=
NULL) {
310 mAcpiBootPerformanceTable = mReceivedAcpiBootPerformanceTable;
317 ZeroMem (&PerformanceVariable,
sizeof (PerformanceVariable));
318 Size =
sizeof (PerformanceVariable);
319 Status =
gRT->GetVariable (
320 EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
321 &gEfiFirmwarePerformanceGuid,
326 if (!EFI_ERROR (Status)) {
327 Status =
gBS->AllocatePages (
333 if (!EFI_ERROR (Status)) {
338 if (mAcpiBootPerformanceTable ==
NULL) {
348 DEBUG ((DEBUG_INFO,
"FPDT: ACPI Boot Performance Table address = 0x%x\n", mAcpiBootPerformanceTable));
349 if (mAcpiBootPerformanceTable ==
NULL) {
350 return EFI_OUT_OF_RESOURCES;
356 CopyMem (mAcpiBootPerformanceTable, &mBootPerformanceTableTemplate,
sizeof (mBootPerformanceTableTemplate));
359 BootPerformanceDataSize = mAcpiBootPerformanceTable->
Header.Length;
383 EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
384 &gEfiFirmwarePerformanceGuid,
386 sizeof (PerformanceVariable),
393 Status = RegisterBasicVariablePolicy (
394 VariablePolicyProtocol,
395 &gEfiFirmwarePerformanceGuid,
396 EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
397 VARIABLE_POLICY_NO_MIN_SIZE,
398 VARIABLE_POLICY_NO_MAX_SIZE,
399 VARIABLE_POLICY_NO_MUST_ATTR,
400 VARIABLE_POLICY_NO_CANT_ATTR,
401 VARIABLE_POLICY_TYPE_LOCK_NOW
403 if (EFI_ERROR (Status)) {
404 DEBUG ((DEBUG_ERROR,
"[FirmwarePerformanceDxe] Error when lock variable %s, Status = %r\n", EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, Status));
412 Status = AcpiTableProtocol->InstallAcpiTable (
414 &mFirmwarePerformanceTableTemplate,
415 mFirmwarePerformanceTableTemplate.
Header.Length,
416 &mFirmwarePerformanceTableTemplateKey
418 if (EFI_ERROR (Status)) {
419 if (mAcpiBootPerformanceTable !=
NULL) {
423 if (mAcpiS3PerformanceTable !=
NULL) {
427 mAcpiBootPerformanceTable =
NULL;
428 mAcpiS3PerformanceTable =
NULL;
470 return EFI_UNSUPPORTED;
473 if (Value == (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT)) {
477 mDxeCoreReportStatusCodeEnable =
TRUE;
481 if (Value ==
PcdGet32 (PcdProgressCodeOsLoaderLoad)) {
485 if (mAcpiBootPerformanceTable ==
NULL) {
493 }
else if (Value ==
PcdGet32 (PcdProgressCodeOsLoaderStart)) {
497 if (mAcpiBootPerformanceTable ==
NULL) {
505 }
else if (Value == (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)) {
514 if (mAcpiBootPerformanceTable ==
NULL) {
522 }
else if (Value == (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT)) {
523 if (mAcpiBootPerformanceTable ==
NULL) {
538 DEBUG ((DEBUG_INFO,
"FPDT: Boot Performance - ResetEnd = %ld\n", mAcpiBootPerformanceTable->
BasicBoot.
ResetEnd));
539 DEBUG ((DEBUG_INFO,
"FPDT: Boot Performance - OsLoaderLoadImageStart = 0\n"));
541 DEBUG ((DEBUG_INFO,
"FPDT: Boot Performance - ExitBootServicesEntry = 0\n"));
542 DEBUG ((DEBUG_INFO,
"FPDT: Boot Performance - ExitBootServicesExit = 0\n"));
543 }
else if ((Data !=
NULL) &&
CompareGuid (&Data->Type, &gEdkiiFpdtExtendedFirmwarePerformanceGuid)) {
547 CopyMem (&mReceivedAcpiBootPerformanceTable, Data + 1, Data->Size);
549 }
else if ((Data !=
NULL) &&
CompareGuid (&Data->Type, &gEfiFirmwarePerformanceGuid)) {
550 DEBUG ((DEBUG_ERROR,
"FpdtStatusCodeListenerDxe: Performance data reported through gEfiFirmwarePerformanceGuid will not be collected by FirmwarePerformanceDataTableDxe\n"));
551 Status = EFI_UNSUPPORTED;
556 Status = EFI_UNSUPPORTED;
586 ASSERT (mReceivedAcpiBootPerformanceTable ==
NULL);
605 if (!mDxeCoreReportStatusCodeEnable) {
613 if (mAcpiBootPerformanceTable ==
NULL) {
628 DEBUG ((DEBUG_INFO,
"FPDT: Boot Performance - ResetEnd = %ld\n", mAcpiBootPerformanceTable->
BasicBoot.
ResetEnd));
662 mFirmwarePerformanceTableTemplate.
Header.OemId,
664 sizeof (mFirmwarePerformanceTableTemplate.
Header.OemId)
666 OemTableId =
PcdGet64 (PcdAcpiDefaultOemTableId);
667 CopyMem (&mFirmwarePerformanceTableTemplate.
Header.OemTableId, &OemTableId, sizeof (UINT64));
668 mFirmwarePerformanceTableTemplate.
Header.OemRevision =
PcdGet32 (PcdAcpiDefaultOemRevision);
669 mFirmwarePerformanceTableTemplate.
Header.CreatorId =
PcdGet32 (PcdAcpiDefaultCreatorId);
670 mFirmwarePerformanceTableTemplate.
Header.CreatorRevision =
PcdGet32 (PcdAcpiDefaultCreatorRevision);
675 Status =
gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid,
NULL, (VOID **)&mRscHandlerProtocol);
687 Status =
gBS->CreateEventEx (
692 &gEfiEndOfDxeEventGroupGuid,
700 Status =
gBS->CreateEventEx (
705 &gEfiEventExitBootServicesGuid,
706 &mExitBootServicesEvent
714 if (GuidHob !=
NULL) {
721 DEBUG ((DEBUG_WARN,
"FPDT: WARNING: SEC Performance Data Hob not found, ResetEnd will be set to 0!\n"));
724 if (
FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) {
730 &gEfiVariableArchProtocolGuid,
737 &gEfiLockBoxProtocolGuid,
#define EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE
#define EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE
#define EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION
#define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME
#define EFI_ACPI_5_0_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER
#define EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE
#define EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME
#define EFI_ACPI_5_0_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER
UINT64 EFIAPI GetTimeInNanoSecond(IN UINT64 Ticks)
UINT64 EFIAPI GetPerformanceCounter(VOID)
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
UINT8 EFIAPI CalculateCheckSum8(IN CONST UINT8 *Buffer, IN UINTN Length)
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
VOID *EFIAPI AllocatePeiAccessiblePages(IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages)
VOID EFIAPI FreePages(IN VOID *Buffer, IN UINTN Pages)
RETURN_STATUS EFIAPI SaveLockBox(IN GUID *Guid, IN VOID *Buffer, IN UINTN Length)
EFI_RUNTIME_SERVICES * gRT
#define OFFSET_OF(TYPE, Field)
#define ASSERT_EFI_ERROR(StatusParameter)
#define DEBUG(Expression)
#define PcdGet64(TokenName)
#define PcdGet8(TokenName)
#define PcdGet32(TokenName)
#define PcdGetPtr(TokenName)
#define FeaturePcdGet(TokenName)
UINT32 EFI_STATUS_CODE_VALUE
#define EFI_PROGRESS_CODE
UINT32 EFI_STATUS_CODE_TYPE
#define EFI_STATUS_CODE_TYPE_MASK
UINT64 EFI_PHYSICAL_ADDRESS
#define EFI_SIZE_TO_PAGES(Size)
EFI_EVENT EFIAPI EfiCreateProtocolNotifyEvent(IN EFI_GUID *ProtocolGuid, IN EFI_TPL NotifyTpl, IN EFI_EVENT_NOTIFY NotifyFunction, IN VOID *NotifyContext OPTIONAL, OUT VOID **Registration)
#define EFI_VARIABLE_NON_VOLATILE
EFI_ACPI_5_0_FPDT_PERFORMANCE_TABLE_HEADER Header
Common ACPI table header.
EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD BasicBoot
Basic Boot Resume performance record.
UINT64 BootPerformanceTablePointer
UINT64 ExitBootServicesExit
UINT64 ExitBootServicesEntry
UINT64 OsLoaderLoadImageStart
UINT64 OsLoaderStartImageStart
UINT64 S3PerformanceTablePointer
EFI_ACPI_DESCRIPTION_HEADER Header
Common ACPI description table header.
EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD S3PointerRecord
S3 Performance Table Pointer record.
EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD BootPointerRecord
Basic Boot Performance Table Pointer record.
EFI_PHYSICAL_ADDRESS S3PerformanceTablePointer
Pointer to S3 Performance Table.
EFI_PHYSICAL_ADDRESS BootPerformanceTablePointer
Pointer to Boot Performance Table.
UINT64 ResetEnd
Timer value logged at the beginning of firmware image execution, in unit of nanosecond.