/** @file
Code for Processor S3 restoration

Copyright (c) 2006 - 2023, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "PiSmmCpuDxeSmm.h"
#include <PiPei.h>
#include <Ppi/MpServices2.h>

#pragma pack(1)
typedef struct {
  UINTN              Lock;
  VOID               *StackStart;
  UINTN              StackSize;
  VOID               *ApFunction;
  IA32_DESCRIPTOR    GdtrProfile;
  IA32_DESCRIPTOR    IdtrProfile;
  UINT32             BufferStart;
  UINT32             Cr3;
  UINTN              InitializeFloatingPointUnitsAddress;
} MP_CPU_EXCHANGE_INFO;
#pragma pack()

typedef struct {
  UINT8    *RendezvousFunnelAddress;
  UINTN    PModeEntryOffset;
  UINTN    FlatJumpOffset;
  UINTN    Size;
  UINTN    LModeEntryOffset;
  UINTN    LongJumpOffset;
} MP_ASSEMBLY_ADDRESS_MAP;

//
// Flags used when program the register.
//
typedef struct {
  volatile UINTN     MemoryMappedLock;              // Spinlock used to program mmio
  volatile UINT32    *CoreSemaphoreCount;           // Semaphore container used to program
                                                    // core level semaphore.
  volatile UINT32    *PackageSemaphoreCount;        // Semaphore container used to program
                                                    // package level semaphore.
} PROGRAM_CPU_REGISTER_FLAGS;

//
// Signal that SMM BASE relocation is complete.
//
volatile BOOLEAN  mInitApsAfterSmmBaseReloc;

/**
  Get starting address and size of the rendezvous entry for APs.
  Information for fixing a jump instruction in the code is also returned.

  @param AddressMap  Output buffer for address map information.
**/
VOID *
EFIAPI
AsmGetAddressMap (
  MP_ASSEMBLY_ADDRESS_MAP  *AddressMap
  );

#define LEGACY_REGION_SIZE  (2 * 0x1000)
#define LEGACY_REGION_BASE  (0xA0000 - LEGACY_REGION_SIZE)

PROGRAM_CPU_REGISTER_FLAGS  mCpuFlags;
ACPI_CPU_DATA               mAcpiCpuData;
volatile UINT32             mNumberToFinish;
MP_CPU_EXCHANGE_INFO        *mExchangeInfo;
BOOLEAN                     mRestoreSmmConfigurationInS3 = FALSE;

//
// S3 boot flag
//
BOOLEAN  mSmmS3Flag = FALSE;

//
// Pointer to structure used during S3 Resume
//
SMM_S3_RESUME_STATE  *mSmmS3ResumeState = NULL;

BOOLEAN  mAcpiS3Enable = TRUE;

UINT8  *mApHltLoopCode          = NULL;
UINT8  mApHltLoopCodeTemplate[] = {
  0x8B, 0x44, 0x24, 0x04, // mov  eax, dword ptr [esp+4]
  0xF0, 0xFF, 0x08,       // lock dec  dword ptr [eax]
  0xFA,                   // cli
  0xF4,                   // hlt
  0xEB, 0xFC              // jmp $-2
};

/**
  Sync up the MTRR values for all processors.

  @param MtrrTable  Table holding fixed/variable MTRR values to be loaded.
**/
VOID
EFIAPI
LoadMtrrData (
  EFI_PHYSICAL_ADDRESS  MtrrTable
  )

/*++

Routine Description:

  Sync up the MTRR values for all processors.

Arguments:

Returns:
    None

--*/
{
  MTRR_SETTINGS  *MtrrSettings;

  MtrrSettings = (MTRR_SETTINGS *)(UINTN)MtrrTable;
  MtrrSetAllMtrrs (MtrrSettings);
}

/**
  Increment semaphore by 1.

  @param      Sem            IN:  32-bit unsigned integer

**/
VOID
S3ReleaseSemaphore (
  IN OUT  volatile UINT32  *Sem
  )
{
  InterlockedIncrement (Sem);
}

/**
  Decrement the semaphore by 1 if it is not zero.

  Performs an atomic decrement operation for semaphore.
  The compare exchange operation must be performed using
  MP safe mechanisms.

  @param      Sem            IN:  32-bit unsigned integer

**/
VOID
S3WaitForSemaphore (
  IN OUT  volatile UINT32  *Sem
  )
{
  UINT32  Value;

  do {
    Value = *Sem;
  } while (Value == 0 ||
           InterlockedCompareExchange32 (
             Sem,
             Value,
             Value - 1
             ) != Value);
}

/**
  Read / write CR value.

  @param[in]      CrIndex         The CR index which need to read/write.
  @param[in]      Read            Read or write. TRUE is read.
  @param[in,out]  CrValue         CR value.

  @retval    EFI_SUCCESS means read/write success, else return EFI_UNSUPPORTED.
**/
UINTN
ReadWriteCr (
  IN     UINT32   CrIndex,
  IN     BOOLEAN  Read,
  IN OUT UINTN    *CrValue
  )
{
  switch (CrIndex) {
    case 0:
      if (Read) {
        *CrValue = AsmReadCr0 ();
      } else {
        AsmWriteCr0 (*CrValue);
      }

      break;
    case 2:
      if (Read) {
        *CrValue = AsmReadCr2 ();
      } else {
        AsmWriteCr2 (*CrValue);
      }

      break;
    case 3:
      if (Read) {
        *CrValue = AsmReadCr3 ();
      } else {
        AsmWriteCr3 (*CrValue);
      }

      break;
    case 4:
      if (Read) {
        *CrValue = AsmReadCr4 ();
      } else {
        AsmWriteCr4 (*CrValue);
      }

      break;
    default:
      return EFI_UNSUPPORTED;
  }

  return EFI_SUCCESS;
}

