/** @file
  Save the S3 data to S3 boot script.

  Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/
#include "InternalBootScriptLib.h"

/**

  Data structure usage:

  +------------------------------+<------- PcdS3BootScriptTablePrivateDataPtr
  | SCRIPT_TABLE_PRIVATE_DATA    |          (mS3BootScriptTablePtr, Before SmmReadyToLock)
  |    TableBase                 |---      PcdS3BootScriptTablePrivateSmmDataPtr
  |    TableLength               |--|--     (mS3BootScriptTablePtr = mS3BootScriptTableSmmPtr, After SmmReadyToLock InSmm)
  |    TableMemoryPageNumber     |--|-|----
  |    AtRuntime                 |  | |   |
  |    InSmm                     |  | |   |
  |    BootTimeScriptLength      |--|-|---|---
  |    SmmLocked                 |  | |   |  |
  |    BackFromS3                |  | |   |  |
  +------------------------------+  | |   |  |
                                    | |   |  |
  +------------------------------+<-- |   |  |
  | EFI_BOOT_SCRIPT_TABLE_HEADER |    |   |  |
  |    TableLength               |----|-- |  |
  +------------------------------+    | | |  |
  |     ......                   |    | | |  |
  +------------------------------+<---- | |  |
  | EFI_BOOT_SCRIPT_TERMINATE    |      | |  |
  +------------------------------+<------ |  |
                                          |  |
                                          |  |
  mBootScriptDataBootTimeGuid LockBox:    |  |
   Used to restore data after back from S3|  |
   to handle potential INSERT boot script |  |
   at runtime.                            |  |
  +------------------------------+        |  |
  | Boot Time Boot Script        |        |  |
  | Before SmmReadyToLock        |        |  |
  |                              |        |  |
  |                              |        |  |
  +------------------------------+        |  |
  | Boot Time Boot Script        |        |  |
  | After SmmReadyToLock InSmm   |        |  |
  |                              |        |  |
  +------------------------------+<-------|--|
                                          |  |
                                          |  |
  mBootScriptDataGuid LockBox: (IN_PLACE) |  |
   Used to restore data at S3 resume.     |  |
  +------------------------------+        |  |
  | Boot Time Boot Script        |        |  |
  | Before SmmReadyToLock        |        |  |
  |                              |        |  |
  |                              |        |  |
  +------------------------------+        |  |
  | Boot Time Boot Script        |        |  |
  | After SmmReadyToLock InSmm   |        |  |
  |                              |        |  |
  +------------------------------+<-------|---
  | Runtime Boot Script          |        |
  | After SmmReadyToLock InSmm   |        |
  +------------------------------+        |
  |     ......                   |        |
  +------------------------------+<--------


  mBootScriptTableBaseGuid LockBox: (IN_PLACE)
  +------------------------------+
  | mS3BootScriptTablePtr->      |
  |  TableBase                   |
  +------------------------------+


  mBootScriptSmmPrivateDataGuid LockBox: (IN_PLACE)
   SMM private data with BackFromS3 = TRUE
   at runtime. S3 will help restore it to
   tell the Library the system is back from S3.
  +------------------------------+
  | SCRIPT_TABLE_PRIVATE_DATA    |
  |    TableBase                 |
  |    TableLength               |
  |    TableMemoryPageNumber     |
  |    AtRuntime                 |
  |    InSmm                     |
  |    BootTimeScriptLength      |
  |    SmmLocked                 |
  |    BackFromS3 = TRUE         |
  +------------------------------+

**/

SCRIPT_TABLE_PRIVATE_DATA  *mS3BootScriptTablePtr;

//
// Allocate SMM copy because we can not use mS3BootScriptTablePtr after SmmReadyToLock in InSmm.
//
SCRIPT_TABLE_PRIVATE_DATA  *mS3BootScriptTableSmmPtr;

EFI_GUID  mBootScriptDataGuid = {
  0xaea6b965, 0xdcf5, 0x4311, { 0xb4, 0xb8, 0xf, 0x12, 0x46, 0x44, 0x94, 0xd2 }
};

EFI_GUID  mBootScriptDataBootTimeGuid = {
  0xb5af1d7a, 0xb8cf, 0x4eb3, { 0x89, 0x25, 0xa8, 0x20, 0xe1, 0x6b, 0x68, 0x7d }
};

EFI_GUID  mBootScriptTableBaseGuid = {
  0x1810ab4a, 0x2314, 0x4df6, { 0x81, 0xeb, 0x67, 0xc6, 0xec, 0x5, 0x85, 0x91 }
};

EFI_GUID  mBootScriptSmmPrivateDataGuid = {
  0x627ee2da, 0x3bf9, 0x439b, { 0x92, 0x9f, 0x2e, 0xe, 0x6e, 0x9d, 0xba, 0x62 }
};

EFI_EVENT              mEventDxeSmmReadyToLock           = NULL;
VOID                   *mRegistrationSmmExitBootServices = NULL;
VOID                   *mRegistrationSmmLegacyBoot       = NULL;
VOID                   *mRegistrationSmmReadyToLock      = NULL;
BOOLEAN                mS3BootScriptTableAllocated       = FALSE;
BOOLEAN                mS3BootScriptTableSmmAllocated    = FALSE;
EFI_SMM_SYSTEM_TABLE2  *mBootScriptSmst                  = NULL;
BOOLEAN                mS3BootScriptAcpiS3Enable         = TRUE;

/**
  This is an internal function to add a terminate node the entry, recalculate the table
  length and fill into the table.

  @return the base address of the boot script table.
 **/
UINT8 *
S3BootScriptInternalCloseTable (
  VOID
  )
{
  UINT8                         *S3TableBase;
  EFI_BOOT_SCRIPT_TERMINATE     ScriptTerminate;
  EFI_BOOT_SCRIPT_TABLE_HEADER  *ScriptTableInfo;

  S3TableBase = mS3BootScriptTablePtr->TableBase;

  if (S3TableBase == NULL) {
    //
    // the table is not exist
    //
    return S3TableBase;
  }

  //
  // Append the termination entry.
  //
  ScriptTerminate.OpCode = S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE;
  ScriptTerminate.Length = (UINT8)sizeof (EFI_BOOT_SCRIPT_TERMINATE);
  CopyMem (mS3BootScriptTablePtr->TableBase + mS3BootScriptTablePtr->TableLength, &ScriptTerminate, sizeof (EFI_BOOT_SCRIPT_TERMINATE));
  //
  // fill the table length
  //
  ScriptTableInfo              = (EFI_BOOT_SCRIPT_TABLE_HEADER *)(mS3BootScriptTablePtr->TableBase);
  ScriptTableInfo->TableLength = mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE);

  return S3TableBase;
  //
  // NOTE: Here we did NOT adjust the mS3BootScriptTablePtr->TableLength to
  // mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE).
  // Because maybe after SmmReadyToLock, we still need add entries into the table,
  // and the entry should be added start before this TERMINATE node.
  //
}

