/** @file
  Interpret and execute the S3 data in S3 boot script.

  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/
#include "InternalBootScriptLib.h"

/**
  Executes an SMBus operation to an SMBus controller. Returns when either the command has been
  executed or an error is encountered in doing the operation.

  The SmbusExecute() function provides a standard way to execute an operation as defined in the System
  Management Bus (SMBus) Specification. The resulting transaction will be either that the SMBus
  slave devices accept this transaction or that this function returns with error.

  @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             The last data that was returned from the access matched the poll
                                  exit criteria.
  @retval EFI_CRC_ERROR           Checksum is not correct (PEC is incorrect).
  @retval EFI_TIMEOUT             Timeout expired before the operation was completed. Timeout is
                                  determined by the SMBus host controller device.
  @retval EFI_OUT_OF_RESOURCES    The request could not be completed due to a lack of resources.
  @retval EFI_DEVICE_ERROR        The request was not completed because a failure that was
                                  reflected in the Host Status Register bit. Device errors are a
                                  result of a transaction collision, illegal command field,
                                  unclaimed cycle (host initiated), or bus errors (collisions).
  @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
InternalSmbusExecute (
  IN     UINTN                SmbusAddress,
  IN     EFI_SMBUS_OPERATION  Operation,
  IN OUT UINTN                *Length,
  IN OUT VOID                 *Buffer
  )
{
  EFI_STATUS  Status;
  UINT8       WorkBuffer[MAX_SMBUS_BLOCK_LEN];

  switch (Operation) {
    case EfiSmbusQuickRead:
      DEBUG ((DEBUG_INFO, "EfiSmbusQuickRead - 0x%08x\n", SmbusAddress));
      SmBusQuickRead (SmbusAddress, &Status);
      break;
    case EfiSmbusQuickWrite:
      DEBUG ((DEBUG_INFO, "EfiSmbusQuickWrite - 0x%08x\n", SmbusAddress));
      SmBusQuickWrite (SmbusAddress, &Status);
      break;
    case EfiSmbusReceiveByte:
      DEBUG ((DEBUG_INFO, "EfiSmbusReceiveByte - 0x%08x\n", SmbusAddress));
      SmBusReceiveByte (SmbusAddress, &Status);
      break;
    case EfiSmbusSendByte:
      DEBUG ((DEBUG_INFO, "EfiSmbusSendByte - 0x%08x (0x%02x)\n", SmbusAddress, (UINTN)*(UINT8 *)Buffer));
      SmBusSendByte (SmbusAddress, *(UINT8 *)Buffer, &Status);
      break;
    case EfiSmbusReadByte:
      DEBUG ((DEBUG_INFO, "EfiSmbusReadByte - 0x%08x\n", SmbusAddress));
      SmBusReadDataByte (SmbusAddress, &Status);
      break;
    case EfiSmbusWriteByte:
      DEBUG ((DEBUG_INFO, "EfiSmbusWriteByte - 0x%08x (0x%02x)\n", SmbusAddress, (UINTN)*(UINT8 *)Buffer));
      SmBusWriteDataByte (SmbusAddress, *(UINT8 *)Buffer, &Status);
      break;
    case EfiSmbusReadWord:
      DEBUG ((DEBUG_INFO, "EfiSmbusReadWord - 0x%08x\n", SmbusAddress));
      SmBusReadDataWord (SmbusAddress, &Status);
      break;
    case EfiSmbusWriteWord:
      DEBUG ((DEBUG_INFO, "EfiSmbusWriteWord - 0x%08x (0x%04x)\n", SmbusAddress, (UINTN)*(UINT16 *)Buffer));
      SmBusWriteDataWord (SmbusAddress, *(UINT16 *)Buffer, &Status);
      break;
    case EfiSmbusProcessCall:
      DEBUG ((DEBUG_INFO, "EfiSmbusProcessCall - 0x%08x (0x%04x)\n", SmbusAddress, (UINTN)*(UINT16 *)Buffer));
      SmBusProcessCall (SmbusAddress, *(UINT16 *)Buffer, &Status);
      break;
    case EfiSmbusReadBlock:
      DEBUG ((DEBUG_INFO, "EfiSmbusReadBlock - 0x%08x\n", SmbusAddress));
      SmBusReadBlock (SmbusAddress, WorkBuffer, &Status);
      break;
    case EfiSmbusWriteBlock:
      DEBUG ((DEBUG_INFO, "EfiSmbusWriteBlock - 0x%08x\n", SmbusAddress));
      SmBusWriteBlock ((SmbusAddress + SMBUS_LIB_ADDRESS (0, 0, (*Length), FALSE)), Buffer, &Status);
      break;
    case EfiSmbusBWBRProcessCall:
      DEBUG ((DEBUG_INFO, "EfiSmbusBWBRProcessCall - 0x%08x\n", SmbusAddress));
      SmBusBlockProcessCall ((SmbusAddress + SMBUS_LIB_ADDRESS (0, 0, (*Length), FALSE)), Buffer, WorkBuffer, &Status);
      break;
    default:
      return EFI_INVALID_PARAMETER;
  }

  return Status;
}

/**
  Translates boot script width and address stride to MDE library interface.


  @param Width          Width of the operation.
  @param Address        Address of the operation.
  @param AddressStride  Instride for stepping input buffer.
  @param BufferStride   Outstride for stepping output buffer.

  @retval EFI_SUCCESS  Successful translation.
  @retval EFI_INVALID_PARAMETER Width or Address is invalid.
**/
EFI_STATUS
BuildLoopData (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT64                    Address,
  OUT UINTN                     *AddressStride,
  OUT UINTN                     *BufferStride
  )
{
  UINTN  AlignMask;

  if (Width >= S3BootScriptWidthMaximum) {
    return EFI_INVALID_PARAMETER;
  }

  *AddressStride = (UINT32)(1 << (Width & 0x03));
  *BufferStride  = *AddressStride;

  AlignMask = *AddressStride - 1;
  if ((Address & AlignMask) != 0) {
    return EFI_INVALID_PARAMETER;
  }

  if ((Width >= S3BootScriptWidthFifoUint8) && (Width <= S3BootScriptWidthFifoUint64)) {
    *AddressStride = 0;
  }

  if ((Width >= S3BootScriptWidthFillUint8) && (Width <= S3BootScriptWidthFillUint64)) {
    *BufferStride = 0;
  }

  return EFI_SUCCESS;
}