/**
  Initialize the CPU registers from a register table.

  @param[in]  RegisterTable         The register table for this AP.
  @param[in]  ApLocation            AP location info for this ap.
  @param[in]  CpuStatus             CPU status info for this CPU.
  @param[in]  CpuFlags              Flags data structure used when program the register.

  @note This service could be called by BSP/APs.
**/
VOID
ProgramProcessorRegister (
  IN CPU_REGISTER_TABLE          *RegisterTable,
  IN EFI_CPU_PHYSICAL_LOCATION   *ApLocation,
  IN CPU_STATUS_INFORMATION      *CpuStatus,
  IN PROGRAM_CPU_REGISTER_FLAGS  *CpuFlags
  )
{
  CPU_REGISTER_TABLE_ENTRY  *RegisterTableEntry;
  UINTN                     Index;
  UINTN                     Value;
  CPU_REGISTER_TABLE_ENTRY  *RegisterTableEntryHead;
  volatile UINT32           *SemaphorePtr;
  UINT32                    FirstThread;
  UINT32                    CurrentThread;
  UINT32                    CurrentCore;
  UINTN                     ProcessorIndex;
  UINT32                    *ThreadCountPerPackage;
  UINT8                     *ThreadCountPerCore;
  EFI_STATUS                Status;
  UINT64                    CurrentValue;

  //
  // Traverse Register Table of this logical processor
  //
  RegisterTableEntryHead = (CPU_REGISTER_TABLE_ENTRY *)(UINTN)RegisterTable->RegisterTableEntry;

  for (Index = 0; Index < RegisterTable->TableLength; Index++) {
    RegisterTableEntry = &RegisterTableEntryHead[Index];

    //
    // Check the type of specified register
    //
    switch (RegisterTableEntry->RegisterType) {
      //
      // The specified register is Control Register
      //
      case ControlRegister:
        Status = ReadWriteCr (RegisterTableEntry->Index, TRUE, &Value);
        if (EFI_ERROR (Status)) {
          break;
        }

        if (RegisterTableEntry->TestThenWrite) {
          CurrentValue = BitFieldRead64 (
                           Value,
                           RegisterTableEntry->ValidBitStart,
                           RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1
                           );
          if (CurrentValue == RegisterTableEntry->Value) {
            break;
          }
        }

        Value = (UINTN)BitFieldWrite64 (
                         Value,
                         RegisterTableEntry->ValidBitStart,
                         RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
                         RegisterTableEntry->Value
                         );
        ReadWriteCr (RegisterTableEntry->Index, FALSE, &Value);
        break;
      //
      // The specified register is Model Specific Register
      //
      case Msr:
        if (RegisterTableEntry->TestThenWrite) {
          Value = (UINTN)AsmReadMsr64 (RegisterTableEntry->Index);
          if (RegisterTableEntry->ValidBitLength >= 64) {
            if (Value == RegisterTableEntry->Value) {
              break;
            }
          } else {
            CurrentValue = BitFieldRead64 (
                             Value,
                             RegisterTableEntry->ValidBitStart,
                             RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1
                             );
            if (CurrentValue == RegisterTableEntry->Value) {
              break;
            }
          }
        }

        //
        // If this function is called to restore register setting after INIT signal,
        // there is no need to restore MSRs in register table.
        //
        if (RegisterTableEntry->ValidBitLength >= 64) {
          //
          // If length is not less than 64 bits, then directly write without reading
          //
          AsmWriteMsr64 (
            RegisterTableEntry->Index,
            RegisterTableEntry->Value
            );
        } else {
          //
          // Set the bit section according to bit start and length
          //
          AsmMsrBitFieldWrite64 (
            RegisterTableEntry->Index,
            RegisterTableEntry->ValidBitStart,
            RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
            RegisterTableEntry->Value
            );
        }

        break;
      //
      // MemoryMapped operations
      //
      case MemoryMapped:
        AcquireSpinLock (&CpuFlags->MemoryMappedLock);
        MmioBitFieldWrite32 (
          (UINTN)(RegisterTableEntry->Index | LShiftU64 (RegisterTableEntry->HighIndex, 32)),
          RegisterTableEntry->ValidBitStart,
          RegisterTableEntry->ValidBitStart + RegisterTableEntry->ValidBitLength - 1,
          (UINT32)RegisterTableEntry->Value
          );
        ReleaseSpinLock (&CpuFlags->MemoryMappedLock);
        break;
      //
      // Enable or disable cache
      //
      case CacheControl:
        //
        // If value of the entry is 0, then disable cache.  Otherwise, enable cache.
        //
        if (RegisterTableEntry->Value == 0) {
          AsmDisableCache ();
        } else {
          AsmEnableCache ();
        }

        break;

      case Semaphore:
        // Semaphore works logic like below:
        //
        //  V(x) = LibReleaseSemaphore (Semaphore[FirstThread + x]);
        //  P(x) = LibWaitForSemaphore (Semaphore[FirstThread + x]);
        //
        //  All threads (T0...Tn) waits in P() line and continues running
        //  together.
        //
        //
        //  T0             T1            ...           Tn
        //
        //  V(0...n)       V(0...n)      ...           V(0...n)
        //  n * P(0)       n * P(1)      ...           n * P(n)
        //
        ASSERT (
          (ApLocation != NULL) &&
          (CpuStatus->ThreadCountPerPackage != 0) &&
          (CpuStatus->ThreadCountPerCore != 0) &&
          (CpuFlags->CoreSemaphoreCount != NULL) &&
          (CpuFlags->PackageSemaphoreCount != NULL)
          );
        switch (RegisterTableEntry->Value) {
          case CoreDepType:
            SemaphorePtr       = CpuFlags->CoreSemaphoreCount;
            ThreadCountPerCore = (UINT8 *)(UINTN)CpuStatus->ThreadCountPerCore;

            CurrentCore = ApLocation->Package * CpuStatus->MaxCoreCount + ApLocation->Core;
            //
            // Get Offset info for the first thread in the core which current thread belongs to.
            //
            FirstThread   = CurrentCore * CpuStatus->MaxThreadCount;
            CurrentThread = FirstThread + ApLocation->Thread;

            //
            // Different cores may have different valid threads in them. If driver maintail clearly
            // thread index in different cores, the logic will be much complicated.
            // Here driver just simply records the max thread number in all cores and use it as expect
            // thread number for all cores.
            // In below two steps logic, first current thread will Release semaphore for each thread
            // in current core. Maybe some threads are not valid in this core, but driver don't
            // care. Second, driver will let current thread wait semaphore for all valid threads in
            // current core. Because only the valid threads will do release semaphore for this
            // thread, driver here only need to wait the valid thread count.
            //

            //
            // First Notify ALL THREADs in current Core that this thread is ready.
            //
            for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount; ProcessorIndex++) {
              S3ReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);
            }

            //
            // Second, check whether all VALID THREADs (not all threads) in current core are ready.
            //
            for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerCore[CurrentCore]; ProcessorIndex++) {
              S3WaitForSemaphore (&SemaphorePtr[CurrentThread]);
            }

            break;

          case PackageDepType:
            SemaphorePtr          = CpuFlags->PackageSemaphoreCount;
            ThreadCountPerPackage = (UINT32 *)(UINTN)CpuStatus->ThreadCountPerPackage;
            //
            // Get Offset info for the first thread in the package which current thread belongs to.
            //
            FirstThread = ApLocation->Package * CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount;
            //
            // Get the possible threads count for current package.
            //
            CurrentThread = FirstThread + CpuStatus->MaxThreadCount * ApLocation->Core + ApLocation->Thread;

            //
            // Different packages may have different valid threads in them. If driver maintail clearly
            // thread index in different packages, the logic will be much complicated.
            // Here driver just simply records the max thread number in all packages and use it as expect
            // thread number for all packages.
            // In below two steps logic, first current thread will Release semaphore for each thread
            // in current package. Maybe some threads are not valid in this package, but driver don't
            // care. Second, driver will let current thread wait semaphore for all valid threads in
            // current package. Because only the valid threads will do release semaphore for this
            // thread, driver here only need to wait the valid thread count.
            //

            //
            // First Notify ALL THREADS in current package that this thread is ready.
            //
            for (ProcessorIndex = 0; ProcessorIndex < CpuStatus->MaxThreadCount * CpuStatus->MaxCoreCount; ProcessorIndex++) {
              S3ReleaseSemaphore (&SemaphorePtr[FirstThread + ProcessorIndex]);
            }

            //
            // Second, check whether VALID THREADS (not all threads) in current package are ready.
            //
            for (ProcessorIndex = 0; ProcessorIndex < ThreadCountPerPackage[ApLocation->Package]; ProcessorIndex++) {
              S3WaitForSemaphore (&SemaphorePtr[CurrentThread]);
            }

            break;

          default:
            break;
        }

        break;

      default:
        break;
    }
  }
}