/**
  This function save boot script data to LockBox.

**/
VOID
SaveBootScriptDataToLockBox (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // Save whole memory copy into LockBox.
  // It will be used to restore data at S3 resume.
  //
  Status = SaveLockBox (
             &mBootScriptDataGuid,
             (VOID *)mS3BootScriptTablePtr->TableBase,
             EFI_PAGES_TO_SIZE (mS3BootScriptTablePtr->TableMemoryPageNumber)
             );
  ASSERT_EFI_ERROR (Status);

  Status = SetLockBoxAttributes (&mBootScriptDataGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
  ASSERT_EFI_ERROR (Status);

  //
  // Just need save TableBase.
  // Do not update other field because they will NOT be used in S3.
  //
  Status = SaveLockBox (
             &mBootScriptTableBaseGuid,
             (VOID *)&mS3BootScriptTablePtr->TableBase,
             sizeof (mS3BootScriptTablePtr->TableBase)
             );
  ASSERT_EFI_ERROR (Status);

  Status = SetLockBoxAttributes (&mBootScriptTableBaseGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
  ASSERT_EFI_ERROR (Status);
}

/**
  This is the Event call back function to notify the Library the system is entering
  SmmLocked phase.

  @param  Event   Pointer to this event
  @param  Context Event handler private data
 **/
VOID
EFIAPI
S3BootScriptEventCallBack (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  EFI_STATUS  Status;
  VOID        *Interface;

  //
  // Try to locate it because EfiCreateProtocolNotifyEvent will trigger it once when registration.
  // Just return if it is not found.
  //
  Status = gBS->LocateProtocol (
                  &gEfiDxeSmmReadyToLockProtocolGuid,
                  NULL,
                  &Interface
                  );
  if (EFI_ERROR (Status)) {
    return;
  }

  //
  // Here we should tell the library that we are entering SmmLocked phase.
  // and the memory page number occupied by the table should not grow anymore.
  //
  if (!mS3BootScriptTablePtr->SmmLocked) {
    //
    // Before SmmReadyToLock, we need not write the terminate node when adding a node to boot scipt table
    // or else, that will impact the performance. However, after SmmReadyToLock, we should append terminate
    // node on every add to boot script table.
    //
    S3BootScriptInternalCloseTable ();
    mS3BootScriptTablePtr->SmmLocked = TRUE;

    //
    // Save BootScript data to lockbox
    //
    SaveBootScriptDataToLockBox ();
  }
}

/**
  This is the Event call back function is triggered in SMM to notify the Library
  the system is entering SmmLocked phase and set InSmm flag.

  @param  Protocol   Points to the protocol's unique identifier
  @param  Interface  Points to the interface instance
  @param  Handle     The handle on which the interface was installed

  @retval EFI_SUCCESS SmmEventCallback runs successfully
 **/
EFI_STATUS
EFIAPI
S3BootScriptSmmEventCallBack (
  IN CONST EFI_GUID  *Protocol,
  IN VOID            *Interface,
  IN EFI_HANDLE      Handle
  )
{
  //
  // Check if it is already done
  //
  if (mS3BootScriptTablePtr == mS3BootScriptTableSmmPtr) {
    return EFI_SUCCESS;
  }

  //
  // Last chance to call-out, just make sure SmmLocked is set.
  //
  S3BootScriptEventCallBack (NULL, NULL);

  //
  // Save a SMM copy. If TableBase is NOT null, it means SMM copy has been ready, skip copy mem.
  //
  if (mS3BootScriptTableSmmPtr->TableBase == NULL) {
    CopyMem (mS3BootScriptTableSmmPtr, mS3BootScriptTablePtr, sizeof (*mS3BootScriptTablePtr));

    //
    // Set InSmm, we allow boot script update when InSmm, but not allow boot script outside SMM.
    // InSmm will only be checked if SmmLocked is TRUE.
    //
    mS3BootScriptTableSmmPtr->InSmm = TRUE;
  }

  //
  // We should not use ACPI Reserved copy, because it is not safe.
  //
  mS3BootScriptTablePtr = mS3BootScriptTableSmmPtr;

  return EFI_SUCCESS;
}

/**
  This function is to save boot time boot script data to LockBox.

  Because there may be INSERT boot script at runtime in SMM.
  The boot time copy will be used to restore data after back from S3.
  Otherwise the data inserted may cause some boot time boot script data lost
  if only BootScriptData used.

**/
VOID
SaveBootTimeDataToLockBox (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // ACPI Reserved copy is not safe, restore from BootScriptData LockBox first,
  // and then save the data to BootScriptDataBootTime LockBox.
  //
  Status = RestoreLockBox (
             &mBootScriptDataGuid,
             NULL,
             NULL
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Save BootScriptDataBootTime
  // It will be used to restore data after back from S3.
  //
  Status = SaveLockBox (
             &mBootScriptDataBootTimeGuid,
             (VOID *)mS3BootScriptTablePtr->TableBase,
             mS3BootScriptTablePtr->BootTimeScriptLength
             );
  ASSERT_EFI_ERROR (Status);
}

/**
  This function save boot script SMM private data to LockBox with BackFromS3 = TRUE at runtime.
  S3 resume will help restore it to tell the Library the system is back from S3.

**/
VOID
SaveSmmPriviateDataToLockBoxAtRuntime (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // Save boot script SMM private data with BackFromS3 = TRUE.
  //
  mS3BootScriptTablePtr->BackFromS3 = TRUE;
  Status                            = SaveLockBox (
                                        &mBootScriptSmmPrivateDataGuid,
                                        (VOID *)mS3BootScriptTablePtr,
                                        sizeof (SCRIPT_TABLE_PRIVATE_DATA)
                                        );
  ASSERT_EFI_ERROR (Status);

  Status = SetLockBoxAttributes (&mBootScriptSmmPrivateDataGuid, LOCK_BOX_ATTRIBUTE_RESTORE_IN_PLACE);
  ASSERT_EFI_ERROR (Status);

  //
  // Set BackFromS3 flag back to FALSE to indicate that now is not back from S3.
  //
  mS3BootScriptTablePtr->BackFromS3 = FALSE;
}

/**
  This is the Event call back function is triggered in SMM to notify the Library
  the system is entering runtime phase.

  @param[in] Protocol   Points to the protocol's unique identifier
  @param[in] Interface  Points to the interface instance
  @param[in] Handle     The handle on which the interface was installed

  @retval EFI_SUCCESS SmmAtRuntimeCallBack runs successfully
 **/
EFI_STATUS
EFIAPI
S3BootScriptSmmAtRuntimeCallBack (
  IN CONST EFI_GUID  *Protocol,
  IN VOID            *Interface,
  IN EFI_HANDLE      Handle
  )
{
  if (!mS3BootScriptTablePtr->AtRuntime) {
    mS3BootScriptTablePtr->BootTimeScriptLength = (UINT32)(mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE));
    SaveBootTimeDataToLockBox ();

    mS3BootScriptTablePtr->AtRuntime = TRUE;
    SaveSmmPriviateDataToLockBoxAtRuntime ();
  }

  return EFI_SUCCESS;
}

/**
  Library Constructor.
  this function just identify it is a smm driver or non-smm driver linked against
  with the library

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.

  @retval RETURN_SUCCESS    The constructor always returns RETURN_SUCCESS.

**/
RETURN_STATUS
EFIAPI
S3BootScriptLibInitialize (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                 Status;
  SCRIPT_TABLE_PRIVATE_DATA  *S3TablePtr;
  SCRIPT_TABLE_PRIVATE_DATA  *S3TableSmmPtr;
  VOID                       *Registration;
  EFI_SMM_BASE2_PROTOCOL     *SmmBase2;
  BOOLEAN                    InSmm;
  EFI_PHYSICAL_ADDRESS       Buffer;

  if (!PcdGetBool (PcdAcpiS3Enable)) {
    mS3BootScriptAcpiS3Enable = FALSE;
    DEBUG ((DEBUG_INFO, "%a: Skip S3BootScript because ACPI S3 disabled.\n", gEfiCallerBaseName));
    return RETURN_SUCCESS;
  }

  S3TablePtr = (SCRIPT_TABLE_PRIVATE_DATA *)(UINTN)PcdGet64 (PcdS3BootScriptTablePrivateDataPtr);
  //
  // The Boot script private data is not be initialized. create it
  //
  if (S3TablePtr == 0) {
    Buffer = SIZE_4GB - 1;
    Status = gBS->AllocatePages (
                    AllocateMaxAddress,
                    EfiReservedMemoryType,
                    EFI_SIZE_TO_PAGES (sizeof (SCRIPT_TABLE_PRIVATE_DATA)),
                    &Buffer
                    );
    ASSERT_EFI_ERROR (Status);
    mS3BootScriptTableAllocated = TRUE;
    S3TablePtr                  = (VOID *)(UINTN)Buffer;

    Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, (UINT64)(UINTN)S3TablePtr);
    ASSERT_EFI_ERROR (Status);
    ZeroMem (S3TablePtr, sizeof (SCRIPT_TABLE_PRIVATE_DATA));
    //
    // Create event to notify the library system enter the SmmLocked phase.
    //
    mEventDxeSmmReadyToLock = EfiCreateProtocolNotifyEvent (
                                &gEfiDxeSmmReadyToLockProtocolGuid,
                                TPL_CALLBACK,
                                S3BootScriptEventCallBack,
                                NULL,
                                &Registration
                                );
    ASSERT (mEventDxeSmmReadyToLock != NULL);
  }

  mS3BootScriptTablePtr = S3TablePtr;

  //
  // Get InSmm, we need to register SmmReadyToLock if this library is linked to SMM driver.
  //
  Status = gBS->LocateProtocol (&gEfiSmmBase2ProtocolGuid, NULL, (VOID **)&SmmBase2);
  if (EFI_ERROR (Status)) {
    return RETURN_SUCCESS;
  }

  Status = SmmBase2->InSmm (SmmBase2, &InSmm);
  if (EFI_ERROR (Status)) {
    return RETURN_SUCCESS;
  }

  if (!InSmm) {
    return RETURN_SUCCESS;
  }

  //
  // Good, we are in SMM
  //
  Status = SmmBase2->GetSmstLocation (SmmBase2, &mBootScriptSmst);
  if (EFI_ERROR (Status)) {
    return RETURN_SUCCESS;
  }

  S3TableSmmPtr = (SCRIPT_TABLE_PRIVATE_DATA *)(UINTN)PcdGet64 (PcdS3BootScriptTablePrivateSmmDataPtr);
  //
  // The Boot script private data in SMM is not be initialized. create it
  //
  if (S3TableSmmPtr == 0) {
    Status = mBootScriptSmst->SmmAllocatePool (
                                EfiRuntimeServicesData,
                                sizeof (SCRIPT_TABLE_PRIVATE_DATA),
                                (VOID **)&S3TableSmmPtr
                                );
    ASSERT_EFI_ERROR (Status);
    mS3BootScriptTableSmmAllocated = TRUE;

    Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, (UINT64)(UINTN)S3TableSmmPtr);
    ASSERT_EFI_ERROR (Status);
    ZeroMem (S3TableSmmPtr, sizeof (SCRIPT_TABLE_PRIVATE_DATA));

    //
    // Register SmmExitBootServices and SmmLegacyBoot notification.
    //
    Status = mBootScriptSmst->SmmRegisterProtocolNotify (
                                &gEdkiiSmmExitBootServicesProtocolGuid,
                                S3BootScriptSmmAtRuntimeCallBack,
                                &mRegistrationSmmExitBootServices
                                );
    ASSERT_EFI_ERROR (Status);

    Status = mBootScriptSmst->SmmRegisterProtocolNotify (
                                &gEdkiiSmmLegacyBootProtocolGuid,
                                S3BootScriptSmmAtRuntimeCallBack,
                                &mRegistrationSmmLegacyBoot
                                );
    ASSERT_EFI_ERROR (Status);
  }

  mS3BootScriptTableSmmPtr = S3TableSmmPtr;

  //
  // Register SmmReadyToLock notification.
  //
  Status = mBootScriptSmst->SmmRegisterProtocolNotify (
                              &gEfiSmmReadyToLockProtocolGuid,
                              S3BootScriptSmmEventCallBack,
                              &mRegistrationSmmReadyToLock
                              );
  ASSERT_EFI_ERROR (Status);

  return RETURN_SUCCESS;
}