/**
  Perform IO read operation

  @param[in]  Width   Width of the operation.
  @param[in]  Address Address of the operation.
  @param[in]  Count   Count of the number of accesses to perform.
  @param[out] Buffer  Pointer to the buffer to read from I/O space.

  @retval EFI_SUCCESS The data was written to the EFI System.
  @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
                                Buffer is NULL.
                                The Buffer is not aligned for the given Width.
                                Address is outside the legal range of I/O ports.

**/
EFI_STATUS
ScriptIoRead (
  IN      S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN      UINT64                    Address,
  IN      UINTN                     Count,
  OUT     VOID                      *Buffer
  )
{
  EFI_STATUS  Status;
  UINTN       AddressStride;
  UINTN       BufferStride;
  PTR         Out;

  Out.Buf = (UINT8 *)Buffer;

  if (Address > MAX_IO_ADDRESS) {
    return EFI_INVALID_PARAMETER;
  }

  Status = BuildLoopData (Width, Address, &AddressStride, &BufferStride);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Loop for each iteration and move the data
  //
  for ( ; Count > 0; Count--, Address += AddressStride, Out.Buf += BufferStride) {
    switch (Width) {
      case S3BootScriptWidthUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint8 - 0x%08x\n", (UINTN)Address));
        *Out.Uint8 = IoRead8 ((UINTN)Address);
        break;
      case S3BootScriptWidthFifoUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x\n", (UINTN)Address));
        *Out.Uint8 = IoRead8 ((UINTN)Address);
        break;
      case S3BootScriptWidthFillUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint8 - 0x%08x\n", (UINTN)Address));
        *Out.Uint8 = IoRead8 ((UINTN)Address);
        break;

      case S3BootScriptWidthUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", (UINTN)Address));
        *Out.Uint16 = IoRead16 ((UINTN)Address);
        break;
      case S3BootScriptWidthFifoUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x\n", (UINTN)Address));
        *Out.Uint16 = IoRead16 ((UINTN)Address);
        break;
      case S3BootScriptWidthFillUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint16 - 0x%08x\n", (UINTN)Address));
        *Out.Uint16 = IoRead16 ((UINTN)Address);
        break;

      case S3BootScriptWidthUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", (UINTN)Address));
        *Out.Uint32 = IoRead32 ((UINTN)Address);
        break;
      case S3BootScriptWidthFifoUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x\n", (UINTN)Address));
        *Out.Uint32 = IoRead32 ((UINTN)Address);
        break;
      case S3BootScriptWidthFillUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint32 - 0x%08x\n", (UINTN)Address));
        *Out.Uint32 = IoRead32 ((UINTN)Address);
        break;

      case S3BootScriptWidthUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint64 - 0x%08x\n", (UINTN)Address));
        *Out.Uint64 = IoRead64 ((UINTN)Address);
        break;
      case S3BootScriptWidthFifoUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x\n", (UINTN)Address));
        *Out.Uint64 = IoRead64 ((UINTN)Address);
        break;
      case S3BootScriptWidthFillUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint64 - 0x%08x\n", (UINTN)Address));
        *Out.Uint64 = IoRead64 ((UINTN)Address);
        break;

      default:
        return EFI_INVALID_PARAMETER;
    }
  }

  return EFI_SUCCESS;
}

/**
  Perform IO write operation

  @param[in]  Width Width of the operation.
  @param[in]  Address Address of the operation.
  @param[in]  Count Count of the number of accesses to perform.
  @param[in]  Buffer Pointer to the buffer to write to I/O space.

  @retval EFI_SUCCESS The data was written to the EFI System.
  @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
                                Buffer is NULL.
                                The Buffer is not aligned for the given Width.
                                Address is outside the legal range of I/O ports.

**/
EFI_STATUS
ScriptIoWrite (
  IN      S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN      UINT64                    Address,
  IN      UINTN                     Count,
  IN      VOID                      *Buffer
  )
{
  EFI_STATUS  Status;
  UINTN       AddressStride;
  UINTN       BufferStride;
  UINT64      OriginalAddress;
  PTR         In;
  PTR         OriginalIn;

  In.Buf = (UINT8 *)Buffer;

  if (Address > MAX_IO_ADDRESS) {
    return EFI_INVALID_PARAMETER;
  }

  Status = BuildLoopData (Width, Address, &AddressStride, &BufferStride);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Loop for each iteration and move the data
  //
  OriginalAddress = Address;
  OriginalIn.Buf  = In.Buf;
  for ( ; Count > 0; Count--, Address += AddressStride, In.Buf += BufferStride) {
    switch (Width) {
      case S3BootScriptWidthUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*In.Uint8));
        IoWrite8 ((UINTN)Address, *In.Uint8);
        break;
      case S3BootScriptWidthFifoUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x (0x%02x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint8));
        IoWrite8 ((UINTN)OriginalAddress, *In.Uint8);
        break;
      case S3BootScriptWidthFillUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint8));
        IoWrite8 ((UINTN)Address, *OriginalIn.Uint8);
        break;
      case S3BootScriptWidthUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*In.Uint16));
        IoWrite16 ((UINTN)Address, *In.Uint16);
        break;
      case S3BootScriptWidthFifoUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x (0x%04x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint16));
        IoWrite16 ((UINTN)OriginalAddress, *In.Uint16);
        break;
      case S3BootScriptWidthFillUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint16));
        IoWrite16 ((UINTN)Address, *OriginalIn.Uint16);
        break;
      case S3BootScriptWidthUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*In.Uint32));
        IoWrite32 ((UINTN)Address, *In.Uint32);
        break;
      case S3BootScriptWidthFifoUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x (0x%08x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint32));
        IoWrite32 ((UINTN)OriginalAddress, *In.Uint32);
        break;
      case S3BootScriptWidthFillUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint32));
        IoWrite32 ((UINTN)Address, *OriginalIn.Uint32);
        break;
      case S3BootScriptWidthUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint64 - 0x%08x (0x%016lx)\n", (UINTN)Address, *In.Uint64));
        IoWrite64 ((UINTN)Address, *In.Uint64);
        break;
      case S3BootScriptWidthFifoUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x (0x%016lx)\n", (UINTN)OriginalAddress, *In.Uint64));
        IoWrite64 ((UINTN)OriginalAddress, *In.Uint64);
        break;
      case S3BootScriptWidthFillUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint64 - 0x%08x (0x%016lx)\n", (UINTN)Address, *OriginalIn.Uint64));
        IoWrite64 ((UINTN)Address, *OriginalIn.Uint64);
        break;
      default:
        return EFI_INVALID_PARAMETER;
    }
  }

  return EFI_SUCCESS;
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_IO_WRITE OP code.

  @param Script       Pointer to the node which is to be interpreted.

  @retval EFI_SUCCESS The data was written to the EFI System.
  @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
                                Buffer is NULL.
                                The Buffer is not aligned for the given Width.
                                Address is outside the legal range of I/O ports.

**/
EFI_STATUS
BootScriptExecuteIoWrite (
  IN UINT8  *Script
  )
{
  S3_BOOT_SCRIPT_LIB_WIDTH  Width;
  UINT64                    Address;
  UINTN                     Count;
  VOID                      *Buffer;
  EFI_BOOT_SCRIPT_IO_WRITE  IoWrite;

  CopyMem ((VOID *)&IoWrite, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_IO_WRITE));
  Width   = (S3_BOOT_SCRIPT_LIB_WIDTH)IoWrite.Width;
  Address = IoWrite.Address;
  Count   = IoWrite.Count;
  Buffer  = Script + sizeof (EFI_BOOT_SCRIPT_IO_WRITE);

  DEBUG ((DEBUG_INFO, "BootScriptExecuteIoWrite - 0x%08x, 0x%08x, 0x%08x\n", (UINTN)Address, Count, (UINTN)Width));
  return ScriptIoWrite (Width, Address, Count, Buffer);
}