/**

  Set Processor register for one AP.

  @param     PreSmmRegisterTable     Use pre Smm register table or register table.

**/
VOID
SetRegister (
  IN BOOLEAN  PreSmmRegisterTable
  )
{
  CPU_FEATURE_INIT_DATA  *FeatureInitData;
  CPU_REGISTER_TABLE     *RegisterTable;
  CPU_REGISTER_TABLE     *RegisterTables;
  UINT32                 InitApicId;
  UINTN                  ProcIndex;
  UINTN                  Index;

  FeatureInitData = &mAcpiCpuData.CpuFeatureInitData;

  if (PreSmmRegisterTable) {
    RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)FeatureInitData->PreSmmInitRegisterTable;
  } else {
    RegisterTables = (CPU_REGISTER_TABLE *)(UINTN)FeatureInitData->RegisterTable;
  }

  if (RegisterTables == NULL) {
    return;
  }

  InitApicId    = GetInitialApicId ();
  RegisterTable = NULL;
  ProcIndex     = (UINTN)-1;
  for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {
    if (RegisterTables[Index].InitialApicId == InitApicId) {
      RegisterTable = &RegisterTables[Index];
      ProcIndex     = Index;
      break;
    }
  }

  ASSERT (RegisterTable != NULL);

  if (FeatureInitData->ApLocation != 0) {
    ProgramProcessorRegister (
      RegisterTable,
      (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)FeatureInitData->ApLocation + ProcIndex,
      &FeatureInitData->CpuStatus,
      &mCpuFlags
      );
  } else {
    ProgramProcessorRegister (
      RegisterTable,
      NULL,
      &FeatureInitData->CpuStatus,
      &mCpuFlags
      );
  }
}

/**
  The function is invoked before SMBASE relocation in S3 path to restores CPU status.

  The function is invoked before SMBASE relocation in S3 path. It does first time microcode load
  and restores MTRRs for both BSP and APs.

  @param   IsBsp   The CPU this function executes on is BSP or not.

**/
VOID
InitializeCpuBeforeRebase (
  IN BOOLEAN  IsBsp
  )
{
  LoadMtrrData (mAcpiCpuData.MtrrTable);

  SetRegister (TRUE);

  ProgramVirtualWireMode ();
  if (!IsBsp) {
    DisableLvtInterrupts ();
  }

  //
  // Count down the number with lock mechanism.
  //
  InterlockedDecrement (&mNumberToFinish);

  if (IsBsp) {
    //
    // Bsp wait here till all AP finish the initialization before rebase
    //
    while (mNumberToFinish > 0) {
      CpuPause ();
    }
  }
}