/**
  Library Destructor to free the resources allocated by
  S3BootScriptLibInitialize() and unregister callbacks.

  NOTICE: The destructor doesn't support unloading as a separate action, and it
  only supports unloading if the containing driver's entry point function fails.

  @param ImageHandle        The firmware allocated handle for the EFI image.
  @param SystemTable        A pointer to the EFI System Table.

  @retval RETURN_SUCCESS    The destructor always returns RETURN_SUCCESS.

**/
RETURN_STATUS
EFIAPI
S3BootScriptLibDeinitialize (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  DEBUG ((DEBUG_INFO, "%a() in %a module\n", __func__, gEfiCallerBaseName));

  if (mEventDxeSmmReadyToLock != NULL) {
    //
    // Close the DxeSmmReadyToLock event.
    //
    Status = gBS->CloseEvent (mEventDxeSmmReadyToLock);
    ASSERT_EFI_ERROR (Status);
  }

  if (mBootScriptSmst != NULL) {
    if (mRegistrationSmmExitBootServices != NULL) {
      //
      // Unregister SmmExitBootServices notification.
      //
      Status = mBootScriptSmst->SmmRegisterProtocolNotify (
                                  &gEdkiiSmmExitBootServicesProtocolGuid,
                                  NULL,
                                  &mRegistrationSmmExitBootServices
                                  );
      ASSERT_EFI_ERROR (Status);
    }

    if (mRegistrationSmmLegacyBoot != NULL) {
      //
      // Unregister SmmLegacyBoot notification.
      //
      Status = mBootScriptSmst->SmmRegisterProtocolNotify (
                                  &gEdkiiSmmLegacyBootProtocolGuid,
                                  NULL,
                                  &mRegistrationSmmLegacyBoot
                                  );
      ASSERT_EFI_ERROR (Status);
    }

    if (mRegistrationSmmReadyToLock != NULL) {
      //
      // Unregister SmmReadyToLock notification.
      //
      Status = mBootScriptSmst->SmmRegisterProtocolNotify (
                                  &gEfiSmmReadyToLockProtocolGuid,
                                  NULL,
                                  &mRegistrationSmmReadyToLock
                                  );
      ASSERT_EFI_ERROR (Status);
    }
  }

  //
  // Free the resources allocated and set PCDs to 0.
  //
  if (mS3BootScriptTableAllocated) {
    Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS)(UINTN)mS3BootScriptTablePtr, EFI_SIZE_TO_PAGES (sizeof (SCRIPT_TABLE_PRIVATE_DATA)));
    ASSERT_EFI_ERROR (Status);
    Status = PcdSet64S (PcdS3BootScriptTablePrivateDataPtr, 0);
    ASSERT_EFI_ERROR (Status);
  }

  if ((mBootScriptSmst != NULL) && mS3BootScriptTableSmmAllocated) {
    Status = mBootScriptSmst->SmmFreePool (mS3BootScriptTableSmmPtr);
    ASSERT_EFI_ERROR (Status);
    Status = PcdSet64S (PcdS3BootScriptTablePrivateSmmDataPtr, 0);
    ASSERT_EFI_ERROR (Status);
  }

  return RETURN_SUCCESS;
}

/**
  To get the start address from which a new boot time s3 boot script entry will write into.
  If the table is not exist, the functio will first allocate a buffer for the table
  If the table buffer is not enough for the new entry, in non-smm mode, the function will
  invoke reallocate to enlarge buffer.

  @param EntryLength      the new entry length.

  @retval the address from which the a new s3 boot script entry will write into
 **/
UINT8 *
S3BootScriptGetBootTimeEntryAddAddress (
  UINT8  EntryLength
  )
{
  EFI_PHYSICAL_ADDRESS          S3TableBase;
  EFI_PHYSICAL_ADDRESS          NewS3TableBase;
  UINT8                         *NewEntryPtr;
  UINT32                        TableLength;
  UINT16                        PageNumber;
  EFI_STATUS                    Status;
  EFI_BOOT_SCRIPT_TABLE_HEADER  *ScriptTableInfo;

  S3TableBase = (EFI_PHYSICAL_ADDRESS)(UINTN)(mS3BootScriptTablePtr->TableBase);
  if (S3TableBase == 0) {
    //
    // The table is not exist. This is the first to add entry.
    // Allocate ACPI script table space under 4G memory.
    //
    S3TableBase = 0xffffffff;
    Status      = gBS->AllocatePages (
                         AllocateMaxAddress,
                         EfiReservedMemoryType,
                         2 + PcdGet16 (PcdS3BootScriptRuntimeTableReservePageNumber),
                         (EFI_PHYSICAL_ADDRESS *)&S3TableBase
                         );

    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return 0;
    }

    //
    // Fill Table Header
    //
    ScriptTableInfo                              = (EFI_BOOT_SCRIPT_TABLE_HEADER *)(UINTN)S3TableBase;
    ScriptTableInfo->OpCode                      = S3_BOOT_SCRIPT_LIB_TABLE_OPCODE;
    ScriptTableInfo->Length                      = (UINT8)sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
    ScriptTableInfo->Version                     = BOOT_SCRIPT_TABLE_VERSION;
    ScriptTableInfo->TableLength                 = 0; // will be calculate at CloseTable
    mS3BootScriptTablePtr->TableLength           = sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
    mS3BootScriptTablePtr->TableBase             = (UINT8 *)(UINTN)S3TableBase;
    mS3BootScriptTablePtr->TableMemoryPageNumber = (UINT16)(2 + PcdGet16 (PcdS3BootScriptRuntimeTableReservePageNumber));
  }

  // Here we do not count the reserved memory for runtime script table.
  PageNumber  = (UINT16)(mS3BootScriptTablePtr->TableMemoryPageNumber - PcdGet16 (PcdS3BootScriptRuntimeTableReservePageNumber));
  TableLength =  mS3BootScriptTablePtr->TableLength;
  if (EFI_PAGES_TO_SIZE ((UINTN)PageNumber) < (TableLength + EntryLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE))) {
    //
    // The buffer is too small to hold the table, Reallocate the buffer
    //
    NewS3TableBase = 0xffffffff;
    Status         = gBS->AllocatePages (
                            AllocateMaxAddress,
                            EfiReservedMemoryType,
                            2 + PageNumber + PcdGet16 (PcdS3BootScriptRuntimeTableReservePageNumber),
                            (EFI_PHYSICAL_ADDRESS *)&NewS3TableBase
                            );

    if (EFI_ERROR (Status)) {
      ASSERT_EFI_ERROR (Status);
      return 0;
    }

    CopyMem ((VOID *)(UINTN)NewS3TableBase, (VOID *)(UINTN)S3TableBase, TableLength);
    gBS->FreePages (S3TableBase, mS3BootScriptTablePtr->TableMemoryPageNumber);

    mS3BootScriptTablePtr->TableBase             = (UINT8 *)(UINTN)NewS3TableBase;
    mS3BootScriptTablePtr->TableMemoryPageNumber =  (UINT16)(2 + PageNumber + PcdGet16 (PcdS3BootScriptRuntimeTableReservePageNumber));
  }

  //
  // calculate the the start address for the new entry.
  //
  NewEntryPtr = mS3BootScriptTablePtr->TableBase + TableLength;

  //
  // update the table lenghth
  //
  mS3BootScriptTablePtr->TableLength =  TableLength + EntryLength;

  //
  // In the boot time, we will not append the termination entry to the boot script
  // table until the callers think there is no boot time data that should be added and
  // it is caller's responsibility to explicit call the CloseTable.
  //
  //

  return NewEntryPtr;
}

/**
  To get the start address from which a new runtime(after SmmReadyToLock) s3 boot script entry will write into.
  In this case, it should be ensured that there is enough buffer to hold the entry.

  @param EntryLength      the new entry length.

  @retval the address from which the a new s3 runtime(after SmmReadyToLock) script entry will write into
 **/
UINT8 *
S3BootScriptGetRuntimeEntryAddAddress (
  UINT8  EntryLength
  )
{
  UINT8  *NewEntryPtr;

  NewEntryPtr = NULL;
  //
  // Check if the memory range reserved for S3 Boot Script table is large enough to hold the node.
  //
  if ((mS3BootScriptTablePtr->TableLength + EntryLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE)) <= EFI_PAGES_TO_SIZE ((UINTN)(mS3BootScriptTablePtr->TableMemoryPageNumber))) {
    NewEntryPtr                        = mS3BootScriptTablePtr->TableBase + mS3BootScriptTablePtr->TableLength;
    mS3BootScriptTablePtr->TableLength = mS3BootScriptTablePtr->TableLength + EntryLength;
    //
    // Append a terminate node on every insert
    //
    S3BootScriptInternalCloseTable ();
  }

  return (UINT8 *)NewEntryPtr;
}