/**
  Perform memory read operation

  @param  Width Width of the operation.
  @param  Address Address of the operation.
  @param  Count Count of the number of accesses to perform.
  @param  Buffer Pointer to the buffer read from memory.

  @retval EFI_SUCCESS The data was written to the EFI System.
  @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
                                Buffer is NULL.
                                The Buffer is not aligned for the given Width.
  @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count
                          is not valid for this EFI System.

**/
EFI_STATUS
ScriptMemoryRead (
  IN       S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN       UINT64                    Address,
  IN       UINTN                     Count,
  IN OUT   VOID                      *Buffer
  )
{
  EFI_STATUS  Status;
  UINTN       AddressStride;
  UINTN       BufferStride;
  PTR         Out;

  Out.Buf = Buffer;

  Status = BuildLoopData (Width, Address, &AddressStride, &BufferStride);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Loop for each iteration and move the data
  //
  for ( ; Count > 0; Count--, Address += AddressStride, Out.Buf += BufferStride) {
    switch (Width) {
      case S3BootScriptWidthUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint8 - 0x%08x\n", (UINTN)Address));
        *Out.Uint8 = MmioRead8 ((UINTN)Address);
        break;
      case S3BootScriptWidthFifoUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x\n", (UINTN)Address));
        *Out.Uint8 = MmioRead8 ((UINTN)Address);
        break;
      case S3BootScriptWidthFillUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint8 - 0x%08x\n", (UINTN)Address));
        *Out.Uint8 = MmioRead8 ((UINTN)Address);
        break;

      case S3BootScriptWidthUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", (UINTN)Address));
        *Out.Uint16 = MmioRead16 ((UINTN)Address);
        break;
      case S3BootScriptWidthFifoUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x\n", (UINTN)Address));
        *Out.Uint16 = MmioRead16 ((UINTN)Address);
        break;
      case S3BootScriptWidthFillUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint16 - 0x%08x\n", (UINTN)Address));
        *Out.Uint16 = MmioRead16 ((UINTN)Address);
        break;

      case S3BootScriptWidthUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", (UINTN)Address));
        *Out.Uint32 = MmioRead32 ((UINTN)Address);
        break;
      case S3BootScriptWidthFifoUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x\n", (UINTN)Address));
        *Out.Uint32 = MmioRead32 ((UINTN)Address);
        break;
      case S3BootScriptWidthFillUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint32 - 0x%08x\n", (UINTN)Address));
        *Out.Uint32 = MmioRead32 ((UINTN)Address);
        break;

      case S3BootScriptWidthUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint64 - 0x%08x\n", (UINTN)Address));
        *Out.Uint64 = MmioRead64 ((UINTN)Address);
        break;
      case S3BootScriptWidthFifoUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x\n", (UINTN)Address));
        *Out.Uint64 = MmioRead64 ((UINTN)Address);
        break;
      case S3BootScriptWidthFillUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint64 - 0x%08x\n", (UINTN)Address));
        *Out.Uint64 = MmioRead64 ((UINTN)Address);
        break;

      default:
        return EFI_UNSUPPORTED;
    }
  }

  return EFI_SUCCESS;
}

/**
  Perform memory write operation

  @param   Width   Width of the operation.
  @param   Address Address of the operation.
  @param   Count   Count of the number of accesses to perform.
  @param   Buffer  Pointer to the buffer write to memory.

  @retval EFI_SUCCESS The data was written to the EFI System.
  @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
                                Buffer is NULL.
                                The Buffer is not aligned for the given Width.
  @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count
                          is not valid for this EFI System.

**/
EFI_STATUS
ScriptMemoryWrite (
  IN      S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN      UINT64                    Address,
  IN      UINTN                     Count,
  IN OUT  VOID                      *Buffer
  )
{
  EFI_STATUS  Status;
  UINTN       AddressStride;
  UINT64      OriginalAddress;
  UINTN       BufferStride;
  PTR         In;
  PTR         OriginalIn;

  In.Buf = Buffer;

  Status = BuildLoopData (Width, Address, &AddressStride, &BufferStride);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Loop for each iteration and move the data
  //
  OriginalAddress = Address;
  OriginalIn.Buf  = In.Buf;
  for ( ; Count > 0; Count--, Address += AddressStride, In.Buf += BufferStride) {
    switch (Width) {
      case S3BootScriptWidthUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*In.Uint8));
        MmioWrite8 ((UINTN)Address, *In.Uint8);
        break;
      case S3BootScriptWidthFifoUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x (0x%02x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint8));
        MmioWrite8 ((UINTN)OriginalAddress, *In.Uint8);
        break;
      case S3BootScriptWidthFillUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint8));
        MmioWrite8 ((UINTN)Address, *OriginalIn.Uint8);
        break;
      case S3BootScriptWidthUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*In.Uint16));
        MmioWrite16 ((UINTN)Address, *In.Uint16);
        break;
      case S3BootScriptWidthFifoUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x (0x%04x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint16));
        MmioWrite16 ((UINTN)OriginalAddress, *In.Uint16);
        break;
      case S3BootScriptWidthFillUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint16));
        MmioWrite16 ((UINTN)Address, *OriginalIn.Uint16);
        break;
      case S3BootScriptWidthUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*In.Uint32));
        MmioWrite32 ((UINTN)Address, *In.Uint32);
        break;
      case S3BootScriptWidthFifoUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x (0x%08x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint32));
        MmioWrite32 ((UINTN)OriginalAddress, *In.Uint32);
        break;
      case S3BootScriptWidthFillUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint32));
        MmioWrite32 ((UINTN)Address, *OriginalIn.Uint32);
        break;
      case S3BootScriptWidthUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint64 - 0x%08x (0x%016lx)\n", (UINTN)Address, *In.Uint64));
        MmioWrite64 ((UINTN)Address, *In.Uint64);
        break;
      case S3BootScriptWidthFifoUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x (0x%016lx)\n", (UINTN)OriginalAddress, *In.Uint64));
        MmioWrite64 ((UINTN)OriginalAddress, *In.Uint64);
        break;
      case S3BootScriptWidthFillUint64:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint64 - 0x%08x (0x%016lx)\n", (UINTN)Address, *OriginalIn.Uint64));
        MmioWrite64 ((UINTN)Address, *OriginalIn.Uint64);
        break;
      default:
        return EFI_UNSUPPORTED;
    }
  }

  return EFI_SUCCESS;
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_MEM_WRITE OP code.

  @param[in]  Script Pointer to the node which is to be interpreted.

  @retval EFI_SUCCESS The data was written to the EFI System.
  @retval EFI_INVALID_PARAMETER Width is invalid for this EFI System.
                                Buffer is NULL.
                                The Buffer is not aligned for the given Width.
  @retval EFI_UNSUPPORTED The address range specified by Address, Width, and Count
                          is not valid for this EFI System.

**/
EFI_STATUS
BootScriptExecuteMemoryWrite (
  IN UINT8  *Script
  )
{
  VOID                       *Buffer;
  S3_BOOT_SCRIPT_LIB_WIDTH   Width;
  UINT64                     Address;
  UINTN                      Count;
  EFI_BOOT_SCRIPT_MEM_WRITE  MemWrite;

  CopyMem ((VOID *)&MemWrite, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_MEM_WRITE));
  Width   = (S3_BOOT_SCRIPT_LIB_WIDTH)MemWrite.Width;
  Address = MemWrite.Address;
  Count   = MemWrite.Count;
  Buffer  = Script + sizeof (EFI_BOOT_SCRIPT_MEM_WRITE);

  DEBUG ((DEBUG_INFO, "BootScriptExecuteMemoryWrite - 0x%08x, 0x%08x, 0x%08x\n", (UINTN)Address, Count, (UINTN)Width));
  return ScriptMemoryWrite (Width, Address, Count, Buffer);
}

