/** @file
  This module install ACPI Firmware Performance Data Table (FPDT).

  This module register report status code listener to collect performance data
  for Firmware Basic Boot Performance Record and other boot performance records,
  and install FPDT to ACPI table.

  Copyright (c) 2011 - 2021, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <PiDxe.h>

#include <Protocol/ReportStatusCodeHandler.h>
#include <Protocol/AcpiTable.h>
#include <Protocol/LockBox.h>
#include <Protocol/Variable.h>
#include <Protocol/VariablePolicy.h>

#include <Guid/Acpi.h>
#include <Guid/FirmwarePerformance.h>

#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/DxeServicesLib.h>
#include <Library/TimerLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
#include <Library/LockBoxLib.h>
#include <Library/UefiLib.h>
#include <Library/VariablePolicyHelperLib.h>
#include <Library/PerformanceLib.h>

#define SMM_BOOT_RECORD_COMM_SIZE (OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data) + sizeof(SMM_BOOT_RECORD_COMMUNICATE))

EFI_RSC_HANDLER_PROTOCOL    *mRscHandlerProtocol = NULL;

BOOLEAN                     mLockBoxReady = FALSE;
EFI_EVENT                   mReadyToBootEvent;
EFI_EVENT                   mLegacyBootEvent;
static EFI_EVENT            mExitBootServicesEvent;
UINTN                       mFirmwarePerformanceTableTemplateKey  = 0;
BOOLEAN                     mDxeCoreReportStatusCodeEnable = FALSE;

BOOT_PERFORMANCE_TABLE                      *mAcpiBootPerformanceTable = NULL;
BOOT_PERFORMANCE_TABLE                      *mReceivedAcpiBootPerformanceTable = NULL;
S3_PERFORMANCE_TABLE                        *mAcpiS3PerformanceTable   = NULL;

FIRMWARE_PERFORMANCE_TABLE  mFirmwarePerformanceTableTemplate = {
  {
    EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_SIGNATURE,
    sizeof (FIRMWARE_PERFORMANCE_TABLE),
    EFI_ACPI_5_0_FIRMWARE_PERFORMANCE_DATA_TABLE_REVISION,    // Revision
    0x00, // Checksum will be updated at runtime
    //
    // It is expected that these values will be updated at EntryPoint.
    //
    {0x00},     // OEM ID is a 6 bytes long field
    0x00,       // OEM Table ID(8 bytes long)
    0x00,       // OEM Revision
    0x00,       // Creator ID
    0x00,       // Creator Revision
  },
  //
  // Firmware Basic Boot Performance Table Pointer Record.
  //
  {
    {
      EFI_ACPI_5_0_FPDT_RECORD_TYPE_FIRMWARE_BASIC_BOOT_POINTER ,       // Type
      sizeof (EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_POINTER_RECORD), // Length
      EFI_ACPI_5_0_FPDT_RECORD_REVISION_FIRMWARE_BASIC_BOOT_POINTER     // Revision
    },
    0,  // Reserved
    0   // BootPerformanceTablePointer will be updated at runtime.
  },
  //
  // S3 Performance Table Pointer Record.
  //
  {
    {
      EFI_ACPI_5_0_FPDT_RECORD_TYPE_S3_PERFORMANCE_TABLE_POINTER,     // Type
      sizeof (EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD), // Length
      EFI_ACPI_5_0_FPDT_RECORD_REVISION_S3_PERFORMANCE_TABLE_POINTER  // Revision
    },
    0,  // Reserved
    0   // S3PerformanceTablePointer will be updated at runtime.
  }
};

BOOT_PERFORMANCE_TABLE mBootPerformanceTableTemplate = {
  {
    EFI_ACPI_5_0_FPDT_BOOT_PERFORMANCE_TABLE_SIGNATURE,
    sizeof (BOOT_PERFORMANCE_TABLE)
  },
  {
    {
      EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_FIRMWARE_BASIC_BOOT,    // Type
      sizeof (EFI_ACPI_5_0_FPDT_FIRMWARE_BASIC_BOOT_RECORD),        // Length
      EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_FIRMWARE_BASIC_BOOT // Revision
    },
    0,  // Reserved
    //
    // These values will be updated at runtime.
    //
    0,  // ResetEnd
    0,  // OsLoaderLoadImageStart
    0,  // OsLoaderStartImageStart
    0,  // ExitBootServicesEntry
    0   // ExitBootServicesExit
  }
};

S3_PERFORMANCE_TABLE        mS3PerformanceTableTemplate = {
  {
    EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE,
    sizeof (S3_PERFORMANCE_TABLE)
  },
  {
    {
      EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_RESUME,     // Type
      sizeof (EFI_ACPI_5_0_FPDT_S3_RESUME_RECORD),         // Length
      EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_RESUME  // Revision
    },
    //
    // These values will be updated by Firmware Performance PEIM.
    //
    0,  // ResumeCount
    0,  // FullResume
    0   // AverageResume
  },
  {
    {
      EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_TYPE_S3_SUSPEND,    // Type
      sizeof (EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD),        // Length
      EFI_ACPI_5_0_FPDT_RUNTIME_RECORD_REVISION_S3_SUSPEND // Revision
    },
    //
    // These values will be updated bye Firmware Performance SMM driver.
    //
    0,  // SuspendStart
    0   // SuspendEnd
  }
};

/**
  This function calculates and updates an UINT8 checksum.

  @param[in]  Buffer          Pointer to buffer to checksum
  @param[in]  Size            Number of bytes to checksum

**/
VOID
FpdtAcpiTableChecksum (
  IN UINT8      *Buffer,
  IN UINTN      Size
  )
{
  UINTN ChecksumOffset;

  ChecksumOffset = OFFSET_OF (EFI_ACPI_DESCRIPTION_HEADER, Checksum);

  //
  // Set checksum to 0 first.
  //
  Buffer[ChecksumOffset] = 0;

  //
  // Update checksum value.
  //
  Buffer[ChecksumOffset] = CalculateCheckSum8 (Buffer, Size);
}