/**
  The function is invoked after SMBASE relocation in S3 path to restores CPU status.

  The function is invoked after SMBASE relocation in S3 path. It restores configuration according to
  data saved by normal boot path for both BSP and APs.

  @param   IsBsp   The CPU this function executes on is BSP or not.

**/
VOID
InitializeCpuAfterRebase (
  IN BOOLEAN  IsBsp
  )
{
  UINTN  TopOfStack;
  UINT8  Stack[128];

  SetRegister (FALSE);

  if (mSmmS3ResumeState->MpService2Ppi == 0) {
    if (IsBsp) {
      while (mNumberToFinish > 0) {
        CpuPause ();
      }
    } else {
      //
      // Place AP into the safe code, count down the number with lock mechanism in the safe code.
      //
      TopOfStack  = (UINTN)Stack + sizeof (Stack);
      TopOfStack &= ~(UINTN)(CPU_STACK_ALIGNMENT - 1);
      CopyMem ((VOID *)(UINTN)mApHltLoopCode, mApHltLoopCodeTemplate, sizeof (mApHltLoopCodeTemplate));
      TransferApToSafeState ((UINTN)mApHltLoopCode, TopOfStack, (UINTN)&mNumberToFinish);
    }
  }
}

/**
  Cpu initialization procedure.

  @param[in,out] Buffer  The pointer to private data buffer.

**/
VOID
EFIAPI
InitializeCpuProcedure (
  IN OUT VOID  *Buffer
  )
{
  BOOLEAN  IsBsp;

  IsBsp =  (BOOLEAN)(mBspApicId == GetApicId ());

  //
  // Skip initialization if mAcpiCpuData is not valid
  //
  if (mAcpiCpuData.NumberOfCpus > 0) {
    //
    // First time microcode load and restore MTRRs
    //
    InitializeCpuBeforeRebase (IsBsp);
  }

  if (IsBsp) {
    DEBUG ((DEBUG_INFO, "SmmRestoreCpu: mSmmRelocated is %d\n", mSmmRelocated));

    //
    // Check whether Smm Relocation is done or not.
    // If not, will do the SmmBases Relocation here!!!
    //
    if (!mSmmRelocated) {
      //
      // Restore SMBASE for BSP and all APs
      //
      SmmRelocateBases ();
    } else {
      //
      // Issue SMI IPI (All Excluding  Self SMM IPI + BSP SMM IPI) to execute first SMI init.
      //
      ExecuteFirstSmiInit ();
    }
  }

  //
  // Skip initialization if mAcpiCpuData is not valid
  //
  if (mAcpiCpuData.NumberOfCpus > 0) {
    if (IsBsp) {
      //
      // mNumberToFinish should be set before AP executes InitializeCpuAfterRebase()
      //
      mNumberToFinish = (UINT32)(mNumberOfCpus - 1);
      //
      // Signal that SMM base relocation is complete and to continue initialization for all APs.
      //
      mInitApsAfterSmmBaseReloc = TRUE;
    } else {
      //
      // AP Wait for BSP to signal SMM Base relocation done.
      //
      while (!mInitApsAfterSmmBaseReloc) {
        CpuPause ();
      }
    }

    //
    // Restore MSRs for BSP and all APs
    //
    InitializeCpuAfterRebase (IsBsp);
  }
}

/**
  Prepares startup vector for APs.

  This function prepares startup vector for APs.

  @param  WorkingBuffer  The address of the work buffer.
**/
VOID
PrepareApStartupVector (
  EFI_PHYSICAL_ADDRESS  WorkingBuffer
  )
{
  EFI_PHYSICAL_ADDRESS     StartupVector;
  MP_ASSEMBLY_ADDRESS_MAP  AddressMap;

  //
  // Get the address map of startup code for AP,
  // including code size, and offset of long jump instructions to redirect.
  //
  ZeroMem (&AddressMap, sizeof (AddressMap));
  AsmGetAddressMap (&AddressMap);

  StartupVector = WorkingBuffer;

  //
  // Copy AP startup code to startup vector, and then redirect the long jump
  // instructions for mode switching.
  //
  CopyMem ((VOID *)(UINTN)StartupVector, AddressMap.RendezvousFunnelAddress, AddressMap.Size);
  *(UINT32 *)(UINTN)(StartupVector + AddressMap.FlatJumpOffset + 3) = (UINT32)(StartupVector + AddressMap.PModeEntryOffset);
  if (AddressMap.LongJumpOffset != 0) {
    *(UINT32 *)(UINTN)(StartupVector + AddressMap.LongJumpOffset + 2) = (UINT32)(StartupVector + AddressMap.LModeEntryOffset);
  }

  //
  // Get the start address of exchange data between BSP and AP.
  //
  mExchangeInfo = (MP_CPU_EXCHANGE_INFO *)(UINTN)(StartupVector + AddressMap.Size);
  ZeroMem ((VOID *)mExchangeInfo, sizeof (MP_CPU_EXCHANGE_INFO));

  CopyMem ((VOID *)(UINTN)&mExchangeInfo->GdtrProfile, (VOID *)(UINTN)mAcpiCpuData.GdtrProfile, sizeof (IA32_DESCRIPTOR));
  CopyMem ((VOID *)(UINTN)&mExchangeInfo->IdtrProfile, (VOID *)(UINTN)mAcpiCpuData.IdtrProfile, sizeof (IA32_DESCRIPTOR));

  mExchangeInfo->StackStart                          = (VOID *)(UINTN)mAcpiCpuData.StackAddress;
  mExchangeInfo->StackSize                           = mAcpiCpuData.StackSize;
  mExchangeInfo->BufferStart                         = (UINT32)StartupVector;
  mExchangeInfo->Cr3                                 = (UINT32)(AsmReadCr3 ());
  mExchangeInfo->InitializeFloatingPointUnitsAddress = (UINTN)InitializeFloatingPointUnits;
  mExchangeInfo->ApFunction                          = (VOID *)(UINTN)InitializeCpuProcedure;
}

