/** @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", __FUNCTION__, 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 funtion 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.
**/
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;

  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.
**/
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;

  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.
**/
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;

  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.
**/
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;

  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.
  @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 ((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.
  @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 ((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.
  @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 ((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.
  @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 ((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.
**/
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 (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.
**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveStall (
  IN  UINTN  Duration
  )
{
  UINT8                  Length;
  UINT8                  *Script;
  EFI_BOOT_SCRIPT_STALL  ScriptStall;

  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.
**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveDispatch2 (
  IN  VOID  *EntryPoint,
  IN  VOID  *Context
  )
{
  UINT8                       Length;
  UINT8                       *Script;
  EFI_BOOT_SCRIPT_DISPATCH_2  ScriptDispatch2;

  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.

**/
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;

  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.

**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveInformation (
  IN  UINT32  InformationLength,
  IN  VOID    *Information
  )
{
  UINT8                        Length;
  UINT8                        *Script;
  EFI_BOOT_SCRIPT_INFORMATION  ScriptInformation;

  //
  // 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.

**/
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.
**/
RETURN_STATUS
EFIAPI
S3BootScriptSaveDispatch (
  IN  VOID  *EntryPoint
  )
{
  UINT8                     Length;
  UINT8                     *Script;
  EFI_BOOT_SCRIPT_DISPATCH  ScriptDispatch;

  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.

**/
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;

  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.
  @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 ((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.
  @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 ((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.
**/
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];

  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.

**/
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;

  //
  // 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. A record was added into the
                                specified script table.
  @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;

  //
  // 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. A record was added into the
                                specified script table.
  @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 (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;
}