/**
  Callback function upon VariableArchProtocol and LockBoxProtocol
  to allocate S3 performance table memory and save the pointer to LockBox.

  @param[in] Event    Event whose notification function is being invoked.
  @param[in] Context  Pointer to the notification function's context.
**/
VOID
EFIAPI
FpdtAllocateS3PerformanceTableMemory (
  IN  EFI_EVENT                             Event,
  IN  VOID                                  *Context
  )
{
  EFI_STATUS                    Status;
  VOID                          *Interface;
  FIRMWARE_PERFORMANCE_VARIABLE PerformanceVariable;
  UINTN                         Size;
  EFI_PHYSICAL_ADDRESS          S3PerformanceTablePointer;

  if (mLockBoxReady && (mAcpiS3PerformanceTable != NULL)) {
    //
    // The memory for S3 performance table should have been ready,
    // and the pointer should have been saved to LockBox, just return.
    //
    return;
  }

  if (!mLockBoxReady) {
    Status = gBS->LocateProtocol (&gEfiLockBoxProtocolGuid, NULL, &Interface);
    if (!EFI_ERROR (Status)) {
      //
      // LockBox services has been ready.
      //
      mLockBoxReady = TRUE;
    }
  }

  if (mAcpiS3PerformanceTable == NULL) {
    Status = gBS->LocateProtocol (&gEfiVariableArchProtocolGuid, NULL, &Interface);
    if (!EFI_ERROR (Status)) {
      //
      // Try to allocate the same runtime buffer as last time boot.
      //
      ZeroMem (&PerformanceVariable, sizeof (PerformanceVariable));
      Size = sizeof (PerformanceVariable);
      Status = gRT->GetVariable (
                      EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
                      &gEfiFirmwarePerformanceGuid,
                      NULL,
                      &Size,
                      &PerformanceVariable
                      );
      if (!EFI_ERROR (Status)) {
        Status = gBS->AllocatePages (
                        AllocateAddress,
                        EfiReservedMemoryType,
                        EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE)),
                        &PerformanceVariable.S3PerformanceTablePointer
                        );
        if (!EFI_ERROR (Status)) {
          mAcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *) (UINTN) PerformanceVariable.S3PerformanceTablePointer;
        }
      }
      if (mAcpiS3PerformanceTable == NULL) {
        //
        // Fail to allocate at specified address, continue to allocate at any address.
        //
        mAcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *) AllocatePeiAccessiblePages (
                                                             EfiReservedMemoryType,
                                                             EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE))
                                                             );
      }
      DEBUG ((EFI_D_INFO, "FPDT: ACPI S3 Performance Table address = 0x%x\n", mAcpiS3PerformanceTable));
      if (mAcpiS3PerformanceTable != NULL) {
        CopyMem (mAcpiS3PerformanceTable, &mS3PerformanceTableTemplate, sizeof (mS3PerformanceTableTemplate));
      }
    }
  }

  if (mLockBoxReady && (mAcpiS3PerformanceTable != NULL)) {
    //
    // If LockBox services has been ready and memory for FPDT S3 performance table has been allocated,
    // save the pointer to LockBox for use in S3 resume.
    //
    S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable;
    Status = SaveLockBox (
               &gFirmwarePerformanceS3PointerGuid,
               &S3PerformanceTablePointer,
               sizeof (EFI_PHYSICAL_ADDRESS)
               );
    ASSERT_EFI_ERROR (Status);
  }
}