/**
  Restore SMM Configuration in S3 boot path.

**/
VOID
RestoreSmmConfigurationInS3 (
  VOID
  )
{
  if (!mAcpiS3Enable) {
    return;
  }

  //
  // Restore SMM Configuration in S3 boot path.
  //
  if (mRestoreSmmConfigurationInS3) {
    //
    // Need make sure gSmst is correct because below function may use them.
    //
    gSmst->SmmStartupThisAp      = gSmmCpuPrivate->SmmCoreEntryContext.SmmStartupThisAp;
    gSmst->CurrentlyExecutingCpu = gSmmCpuPrivate->SmmCoreEntryContext.CurrentlyExecutingCpu;
    gSmst->NumberOfCpus          = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus;
    gSmst->CpuSaveStateSize      = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveStateSize;
    gSmst->CpuSaveState          = gSmmCpuPrivate->SmmCoreEntryContext.CpuSaveState;

    //
    // Configure SMM Code Access Check feature if available.
    //
    ConfigSmmCodeAccessCheck ();

    SmmCpuFeaturesCompleteSmmReadyToLock ();

    mRestoreSmmConfigurationInS3 = FALSE;
  }
}

/**
  Perform SMM initialization for all processors in the S3 boot path.

  For a native platform, MP initialization in the S3 boot path is also performed in this function.
**/
VOID
EFIAPI
SmmRestoreCpu (
  VOID
  )
{
  SMM_S3_RESUME_STATE         *SmmS3ResumeState;
  IA32_DESCRIPTOR             Ia32Idtr;
  IA32_DESCRIPTOR             X64Idtr;
  IA32_IDT_GATE_DESCRIPTOR    IdtEntryTable[EXCEPTION_VECTOR_NUMBER];
  EFI_STATUS                  Status;
  EDKII_PEI_MP_SERVICES2_PPI  *Mp2ServicePpi;

  DEBUG ((DEBUG_INFO, "SmmRestoreCpu()\n"));

  mSmmS3Flag = TRUE;

  //
  // See if there is enough context to resume PEI Phase
  //
  if (mSmmS3ResumeState == NULL) {
    DEBUG ((DEBUG_ERROR, "No context to return to PEI Phase\n"));
    CpuDeadLoop ();
  }

  SmmS3ResumeState = mSmmS3ResumeState;
  ASSERT (SmmS3ResumeState != NULL);

  //
  // Setup 64bit IDT in 64bit SMM env when called from 32bit PEI.
  // Note: 64bit PEI and 32bit DXE is not a supported combination.
  //
  if ((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) && (FeaturePcdGet (PcdDxeIplSwitchToLongMode) == TRUE)) {
    //
    // Save the IA32 IDT Descriptor
    //
    AsmReadIdtr ((IA32_DESCRIPTOR *)&Ia32Idtr);

    //
    // Setup X64 IDT table
    //
    ZeroMem (IdtEntryTable, sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32);
    X64Idtr.Base  = (UINTN)IdtEntryTable;
    X64Idtr.Limit = (UINT16)(sizeof (IA32_IDT_GATE_DESCRIPTOR) * 32 - 1);
    AsmWriteIdtr ((IA32_DESCRIPTOR *)&X64Idtr);

    //
    // Setup the default exception handler
    //
    Status = InitializeCpuExceptionHandlers (NULL);
    ASSERT_EFI_ERROR (Status);

    //
    // Initialize Debug Agent to support source level debug
    //
    InitializeDebugAgent (DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64, (VOID *)&Ia32Idtr, NULL);
  }

  mBspApicId = GetApicId ();
  //
  // Skip AP initialization if mAcpiCpuData is not valid
  //
  if (mAcpiCpuData.NumberOfCpus > 0) {
    if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
      ASSERT (mNumberOfCpus <= mAcpiCpuData.NumberOfCpus);
    } else {
      ASSERT (mNumberOfCpus == mAcpiCpuData.NumberOfCpus);
    }

    mNumberToFinish = (UINT32)mNumberOfCpus;

    //
    // Execute code for before SmmBaseReloc. Note: This flag is maintained across S3 boots.
    //
    mInitApsAfterSmmBaseReloc = FALSE;

    if (mSmmS3ResumeState->MpService2Ppi != 0) {
      Mp2ServicePpi = (EDKII_PEI_MP_SERVICES2_PPI *)(UINTN)mSmmS3ResumeState->MpService2Ppi;
      Mp2ServicePpi->StartupAllCPUs (Mp2ServicePpi, InitializeCpuProcedure, 0, NULL);
    } else {
      PrepareApStartupVector (mAcpiCpuData.StartupVector);
      //
      // Send INIT IPI - SIPI to all APs
      //
      SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);
      InitializeCpuProcedure (NULL);
    }
  } else {
    InitializeCpuProcedure (NULL);
  }

  //
  // Set a flag to restore SMM configuration in S3 path.
  //
  mRestoreSmmConfigurationInS3 = TRUE;

  DEBUG ((DEBUG_INFO, "SMM S3 Return CS                = %x\n", SmmS3ResumeState->ReturnCs));
  DEBUG ((DEBUG_INFO, "SMM S3 Return Entry Point       = %x\n", SmmS3ResumeState->ReturnEntryPoint));
  DEBUG ((DEBUG_INFO, "SMM S3 Return Context1          = %x\n", SmmS3ResumeState->ReturnContext1));
  DEBUG ((DEBUG_INFO, "SMM S3 Return Context2          = %x\n", SmmS3ResumeState->ReturnContext2));
  DEBUG ((DEBUG_INFO, "SMM S3 Return Stack Pointer     = %x\n", SmmS3ResumeState->ReturnStackPointer));

  //
  // If SMM is in 32-bit mode or PcdDxeIplSwitchToLongMode is FALSE, then use SwitchStack() to resume PEI Phase.
  // Note: 64bit PEI and 32bit DXE is not a supported combination.
  //
  if ((SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_32) || (FeaturePcdGet (PcdDxeIplSwitchToLongMode) == FALSE)) {
    DEBUG ((DEBUG_INFO, "Call SwitchStack() to return to S3 Resume in PEI Phase\n"));

    SwitchStack (
      (SWITCH_STACK_ENTRY_POINT)(UINTN)SmmS3ResumeState->ReturnEntryPoint,
      (VOID *)(UINTN)SmmS3ResumeState->ReturnContext1,
      (VOID *)(UINTN)SmmS3ResumeState->ReturnContext2,
      (VOID *)(UINTN)SmmS3ResumeState->ReturnStackPointer
      );
  }

  //
  // If SMM is in 64-bit mode, then use AsmDisablePaging64() to resume PEI Phase
  //
  if (SmmS3ResumeState->Signature == SMM_S3_RESUME_SMM_64) {
    DEBUG ((DEBUG_INFO, "Call AsmDisablePaging64() to return to S3 Resume in PEI Phase\n"));
    //
    // Disable interrupt of Debug timer, since new IDT table is for IA32 and will not work in long mode.
    //
    SaveAndSetDebugTimerInterrupt (FALSE);
    //
    // Restore IA32 IDT table
    //
    AsmWriteIdtr ((IA32_DESCRIPTOR *)&Ia32Idtr);
    AsmDisablePaging64 (
      SmmS3ResumeState->ReturnCs,
      (UINT32)SmmS3ResumeState->ReturnEntryPoint,
      (UINT32)SmmS3ResumeState->ReturnContext1,
      (UINT32)SmmS3ResumeState->ReturnContext2,
      (UINT32)SmmS3ResumeState->ReturnStackPointer
      );
  }

  //
  // Can not resume PEI Phase
  //
  DEBUG ((DEBUG_ERROR, "No context to return to PEI Phase\n"));
  CpuDeadLoop ();
}