/**
  This function is to restore boot time boot script data from LockBox.

**/
VOID
RestoreBootTimeDataFromLockBox (
  VOID
  )
{
  EFI_STATUS  Status;
  UINTN       LockBoxLength;

  //
  // Restore boot time boot script data from LockBox.
  //
  LockBoxLength = mS3BootScriptTablePtr->BootTimeScriptLength;
  Status        = RestoreLockBox (
                    &mBootScriptDataBootTimeGuid,
                    (VOID *)mS3BootScriptTablePtr->TableBase,
                    &LockBoxLength
                    );
  ASSERT_EFI_ERROR (Status);

  //
  // Update the data to BootScriptData LockBox.
  //
  Status = UpdateLockBox (
             &mBootScriptDataGuid,
             0,
             (VOID *)mS3BootScriptTablePtr->TableBase,
             LockBoxLength
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Update TableLength.
  //
  mS3BootScriptTablePtr->TableLength = (UINT32)(mS3BootScriptTablePtr->BootTimeScriptLength - sizeof (EFI_BOOT_SCRIPT_TERMINATE));
}

/**
  To get the start address from which a new s3 boot script entry will write into.

  @param EntryLength      the new entry length.

  @retval the address from which the a new s3 boot script entry will write into
 **/
UINT8 *
S3BootScriptGetEntryAddAddress (
  UINT8  EntryLength
  )
{
  UINT8  *NewEntryPtr;

  if (!mS3BootScriptAcpiS3Enable) {
    return NULL;
  }

  if (mS3BootScriptTablePtr->SmmLocked) {
    //
    // We need check InSmm, because after SmmReadyToLock, only SMM driver is allowed to write boot script.
    //
    if (!mS3BootScriptTablePtr->InSmm) {
      //
      // Add DEBUG ERROR, so that we can find it after SmmReadyToLock.
      // Do not use ASSERT, because we may have test to invoke this interface.
      //
      DEBUG ((DEBUG_ERROR, "FATAL ERROR: Set boot script outside SMM after SmmReadyToLock!!!\n"));
      return NULL;
    }

    if (mS3BootScriptTablePtr->BackFromS3) {
      //
      // Back from S3, restore boot time boot script data from LockBox
      // and set BackFromS3 flag back to FALSE.
      //
      RestoreBootTimeDataFromLockBox ();
      mS3BootScriptTablePtr->BackFromS3 = FALSE;
    }

    NewEntryPtr = S3BootScriptGetRuntimeEntryAddAddress (EntryLength);
  } else {
    NewEntryPtr = S3BootScriptGetBootTimeEntryAddAddress (EntryLength);
  }

  return NewEntryPtr;
}

/**
  Sync BootScript LockBox data.

  @param Script           The address from where the boot script has been added or updated.

**/
VOID
SyncBootScript (
  IN UINT8  *Script
  )
{
  EFI_STATUS  Status;
  UINT32      ScriptOffset;
  UINT32      TotalScriptLength;

  if (!mS3BootScriptTablePtr->SmmLocked || !mS3BootScriptTablePtr->InSmm) {
    //
    // If it is not after SmmReadyToLock in SMM,
    // just return.
    //
    return;
  }

  ScriptOffset = (UINT32)(Script - mS3BootScriptTablePtr->TableBase);

  TotalScriptLength = (UINT32)(mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE));

  //
  // Update BootScriptData
  // So in S3 resume, the data can be restored correctly.
  //
  Status = UpdateLockBox (
             &mBootScriptDataGuid,
             ScriptOffset,
             (VOID *)((UINTN)mS3BootScriptTablePtr->TableBase + ScriptOffset),
             TotalScriptLength - ScriptOffset
             );
  ASSERT_EFI_ERROR (Status);

  //
  // Now the length field is updated, need sync to lockbox.
  // So at S3 resume, the data can be restored correctly.
  //
  Status = UpdateLockBox (
             &mBootScriptDataGuid,
             OFFSET_OF (EFI_BOOT_SCRIPT_TABLE_HEADER, TableLength),
             &TotalScriptLength,
             sizeof (TotalScriptLength)
             );
  ASSERT_EFI_ERROR (Status);
}

/**
  This is an function to close the S3 boot script table. The function could only be called in
  BOOT time phase. To comply with the Framework spec definition on
  EFI_BOOT_SCRIPT_SAVE_PROTOCOL.CloseTable(), this function will fulfill following things:
  1. Closes the specified boot script table
  2. It allocates a new memory pool to duplicate all the boot scripts in the specified table.
     Once this function is called, the table maintained by the library will be destroyed
     after it is copied into the allocated pool.
  3. Any attempts to add a script record after calling this function will cause a new table
     to be created by the library.
  4. The base address of the allocated pool will be returned in Address. Note that after
     using the boot script table, the CALLER is responsible for freeing the pool that is allocated
     by this function.

  In Spec PI1.1, this EFI_BOOT_SCRIPT_SAVE_PROTOCOL.CloseTable() is retired. To provides this API for now is
  for Framework Spec compatibility.

  If anyone does call CloseTable() on a real platform, then the caller is responsible for figuring out
  how to get the script to run at S3 resume because the boot script maintained by the lib will be
  destroyed.

  @return the base address of the new copy of the boot script table.
  @note this function could only called in boot time phase

**/
UINT8 *
EFIAPI
S3BootScriptCloseTable (
  VOID
  )
{
  UINT8                         *S3TableBase;
  UINT32                        TableLength;
  UINT8                         *Buffer;
  EFI_STATUS                    Status;
  EFI_BOOT_SCRIPT_TABLE_HEADER  *ScriptTableInfo;

  S3TableBase =    mS3BootScriptTablePtr->TableBase;
  if (S3TableBase == 0) {
    return 0;
  }

  //
  // Append the termination record the S3 boot script table
  //
  S3BootScriptInternalCloseTable ();
  TableLength = mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE);
  //
  // Allocate the buffer and copy the boot script to the buffer.
  //
  Status = gBS->AllocatePool (
                  EfiBootServicesData,
                  (UINTN)TableLength,
                  (VOID **)&Buffer
                  );
  if (EFI_ERROR (Status)) {
    return 0;
  }

  CopyMem (Buffer, S3TableBase, TableLength);

  //
  // Destroy the table maintained by the library so that the next write operation
  // will write the record to the first entry of the table.
  //
  // Fill the table header.
  ScriptTableInfo              = (EFI_BOOT_SCRIPT_TABLE_HEADER *)S3TableBase;
  ScriptTableInfo->OpCode      = S3_BOOT_SCRIPT_LIB_TABLE_OPCODE;
  ScriptTableInfo->Length      = (UINT8)sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
  ScriptTableInfo->TableLength = 0;   // will be calculate at close the table

  mS3BootScriptTablePtr->TableLength = sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
  return Buffer;
}