/**
  Install ACPI Firmware Performance Data Table (FPDT).

  @return Status code.

**/
EFI_STATUS
InstallFirmwarePerformanceDataTable (
  VOID
  )
{
  EFI_STATUS                      Status;
  EFI_ACPI_TABLE_PROTOCOL         *AcpiTableProtocol;
  UINTN                           BootPerformanceDataSize;
  FIRMWARE_PERFORMANCE_VARIABLE   PerformanceVariable;
  UINTN                           Size;
  EDKII_VARIABLE_POLICY_PROTOCOL  *VariablePolicyProtocol;

  //
  // Get AcpiTable Protocol.
  //
  Status = gBS->LocateProtocol (&gEfiAcpiTableProtocolGuid, NULL, (VOID **) &AcpiTableProtocol);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Get VariablePolicy Protocol.
  //
  Status = gBS->LocateProtocol(&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&VariablePolicyProtocol);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  if (mReceivedAcpiBootPerformanceTable != NULL) {
    mAcpiBootPerformanceTable = mReceivedAcpiBootPerformanceTable;
    mAcpiBootPerformanceTable->BasicBoot.ResetEnd = mBootPerformanceTableTemplate.BasicBoot.ResetEnd;
  } else {
    //
    // Try to allocate the same runtime buffer as last time boot.
    //
    BootPerformanceDataSize = sizeof (BOOT_PERFORMANCE_TABLE);
    ZeroMem (&PerformanceVariable, sizeof (PerformanceVariable));
    Size = sizeof (PerformanceVariable);
    Status = gRT->GetVariable (
                    EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
                    &gEfiFirmwarePerformanceGuid,
                    NULL,
                    &Size,
                    &PerformanceVariable
                    );
    if (!EFI_ERROR (Status)) {
      Status = gBS->AllocatePages (
                      AllocateAddress,
                      EfiReservedMemoryType,
                      EFI_SIZE_TO_PAGES (BootPerformanceDataSize),
                      &PerformanceVariable.BootPerformanceTablePointer
                      );
      if (!EFI_ERROR (Status)) {
         mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) (UINTN) PerformanceVariable.BootPerformanceTablePointer;
      }
    }
    if (mAcpiBootPerformanceTable == NULL) {
      //
      // Fail to allocate at specified address, continue to allocate at any address.
      //
      mAcpiBootPerformanceTable = (BOOT_PERFORMANCE_TABLE *) AllocatePeiAccessiblePages (
                                                               EfiReservedMemoryType,
                                                               EFI_SIZE_TO_PAGES (BootPerformanceDataSize)
                                                               );
    }
    DEBUG ((DEBUG_INFO, "FPDT: ACPI Boot Performance Table address = 0x%x\n", mAcpiBootPerformanceTable));
    if (mAcpiBootPerformanceTable == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }
    //
    // Fill Basic Boot record to Boot Performance Table.
    //
    CopyMem (mAcpiBootPerformanceTable, &mBootPerformanceTableTemplate, sizeof (mBootPerformanceTableTemplate));
  }
  BootPerformanceDataSize   = mAcpiBootPerformanceTable->Header.Length;

  //
  // Save Boot Performance Table address to Variable for use in S4 resume.
  //
  PerformanceVariable.BootPerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiBootPerformanceTable;
  //
  // Update Boot Performance Table Pointer in template.
  //
  mFirmwarePerformanceTableTemplate.BootPointerRecord.BootPerformanceTablePointer = (UINT64) (UINTN) mAcpiBootPerformanceTable;

  //
  // Save S3 Performance Table address to Variable for use in S4 resume.
  //
  PerformanceVariable.S3PerformanceTablePointer = (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiS3PerformanceTable;
  //
  // Update S3 Performance Table Pointer in template.
  //
  mFirmwarePerformanceTableTemplate.S3PointerRecord.S3PerformanceTablePointer = (UINT64) (UINTN) mAcpiS3PerformanceTable;
  //
  // Save Runtime Performance Table pointers to Variable.
  // Don't check SetVariable return status. It doesn't impact FPDT table generation.
  //
  gRT->SetVariable (
        EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
        &gEfiFirmwarePerformanceGuid,
        EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
        sizeof (PerformanceVariable),
        &PerformanceVariable
        );

  //
  // Lock the variable which stores the Performance Table pointers.
  //
  Status = RegisterBasicVariablePolicy (
             VariablePolicyProtocol,
             &gEfiFirmwarePerformanceGuid,
             EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
             VARIABLE_POLICY_NO_MIN_SIZE,
             VARIABLE_POLICY_NO_MAX_SIZE,
             VARIABLE_POLICY_NO_MUST_ATTR,
             VARIABLE_POLICY_NO_CANT_ATTR,
             VARIABLE_POLICY_TYPE_LOCK_NOW
             );
  if (EFI_ERROR(Status)) {
    DEBUG((DEBUG_ERROR, "[FirmwarePerformanceDxe] Error when lock variable %s, Status = %r\n", EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME, Status));
    ASSERT_EFI_ERROR(Status);
  }

  //
  // Publish Firmware Performance Data Table.
  //
  FpdtAcpiTableChecksum ((UINT8 *) &mFirmwarePerformanceTableTemplate, mFirmwarePerformanceTableTemplate.Header.Length);
  Status = AcpiTableProtocol->InstallAcpiTable (
                                AcpiTableProtocol,
                                &mFirmwarePerformanceTableTemplate,
                                mFirmwarePerformanceTableTemplate.Header.Length,
                                &mFirmwarePerformanceTableTemplateKey
                                );
  if (EFI_ERROR (Status)) {
    if (mAcpiBootPerformanceTable != NULL) {
      FreePages (mAcpiBootPerformanceTable, EFI_SIZE_TO_PAGES (BootPerformanceDataSize));
    }
    if (mAcpiS3PerformanceTable != NULL) {
      FreePages (mAcpiS3PerformanceTable, EFI_SIZE_TO_PAGES (sizeof (S3_PERFORMANCE_TABLE)));
    }
    mAcpiBootPerformanceTable = NULL;
    mAcpiS3PerformanceTable = NULL;
    return Status;
  }
  return EFI_SUCCESS;
}

