/** @file
  This module updates S3 Resume Performance Record in ACPI Firmware Performance
  Data Table in S3 resume boot mode.

  This module register report status code listener to collect performance data
  for S3 Resume Performance Record on S3 resume boot path.

  Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include <PiPei.h>

#include <Ppi/ReportStatusCodeHandler.h>
#include <Ppi/ReadOnlyVariable2.h>

#include <Guid/FirmwarePerformance.h>
#include <Guid/Performance.h>
#include <Guid/ExtendedFirmwarePerformance.h>

#include <Library/PeiServicesLib.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/TimerLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/LockBoxLib.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>

/**
  Report status code listener for PEI. This is used to record the performance
  data for S3 FullResume in FPDT.

  @param[in]  PeiServices         An indirect pointer to the EFI_PEI_SERVICES table published by the PEI Foundation.
  @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
FpdtStatusCodeListenerPei (
  IN CONST  EFI_PEI_SERVICES       **PeiServices,
  IN        EFI_STATUS_CODE_TYPE   CodeType,
  IN        EFI_STATUS_CODE_VALUE  Value,
  IN        UINT32                 Instance,
  IN CONST  EFI_GUID               *CallerId,
  IN CONST  EFI_STATUS_CODE_DATA   *Data
  )
{
  EFI_STATUS                           Status;
  UINT64                               CurrentTime;
  UINTN                                VarSize;
  EFI_PHYSICAL_ADDRESS                 S3PerformanceTablePointer;
  S3_PERFORMANCE_TABLE                 *AcpiS3PerformanceTable;
  EFI_ACPI_5_0_FPDT_S3_RESUME_RECORD   *AcpiS3ResumeRecord;
  UINT64                               S3ResumeTotal;
  EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD  S3SuspendRecord;
  EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD  *AcpiS3SuspendRecord;
  EFI_PEI_READ_ONLY_VARIABLE2_PPI      *VariableServices;
  UINT8                                *BootPerformanceTable;
  FIRMWARE_PERFORMANCE_VARIABLE        PerformanceVariable;
  EFI_HOB_GUID_TYPE                    *GuidHob;
  FPDT_PEI_EXT_PERF_HEADER             *PeiPerformanceLogHeader;
  UINT8                                *FirmwarePerformanceData;
  UINT8                                *FirmwarePerformanceTablePtr;

  //
  // Check whether status code is what we are interested in.
  //
  if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) != EFI_PROGRESS_CODE) ||
      (Value != (EFI_SOFTWARE_PEI_MODULE | EFI_SW_PEI_PC_OS_WAKE)))
  {
    return EFI_UNSUPPORTED;
  }

  //
  // Retrieve current time as early as possible.
  //
  CurrentTime = GetTimeInNanoSecond (GetPerformanceCounter ());

  //
  // Update S3 Resume Performance Record.
  //
  S3PerformanceTablePointer = 0;
  VarSize                   = sizeof (EFI_PHYSICAL_ADDRESS);
  Status                    = RestoreLockBox (&gFirmwarePerformanceS3PointerGuid, &S3PerformanceTablePointer, &VarSize);
  ASSERT_EFI_ERROR (Status);

  AcpiS3PerformanceTable = (S3_PERFORMANCE_TABLE *)(UINTN)S3PerformanceTablePointer;
  ASSERT (AcpiS3PerformanceTable != NULL);
  if (AcpiS3PerformanceTable->Header.Signature != EFI_ACPI_5_0_FPDT_S3_PERFORMANCE_TABLE_SIGNATURE) {
    DEBUG ((DEBUG_ERROR, "FPDT S3 performance data in ACPI memory get corrupted\n"));
    return EFI_ABORTED;
  }

  AcpiS3ResumeRecord             = &AcpiS3PerformanceTable->S3Resume;
  AcpiS3ResumeRecord->FullResume = CurrentTime;
  //
  // Calculate average S3 resume time.
  //
  S3ResumeTotal = MultU64x32 (AcpiS3ResumeRecord->AverageResume, AcpiS3ResumeRecord->ResumeCount);
  AcpiS3ResumeRecord->ResumeCount++;
  if (AcpiS3ResumeRecord->ResumeCount > 0) {
    AcpiS3ResumeRecord->AverageResume = DivU64x32 (S3ResumeTotal + AcpiS3ResumeRecord->FullResume, AcpiS3ResumeRecord->ResumeCount);
    DEBUG ((DEBUG_INFO, "\nFPDT: S3 Resume Performance - AverageResume = 0x%x\n", AcpiS3ResumeRecord->AverageResume));
  } else {
    DEBUG ((DEBUG_ERROR, "\nFPDT: S3 ResumeCount reaches the MAX_UINT32 value. S3 ResumeCount record reset to Zero."));
  }

  DEBUG ((DEBUG_INFO, "FPDT: S3 Resume Performance - ResumeCount   = 0x%x\n", AcpiS3ResumeRecord->ResumeCount));
  DEBUG ((DEBUG_INFO, "FPDT: S3 Resume Performance - FullResume    = 0x%x\n", AcpiS3ResumeRecord->FullResume));

  //
  // Update S3 Suspend Performance Record.
  //
  AcpiS3SuspendRecord = &AcpiS3PerformanceTable->S3Suspend;
  VarSize             = sizeof (EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD);
  ZeroMem (&S3SuspendRecord, sizeof (EFI_ACPI_5_0_FPDT_S3_SUSPEND_RECORD));
  Status = RestoreLockBox (
             &gEfiFirmwarePerformanceGuid,
             &S3SuspendRecord,
             &VarSize
             );
  ASSERT_EFI_ERROR (Status);

  AcpiS3SuspendRecord->SuspendStart = S3SuspendRecord.SuspendStart;
  AcpiS3SuspendRecord->SuspendEnd   = S3SuspendRecord.SuspendEnd;

  DEBUG ((DEBUG_INFO, "FPDT: S3 Suspend Performance - SuspendStart = %ld\n", AcpiS3SuspendRecord->SuspendStart));
  DEBUG ((DEBUG_INFO, "FPDT: S3 Suspend Performance - SuspendEnd   = %ld\n", AcpiS3SuspendRecord->SuspendEnd));

  Status = PeiServicesLocatePpi (
             &gEfiPeiReadOnlyVariable2PpiGuid,
             0,
             NULL,
             (VOID **)&VariableServices
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Update S3 boot records into the basic boot performance table.
  //
  VarSize = sizeof (PerformanceVariable);
  Status  = VariableServices->GetVariable (
                                VariableServices,
                                EFI_FIRMWARE_PERFORMANCE_VARIABLE_NAME,
                                &gEfiFirmwarePerformanceGuid,
                                NULL,
                                &VarSize,
                                &PerformanceVariable
                                );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  BootPerformanceTable = (UINT8 *)(UINTN)PerformanceVariable.BootPerformanceTablePointer;

  //
  // Dump PEI boot records
  //
  FirmwarePerformanceTablePtr = (BootPerformanceTable + sizeof (BOOT_PERFORMANCE_TABLE));
  GuidHob                     = GetFirstGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid);
  while (GuidHob != NULL) {
    FirmwarePerformanceData = GET_GUID_HOB_DATA (GuidHob);
    PeiPerformanceLogHeader = (FPDT_PEI_EXT_PERF_HEADER *)FirmwarePerformanceData;

    CopyMem (FirmwarePerformanceTablePtr, FirmwarePerformanceData + sizeof (FPDT_PEI_EXT_PERF_HEADER), (UINTN)(PeiPerformanceLogHeader->SizeOfAllEntries));

    GuidHob = GetNextGuidHob (&gEdkiiFpdtExtendedFirmwarePerformanceGuid, GET_NEXT_HOB (GuidHob));

    FirmwarePerformanceTablePtr += (UINTN)(PeiPerformanceLogHeader->SizeOfAllEntries);
  }

  //
  // Update Table length.
  //
  ((BOOT_PERFORMANCE_TABLE *)BootPerformanceTable)->Header.Length = (UINT32)((UINTN)FirmwarePerformanceTablePtr - (UINTN)BootPerformanceTable);

  return EFI_SUCCESS;
}

/**
  Main entry for Firmware Performance Data Table PEIM.

  This routine is to register report status code listener for FPDT.

  @param[in]  FileHandle              Handle of the file being invoked.
  @param[in]  PeiServices             Pointer to PEI Services table.

  @retval EFI_SUCCESS Report status code listener is registered successfully.

**/
EFI_STATUS
EFIAPI
FirmwarePerformancePeiEntryPoint (
  IN       EFI_PEI_FILE_HANDLE  FileHandle,
  IN CONST EFI_PEI_SERVICES     **PeiServices
  )
{
  EFI_STATUS               Status;
  EFI_PEI_RSC_HANDLER_PPI  *RscHandler;

  if (FeaturePcdGet (PcdFirmwarePerformanceDataTableS3Support)) {
    //
    // S3 resume - register status code listener for OS wake vector.
    //
    Status = PeiServicesLocatePpi (
               &gEfiPeiRscHandlerPpiGuid,
               0,
               NULL,
               (VOID **)&RscHandler
               );
    ASSERT_EFI_ERROR (Status);

    Status = RscHandler->Register (FpdtStatusCodeListenerPei);
    ASSERT_EFI_ERROR (Status);
  }

  return EFI_SUCCESS;
}