/**
  Save I/O write to boot script

  @param Width   The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.
  @param Address The base address of the I/O operations.
  @param Count   The number of I/O operations to perform.
  @param Buffer  The source buffer from which to write data.

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveIoWrite (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT64                    Address,
  IN  UINTN                     Count,
  IN  VOID                      *Buffer
  )

{
  UINT8                     Length;
  UINT8                     *Script;
  UINT8                     WidthInByte;
  EFI_BOOT_SCRIPT_IO_WRITE  ScriptIoWrite;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));

  //
  // Truncation check
  //
  if ((Count > MAX_UINT8) ||
      (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_IO_WRITE)))
  {
    return RETURN_OUT_OF_RESOURCES;
  }

  Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_IO_WRITE) + (WidthInByte * Count));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // save script data
  //
  ScriptIoWrite.OpCode  = EFI_BOOT_SCRIPT_IO_WRITE_OPCODE;
  ScriptIoWrite.Length  = Length;
  ScriptIoWrite.Width   = Width;
  ScriptIoWrite.Address = Address;
  ScriptIoWrite.Count   = (UINT32)Count;
  CopyMem ((VOID *)Script, (VOID *)&ScriptIoWrite, sizeof (EFI_BOOT_SCRIPT_IO_WRITE));
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_IO_WRITE)), Buffer, WidthInByte * Count);

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for an I/O modify operation into a S3 boot script table

  @param Width   The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.
  @param Address The base address of the I/O operations.
  @param Data    A pointer to the data to be OR-ed.
  @param DataMask  A pointer to the data mask to be AND-ed with the data read from the register

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveIoReadWrite (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT64                    Address,
  IN  VOID                      *Data,
  IN  VOID                      *DataMask
  )
{
  UINT8                          Length;
  UINT8                          *Script;
  UINT8                          WidthInByte;
  EFI_BOOT_SCRIPT_IO_READ_WRITE  ScriptIoReadWrite;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));
  Length      = (UINT8)(sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE) + (WidthInByte * 2));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptIoReadWrite.OpCode  = EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE;
  ScriptIoReadWrite.Length  = Length;
  ScriptIoReadWrite.Width   = Width;
  ScriptIoReadWrite.Address = Address;

  CopyMem ((VOID *)Script, (VOID *)&ScriptIoReadWrite, sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE));
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE)), Data, WidthInByte);
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE) + WidthInByte), DataMask, WidthInByte);

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for a memory write operation into a specified boot script table.

  @param Width   The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.
  @param Address The base address of the memory operations
  @param Count   The number of memory operations to perform.
  @param Buffer  The source buffer from which to write the data.

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveMemWrite (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT64                    Address,
  IN  UINTN                     Count,
  IN  VOID                      *Buffer
  )
{
  UINT8                      Length;
  UINT8                      *Script;
  UINT8                      WidthInByte;
  EFI_BOOT_SCRIPT_MEM_WRITE  ScriptMemWrite;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));

  //
  // Truncation check
  //
  if ((Count > MAX_UINT8) ||
      (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_MEM_WRITE)))
  {
    return RETURN_OUT_OF_RESOURCES;
  }

  Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_MEM_WRITE) + (WidthInByte * Count));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptMemWrite.OpCode  = EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE;
  ScriptMemWrite.Length  = Length;
  ScriptMemWrite.Width   = Width;
  ScriptMemWrite.Address = Address;
  ScriptMemWrite.Count   = (UINT32)Count;

  CopyMem ((VOID *)Script, (VOID *)&ScriptMemWrite, sizeof (EFI_BOOT_SCRIPT_MEM_WRITE));
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_WRITE)), Buffer, WidthInByte * Count);

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for a memory modify operation into a specified boot script table.

  @param Width     The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.
  @param Address   The base address of the memory operations. Address needs alignment if required
  @param Data      A pointer to the data to be OR-ed.
  @param DataMask  A pointer to the data mask to be AND-ed with the data read from the register.

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveMemReadWrite (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT64                    Address,
  IN  VOID                      *Data,
  IN  VOID                      *DataMask
  )
{
  UINT8                           Length;
  UINT8                           *Script;
  UINT8                           WidthInByte;
  EFI_BOOT_SCRIPT_MEM_READ_WRITE  ScriptMemReadWrite;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));
  Length      = (UINT8)(sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE) + (WidthInByte * 2));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptMemReadWrite.OpCode  = EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE;
  ScriptMemReadWrite.Length  = Length;
  ScriptMemReadWrite.Width   = Width;
  ScriptMemReadWrite.Address = Address;

  CopyMem ((VOID *)Script, (VOID *)&ScriptMemReadWrite, sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE));
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE)), Data, WidthInByte);
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE) + WidthInByte), DataMask, WidthInByte);

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for a PCI configuration space write operation into a specified boot script table.

  @param Width     The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.
  @param Address   The address within the PCI configuration space.
  @param Count     The number of PCI operations to perform.
  @param Buffer    The source buffer from which to write the data.

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
  @note  A known Limitations in the implementation which is 64bits operations are not supported.

**/
RETURN_STATUS
EFIAPI
S3BootScriptSavePciCfgWrite (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT64                    Address,
  IN  UINTN                     Count,
  IN  VOID                      *Buffer
  )
{
  UINT8                             Length;
  UINT8                             *Script;
  UINT8                             WidthInByte;
  EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE  ScriptPciWrite;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  if ((Width == S3BootScriptWidthUint64) ||
      (Width == S3BootScriptWidthFifoUint64) ||
      (Width == S3BootScriptWidthFillUint64))
  {
    return EFI_INVALID_PARAMETER;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));

  //
  // Truncation check
  //
  if ((Count > MAX_UINT8) ||
      (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE)))
  {
    return RETURN_OUT_OF_RESOURCES;
  }

  Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE) + (WidthInByte * Count));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptPciWrite.OpCode  = EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE;
  ScriptPciWrite.Length  = Length;
  ScriptPciWrite.Width   = Width;
  ScriptPciWrite.Address = Address;
  ScriptPciWrite.Count   = (UINT32)Count;

  CopyMem ((VOID *)Script, (VOID *)&ScriptPciWrite, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE));
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE)), Buffer, WidthInByte * Count);

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for a PCI configuration space modify operation into a specified boot script table.

  @param Width     The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.
  @param Address   The address within the PCI configuration space.
  @param Data      A pointer to the data to be OR-ed.The size depends on Width.
  @param DataMask    A pointer to the data mask to be AND-ed.

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN__SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
  @note  A known Limitations in the implementation which is 64bits operations are not supported.

**/
RETURN_STATUS
EFIAPI
S3BootScriptSavePciCfgReadWrite (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT64                    Address,
  IN  VOID                      *Data,
  IN  VOID                      *DataMask
  )
{
  UINT8                                  Length;
  UINT8                                  *Script;
  UINT8                                  WidthInByte;
  EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE  ScriptPciReadWrite;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  if ((Width == S3BootScriptWidthUint64) ||
      (Width == S3BootScriptWidthFifoUint64) ||
      (Width == S3BootScriptWidthFillUint64))
  {
    return EFI_INVALID_PARAMETER;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));
  Length      = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE) + (WidthInByte * 2));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptPciReadWrite.OpCode  = EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE;
  ScriptPciReadWrite.Length  = Length;
  ScriptPciReadWrite.Width   = Width;
  ScriptPciReadWrite.Address = Address;

  CopyMem ((VOID *)Script, (VOID *)&ScriptPciReadWrite, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE));
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE)), Data, WidthInByte);
  CopyMem (
    (VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE) + WidthInByte),
    DataMask,
    WidthInByte
    );

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for a PCI configuration 2 space write operation into a specified boot script table.

  @param Width     The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.
  @param Segment   The PCI segment number for Address.
  @param Address   The address within the PCI configuration space.
  @param Count     The number of PCI operations to perform.
  @param Buffer    The source buffer from which to write the data.

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
  @note  A known Limitations in the implementation which is 64bits operations are not supported.

**/
RETURN_STATUS
EFIAPI
S3BootScriptSavePciCfg2Write (
  IN S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN UINT16                    Segment,
  IN UINT64                    Address,
  IN UINTN                     Count,
  IN VOID                      *Buffer
  )
{
  UINT8                              Length;
  UINT8                              *Script;
  UINT8                              WidthInByte;
  EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE  ScriptPciWrite2;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  if ((Width == S3BootScriptWidthUint64) ||
      (Width == S3BootScriptWidthFifoUint64) ||
      (Width == S3BootScriptWidthFillUint64))
  {
    return EFI_INVALID_PARAMETER;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));

  //
  // Truncation check
  //
  if ((Count > MAX_UINT8) ||
      (WidthInByte * Count > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE)))
  {
    return RETURN_OUT_OF_RESOURCES;
  }

  Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE) + (WidthInByte * Count));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptPciWrite2.OpCode  = EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE;
  ScriptPciWrite2.Length  = Length;
  ScriptPciWrite2.Width   = Width;
  ScriptPciWrite2.Address = Address;
  ScriptPciWrite2.Segment = Segment;
  ScriptPciWrite2.Count   = (UINT32)Count;

  CopyMem ((VOID *)Script, (VOID *)&ScriptPciWrite2, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE));
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE)), Buffer, WidthInByte * Count);

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for a PCI configuration 2 space modify operation into a specified boot script table.

  @param Width     The width of the I/O operations.Enumerated in S3_BOOT_SCRIPT_LIB_WIDTH.
  @param Segment   The PCI segment number for Address.
  @param Address   The address within the PCI configuration space.
  @param Data      A pointer to the data to be OR-ed. The size depends on Width.
  @param DataMask    A pointer to the data mask to be AND-ed.

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
  @note  A known Limitations in the implementation which is 64bits operations are not supported.

**/
RETURN_STATUS
EFIAPI
S3BootScriptSavePciCfg2ReadWrite (
  IN S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN UINT16                    Segment,
  IN UINT64                    Address,
  IN VOID                      *Data,
  IN VOID                      *DataMask
  )
{
  UINT8                                   Length;
  UINT8                                   *Script;
  UINT8                                   WidthInByte;
  EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE  ScriptPciReadWrite2;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  if ((Width == S3BootScriptWidthUint64) ||
      (Width == S3BootScriptWidthFifoUint64) ||
      (Width == S3BootScriptWidthFillUint64))
  {
    return EFI_INVALID_PARAMETER;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));
  Length      = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE) + (WidthInByte * 2));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptPciReadWrite2.OpCode  = EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE;
  ScriptPciReadWrite2.Length  = Length;
  ScriptPciReadWrite2.Width   = Width;
  ScriptPciReadWrite2.Segment = Segment;
  ScriptPciReadWrite2.Address = Address;

  CopyMem ((VOID *)Script, (VOID *)&ScriptPciReadWrite2, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE));
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE)), Data, WidthInByte);
  CopyMem (
    (VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE) + WidthInByte),
    DataMask,
    WidthInByte
    );

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Checks the parameter of S3BootScriptSaveSmbusExecute().

  This function checks the input parameters of SmbusExecute().  If the input parameters are valid
  for certain SMBus bus protocol, it will return EFI_SUCCESS; otherwise, it will return certain
  error code based on the input SMBus bus protocol.

  @param  SmBusAddress            Address that encodes the SMBUS Slave Address, SMBUS Command, SMBUS Data Length,
                                  and PEC.
  @param  Operation               Signifies which particular SMBus hardware protocol instance that
                                  it will use to execute the SMBus transactions. This SMBus
                                  hardware protocol is defined by the SMBus Specification and is
                                  not related to EFI.
  @param  Length                  Signifies the number of bytes that this operation will do. The
                                  maximum number of bytes can be revision specific and operation
                                  specific. This field will contain the actual number of bytes that
                                  are executed for this operation. Not all operations require this
                                  argument.
  @param  Buffer                  Contains the value of data to execute to the SMBus slave device.
                                  Not all operations require this argument. The length of this
                                  buffer is identified by Length.

  @retval EFI_SUCCESS             All the parameters are valid for the corresponding SMBus bus
                                  protocol.
  @retval EFI_INVALID_PARAMETER   Operation is not defined in EFI_SMBUS_OPERATION.
  @retval EFI_INVALID_PARAMETER   Length/Buffer is NULL for operations except for EfiSmbusQuickRead
                                  and EfiSmbusQuickWrite. Length is outside the range of valid
                                  values.
  @retval EFI_UNSUPPORTED         The SMBus operation or PEC is not supported.
  @retval EFI_BUFFER_TOO_SMALL    Buffer is not sufficient for this operation.