/**
  Report status code listener of FPDT. This is used to collect performance data
  for OsLoaderLoadImageStart and OsLoaderStartImageStart in FPDT.

  @param[in]  CodeType            Indicates the type of status code being reported.
  @param[in]  Value               Describes the current status of a hardware or software entity.
                                  This included information about the class and subclass that is used to
                                  classify the entity as well as an operation.
  @param[in]  Instance            The enumeration of a hardware or software entity within
                                  the system. Valid instance numbers start with 1.
  @param[in]  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.
  @param[in]  Data                This optional parameter may be used to pass additional data.

  @retval EFI_SUCCESS             Status code is what we expected.
  @retval EFI_UNSUPPORTED         Status code not supported.

**/
EFI_STATUS
EFIAPI
FpdtStatusCodeListenerDxe (
  IN EFI_STATUS_CODE_TYPE     CodeType,
  IN EFI_STATUS_CODE_VALUE    Value,
  IN UINT32                   Instance,
  IN EFI_GUID                 *CallerId,
  IN EFI_STATUS_CODE_DATA     *Data
  )
{
  EFI_STATUS  Status;

  //
  // Check whether status code is what we are interested in.
  //
  if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) != EFI_PROGRESS_CODE) {
    return EFI_UNSUPPORTED;
  }

  if (Value == (EFI_SOFTWARE_DXE_CORE | EFI_SW_DXE_CORE_PC_HANDOFF_TO_NEXT)) {
    //
    // DxeCore ReportStatusCode Enable so that the capability can be supported.
    //
    mDxeCoreReportStatusCodeEnable = TRUE;
  }

  Status = EFI_SUCCESS;
  if (Value == PcdGet32 (PcdProgressCodeOsLoaderLoad)) {
    //
    // Progress code for OS Loader LoadImage.
    //
    if (mAcpiBootPerformanceTable == NULL) {
      return Status;
    }

    //
    // Update OS Loader LoadImage Start for UEFI boot.
    //
    mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart = GetTimeInNanoSecond (GetPerformanceCounter ());
  } else if (Value == PcdGet32 (PcdProgressCodeOsLoaderStart)) {
    //
    // Progress code for OS Loader StartImage.
    //
    if (mAcpiBootPerformanceTable == NULL) {
      return Status;
    }

    //
    // Update OS Loader StartImage Start for UEFI boot.
    //
    mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart = GetTimeInNanoSecond (GetPerformanceCounter ());
  } else if (Value == (EFI_SOFTWARE_EFI_BOOT_SERVICE | EFI_SW_BS_PC_EXIT_BOOT_SERVICES)) {
    //
    // Unregister boot time report status code listener.
    //
    mRscHandlerProtocol->Unregister (FpdtStatusCodeListenerDxe);

    //
    // Progress code for ExitBootServices.
    //
    if (mAcpiBootPerformanceTable == NULL) {
      return Status;
    }

    //
    // Update ExitBootServicesExit for UEFI boot.
    //
    mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesExit = GetTimeInNanoSecond (GetPerformanceCounter ());
  } else if (Value == (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_DXE_BS_PC_LEGACY_BOOT_EVENT)) {
    if (mAcpiBootPerformanceTable == NULL) {
      //
      // Firmware Performance Data Table not installed, do nothing.
      //
      return Status;
    }

    //
    // Update Firmware Basic Boot Performance Record for legacy boot.
    //
    mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart = GetTimeInNanoSecond (GetPerformanceCounter ());

    //
    // Dump FPDT Boot Performance record.
    //
    DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ResetEnd                = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ResetEnd));
    DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderLoadImageStart  = 0\n"));
    DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderStartImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart));
    DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesEntry   = 0\n"));
    DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesExit    = 0\n"));
  } else if (Data != NULL && CompareGuid (&Data->Type, &gEdkiiFpdtExtendedFirmwarePerformanceGuid)) {
    //
    // Get the Boot performance table and then install it to ACPI table.
    //
    CopyMem (&mReceivedAcpiBootPerformanceTable, Data + 1, Data->Size);
    InstallFirmwarePerformanceDataTable ();
  } else if (Data != NULL && CompareGuid (&Data->Type, &gEfiFirmwarePerformanceGuid)) {
    DEBUG ((DEBUG_ERROR, "FpdtStatusCodeListenerDxe: Performance data reported through gEfiFirmwarePerformanceGuid will not be collected by FirmwarePerformanceDataTableDxe\n"));
    Status = EFI_UNSUPPORTED;
  } else {
    //
    // Ignore else progress code.
    //
    Status = EFI_UNSUPPORTED;
  }

  return Status;
}