/**
  Performance PCI configuration 2 read operation

  @param  Width   Width of the operation.
  @param  Segment Pci segment number
  @param  Address Address of the operation.
  @param  Count   Count of the number of accesses to perform.
  @param  Buffer  Pointer to the buffer read from PCI config space

  @retval EFI_SUCCESS The read succeed.
  @retval EFI_INVALID_PARAMETER if Width is not defined
  @note  A known Limitations in the implementation which is 64bits operations are not supported.

**/
EFI_STATUS
ScriptPciCfg2Read (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT16                    Segment,
  IN  UINT64                    Address,
  IN  UINTN                     Count,
  OUT VOID                      *Buffer
  )
{
  EFI_STATUS  Status;
  UINTN       AddressStride;
  UINTN       BufferStride;
  PTR         Out;
  UINT64      PciAddress;

  Out.Buf = (UINT8 *)Buffer;

  PciAddress = PCI_ADDRESS_ENCODE (Segment, Address);

  Status = BuildLoopData (Width, PciAddress, &AddressStride, &BufferStride);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Loop for each iteration and move the data
  //
  for ( ; Count > 0; Count--, PciAddress += AddressStride, Out.Buf += BufferStride) {
    switch (Width) {
      case S3BootScriptWidthUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint8 - 0x%016lx\n", PciAddress));
        *Out.Uint8 = PciSegmentRead8 (PciAddress);
        break;
      case S3BootScriptWidthFifoUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint8 - 0x%016lx\n", PciAddress));
        *Out.Uint8 = PciSegmentRead8 (PciAddress);
        break;
      case S3BootScriptWidthFillUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint8 - 0x%016lx\n", PciAddress));
        *Out.Uint8 = PciSegmentRead8 (PciAddress);
        break;

      case S3BootScriptWidthUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint16 - 0x%016lx\n", PciAddress));
        *Out.Uint16 = PciSegmentRead16 (PciAddress);
        break;
      case S3BootScriptWidthFifoUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint16 - 0x%016lx\n", PciAddress));
        *Out.Uint16 = PciSegmentRead16 (PciAddress);
        break;
      case S3BootScriptWidthFillUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint16 - 0x%016lx\n", PciAddress));
        *Out.Uint16 = PciSegmentRead16 (PciAddress);
        break;

      case S3BootScriptWidthUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint32 - 0x%016lx\n", PciAddress));
        *Out.Uint32 = PciSegmentRead32 (PciAddress);
        break;
      case S3BootScriptWidthFifoUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint32 - 0x%016lx\n", PciAddress));
        *Out.Uint32 = PciSegmentRead32 (PciAddress);
        break;
      case S3BootScriptWidthFillUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint32 - 0x%016lx\n", PciAddress));
        *Out.Uint32 = PciSegmentRead32 (PciAddress);
        break;

      default:
        return EFI_INVALID_PARAMETER;
    }
  }

  return EFI_SUCCESS;
}

/**
  Performance PCI configuration 2 write operation

  @param  Width   Width of the operation.
  @param  Segment Pci segment number
  @param  Address Address of the operation.
  @param  Count   Count of the number of accesses to perform.
  @param  Buffer  Pointer to the buffer write to PCI config space

  @retval EFI_SUCCESS The write succeed.
  @retval EFI_INVALID_PARAMETER if Width is not defined
  @note  A known Limitations in the implementation which is 64bits operations are not supported.

**/
EFI_STATUS
ScriptPciCfg2Write (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT16                    Segment,
  IN  UINT64                    Address,
  IN  UINTN                     Count,
  IN  VOID                      *Buffer
  )
{
  EFI_STATUS  Status;
  UINTN       AddressStride;
  UINTN       BufferStride;
  UINT64      OriginalPciAddress;
  PTR         In;
  PTR         OriginalIn;
  UINT64      PciAddress;

  In.Buf = (UINT8 *)Buffer;

  PciAddress = PCI_ADDRESS_ENCODE (Segment, Address);

  Status = BuildLoopData (Width, PciAddress, &AddressStride, &BufferStride);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Loop for each iteration and move the data
  //
  OriginalPciAddress = PciAddress;
  OriginalIn.Buf     = In.Buf;
  for ( ; Count > 0; Count--, PciAddress += AddressStride, In.Buf += BufferStride) {
    switch (Width) {
      case S3BootScriptWidthUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint8 - 0x%016lx (0x%02x)\n", PciAddress, (UINTN)*In.Uint8));
        PciSegmentWrite8 (PciAddress, *In.Uint8);
        break;
      case S3BootScriptWidthFifoUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint8 - 0x%016lx (0x%02x)\n", OriginalPciAddress, (UINTN)*In.Uint8));
        PciSegmentWrite8 (OriginalPciAddress, *In.Uint8);
        break;
      case S3BootScriptWidthFillUint8:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint8 - 0x%016lx (0x%02x)\n", PciAddress, (UINTN)*OriginalIn.Uint8));
        PciSegmentWrite8 (PciAddress, *OriginalIn.Uint8);
        break;
      case S3BootScriptWidthUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint16 - 0x%016lx (0x%04x)\n", PciAddress, (UINTN)*In.Uint16));
        PciSegmentWrite16 (PciAddress, *In.Uint16);
        break;
      case S3BootScriptWidthFifoUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint16 - 0x%016lx (0x%04x)\n", OriginalPciAddress, (UINTN)*In.Uint16));
        PciSegmentWrite16 (OriginalPciAddress, *In.Uint16);
        break;
      case S3BootScriptWidthFillUint16:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint16 - 0x%016lx (0x%04x)\n", PciAddress, (UINTN)*OriginalIn.Uint16));
        PciSegmentWrite16 (PciAddress, *OriginalIn.Uint16);
        break;
      case S3BootScriptWidthUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthUint32 - 0x%016lx (0x%08x)\n", PciAddress, (UINTN)*In.Uint32));
        PciSegmentWrite32 (PciAddress, *In.Uint32);
        break;
      case S3BootScriptWidthFifoUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFifoUint32 - 0x%016lx (0x%08x)\n", OriginalPciAddress, (UINTN)*In.Uint32));
        PciSegmentWrite32 (OriginalPciAddress, *In.Uint32);
        break;
      case S3BootScriptWidthFillUint32:
        DEBUG ((DEBUG_INFO, "S3BootScriptWidthFillUint32 - 0x%016lx (0x%08x)\n", (UINTN)PciAddress, (UINTN)*OriginalIn.Uint32));
        PciSegmentWrite32 (PciAddress, *OriginalIn.Uint32);
        break;
      default:
        return EFI_INVALID_PARAMETER;
    }
  }

  return EFI_SUCCESS;
}

/**
  Performance PCI configuration read operation

  @param     Width                      Width of the operation.
  @param     Address                    Address of the operation.
  @param     Count                      Count of the number of accesses to perform.
  @param     Buffer                     Pointer to the buffer to read from PCI config space.

  @retval    EFI_SUCCESS                The data was written to the EFI System.
  @retval    EFI_INVALID_PARAMETER      Width is invalid for this EFI System.
                                        Buffer is NULL.
                                        The Buffer is not aligned for the given Width.
                                        Address is outside the legal range of I/O ports.

**/
EFI_STATUS
ScriptPciCfgRead (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT64                    Address,
  IN  UINTN                     Count,
  OUT VOID                      *Buffer
  )
{
  return ScriptPciCfg2Read (Width, 0, Address, Count, Buffer);
}