**/
EFI_STATUS
CheckParameters (
  IN     UINTN                SmBusAddress,
  IN     EFI_SMBUS_OPERATION  Operation,
  IN OUT UINTN                *Length,
  IN     VOID                 *Buffer
  )
{
  EFI_STATUS                Status;
  UINTN                     RequiredLen;
  EFI_SMBUS_DEVICE_COMMAND  Command;
  BOOLEAN                   PecCheck;

  Command  = SMBUS_LIB_COMMAND (SmBusAddress);
  PecCheck = SMBUS_LIB_PEC (SmBusAddress);
  //
  // Set default value to be 2:
  // for SmbusReadWord, SmbusWriteWord and SmbusProcessCall.
  //
  RequiredLen = 2;
  Status      = EFI_SUCCESS;
  switch (Operation) {
    case EfiSmbusQuickRead:
    case EfiSmbusQuickWrite:
      if (PecCheck || (Command != 0)) {
        return EFI_UNSUPPORTED;
      }

      break;
    case EfiSmbusReceiveByte:
    case EfiSmbusSendByte:
      if (Command != 0) {
        return EFI_UNSUPPORTED;
      }

    //
    // Cascade to check length parameter.
    //
    case EfiSmbusReadByte:
    case EfiSmbusWriteByte:
      RequiredLen = 1;
    //
    // Cascade to check length parameter.
    //
    case EfiSmbusReadWord:
    case EfiSmbusWriteWord:
    case EfiSmbusProcessCall:
      if ((Buffer == NULL) || (Length == NULL)) {
        return EFI_INVALID_PARAMETER;
      } else if (*Length < RequiredLen) {
        Status = EFI_BUFFER_TOO_SMALL;
      }

      *Length = RequiredLen;
      break;
    case EfiSmbusReadBlock:
    case EfiSmbusWriteBlock:
    case EfiSmbusBWBRProcessCall:
      if ((Buffer == NULL) ||
          (Length == NULL) ||
          (*Length < MIN_SMBUS_BLOCK_LEN) ||
          (*Length > MAX_SMBUS_BLOCK_LEN))
      {
        return EFI_INVALID_PARAMETER;
      }

      break;
    default:
      return EFI_INVALID_PARAMETER;
  }

  return Status;
}

/**
  Adds a record for an SMBus command execution into a specified boot script table.

  @param  SmBusAddress  Address that encodes the SMBUS Slave Address, SMBUS Command, SMBUS Data Length, and PEC.
  @param Operation      Indicates which particular SMBus protocol it will use to execute the SMBus
                        transactions.
  @param Length         A pointer to signify the number of bytes that this operation will do.
  @param Buffer         Contains the value of data to execute to the SMBUS slave device.

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveSmbusExecute (
  IN  UINTN                SmBusAddress,
  IN  EFI_SMBUS_OPERATION  Operation,
  IN  UINTN                *Length,
  IN  VOID                 *Buffer
  )
{
  EFI_STATUS                     Status;
  UINTN                          BufferLength;
  UINT8                          DataSize;
  UINT8                          *Script;
  EFI_BOOT_SCRIPT_SMBUS_EXECUTE  ScriptSmbusExecute;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  if (Length == NULL) {
    BufferLength = 0;
  } else {
    BufferLength = *Length;
  }

  Status = CheckParameters (SmBusAddress, Operation, &BufferLength, Buffer);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Truncation check
  //
  if (BufferLength > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)) {
    return RETURN_OUT_OF_RESOURCES;
  }

  DataSize = (UINT8)(sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE) + BufferLength);

  Script = S3BootScriptGetEntryAddAddress (DataSize);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptSmbusExecute.OpCode       = EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE;
  ScriptSmbusExecute.Length       = DataSize;
  ScriptSmbusExecute.SmBusAddress = (UINT64)SmBusAddress;
  ScriptSmbusExecute.Operation    = Operation;
  ScriptSmbusExecute.DataSize     = (UINT32)BufferLength;

  CopyMem ((VOID *)Script, (VOID *)&ScriptSmbusExecute, sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE));
  CopyMem (
    (VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)),
    Buffer,
    BufferLength
    );

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for an execution stall on the processor into a specified boot script table.

  @param Duration   Duration in microseconds of the stall

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveStall (
  IN  UINTN  Duration
  )
{
  UINT8                  Length;
  UINT8                  *Script;
  EFI_BOOT_SCRIPT_STALL  ScriptStall;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_STALL));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptStall.OpCode   = EFI_BOOT_SCRIPT_STALL_OPCODE;
  ScriptStall.Length   = Length;
  ScriptStall.Duration = Duration;

  CopyMem ((VOID *)Script, (VOID *)&ScriptStall, sizeof (EFI_BOOT_SCRIPT_STALL));

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for dispatching specified arbitrary code into a specified boot script table.

  @param EntryPoint   Entry point of the code to be dispatched.
  @param Context      Argument to be passed into the EntryPoint of the code to be dispatched.

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveDispatch2 (
  IN  VOID  *EntryPoint,
  IN  VOID  *Context
  )
{
  UINT8                       Length;
  UINT8                       *Script;
  EFI_BOOT_SCRIPT_DISPATCH_2  ScriptDispatch2;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_DISPATCH_2));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptDispatch2.OpCode     = EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE;
  ScriptDispatch2.Length     = Length;
  ScriptDispatch2.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPoint;
  ScriptDispatch2.Context    =   (EFI_PHYSICAL_ADDRESS)(UINTN)Context;

  CopyMem ((VOID *)Script, (VOID *)&ScriptDispatch2, sizeof (EFI_BOOT_SCRIPT_DISPATCH_2));

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for memory reads of the memory location and continues when the exit criteria is
  satisfied or after a defined duration.

  Please aware, below interface is different with PI specification, Vol 5:
  EFI_S3_SAVE_STATE_PROTOCOL.Write() for EFI_BOOT_SCRIPT_MEM_POLL_OPCODE.
  "Duration" below is microseconds, while "Delay" in PI specification means
  the number of 100ns units to poll.

  @param Width     The width of the memory operations.
  @param Address   The base address of the memory operations.
  @param BitMask   A pointer to the bit mask to be AND-ed with the data read from the register.
  @param BitValue  A pointer to the data value after to be Masked.
  @param Duration  Duration in microseconds of the stall.
  @param LoopTimes The times of the register polling.

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.

**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveMemPoll (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT64                    Address,
  IN  VOID                      *BitMask,
  IN  VOID                      *BitValue,
  IN  UINTN                     Duration,
  IN  UINT64                    LoopTimes
  )
{
  UINT8                     Length;
  UINT8                     *Script;
  UINT8                     WidthInByte;
  EFI_BOOT_SCRIPT_MEM_POLL  ScriptMemPoll;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));

  Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_MEM_POLL) + (WidthInByte * 2));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptMemPoll.OpCode    = EFI_BOOT_SCRIPT_MEM_POLL_OPCODE;
  ScriptMemPoll.Length    = Length;
  ScriptMemPoll.Width     = Width;
  ScriptMemPoll.Address   = Address;
  ScriptMemPoll.Duration  = Duration;
  ScriptMemPoll.LoopTimes = LoopTimes;

  CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_POLL)), BitValue, WidthInByte);
  CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_MEM_POLL) + WidthInByte), BitMask, WidthInByte);
  CopyMem ((VOID *)Script, (VOID *)&ScriptMemPoll, sizeof (EFI_BOOT_SCRIPT_MEM_POLL));

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Store arbitrary information in the boot script table. This opcode is a no-op on dispatch and is only
  used for debugging script issues.

  @param InformationLength   Length of the data in bytes
  @param Information       Information to be logged in the boot scrpit

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.

**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveInformation (
  IN  UINT32  InformationLength,
  IN  VOID    *Information
  )
{
  UINT8                        Length;
  UINT8                        *Script;
  EFI_BOOT_SCRIPT_INFORMATION  ScriptInformation;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  //
  // Truncation check
  //
  if (InformationLength > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_INFORMATION)) {
    return RETURN_OUT_OF_RESOURCES;
  }

  Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_INFORMATION) + InformationLength);

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptInformation.OpCode = EFI_BOOT_SCRIPT_INFORMATION_OPCODE;
  ScriptInformation.Length = Length;

  ScriptInformation.InformationLength = InformationLength;

  CopyMem ((VOID *)Script, (VOID *)&ScriptInformation, sizeof (EFI_BOOT_SCRIPT_INFORMATION));
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION)), (VOID *)Information, (UINTN)InformationLength);

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Store a string in the boot script table. This opcode is a no-op on dispatch and is only
  used for debugging script issues.

  @param String            The string to save to boot script table

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.

**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveInformationAsciiString (
  IN  CONST CHAR8  *String
  )
{
  return S3BootScriptSaveInformation (
           (UINT32)AsciiStrLen (String) + 1,
           (VOID *)String
           );
}

/**
  Adds a record for dispatching specified arbitrary code into a specified boot script table.

  @param EntryPoint   Entry point of the code to be dispatched.

  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveDispatch (
  IN  VOID  *EntryPoint
  )
{
  UINT8                     Length;
  UINT8                     *Script;
  EFI_BOOT_SCRIPT_DISPATCH  ScriptDispatch;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_DISPATCH));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptDispatch.OpCode     = EFI_BOOT_SCRIPT_DISPATCH_OPCODE;
  ScriptDispatch.Length     = Length;
  ScriptDispatch.EntryPoint = (EFI_PHYSICAL_ADDRESS)(UINTN)EntryPoint;

  CopyMem ((VOID *)Script, (VOID *)&ScriptDispatch, sizeof (EFI_BOOT_SCRIPT_DISPATCH));

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for I/O reads the I/O location and continues when the exit criteria is satisfied or after a
  defined duration.

  @param  Width                 The width of the I/O operations.
  @param  Address               The base address of the I/O operations.
  @param  Data                  The comparison value used for the polling exit criteria.
  @param  DataMask              Mask used for the polling criteria. The bits in the bytes below Width which are zero
                                in Data are ignored when polling the memory address.
  @param  Delay                 The number of 100ns units to poll. Note that timer available may be of poorer
                                granularity so the delay may be longer.

 @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
 @retval RETURN_SUCCESS          Opcode is added or no action is required as ACPI S3 was disabled.

**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveIoPoll (
  IN S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN UINT64                    Address,
  IN VOID                      *Data,
  IN VOID                      *DataMask,
  IN UINT64                    Delay
  )
{
  UINT8                    WidthInByte;
  UINT8                    *Script;
  UINT8                    Length;
  EFI_BOOT_SCRIPT_IO_POLL  ScriptIoPoll;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));
  Length      = (UINT8)(sizeof (EFI_BOOT_SCRIPT_IO_POLL) + (WidthInByte * 2));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptIoPoll.OpCode  = EFI_BOOT_SCRIPT_IO_POLL_OPCODE;
  ScriptIoPoll.Length  = (UINT8)(sizeof (EFI_BOOT_SCRIPT_IO_POLL) + (WidthInByte * 2));
  ScriptIoPoll.Width   = Width;
  ScriptIoPoll.Address = Address;
  ScriptIoPoll.Delay   = Delay;

  CopyMem ((VOID *)Script, (VOID *)&ScriptIoPoll, sizeof (EFI_BOOT_SCRIPT_IO_POLL));
  CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_IO_POLL)), Data, WidthInByte);
  CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_IO_POLL) + WidthInByte), DataMask, WidthInByte);

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for PCI configuration space reads and continues when the exit criteria is satisfied or
  after a defined duration.

  @param  Width                 The width of the I/O operations.
  @param  Address               The address within the PCI configuration space.
  @param  Data                  The comparison value used for the polling exit criteria.
  @param  DataMask              Mask used for the polling criteria. The bits in the bytes below Width which are zero
                                in Data are ignored when polling the memory address
  @param  Delay                 The number of 100ns units to poll. Note that timer available may be of poorer
                                granularity so the delay may be longer.

 @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
 @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
  @note  A known Limitations in the implementation which is 64bits operations are not supported.

**/
RETURN_STATUS
EFIAPI
S3BootScriptSavePciPoll (
  IN S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN UINT64                    Address,
  IN VOID                      *Data,
  IN VOID                      *DataMask,
  IN UINT64                    Delay
  )
{
  UINT8                            *Script;
  UINT8                            WidthInByte;
  UINT8                            Length;
  EFI_BOOT_SCRIPT_PCI_CONFIG_POLL  ScriptPciPoll;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  if ((Width == S3BootScriptWidthUint64) ||
      (Width == S3BootScriptWidthFifoUint64) ||
      (Width == S3BootScriptWidthFillUint64))
  {
    return EFI_INVALID_PARAMETER;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));
  Length      = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL) + (WidthInByte * 2));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptPciPoll.OpCode  = EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE;
  ScriptPciPoll.Length  = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL) + (WidthInByte * 2));
  ScriptPciPoll.Width   = Width;
  ScriptPciPoll.Address = Address;
  ScriptPciPoll.Delay   = Delay;

  CopyMem ((VOID *)Script, (VOID *)&ScriptPciPoll, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL));
  CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL)), Data, WidthInByte);
  CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL) + WidthInByte), DataMask, WidthInByte);

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Adds a record for PCI configuration space reads and continues when the exit criteria is satisfied or
  after a defined duration.

  @param  Width                 The width of the I/O operations.
  @param  Segment               The PCI segment number for Address.
  @param  Address               The address within the PCI configuration space.
  @param  Data                  The comparison value used for the polling exit criteria.
  @param  DataMask              Mask used for the polling criteria. The bits in the bytes below Width which are zero
                                in Data are ignored when polling the memory address
  @param  Delay                 The number of 100ns units to poll. Note that timer available may be of poorer
                                granularity so the delay may be longer.

 @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
 @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.
  @note  A known Limitations in the implementation which is 64bits operations are not supported.