/**
  Notify function for event EndOfDxe.

  This is used to install ACPI Firmware Performance Data Table for basic boot records.

  @param[in]  Event   The Event that is being processed.
  @param[in]  Context The Event Context.

**/
VOID
EFIAPI
FpdtEndOfDxeEventNotify (
  IN EFI_EVENT        Event,
  IN VOID             *Context
  )
{
  //
  // When performance is enabled, the FPDT will be installed when DxeCorePerformanceLib report the data to FimwarePerformanceDxe.
  // This is used to install the FPDT for the basic boot recods when performance infrastructure is not enabled.
  //
  if ((PcdGet8(PcdPerformanceLibraryPropertyMask) & PERFORMANCE_LIBRARY_PROPERTY_MEASUREMENT_ENABLED) != 0) {
    return;
  }
  ASSERT (mReceivedAcpiBootPerformanceTable == NULL);
  InstallFirmwarePerformanceDataTable ();
}

/**
  Notify function for event EVT_SIGNAL_EXIT_BOOT_SERVICES. This is used to record
  performance data for ExitBootServicesEntry in FPDT.

  @param[in]  Event   The Event that is being processed.
  @param[in]  Context The Event Context.

**/
VOID
EFIAPI
FpdtExitBootServicesEventNotify (
  IN EFI_EVENT        Event,
  IN VOID             *Context
  )
{
  if (!mDxeCoreReportStatusCodeEnable) {
    //
    // When DxeCore Report Status Code is disabled,
    // Unregister boot time report status code listener at ExitBootService Event.
    //
    mRscHandlerProtocol->Unregister (FpdtStatusCodeListenerDxe);
  }

  if (mAcpiBootPerformanceTable == NULL) {
    //
    // Firmware Performance Data Table not installed, do nothing.
    //
    return ;
  }

  //
  // Update Firmware Basic Boot Performance Record for UEFI boot.
  //
  mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry = GetTimeInNanoSecond (GetPerformanceCounter ());

  //
  // Dump FPDT Boot Performance record.
  //
  DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ResetEnd                = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ResetEnd));
  DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderLoadImageStart  = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderLoadImageStart));
  DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - OsLoaderStartImageStart = %ld\n", mAcpiBootPerformanceTable->BasicBoot.OsLoaderStartImageStart));
  DEBUG ((EFI_D_INFO, "FPDT: Boot Performance - ExitBootServicesEntry   = %ld\n", mAcpiBootPerformanceTable->BasicBoot.ExitBootServicesEntry));
  //
  // ExitBootServicesExit will be updated later, so don't dump it here.
  //
}