/**
  Initialize SMM S3 resume state structure used during S3 Resume.

  @param[in] Cr3    The base address of the page tables to use in SMM.

**/
VOID
InitSmmS3ResumeState (
  IN UINT32  Cr3
  )
{
  VOID                  *GuidHob;
  EFI_SMRAM_DESCRIPTOR  *SmramDescriptor;
  SMM_S3_RESUME_STATE   *SmmS3ResumeState;
  EFI_PHYSICAL_ADDRESS  Address;
  EFI_STATUS            Status;

  if (!mAcpiS3Enable) {
    return;
  }

  GuidHob = GetFirstGuidHob (&gEfiAcpiVariableGuid);
  if (GuidHob == NULL) {
    DEBUG ((
      DEBUG_ERROR,
      "ERROR:%a(): HOB(gEfiAcpiVariableGuid=%g) needed by S3 resume doesn't exist!\n",
      __func__,
      &gEfiAcpiVariableGuid
      ));
    CpuDeadLoop ();
  } else {
    SmramDescriptor = (EFI_SMRAM_DESCRIPTOR *)GET_GUID_HOB_DATA (GuidHob);

    DEBUG ((DEBUG_INFO, "SMM S3 SMRAM Structure = %x\n", SmramDescriptor));
    DEBUG ((DEBUG_INFO, "SMM S3 Structure = %x\n", SmramDescriptor->CpuStart));

    SmmS3ResumeState = (SMM_S3_RESUME_STATE *)(UINTN)SmramDescriptor->CpuStart;
    ZeroMem (SmmS3ResumeState, sizeof (SMM_S3_RESUME_STATE));

    mSmmS3ResumeState      = SmmS3ResumeState;
    SmmS3ResumeState->Smst = (EFI_PHYSICAL_ADDRESS)(UINTN)gSmst;

    SmmS3ResumeState->SmmS3ResumeEntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)SmmRestoreCpu;

    SmmS3ResumeState->SmmS3StackSize = SIZE_32KB;
    SmmS3ResumeState->SmmS3StackBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePages (EFI_SIZE_TO_PAGES ((UINTN)SmmS3ResumeState->SmmS3StackSize));
    if (SmmS3ResumeState->SmmS3StackBase == 0) {
      SmmS3ResumeState->SmmS3StackSize = 0;
    }

    SmmS3ResumeState->SmmS3Cr0 = mSmmCr0;
    SmmS3ResumeState->SmmS3Cr3 = Cr3;
    SmmS3ResumeState->SmmS3Cr4 = mSmmCr4;

    if (sizeof (UINTN) == sizeof (UINT64)) {
      SmmS3ResumeState->Signature = SMM_S3_RESUME_SMM_64;
    }

    if (sizeof (UINTN) == sizeof (UINT32)) {
      SmmS3ResumeState->Signature = SMM_S3_RESUME_SMM_32;
    }

    //
    // Patch SmmS3ResumeState->SmmS3Cr3
    //
    InitSmmS3Cr3 ();
  }

  //
  // Allocate safe memory in ACPI NVS for AP to execute hlt loop in
  // protected mode on S3 path
  //
  Address = BASE_4GB - 1;
  Status  = gBS->AllocatePages (
                   AllocateMaxAddress,
                   EfiACPIMemoryNVS,
                   EFI_SIZE_TO_PAGES (sizeof (mApHltLoopCodeTemplate)),
                   &Address
                   );
  ASSERT_EFI_ERROR (Status);
  mApHltLoopCode = (UINT8 *)(UINTN)Address;
}

