/** @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
  )

{
  UINT32                       Index;
  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));

  DEBUG ((DEBUG_INFO, "BootScriptInformation: "));
  for (Index = 0; Index < Information.InformationLength; Index++) {
    DEBUG ((DEBUG_INFO, "%02x ", InformationData[Index]));
  }

  DEBUG ((DEBUG_INFO, "\n"));
}

/**
  Execute the boot script to interpret the Label information.

  @param Script       The pointer of node in boot script table

**/
VOID
BootScriptExecuteLabel (
  IN UINT8  *Script
  )

{
  UINT32                       Index;
  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));

  DEBUG ((DEBUG_INFO, "BootScriptLabel: "));
  for (Index = 0; Index < Information.InformationLength; Index++) {
    DEBUG ((DEBUG_INFO, "%02x ", InformationData[Index]));
  }

  DEBUG ((DEBUG_INFO, "\n"));
}

/**
  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;
}