**/
RETURN_STATUS
EFIAPI
S3BootScriptSavePci2Poll (
  IN S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN UINT16                    Segment,
  IN UINT64                    Address,
  IN VOID                      *Data,
  IN VOID                      *DataMask,
  IN UINT64                    Delay
  )
{
  UINT8                             WidthInByte;
  UINT8                             *Script;
  UINT8                             Length;
  EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL  ScriptPci2Poll;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  if ((Width == S3BootScriptWidthUint64) ||
      (Width == S3BootScriptWidthFifoUint64) ||
      (Width == S3BootScriptWidthFillUint64))
  {
    return EFI_INVALID_PARAMETER;
  }

  WidthInByte = (UINT8)(0x01 << (Width & 0x03));
  Length      = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL) + (WidthInByte * 2));

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptPci2Poll.OpCode  = EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE;
  ScriptPci2Poll.Length  = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL) + (WidthInByte * 2));
  ScriptPci2Poll.Width   = Width;
  ScriptPci2Poll.Segment = Segment;
  ScriptPci2Poll.Address = Address;
  ScriptPci2Poll.Delay   = Delay;

  CopyMem ((VOID *)Script, (VOID *)&ScriptPci2Poll, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL));
  CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL)), Data, WidthInByte);
  CopyMem ((UINT8 *)(Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL) + WidthInByte), DataMask, WidthInByte);

  SyncBootScript (Script);

  return RETURN_SUCCESS;
}

/**
  Do the calculation of start address from which a new s3 boot script entry will write into.

  @param EntryLength      The new entry length.
  @param Position         specifies the position in the boot script table where the opcode will be
                          inserted, either before or after, depending on BeforeOrAfter.
  @param BeforeOrAfter    The flag to indicate to insert the nod before or after the position.
                          This parameter is effective when InsertFlag is TRUE
  @param Script           return out the position from which the a new s3 boot script entry will write into
**/
VOID
S3BootScriptCalculateInsertAddress (
  IN  UINT8    EntryLength,
  IN  VOID     *Position OPTIONAL,
  IN  BOOLEAN  BeforeOrAfter OPTIONAL,
  OUT UINT8    **Script
  )
{
  UINTN                          TableLength;
  UINT8                          *S3TableBase;
  UINTN                          PositionOffset;
  EFI_BOOT_SCRIPT_COMMON_HEADER  ScriptHeader;

  //
  // The entry inserting to table is already added to the end of the table
  //
  TableLength =  mS3BootScriptTablePtr->TableLength - EntryLength;
  S3TableBase = mS3BootScriptTablePtr->TableBase;
  //
  // calculate the Position offset
  //
  if (Position != NULL) {
    PositionOffset = (UINTN)Position - (UINTN)S3TableBase;

    //
    // If the BeforeOrAfter is FALSE, that means to insert the node right after the node.
    //
    if (!BeforeOrAfter) {
      CopyMem ((VOID *)&ScriptHeader, Position, sizeof (EFI_BOOT_SCRIPT_COMMON_HEADER));
      PositionOffset += (ScriptHeader.Length);
    }

    //
    // Insert the node before the adjusted Position
    //
    CopyMem (S3TableBase+PositionOffset+EntryLength, S3TableBase+PositionOffset, TableLength - PositionOffset);
    //
    // calculate the the start address for the new entry.
    //
    *Script = S3TableBase + PositionOffset;
  } else {
    if (!BeforeOrAfter) {
      //
      //  Insert the node to the end of the table
      //
      *Script = S3TableBase + TableLength;
    } else {
      //
      // Insert the node to the beginning of the table
      //
      PositionOffset = (UINTN)sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
      CopyMem (S3TableBase+PositionOffset+EntryLength, S3TableBase+PositionOffset, TableLength - PositionOffset);
      *Script = S3TableBase + PositionOffset;
    }
  }
}