/**
  The module Entry Point of the Firmware Performance Data Table DXE driver.

  @param[in]  ImageHandle    The firmware allocated handle for the EFI image.
  @param[in]  SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS    The entry point is executed successfully.
  @retval Other          Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
FirmwarePerformanceDxeEntryPoint (
  IN EFI_HANDLE          ImageHandle,
  IN EFI_SYSTEM_TABLE    *SystemTable
  )
{
  EFI_STATUS               Status;
  EFI_HOB_GUID_TYPE        *GuidHob;
  FIRMWARE_SEC_PERFORMANCE *Performance;
  VOID                     *Registration;
  UINT64                   OemTableId;
  EFI_EVENT                EndOfDxeEvent;

  CopyMem (
    mFirmwarePerformanceTableTemplate.Header.OemId,
    PcdGetPtr (PcdAcpiDefaultOemId),
    sizeof (mFirmwarePerformanceTableTemplate.Header.OemId)
    );
  OemTableId = PcdGet64 (PcdAcpiDefaultOemTableId);
  CopyMem (&mFirmwarePerformanceTableTemplate.Header.OemTableId, &OemTableId, sizeof (UINT64));
  mFirmwarePerformanceTableTemplate.Header.OemRevision      = PcdGet32 (PcdAcpiDefaultOemRevision);
  mFirmwarePerformanceTableTemplate.Header.CreatorId        = PcdGet32 (PcdAcpiDefaultCreatorId);
  mFirmwarePerformanceTableTemplate.Header.CreatorRevision  = PcdGet32 (PcdAcpiDefaultCreatorRevision);

  //
  // Get Report Status Code Handler Protocol.
  //
  Status = gBS->LocateProtocol (&gEfiRscHandlerProtocolGuid, NULL, (VOID **) &mRscHandlerProtocol);
  ASSERT_EFI_ERROR (Status);

  //
  // Register report status code listener for OS Loader load and start.
  //
  Status = mRscHandlerProtocol->Register (FpdtStatusCodeListenerDxe, TPL_HIGH_LEVEL);
  ASSERT_EFI_ERROR (Status);

  //
  // Register the notify function to install FPDT at EndOfDxe.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  FpdtEndOfDxeEventNotify,
                  NULL,
                  &gEfiEndOfDxeEventGroupGuid,
                  &EndOfDxeEvent
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Register the notify function to update FPDT on ExitBootServices Event.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_NOTIFY,
                  FpdtExitBootServicesEventNotify,
                  NULL,
                  &gEfiEventExitBootServicesGuid,
                  &mExitBootServicesEvent
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Retrieve GUID HOB data that contains the ResetEnd.
  //
  GuidHob = GetFirstGuidHob (&gEfiFirmwarePerformanceGuid);
  if (GuidHob != NULL) {
    Performance = (FIRMWARE_SEC_PERFORMANCE *) GET_GUID_HOB_DATA (GuidHob);
    mBootPerformanceTableTemplate.BasicBoot.ResetEnd = Performance->ResetEnd;
  } else {
    //
    // SEC Performance Data Hob not found, ResetEnd in ACPI FPDT table will be 0.
    //
    DEBUG ((DEBUG_WARN, "FPDT: WARNING: SEC Performance Data Hob not found, ResetEnd will be set to 0!\n"));
  }

  if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) {
    //
    // Register callback function upon VariableArchProtocol and LockBoxProtocol
    // to allocate S3 performance table memory and save the pointer to LockBox.
    //
    EfiCreateProtocolNotifyEvent (
      &gEfiVariableArchProtocolGuid,
      TPL_CALLBACK,
      FpdtAllocateS3PerformanceTableMemory,
      NULL,
      &Registration
      );
    EfiCreateProtocolNotifyEvent (
      &gEfiLockBoxProtocolGuid,
      TPL_CALLBACK,
      FpdtAllocateS3PerformanceTableMemory,
      NULL,
      &Registration
      );
  } else {
    //
    // Exclude S3 Performance Table Pointer from FPDT table template.
    //
    mFirmwarePerformanceTableTemplate.Header.Length -= sizeof (EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_POINTER_RECORD);
  }

  return EFI_SUCCESS;
}