/**
  Performance PCI configuration write operation

  @param     Width                      Width of the operation.
  @param     Address                    Address of the operation.
  @param     Count                      Count of the number of accesses to perform.
  @param     Buffer                     Pointer to the buffer to write to PCI config space.

  @retval    EFI_SUCCESS                The data was written to the EFI System.
  @retval    EFI_INVALID_PARAMETER      Width is invalid for this EFI System.
                                        Buffer is NULL.
                                        The Buffer is not aligned for the given Width.
                                        Address is outside the legal range of I/O ports.

**/
EFI_STATUS
EFIAPI
ScriptPciCfgWrite (
  IN  S3_BOOT_SCRIPT_LIB_WIDTH  Width,
  IN  UINT64                    Address,
  IN  UINTN                     Count,
  IN  VOID                      *Buffer
  )
{
  return ScriptPciCfg2Write (Width, 0, Address, Count, Buffer);
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE OP code.

  @param  Script        The pointer of typed node in boot script table

  @retval EFI_SUCCESS  The operation was executed successfully
**/
EFI_STATUS
BootScriptExecutePciCfgWrite (
  IN UINT8  *Script
  )
{
  VOID                              *Buffer;
  S3_BOOT_SCRIPT_LIB_WIDTH          Width;
  UINT64                            Address;
  UINTN                             Count;
  EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE  PciCfgWrite;

  CopyMem ((VOID *)&PciCfgWrite, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE));

  Width   = (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfgWrite.Width;
  Address = PciCfgWrite.Address;
  Count   = PciCfgWrite.Count;
  Buffer  = Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE);

  DEBUG ((DEBUG_INFO, "BootScriptExecutePciCfgWrite - 0x%016lx, 0x%08x, 0x%08x\n", PCI_ADDRESS_ENCODE (0, Address), Count, (UINTN)Width));
  return ScriptPciCfgWrite (Width, Address, Count, Buffer);
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_IO_READ_WRITE OP code.

  @param Script   The pointer of typed node in boot script table
  @param AndMask  Mask value for 'and' operation
  @param OrMask   Mask value for 'or' operation

  @retval EFI_SUCCESS    The operation was executed successfully
**/
EFI_STATUS
BootScriptExecuteIoReadWrite (
  IN  UINT8   *Script,
  IN  UINT64  AndMask,
  IN  UINT64  OrMask
  )

{
  EFI_STATUS                     Status;
  UINT64                         Data;
  EFI_BOOT_SCRIPT_IO_READ_WRITE  IoReadWrite;

  Data = 0;

  CopyMem ((VOID *)&IoReadWrite, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE));

  DEBUG ((DEBUG_INFO, "BootScriptExecuteIoReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)IoReadWrite.Address, AndMask, OrMask));

  Status = ScriptIoRead (
             (S3_BOOT_SCRIPT_LIB_WIDTH)IoReadWrite.Width,
             IoReadWrite.Address,
             1,
             &Data
             );
  if (!EFI_ERROR (Status)) {
    Data   = (Data & AndMask) | OrMask;
    Status = ScriptIoWrite (
               (S3_BOOT_SCRIPT_LIB_WIDTH)IoReadWrite.Width,
               IoReadWrite.Address,
               1,
               &Data
               );
  }

  return Status;
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_MEM_READ_WRITE OP code.

  @param Script    The pointer of typed node in boot script table
  @param AndMask   Mask value for 'and' operation
  @param OrMask    Mask value for 'or' operation

  @retval EFI_SUCCESS The operation was executed successfully
**/
EFI_STATUS
BootScriptExecuteMemoryReadWrite (
  IN UINT8   *Script,
  IN UINT64  AndMask,
  IN UINT64  OrMask
  )

{
  EFI_STATUS                      Status;
  UINT64                          Data;
  EFI_BOOT_SCRIPT_MEM_READ_WRITE  MemReadWrite;

  Data = 0;

  CopyMem ((VOID *)&MemReadWrite, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE));

  DEBUG ((DEBUG_INFO, "BootScriptExecuteMemoryReadWrite - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)MemReadWrite.Address, AndMask, OrMask));

  Status = ScriptMemoryRead (
             (S3_BOOT_SCRIPT_LIB_WIDTH)MemReadWrite.Width,
             MemReadWrite.Address,
             1,
             &Data
             );
  if (!EFI_ERROR (Status)) {
    Data   = (Data & AndMask) | OrMask;
    Status = ScriptMemoryWrite (
               (S3_BOOT_SCRIPT_LIB_WIDTH)MemReadWrite.Width,
               MemReadWrite.Address,
               1,
               &Data
               );
  }

  return Status;
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_PCI_CFG_READ_WRITE OP code.

  @param Script   The pointer of typed node in boot script table
  @param AndMask  Mask value for 'and' operation
  @param OrMask   Mask value for 'or' operation

  @retval EFI_SUCCESS   The operation was executed successfully
**/
EFI_STATUS
BootScriptExecutePciCfgReadWrite (
  IN UINT8   *Script,
  IN UINT64  AndMask,
  IN UINT64  OrMask
  )

{
  EFI_STATUS                             Status;
  UINT64                                 Data;
  EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE  PciCfgReadWrite;

  Data = 0;

  CopyMem ((VOID *)&PciCfgReadWrite, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE));

  DEBUG ((DEBUG_INFO, "BootScriptExecutePciCfgReadWrite - 0x%016lx, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (0, PciCfgReadWrite.Address), AndMask, OrMask));

  Status = ScriptPciCfgRead (
             (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfgReadWrite.Width,
             PciCfgReadWrite.Address,
             1,
             &Data
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Data = (Data & AndMask) | OrMask;

  Status = ScriptPciCfgWrite (
             (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfgReadWrite.Width,
             PciCfgReadWrite.Address,
             1,
             &Data
             );

  return Status;
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_SMBUS_EXECUTE OP code.

  @param Script  The pointer of typed node in boot script table

  @retval EFI_SUCCESS      The operation was executed successfully
  @retval EFI_UNSUPPORTED  Cannot locate smbus ppi or occur error of script execution
  @retval Others           Result of script execution
**/
EFI_STATUS
BootScriptExecuteSmbusExecute (
  IN UINT8  *Script
  )
{
  UINTN                          SmBusAddress;
  UINTN                          DataSize;
  EFI_BOOT_SCRIPT_SMBUS_EXECUTE  SmbusExecuteEntry;

  CopyMem ((VOID *)&SmbusExecuteEntry, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE));

  DEBUG ((DEBUG_INFO, "BootScriptExecuteSmbusExecute - 0x%08x, 0x%08x\n", (UINTN)SmbusExecuteEntry.SmBusAddress, (UINTN)SmbusExecuteEntry.Operation));

  SmBusAddress = (UINTN)SmbusExecuteEntry.SmBusAddress;
  DataSize     = (UINTN)SmbusExecuteEntry.DataSize;
  return InternalSmbusExecute (
           SmBusAddress,
           (EFI_SMBUS_OPERATION)SmbusExecuteEntry.Operation,
           &DataSize,
           Script + sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)
           );
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_STALL OP code.

  @param Script      The pointer of typed node in boot script table

  @retval EFI_SUCCESS The operation was executed successfully
**/
EFI_STATUS
BootScriptExecuteStall (
  IN UINT8  *Script
  )
{
  EFI_BOOT_SCRIPT_STALL  Stall;

  CopyMem ((VOID *)&Stall, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_STALL));

  DEBUG ((DEBUG_INFO, "BootScriptExecuteStall - 0x%08x\n", (UINTN)Stall.Duration));

  MicroSecondDelay ((UINTN)Stall.Duration);
  return EFI_SUCCESS;
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_DISPATCH OP code.

  @param Script  The pointer of typed node in boot script table
  @retval EFI_SUCCESS  The operation was executed successfully
**/
EFI_STATUS
BootScriptExecuteDispatch (
  IN UINT8  *Script
  )
{
  EFI_STATUS                Status;
  DISPATCH_ENTRYPOINT_FUNC  EntryFunc;
  EFI_BOOT_SCRIPT_DISPATCH  ScriptDispatch;

  CopyMem ((VOID *)&ScriptDispatch, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_DISPATCH));
  EntryFunc = (DISPATCH_ENTRYPOINT_FUNC)(UINTN)(ScriptDispatch.EntryPoint);

  DEBUG ((DEBUG_INFO, "BootScriptExecuteDispatch - 0x%08x\n", (UINTN)ScriptDispatch.EntryPoint));

  Status = EntryFunc (NULL, NULL);

  return Status;
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_DISPATCH_2 OP code.

  @param  Script       The pointer of typed node in boot script table
  @retval EFI_SUCCESS  The operation was executed successfully
**/
EFI_STATUS
BootScriptExecuteDispatch2 (
  IN UINT8  *Script
  )
{
  EFI_STATUS                  Status;
  DISPATCH_ENTRYPOINT_FUNC    EntryFunc;
  EFI_BOOT_SCRIPT_DISPATCH_2  ScriptDispatch2;

  CopyMem ((VOID *)&ScriptDispatch2, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_DISPATCH_2));

  DEBUG ((DEBUG_INFO, "BootScriptExecuteDispatch2 - 0x%08x(0x%08x)\n", (UINTN)ScriptDispatch2.EntryPoint, (UINTN)ScriptDispatch2.Context));

  EntryFunc = (DISPATCH_ENTRYPOINT_FUNC)(UINTN)(ScriptDispatch2.EntryPoint);

  Status = EntryFunc (NULL, (VOID *)(UINTN)ScriptDispatch2.Context);

  return Status;
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_MEM_POLL OP code.

  @param  Script  The pointer of typed node in boot script table
  @param  AndMask  Mask value for 'and' operation
  @param  OrMask   Mask value for 'or' operation

  @retval EFI_DEVICE_ERROR Data polled from memory does not equal to
                           the epecting data within the Loop Times.
  @retval EFI_SUCCESS      The operation was executed successfully
**/
EFI_STATUS
BootScriptExecuteMemPoll (
  IN UINT8   *Script,
  IN UINT64  AndMask,
  IN UINT64  OrMask
  )
{
  UINT64                    Data;
  UINT64                    LoopTimes;
  EFI_STATUS                Status;
  EFI_BOOT_SCRIPT_MEM_POLL  MemPoll;

  CopyMem ((VOID *)&MemPoll, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_MEM_POLL));

  DEBUG ((DEBUG_INFO, "BootScriptExecuteMemPoll - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)MemPoll.Address, AndMask, OrMask));

  Data   = 0;
  Status = ScriptMemoryRead (
             (S3_BOOT_SCRIPT_LIB_WIDTH)MemPoll.Width,
             MemPoll.Address,
             1,
             &Data
             );
  if ((!EFI_ERROR (Status)) && ((Data & AndMask) == OrMask)) {
    return EFI_SUCCESS;
  }

  for (LoopTimes = 0; LoopTimes < MemPoll.LoopTimes; LoopTimes++) {
    MicroSecondDelay ((UINTN)MemPoll.Duration);

    Data   = 0;
    Status = ScriptMemoryRead (
               (S3_BOOT_SCRIPT_LIB_WIDTH)MemPoll.Width,
               MemPoll.Address,
               1,
               &Data
               );
    if ((!EFI_ERROR (Status)) && ((Data & AndMask) == OrMask)) {
      return EFI_SUCCESS;
    }
  }

  if (LoopTimes < MemPoll.LoopTimes) {
    return EFI_SUCCESS;
  } else {
    return EFI_DEVICE_ERROR;
  }
}

/**
  Execute the boot script to interpret the Store arbitrary information.
  This opcode is a no-op on dispatch and is only used for debugging script issues.

  @param Script       The pointer of node in boot script table

**/
VOID
BootScriptExecuteInformation (
  IN UINT8  *Script
  )

{
  EFI_BOOT_SCRIPT_INFORMATION  Information;
  UINT8                        *InformationData;

  CopyMem ((VOID *)&Information, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_INFORMATION));

  InformationData = Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION);
  DEBUG ((DEBUG_INFO, "BootScriptExecuteInformation - 0x%08x\n", (UINTN)InformationData));

  DUMP_HEX (DEBUG_INFO, 0, InformationData, Information.InformationLength, "BootScriptInformation: ");
}

/**
  Execute the boot script to interpret the Label information.

  @param Script       The pointer of node in boot script table

**/
VOID
BootScriptExecuteLabel (
  IN UINT8  *Script
  )

{
  EFI_BOOT_SCRIPT_INFORMATION  Information;
  UINT8                        *InformationData;

  CopyMem ((VOID *)&Information, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_INFORMATION));

  InformationData = Script + sizeof (EFI_BOOT_SCRIPT_INFORMATION);
  DEBUG ((DEBUG_INFO, "BootScriptExecuteLabel - 0x%08x\n", (UINTN)InformationData));

  DUMP_HEX (DEBUG_INFO, 0, InformationData, Information.InformationLength, "BootScriptLabel: ");
}

/**
  calculate the mask value for 'and' and 'or' operation
  @param ScriptHeader   The pointer of header of node in boot script table
  @param AndMask  The Mask value for 'and' operation
  @param OrMask   The Mask value for 'or' operation
  @param Script   Pointer to the entry.

**/
VOID
CheckAndOrMask (
  IN   EFI_BOOT_SCRIPT_COMMON_HEADER  *ScriptHeader,
  OUT UINT64                          *AndMask,
  OUT UINT64                          *OrMask,
  IN  UINT8                           *Script
  )
{
  UINT8  *DataPtr;
  UINTN  Size;

  switch (ScriptHeader->OpCode) {
    case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:
      Size = sizeof (EFI_BOOT_SCRIPT_IO_READ_WRITE);
      break;

    case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:
      Size = sizeof (EFI_BOOT_SCRIPT_MEM_READ_WRITE);
      break;

    case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:
      Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE);
      break;
    case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:
      Size = sizeof (EFI_BOOT_SCRIPT_MEM_POLL);
      break;

    case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:
      Size = sizeof (EFI_BOOT_SCRIPT_IO_POLL);
      break;

    case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:
      Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE);
      break;

    case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:
      Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL);
      break;

    case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:
      Size = sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL);
      break;

    default:
      return;
  }

  DataPtr = Script + Size;

  switch (ScriptHeader->Width) {
    case S3BootScriptWidthUint8:
      *AndMask = (UINT64)(*(UINT8 *)(DataPtr + 1));
      *OrMask  = (UINT64)(*DataPtr);
      break;

    case S3BootScriptWidthUint16:
      *AndMask = (UINT64)(*(UINT16 *)(DataPtr + 2));
      *OrMask  = (UINT64)(*(UINT16 *)DataPtr);
      break;

    case S3BootScriptWidthUint32:
      *AndMask = (UINT64)(*(UINT32 *)(DataPtr + 4));
      *OrMask  = (UINT64)(*(UINT32 *)DataPtr);
      break;

    case S3BootScriptWidthUint64:
      *AndMask = (UINT64)(*(UINT64 *)(DataPtr + 8));
      *OrMask  = (UINT64)(*(UINT64 *)DataPtr);
      break;

    default:
      break;
  }

  return;
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_IO_POLL OP code.

  @param  Script  The pointer of typed node in boot script table
  @param  AndMask  Mask value for 'and' operation
  @param  OrMask   Mask value for 'or' operation

  @retval EFI_DEVICE_ERROR Data polled from memory does not equal to
                           the epecting data within the Loop Times.
  @retval EFI_SUCCESS      The operation was executed successfully
**/
EFI_STATUS
BootScriptExecuteIoPoll (
  IN UINT8   *Script,
  IN UINT64  AndMask,
  IN UINT64  OrMask
  )
{
  EFI_STATUS               Status;
  UINT64                   Data;
  UINT64                   LoopTimes;
  EFI_BOOT_SCRIPT_IO_POLL  IoPoll;

  CopyMem ((VOID *)&IoPoll, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_IO_POLL));

  DEBUG ((DEBUG_INFO, "BootScriptExecuteIoPoll - 0x%08x, 0x%016lx, 0x%016lx\n", (UINTN)IoPoll.Address, AndMask, OrMask));

  Data   = 0;
  Status = ScriptIoRead (
             (S3_BOOT_SCRIPT_LIB_WIDTH)IoPoll.Width,
             IoPoll.Address,
             1,
             &Data
             );
  if ((!EFI_ERROR (Status)) && ((Data & AndMask) == OrMask)) {
    return EFI_SUCCESS;
  }

  for (LoopTimes = 0; LoopTimes < IoPoll.Delay; LoopTimes++) {
    NanoSecondDelay (100);
    Data   = 0;
    Status = ScriptIoRead (
               (S3_BOOT_SCRIPT_LIB_WIDTH)IoPoll.Width,
               IoPoll.Address,
               1,
               &Data
               );
    if ((!EFI_ERROR (Status)) && ((Data & AndMask) == OrMask)) {
      return EFI_SUCCESS;
    }
  }

  if (LoopTimes < IoPoll.Delay) {
    return EFI_SUCCESS;
  } else {
    return EFI_DEVICE_ERROR;
  }
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE OP code.

  @param    Script              The pointer of S3 boot script

  @retval   EFI_SUCCESS         The operation was executed successfully

**/
EFI_STATUS
BootScriptExecutePciCfg2Write (
  IN UINT8  *Script
  )
{
  VOID                               *Buffer;
  S3_BOOT_SCRIPT_LIB_WIDTH           Width;
  UINT16                             Segment;
  UINT64                             Address;
  UINTN                              Count;
  EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE  PciCfg2Write;

  CopyMem ((VOID *)&PciCfg2Write, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE));

  Width   = (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfg2Write.Width;
  Segment = PciCfg2Write.Segment;
  Address = PciCfg2Write.Address;
  Count   = PciCfg2Write.Count;
  Buffer  = Script + sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE);

  DEBUG ((DEBUG_INFO, "BootScriptExecutePciCfg2Write - 0x%016lx, 0x%08x, 0x%08x\n", PCI_ADDRESS_ENCODE (Segment, Address), Count, (UINTN)Width));
  return ScriptPciCfg2Write (Width, Segment, Address, Count, Buffer);
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE OP code.

  @param     Script                     The pointer of S3 boot script
  @param     AndMask                    Mask value for 'and' operation
  @param     OrMask                     Mask value for 'or' operation

  @retval    EFI_SUCCESS                The operation was executed successfully

**/
EFI_STATUS
BootScriptExecutePciCfg2ReadWrite (
  IN UINT8   *Script,
  IN UINT64  AndMask,
  IN UINT64  OrMask
  )
{
  UINT64                                  Data;
  EFI_STATUS                              Status;
  EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE  PciCfg2ReadWrite;

  Data = 0;

  CopyMem ((VOID *)&PciCfg2ReadWrite, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE));

  DEBUG ((DEBUG_INFO, "BootScriptExecutePciCfg2ReadWrite - 0x%016lx, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (PciCfg2ReadWrite.Segment, PciCfg2ReadWrite.Address), AndMask, OrMask));

  Status = ScriptPciCfg2Read (
             (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfg2ReadWrite.Width,
             PciCfg2ReadWrite.Segment,
             PciCfg2ReadWrite.Address,
             1,
             &Data
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Data   = (Data & AndMask) | OrMask;
  Status = ScriptPciCfg2Write (
             (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfg2ReadWrite.Width,
             PciCfg2ReadWrite.Segment,
             PciCfg2ReadWrite.Address,
             1,
             &Data
             );
  return Status;
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG_POLL OP code.

  @param     Script                     The pointer of S3 boot script
  @param     AndMask                    Mask value for 'and' operation
  @param     OrMask                     Mask value for 'or' operation

  @retval    EFI_SUCCESS                The operation was executed successfully
  @retval    EFI_DEVICE_ERROR           Data polled from Pci configuration space does not equal to
                                        epecting data within the Loop Times.
**/
EFI_STATUS
BootScriptPciCfgPoll (
  IN UINT8   *Script,
  IN UINT64  AndMask,
  IN UINT64  OrMask
  )
{
  UINT64                           Data;
  UINT64                           LoopTimes;
  EFI_STATUS                       Status;
  EFI_BOOT_SCRIPT_PCI_CONFIG_POLL  PciCfgPoll;

  CopyMem ((VOID *)&PciCfgPoll, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL));

  DEBUG ((DEBUG_INFO, "BootScriptPciCfgPoll - 0x%016lx, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (0, PciCfgPoll.Address), AndMask, OrMask));

  Data   = 0;
  Status = ScriptPciCfgRead (
             (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfgPoll.Width,
             PciCfgPoll.Address,
             1,
             &Data
             );
  if ((!EFI_ERROR (Status)) && ((Data & AndMask) == OrMask)) {
    return EFI_SUCCESS;
  }

  for (LoopTimes = 0; LoopTimes < PciCfgPoll.Delay; LoopTimes++) {
    NanoSecondDelay (100);
    Data   = 0;
    Status = ScriptPciCfgRead (
               (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfgPoll.Width,
               PciCfgPoll.Address,
               1,
               &Data
               );
    if ((!EFI_ERROR (Status)) &&
        ((Data & AndMask) == OrMask))
    {
      return EFI_SUCCESS;
    }
  }

  if (LoopTimes < PciCfgPoll.Delay) {
    return EFI_SUCCESS;
  } else {
    return EFI_DEVICE_ERROR;
  }
}

/**
  Interpret the boot script node with EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL OP code.

  @param     Script                     The pointer of S3 Boot Script
  @param     AndMask                    Mask value for 'and' operation
  @param     OrMask                     Mask value for 'or' operation

  @retval    EFI_SUCCESS                The operation was executed successfully
  @retval    EFI_DEVICE_ERROR           Data polled from Pci configuration space does not equal to
                                        epecting data within the Loop Times.

**/
EFI_STATUS
BootScriptPciCfg2Poll (
  IN UINT8   *Script,
  IN UINT64  AndMask,
  IN UINT64  OrMask
  )
{
  EFI_STATUS                        Status;
  UINT64                            Data;
  UINT64                            LoopTimes;
  EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL  PciCfg2Poll;

  Data = 0;
  CopyMem ((VOID *)&PciCfg2Poll, (VOID *)Script, sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL));

  DEBUG ((DEBUG_INFO, "BootScriptPciCfg2Poll - 0x%016lx, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (PciCfg2Poll.Segment, PciCfg2Poll.Address), AndMask, OrMask));

  Status = ScriptPciCfg2Read (
             (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfg2Poll.Width,
             PciCfg2Poll.Segment,
             PciCfg2Poll.Address,
             1,
             &Data
             );
  if ((!EFI_ERROR (Status)) && ((Data & AndMask) == OrMask)) {
    return EFI_SUCCESS;
  }

  for (LoopTimes = 0; LoopTimes < PciCfg2Poll.Delay; LoopTimes++) {
    NanoSecondDelay (100);

    Data   = 0;
    Status = ScriptPciCfg2Read (
               (S3_BOOT_SCRIPT_LIB_WIDTH)PciCfg2Poll.Width,
               PciCfg2Poll.Segment,
               PciCfg2Poll.Address,
               1,
               &Data
               );
    if ((!EFI_ERROR (Status)) &&  ((Data & AndMask) == OrMask)) {
      return EFI_SUCCESS;
    }
  }

  if (LoopTimes < PciCfg2Poll.Delay) {
    return EFI_SUCCESS;
  } else {
    return EFI_DEVICE_ERROR;
  }
}

/**
  Executes the S3 boot script table.

  @retval RETURN_SUCCESS           The boot script table was executed successfully.
  @retval RETURN_UNSUPPORTED       Invalid script table or opcode.

**/
RETURN_STATUS
EFIAPI
S3BootScriptExecute (
  VOID
  )
{
  EFI_STATUS                     Status;
  UINT8                          *Script;
  UINTN                          StartAddress;
  UINT32                         TableLength;
  UINT64                         AndMask;
  UINT64                         OrMask;
  EFI_BOOT_SCRIPT_COMMON_HEADER  ScriptHeader;
  EFI_BOOT_SCRIPT_TABLE_HEADER   TableHeader;

  Script = mS3BootScriptTablePtr->TableBase;
  if (Script != 0) {
    CopyMem ((VOID *)&TableHeader, Script, sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER));
  } else {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((DEBUG_INFO, "S3BootScriptExecute:\n"));
  if (TableHeader.OpCode != S3_BOOT_SCRIPT_LIB_TABLE_OPCODE) {
    return EFI_UNSUPPORTED;
  }

  DEBUG ((DEBUG_INFO, "TableHeader - 0x%08x\n", Script));

  StartAddress = (UINTN)Script;
  TableLength  = TableHeader.TableLength;
  Script       =    Script + TableHeader.Length;
  Status       = EFI_SUCCESS;
  AndMask      = 0;
  OrMask       = 0;

  DEBUG ((DEBUG_INFO, "TableHeader.Version - 0x%04x\n", (UINTN)TableHeader.Version));
  DEBUG ((DEBUG_INFO, "TableHeader.TableLength - 0x%08x\n", (UINTN)TableLength));

  while ((UINTN)Script < (UINTN)(StartAddress + TableLength)) {
    DEBUG ((DEBUG_INFO, "ExecuteBootScript - %08x\n", (UINTN)Script));

    CopyMem ((VOID *)&ScriptHeader, Script, sizeof (EFI_BOOT_SCRIPT_COMMON_HEADER));
    switch (ScriptHeader.OpCode) {
      case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE\n"));
        Status = BootScriptExecuteMemoryWrite (Script);
        break;

      case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE\n"));
        CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);
        Status = BootScriptExecuteMemoryReadWrite (
                   Script,
                   AndMask,
                   OrMask
                   );
        break;

      case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_IO_WRITE_OPCODE\n"));
        Status = BootScriptExecuteIoWrite (Script);
        break;

      case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE\n"));
        Status = BootScriptExecutePciCfgWrite (Script);
        break;

      case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE\n"));
        CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);
        Status = BootScriptExecutePciCfgReadWrite (
                   Script,
                   AndMask,
                   OrMask
                   );
        break;
      case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE\n"));
        Status = BootScriptExecutePciCfg2Write (Script);
        break;

      case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE\n"));
        CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);
        Status = BootScriptExecutePciCfg2ReadWrite (
                   Script,
                   AndMask,
                   OrMask
                   );
        break;
      case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_DISPATCH_OPCODE\n"));
        Status = BootScriptExecuteDispatch (Script);
        break;

      case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE\n"));
        Status = BootScriptExecuteDispatch2 (Script);
        break;

      case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_INFORMATION_OPCODE\n"));
        BootScriptExecuteInformation (Script);
        break;

      case S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE:
        DEBUG ((DEBUG_INFO, "S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE\n"));
        DEBUG ((DEBUG_INFO, "S3BootScriptDone - %r\n", EFI_SUCCESS));
        return EFI_SUCCESS;

      case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE\n"));
        CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);
        Status = BootScriptExecuteIoReadWrite (
                   Script,
                   AndMask,
                   OrMask
                   );
        break;

      case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE\n"));
        Status = BootScriptExecuteSmbusExecute (Script);
        break;

      case EFI_BOOT_SCRIPT_STALL_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_STALL_OPCODE\n"));
        Status = BootScriptExecuteStall (Script);
        break;

      case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_MEM_POLL_OPCODE\n"));
        CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);
        Status = BootScriptExecuteMemPoll (Script, AndMask, OrMask);

        break;

      case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_IO_POLL_OPCODE\n"));
        CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);
        Status = BootScriptExecuteIoPoll (Script, AndMask, OrMask);
        break;

      case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE\n"));
        CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);
        Status = BootScriptPciCfgPoll (Script, AndMask, OrMask);
        break;

      case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:
        DEBUG ((DEBUG_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE\n"));
        CheckAndOrMask (&ScriptHeader, &AndMask, &OrMask, Script);
        Status = BootScriptPciCfg2Poll (Script, AndMask, OrMask);
        break;

      case S3_BOOT_SCRIPT_LIB_LABEL_OPCODE:
        //
        // For label
        //
        DEBUG ((DEBUG_INFO, "S3_BOOT_SCRIPT_LIB_LABEL_OPCODE\n"));
        BootScriptExecuteLabel (Script);
        break;
      default:
        DEBUG ((DEBUG_INFO, "S3BootScriptDone - %r\n", EFI_UNSUPPORTED));
        return EFI_UNSUPPORTED;
    }

    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_INFO, "S3BootScriptDone - %r\n", Status));
      return Status;
    }

    Script = Script + ScriptHeader.Length;
  }

  DEBUG ((DEBUG_INFO, "S3BootScriptDone - %r\n", Status));

  return Status;
}