/**
  Copy register table from non-SMRAM into SMRAM.

  @param[in] DestinationRegisterTableList  Points to destination register table.
  @param[in] SourceRegisterTableList       Points to source register table.
  @param[in] NumberOfCpus                  Number of CPUs.

**/
VOID
CopyRegisterTable (
  IN CPU_REGISTER_TABLE  *DestinationRegisterTableList,
  IN CPU_REGISTER_TABLE  *SourceRegisterTableList,
  IN UINT32              NumberOfCpus
  )
{
  UINTN                     Index;
  CPU_REGISTER_TABLE_ENTRY  *RegisterTableEntry;

  CopyMem (DestinationRegisterTableList, SourceRegisterTableList, NumberOfCpus * sizeof (CPU_REGISTER_TABLE));
  for (Index = 0; Index < NumberOfCpus; Index++) {
    if (DestinationRegisterTableList[Index].TableLength != 0) {
      DestinationRegisterTableList[Index].AllocatedSize = DestinationRegisterTableList[Index].TableLength * sizeof (CPU_REGISTER_TABLE_ENTRY);
      RegisterTableEntry                                = AllocateCopyPool (
                                                            DestinationRegisterTableList[Index].AllocatedSize,
                                                            (VOID *)(UINTN)SourceRegisterTableList[Index].RegisterTableEntry
                                                            );
      ASSERT (RegisterTableEntry != NULL);
      DestinationRegisterTableList[Index].RegisterTableEntry = (EFI_PHYSICAL_ADDRESS)(UINTN)RegisterTableEntry;
    }
  }
}

/**
  Check whether the register table is empty or not.

  @param[in] RegisterTable  Point to the register table.
  @param[in] NumberOfCpus   Number of CPUs.

  @retval TRUE              The register table is empty.
  @retval FALSE             The register table is not empty.
**/
BOOLEAN
IsRegisterTableEmpty (
  IN CPU_REGISTER_TABLE  *RegisterTable,
  IN UINT32              NumberOfCpus
  )
{
  UINTN  Index;

  if (RegisterTable != NULL) {
    for (Index = 0; Index < NumberOfCpus; Index++) {
      if (RegisterTable[Index].TableLength != 0) {
        return FALSE;
      }
    }
  }

  return TRUE;
}