/**
  Move the last boot script entry to the position

  @param  BeforeOrAfter         Specifies whether the opcode is stored before (TRUE) or after (FALSE) the position
                                in the boot script table specified by Position. If Position is NULL or points to
                                NULL then the new opcode is inserted at the beginning of the table (if TRUE) or end
                                of the table (if FALSE).
  @param  Position              On entry, specifies the position in the boot script table where the opcode will be
                                inserted, either before or after, depending on BeforeOrAfter. On exit, specifies
                                the position of the inserted opcode in the boot script table.

  @retval RETURN_OUT_OF_RESOURCES  The table is not available.
  @retval RETURN_INVALID_PARAMETER The Position is not a valid position in the boot script table.
  @retval RETURN_SUCCESS           Opcode is inserted no action is required as ACPI S3 was disabled.
**/
RETURN_STATUS
EFIAPI
S3BootScriptMoveLastOpcode (
  IN     BOOLEAN  BeforeOrAfter,
  IN OUT VOID     **Position OPTIONAL
  )
{
  UINT8                          *Script;
  VOID                           *TempPosition;
  UINTN                          StartAddress;
  UINT32                         TableLength;
  EFI_BOOT_SCRIPT_COMMON_HEADER  ScriptHeader;
  BOOLEAN                        ValidatePosition;
  UINT8                          *LastOpcode;
  UINT8                          TempBootScriptEntry[BOOT_SCRIPT_NODE_MAX_LENGTH];

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  ValidatePosition = FALSE;
  TempPosition     = (Position == NULL) ? NULL : (*Position);

  //
  // Check that the script is initialized and synced without adding an entry to the script.
  //
  Script = S3BootScriptGetEntryAddAddress (0);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  Script = mS3BootScriptTablePtr->TableBase;

  StartAddress = (UINTN)Script;
  TableLength  = mS3BootScriptTablePtr->TableLength;
  Script       = Script + sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);
  LastOpcode   = Script;
  //
  // Find the last boot Script Entry which is not the terminate node
  //
  while ((UINTN)Script < (UINTN)(StartAddress + TableLength)) {
    CopyMem ((VOID *)&ScriptHeader, Script, sizeof (EFI_BOOT_SCRIPT_COMMON_HEADER));
    if ((TempPosition != NULL) && (TempPosition == Script)) {
      //
      // If the position is specified, the position must be pointed to a boot script entry start address.
      //
      ValidatePosition = TRUE;
    }

    if (ScriptHeader.OpCode != S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE) {
      LastOpcode = Script;
    }

    Script = Script + ScriptHeader.Length;
  }

  //
  // If the position is specified, but not the start of a boot script entry, it is a invalid input
  //
  if ((TempPosition != NULL) && !ValidatePosition) {
    return RETURN_INVALID_PARAMETER;
  }

  CopyMem ((VOID *)&ScriptHeader, LastOpcode, sizeof (EFI_BOOT_SCRIPT_COMMON_HEADER));

  CopyMem ((VOID *)TempBootScriptEntry, LastOpcode, ScriptHeader.Length);
  //
  // Find the right position to write the node in
  //
  S3BootScriptCalculateInsertAddress (
    ScriptHeader.Length,
    TempPosition,
    BeforeOrAfter,
    &Script
    );
  //
  // Copy the node to Boot script table
  //
  CopyMem ((VOID *)Script, (VOID *)TempBootScriptEntry, ScriptHeader.Length);

  SyncBootScript (Script);

  //
  // return out the Position
  //
  if (Position != NULL) {
    *Position = Script;
  }

  return RETURN_SUCCESS;
}

/**
  Create a Label node in the boot script table.

  @param  BeforeOrAfter         Specifies whether the opcode is stored before (TRUE) or after (FALSE) the position
                                in the boot script table specified by Position. If Position is NULL or points to
                                NULL then the new opcode is inserted at the beginning of the table (if TRUE) or end
                                of the table (if FALSE).
  @param  Position              On entry, specifies the position in the boot script table where the opcode will be
                                inserted, either before or after, depending on BeforeOrAfter. On exit, specifies
                                the position of the inserted opcode in the boot script table.
  @param InformationLength      Length of the label in bytes
  @param Information            Label to be logged in the boot scrpit

  @retval RETURN_INVALID_PARAMETER The Position is not a valid position in the boot script table.
  @retval RETURN_OUT_OF_RESOURCES  Not enough memory for the table do operation.
  @retval RETURN_SUCCESS           Opcode is added or no action is required as ACPI S3 was disabled.

**/
RETURN_STATUS
EFIAPI
S3BootScriptLabelInternal (
  IN        BOOLEAN  BeforeOrAfter,
  IN OUT    VOID     **Position OPTIONAL,
  IN        UINT32   InformationLength,
  IN CONST  CHAR8    *Information
  )
{
  UINT8                        Length;
  UINT8                        *Script;
  EFI_BOOT_SCRIPT_INFORMATION  ScriptInformation;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  //
  // Truncation check
  //
  if (InformationLength > MAX_UINT8 - sizeof (EFI_BOOT_SCRIPT_INFORMATION)) {
    return RETURN_OUT_OF_RESOURCES;
  }

  Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_INFORMATION) + InformationLength);

  Script = S3BootScriptGetEntryAddAddress (Length);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Build script data
  //
  ScriptInformation.OpCode = S3_BOOT_SCRIPT_LIB_LABEL_OPCODE;
  ScriptInformation.Length = Length;

  ScriptInformation.InformationLength = InformationLength;

  CopyMem ((VOID *)Script, (VOID *)&ScriptInformation, sizeof (EFI_BOOT_SCRIPT_INFORMATION));
  CopyMem ((VOID *)(Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION)), (VOID *)Information, (UINTN)InformationLength);

  SyncBootScript (Script);

  return S3BootScriptMoveLastOpcode (BeforeOrAfter, Position);
}

/**
  Find a label within the boot script table and, if not present, optionally create it.

  @param  BeforeOrAfter         Specifies whether the opcode is stored before (TRUE)
                                or after (FALSE) the position in the boot script table
                                specified by Position.
  @param  CreateIfNotFound      Specifies whether the label will be created if the label
                                does not exists (TRUE) or not (FALSE).
  @param  Position              On entry, specifies the position in the boot script table
                                where the opcode will be inserted, either before or after,
                                depending on BeforeOrAfter. On exit, specifies the position
                                of the inserted opcode in the boot script table.
  @param  Label                 Points to the label which will be inserted in the boot script table.

  @retval EFI_SUCCESS           The operation succeeded or no action is required.
                                A record was added into the specified script table if ACPI S3 was enabled.
  @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.
                                If the opcode is unknow or not supported because of the PCD
                                Feature Flags.
  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.

**/
RETURN_STATUS
EFIAPI
S3BootScriptLabel (
  IN       BOOLEAN  BeforeOrAfter,
  IN       BOOLEAN  CreateIfNotFound,
  IN OUT   VOID     **Position OPTIONAL,
  IN CONST CHAR8    *Label
  )
{
  UINT8                          *Script;
  UINTN                          StartAddress;
  UINT32                         TableLength;
  EFI_BOOT_SCRIPT_COMMON_HEADER  ScriptHeader;
  EFI_BOOT_SCRIPT_TABLE_HEADER   TableHeader;
  UINT32                         LabelLength;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  //
  // Check NULL Label
  //
  if (Label == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check empty Label
  //
  if (Label[0] == '\0') {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check that the script is initialized and synced without adding an entry to the script.
  // The code must search for the label first before it knows if a new entry needs
  // to be added.
  //
  Script = S3BootScriptGetEntryAddAddress (0);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  //
  // Check the header and search for existing label.
  //
  Script = mS3BootScriptTablePtr->TableBase;
  CopyMem ((VOID *)&TableHeader, Script, sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER));
  if (TableHeader.OpCode != S3_BOOT_SCRIPT_LIB_TABLE_OPCODE) {
    return EFI_INVALID_PARAMETER;
  }

  StartAddress = (UINTN)Script;
  TableLength  = mS3BootScriptTablePtr->TableLength;
  Script       =     Script + TableHeader.Length;
  while ((UINTN)Script < (UINTN)(StartAddress + TableLength)) {
    CopyMem ((VOID *)&ScriptHeader, Script, sizeof (EFI_BOOT_SCRIPT_COMMON_HEADER));
    if (ScriptHeader.OpCode == S3_BOOT_SCRIPT_LIB_LABEL_OPCODE) {
      if (AsciiStrCmp ((CHAR8 *)(UINTN)(Script+sizeof (EFI_BOOT_SCRIPT_INFORMATION)), Label) == 0) {
        (*Position) = Script;
        return EFI_SUCCESS;
      }
    }

    Script = Script + ScriptHeader.Length;
  }

  if (CreateIfNotFound) {
    LabelLength = (UINT32)AsciiStrSize (Label);
    return S3BootScriptLabelInternal (BeforeOrAfter, Position, LabelLength, Label);
  } else {
    return EFI_NOT_FOUND;
  }
}

/**
  Compare two positions in the boot script table and return their relative position.
  @param  Position1             The positions in the boot script table to compare
  @param  Position2             The positions in the boot script table to compare
  @param  RelativePosition      On return, points to the result of the comparison

  @retval EFI_SUCCESS           The operation succeeded or no action is required.
                                A record was added into the specified script table if ACPI S3 was enabled.
  @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.
                                If the opcode is unknow or not supported because of the PCD
                                Feature Flags.
  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.

**/
RETURN_STATUS
EFIAPI
S3BootScriptCompare (
  IN  UINT8  *Position1,
  IN  UINT8  *Position2,
  OUT UINTN  *RelativePosition
  )
{
  UINT8   *Script;
  UINT32  TableLength;

  if (!mS3BootScriptAcpiS3Enable) {
    return RETURN_SUCCESS;
  }

  if (RelativePosition == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check that the script is initialized and synced without adding an entry to the script.
  //
  Script = S3BootScriptGetEntryAddAddress (0);
  if (Script == NULL) {
    return RETURN_OUT_OF_RESOURCES;
  }

  Script = mS3BootScriptTablePtr->TableBase;

  //
  // mS3BootScriptTablePtr->TableLength does not include the termination node, so add it up
  //
  TableLength = mS3BootScriptTablePtr->TableLength + sizeof (EFI_BOOT_SCRIPT_TERMINATE);
  if ((Position1 < Script) || (Position1 > Script+TableLength)) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Position2 < Script) || (Position2 > Script+TableLength)) {
    return EFI_INVALID_PARAMETER;
  }

  *RelativePosition = (Position1 < Position2) ? -1 : ((Position1 == Position2) ? 0 : 1);

  return EFI_SUCCESS;
}