/**
  Copy the data used to initialize processor register into SMRAM.

  @param[in,out]  CpuFeatureInitDataDst   Pointer to the destination CPU_FEATURE_INIT_DATA structure.
  @param[in]      CpuFeatureInitDataSrc   Pointer to the source CPU_FEATURE_INIT_DATA structure.

**/
VOID
CopyCpuFeatureInitDatatoSmram (
  IN OUT CPU_FEATURE_INIT_DATA  *CpuFeatureInitDataDst,
  IN     CPU_FEATURE_INIT_DATA  *CpuFeatureInitDataSrc
  )
{
  CPU_STATUS_INFORMATION  *CpuStatus;

  if (!IsRegisterTableEmpty ((CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->PreSmmInitRegisterTable, mAcpiCpuData.NumberOfCpus)) {
    CpuFeatureInitDataDst->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE));
    ASSERT (CpuFeatureInitDataDst->PreSmmInitRegisterTable != 0);

    CopyRegisterTable (
      (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataDst->PreSmmInitRegisterTable,
      (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->PreSmmInitRegisterTable,
      mAcpiCpuData.NumberOfCpus
      );
  }

  if (!IsRegisterTableEmpty ((CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->RegisterTable, mAcpiCpuData.NumberOfCpus)) {
    CpuFeatureInitDataDst->RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE));
    ASSERT (CpuFeatureInitDataDst->RegisterTable != 0);

    CopyRegisterTable (
      (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataDst->RegisterTable,
      (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->RegisterTable,
      mAcpiCpuData.NumberOfCpus
      );
  }

  CpuStatus = &CpuFeatureInitDataDst->CpuStatus;
  CopyMem (CpuStatus, &CpuFeatureInitDataSrc->CpuStatus, sizeof (CPU_STATUS_INFORMATION));

  if (CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerPackage != 0) {
    CpuStatus->ThreadCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool (
                                                                      sizeof (UINT32) * CpuStatus->PackageCount,
                                                                      (UINT32 *)(UINTN)CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerPackage
                                                                      );
    ASSERT (CpuStatus->ThreadCountPerPackage != 0);
  }

  if (CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerCore != 0) {
    CpuStatus->ThreadCountPerCore = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool (
                                                                   sizeof (UINT8) * (CpuStatus->PackageCount * CpuStatus->MaxCoreCount),
                                                                   (UINT32 *)(UINTN)CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerCore
                                                                   );
    ASSERT (CpuStatus->ThreadCountPerCore != 0);
  }

  if (CpuFeatureInitDataSrc->ApLocation != 0) {
    CpuFeatureInitDataDst->ApLocation = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool (
                                                                       mAcpiCpuData.NumberOfCpus * sizeof (EFI_CPU_PHYSICAL_LOCATION),
                                                                       (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)CpuFeatureInitDataSrc->ApLocation
                                                                       );
    ASSERT (CpuFeatureInitDataDst->ApLocation != 0);
  }
}

/**
  Get ACPI CPU data.

**/
VOID
GetAcpiCpuData (
  VOID
  )
{
  ACPI_CPU_DATA           *AcpiCpuData;
  IA32_DESCRIPTOR         *Gdtr;
  IA32_DESCRIPTOR         *Idtr;
  VOID                    *GdtForAp;
  VOID                    *IdtForAp;
  VOID                    *MachineCheckHandlerForAp;
  CPU_STATUS_INFORMATION  *CpuStatus;

  if (!mAcpiS3Enable) {
    return;
  }

  //
  // Prevent use of mAcpiCpuData by initialize NumberOfCpus to 0
  //
  mAcpiCpuData.NumberOfCpus = 0;

  //
  // If PcdCpuS3DataAddress was never set, then do not copy CPU S3 Data into SMRAM
  //
  AcpiCpuData = (ACPI_CPU_DATA *)(UINTN)PcdGet64 (PcdCpuS3DataAddress);
  if (AcpiCpuData == 0) {
    return;
  }

  //
  // For a native platform, copy the CPU S3 data into SMRAM for use on CPU S3 Resume.
  //
  CopyMem (&mAcpiCpuData, AcpiCpuData, sizeof (mAcpiCpuData));

  mAcpiCpuData.MtrrTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (MTRR_SETTINGS));
  ASSERT (mAcpiCpuData.MtrrTable != 0);

  CopyMem ((VOID *)(UINTN)mAcpiCpuData.MtrrTable, (VOID *)(UINTN)AcpiCpuData->MtrrTable, sizeof (MTRR_SETTINGS));

  mAcpiCpuData.GdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (IA32_DESCRIPTOR));
  ASSERT (mAcpiCpuData.GdtrProfile != 0);

  CopyMem ((VOID *)(UINTN)mAcpiCpuData.GdtrProfile, (VOID *)(UINTN)AcpiCpuData->GdtrProfile, sizeof (IA32_DESCRIPTOR));

  mAcpiCpuData.IdtrProfile = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (sizeof (IA32_DESCRIPTOR));
  ASSERT (mAcpiCpuData.IdtrProfile != 0);

  CopyMem ((VOID *)(UINTN)mAcpiCpuData.IdtrProfile, (VOID *)(UINTN)AcpiCpuData->IdtrProfile, sizeof (IA32_DESCRIPTOR));

  //
  // Copy AP's GDT, IDT and Machine Check handler into SMRAM.
  //
  Gdtr = (IA32_DESCRIPTOR *)(UINTN)mAcpiCpuData.GdtrProfile;
  Idtr = (IA32_DESCRIPTOR *)(UINTN)mAcpiCpuData.IdtrProfile;

  GdtForAp = AllocatePool ((Gdtr->Limit + 1) + (Idtr->Limit + 1) + mAcpiCpuData.ApMachineCheckHandlerSize);
  ASSERT (GdtForAp != NULL);
  IdtForAp                 = (VOID *)((UINTN)GdtForAp + (Gdtr->Limit + 1));
  MachineCheckHandlerForAp = (VOID *)((UINTN)IdtForAp + (Idtr->Limit + 1));

  CopyMem (GdtForAp, (VOID *)Gdtr->Base, Gdtr->Limit + 1);
  CopyMem (IdtForAp, (VOID *)Idtr->Base, Idtr->Limit + 1);
  CopyMem (MachineCheckHandlerForAp, (VOID *)(UINTN)mAcpiCpuData.ApMachineCheckHandlerBase, mAcpiCpuData.ApMachineCheckHandlerSize);

  Gdtr->Base                             = (UINTN)GdtForAp;
  Idtr->Base                             = (UINTN)IdtForAp;
  mAcpiCpuData.ApMachineCheckHandlerBase = (EFI_PHYSICAL_ADDRESS)(UINTN)MachineCheckHandlerForAp;

  ZeroMem (&mAcpiCpuData.CpuFeatureInitData, sizeof (CPU_FEATURE_INIT_DATA));

  if (!PcdGetBool (PcdCpuFeaturesInitOnS3Resume)) {
    //
    // If the CPU features will not be initialized by CpuFeaturesPei module during
    // next ACPI S3 resume, copy the CPU features initialization data into SMRAM,
    // which will be consumed in SmmRestoreCpu during next S3 resume.
    //
    CopyCpuFeatureInitDatatoSmram (&mAcpiCpuData.CpuFeatureInitData, &AcpiCpuData->CpuFeatureInitData);

    CpuStatus = &mAcpiCpuData.CpuFeatureInitData.CpuStatus;

    mCpuFlags.CoreSemaphoreCount = AllocateZeroPool (
                                     sizeof (UINT32) * CpuStatus->PackageCount *
                                     CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount
                                     );
    ASSERT (mCpuFlags.CoreSemaphoreCount != NULL);

    mCpuFlags.PackageSemaphoreCount = AllocateZeroPool (
                                        sizeof (UINT32) * CpuStatus->PackageCount *
                                        CpuStatus->MaxCoreCount * CpuStatus->MaxThreadCount
                                        );
    ASSERT (mCpuFlags.PackageSemaphoreCount != NULL);

    InitializeSpinLock ((SPIN_LOCK *)&mCpuFlags.MemoryMappedLock);
  }
}

/**
  Get ACPI S3 enable flag.

**/
VOID
GetAcpiS3EnableFlag (
  VOID
  )
{
  mAcpiS3Enable = PcdGetBool (PcdAcpiS3Enable);
}
