/** @file
  Interpret and execute the S3 data in S3 boot script.

  Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>

  This program and the accompanying materials
  are licensed and made available under the terms and conditions
  of the BSD License which accompanies this distribution.  The
  full text of the license may be found at
  http://opensource.org/licenses/bsd-license.php

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/
#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
SmbusExecute (
  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 ((EFI_D_INFO, "EfiSmbusQuickRead - 0x%08x\n", SmbusAddress));
      SmBusQuickRead (SmbusAddress, &Status);
      break;
    case EfiSmbusQuickWrite:
      DEBUG ((EFI_D_INFO, "EfiSmbusQuickWrite - 0x%08x\n", SmbusAddress));
      SmBusQuickWrite (SmbusAddress, &Status);
      break;
    case EfiSmbusReceiveByte:
      DEBUG ((EFI_D_INFO, "EfiSmbusReceiveByte - 0x%08x\n", SmbusAddress));
      SmBusReceiveByte (SmbusAddress, &Status);
      break;
    case EfiSmbusSendByte:
      DEBUG ((EFI_D_INFO, "EfiSmbusSendByte - 0x%08x (0x%02x)\n", SmbusAddress, (UINTN)*(UINT8 *) Buffer));
      SmBusSendByte (SmbusAddress, *(UINT8 *) Buffer, &Status);
      break;
    case EfiSmbusReadByte:
      DEBUG ((EFI_D_INFO, "EfiSmbusReadByte - 0x%08x\n", SmbusAddress));
      SmBusReadDataByte (SmbusAddress, &Status);
      break;
    case EfiSmbusWriteByte:
      DEBUG ((EFI_D_INFO, "EfiSmbusWriteByte - 0x%08x (0x%02x)\n", SmbusAddress, (UINTN)*(UINT8 *) Buffer));
      SmBusWriteDataByte (SmbusAddress, *(UINT8 *) Buffer, &Status);
      break;
    case EfiSmbusReadWord:
      DEBUG ((EFI_D_INFO, "EfiSmbusReadWord - 0x%08x\n", SmbusAddress));
      SmBusReadDataWord (SmbusAddress, &Status);
      break;
    case EfiSmbusWriteWord:
      DEBUG ((EFI_D_INFO, "EfiSmbusWriteWord - 0x%08x (0x%04x)\n", SmbusAddress, (UINTN)*(UINT16 *) Buffer));
      SmBusWriteDataWord (SmbusAddress, *(UINT16 *) Buffer, &Status);
      break;
    case EfiSmbusProcessCall:
      DEBUG ((EFI_D_INFO, "EfiSmbusProcessCall - 0x%08x (0x%04x)\n", SmbusAddress, (UINTN)*(UINT16 *) Buffer));
      SmBusProcessCall (SmbusAddress, *(UINT16 *) Buffer, &Status);
      break;
    case EfiSmbusReadBlock:
      DEBUG ((EFI_D_INFO, "EfiSmbusReadBlock - 0x%08x\n", SmbusAddress));
      SmBusReadBlock (SmbusAddress, WorkBuffer, &Status);
      break;
    case EfiSmbusWriteBlock:
      DEBUG ((EFI_D_INFO, "EfiSmbusWriteBlock - 0x%08x\n", SmbusAddress));
      SmBusWriteBlock ((SmbusAddress + SMBUS_LIB_ADDRESS (0, 0, (*Length), FALSE)), Buffer, &Status);
      break;
    case EfiSmbusBWBRProcessCall:
      DEBUG ((EFI_D_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 ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x\n", (UINTN) Address));
      *Out.Uint8 = IoRead8 ((UINTN) Address);
      break;
    case S3BootScriptWidthFifoUint8:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x\n", (UINTN) Address));
      *Out.Uint8 = IoRead8 ((UINTN) Address);
      break;
    case S3BootScriptWidthFillUint8:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x\n", (UINTN) Address));
      *Out.Uint8 = IoRead8 ((UINTN) Address);
      break;

    case S3BootScriptWidthUint16:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", (UINTN) Address));
      *Out.Uint16 = IoRead16 ((UINTN) Address);
      break;
    case S3BootScriptWidthFifoUint16:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x\n", (UINTN) Address));
      *Out.Uint16 = IoRead16 ((UINTN) Address);
      break;
    case S3BootScriptWidthFillUint16:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x\n", (UINTN) Address));
      *Out.Uint16 = IoRead16 ((UINTN) Address);
      break;

    case S3BootScriptWidthUint32:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", (UINTN) Address));
      *Out.Uint32 = IoRead32 ((UINTN) Address);
      break;
    case S3BootScriptWidthFifoUint32:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x\n", (UINTN) Address));
      *Out.Uint32 = IoRead32 ((UINTN) Address);
      break;
    case S3BootScriptWidthFillUint32:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x\n", (UINTN) Address));
      *Out.Uint32 = IoRead32 ((UINTN) Address);
      break;

    case S3BootScriptWidthUint64:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint64 - 0x%08x\n", (UINTN) Address));
      *Out.Uint64 = IoRead64 ((UINTN) Address);
      break;
    case S3BootScriptWidthFifoUint64:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x\n", (UINTN) Address));
      *Out.Uint64 = IoRead64 ((UINTN) Address);
      break;
    case S3BootScriptWidthFillUint64:
      DEBUG ((EFI_D_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 ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*In.Uint8));
        IoWrite8 ((UINTN) Address, *In.Uint8);
        break;
      case S3BootScriptWidthFifoUint8:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x (0x%02x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint8));
        IoWrite8 ((UINTN) OriginalAddress, *In.Uint8);
        break;
      case S3BootScriptWidthFillUint8:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint8));
        IoWrite8 ((UINTN) Address, *OriginalIn.Uint8);
        break;
      case S3BootScriptWidthUint16:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*In.Uint16));
        IoWrite16 ((UINTN) Address, *In.Uint16);
        break;
      case S3BootScriptWidthFifoUint16:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x (0x%04x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint16));
        IoWrite16 ((UINTN) OriginalAddress, *In.Uint16);
        break;
      case S3BootScriptWidthFillUint16:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint16));
        IoWrite16 ((UINTN) Address, *OriginalIn.Uint16);
        break;
      case S3BootScriptWidthUint32:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*In.Uint32));
        IoWrite32 ((UINTN) Address, *In.Uint32);
        break;
      case S3BootScriptWidthFifoUint32:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x (0x%08x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint32));
        IoWrite32 ((UINTN) OriginalAddress, *In.Uint32);
        break;
      case S3BootScriptWidthFillUint32:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint32));
        IoWrite32 ((UINTN) Address, *OriginalIn.Uint32);
        break;
      case S3BootScriptWidthUint64:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint64 - 0x%08x (0x%016lx)\n", (UINTN)Address, *In.Uint64));
        IoWrite64 ((UINTN) Address, *In.Uint64);
        break;
      case S3BootScriptWidthFifoUint64:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x (0x%016lx)\n", (UINTN)OriginalAddress, *In.Uint64));
        IoWrite64 ((UINTN) OriginalAddress, *In.Uint64);
        break;
      case S3BootScriptWidthFillUint64:
        DEBUG ((EFI_D_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;
}
/**
  Interprete 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 ((EFI_D_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 ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x\n", (UINTN)Address));
      *Out.Uint8 = MmioRead8 ((UINTN) Address);
      break;
    case S3BootScriptWidthFifoUint8:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x\n", (UINTN)Address));
      *Out.Uint8 = MmioRead8 ((UINTN) Address);
      break;
    case S3BootScriptWidthFillUint8:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x\n", (UINTN)Address));
      *Out.Uint8 = MmioRead8 ((UINTN) Address);
      break;

    case S3BootScriptWidthUint16:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", (UINTN)Address));
      *Out.Uint16 = MmioRead16 ((UINTN) Address);
      break;
    case S3BootScriptWidthFifoUint16:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x\n", (UINTN)Address));
      *Out.Uint16 = MmioRead16 ((UINTN) Address);
      break;
    case S3BootScriptWidthFillUint16:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x\n", (UINTN)Address));
      *Out.Uint16 = MmioRead16 ((UINTN) Address);
      break;

    case S3BootScriptWidthUint32:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", (UINTN)Address));
      *Out.Uint32 = MmioRead32 ((UINTN) Address);
      break;
    case S3BootScriptWidthFifoUint32:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x\n", (UINTN)Address));
      *Out.Uint32 = MmioRead32 ((UINTN) Address);
      break;
    case S3BootScriptWidthFillUint32:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x\n", (UINTN)Address));
      *Out.Uint32 = MmioRead32 ((UINTN) Address);
      break;

    case S3BootScriptWidthUint64:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint64 - 0x%08x\n", (UINTN)Address));
      *Out.Uint64 = MmioRead64 ((UINTN) Address);
      break;
    case S3BootScriptWidthFifoUint64:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x\n", (UINTN)Address));
      *Out.Uint64 = MmioRead64 ((UINTN) Address);
      break;
    case S3BootScriptWidthFillUint64:
      DEBUG ((EFI_D_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 ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*In.Uint8));
        MmioWrite8 ((UINTN) Address, *In.Uint8);
        break;
      case S3BootScriptWidthFifoUint8:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x (0x%02x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint8));
        MmioWrite8 ((UINTN) OriginalAddress, *In.Uint8);
        break;
      case S3BootScriptWidthFillUint8:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x (0x%02x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint8));
        MmioWrite8 ((UINTN) Address, *OriginalIn.Uint8);
        break;
      case S3BootScriptWidthUint16:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*In.Uint16));
        MmioWrite16 ((UINTN) Address, *In.Uint16);
        break;
      case S3BootScriptWidthFifoUint16:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x (0x%04x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint16));
        MmioWrite16 ((UINTN) OriginalAddress, *In.Uint16);
        break;
      case S3BootScriptWidthFillUint16:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x (0x%04x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint16));
        MmioWrite16 ((UINTN) Address, *OriginalIn.Uint16);
        break;
      case S3BootScriptWidthUint32:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*In.Uint32));
        MmioWrite32 ((UINTN) Address, *In.Uint32);
        break;
      case S3BootScriptWidthFifoUint32:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x (0x%08x)\n", (UINTN)OriginalAddress, (UINTN)*In.Uint32));
        MmioWrite32 ((UINTN) OriginalAddress, *In.Uint32);
        break;
      case S3BootScriptWidthFillUint32:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x (0x%08x)\n", (UINTN)Address, (UINTN)*OriginalIn.Uint32));
        MmioWrite32 ((UINTN) Address, *OriginalIn.Uint32);
        break;
      case S3BootScriptWidthUint64:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint64 - 0x%08x (0x%016lx)\n", (UINTN)Address, *In.Uint64));
        MmioWrite64 ((UINTN) Address, *In.Uint64);
        break;
      case S3BootScriptWidthFifoUint64:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint64 - 0x%08x (0x%016lx)\n", (UINTN)OriginalAddress, *In.Uint64));
        MmioWrite64 ((UINTN) OriginalAddress, *In.Uint64);
        break;
      case S3BootScriptWidthFillUint64:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint64 - 0x%08x (0x%016lx)\n", (UINTN)Address, *OriginalIn.Uint64));
        MmioWrite64 ((UINTN) Address, *OriginalIn.Uint64);
        break;
      default:
        return EFI_UNSUPPORTED;
    }
  }
  return EFI_SUCCESS;
}
/**
  Interprete 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 ((EFI_D_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 ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%016lx\n", PciAddress));
      *Out.Uint8 = PciSegmentRead8 (PciAddress);
      break;
    case S3BootScriptWidthFifoUint8:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%016lx\n", PciAddress));
      *Out.Uint8 = PciSegmentRead8 (PciAddress);
      break;
    case S3BootScriptWidthFillUint8:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%016lx\n", PciAddress));
      *Out.Uint8 = PciSegmentRead8 (PciAddress);
      break;

    case S3BootScriptWidthUint16:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%016lx\n", PciAddress));
      *Out.Uint16 = PciSegmentRead16 (PciAddress);
      break;
    case S3BootScriptWidthFifoUint16:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%016lx\n", PciAddress));
      *Out.Uint16 = PciSegmentRead16 (PciAddress);
      break;
    case S3BootScriptWidthFillUint16:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%016lx\n", PciAddress));
      *Out.Uint16 = PciSegmentRead16 (PciAddress);
      break;

    case S3BootScriptWidthUint32:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%016lx\n", PciAddress));
      *Out.Uint32 = PciSegmentRead32 (PciAddress);
      break;
    case S3BootScriptWidthFifoUint32:
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%016lx\n", PciAddress));
      *Out.Uint32 = PciSegmentRead32 (PciAddress);
      break;
    case S3BootScriptWidthFillUint32:
      DEBUG ((EFI_D_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 ((EFI_D_INFO, "S3BootScriptWidthUint8 - 0x%016lx (0x%02x)\n", PciAddress, (UINTN)*In.Uint8));
        PciSegmentWrite8 (PciAddress, *In.Uint8);
        break;
      case S3BootScriptWidthFifoUint8:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%016lx (0x%02x)\n", OriginalPciAddress, (UINTN)*In.Uint8));
        PciSegmentWrite8 (OriginalPciAddress, *In.Uint8);
        break;
      case S3BootScriptWidthFillUint8:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%016lx (0x%02x)\n", PciAddress, (UINTN)*OriginalIn.Uint8));
        PciSegmentWrite8 (PciAddress, *OriginalIn.Uint8);
        break;
      case S3BootScriptWidthUint16:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%016lx (0x%04x)\n", PciAddress, (UINTN)*In.Uint16));
        PciSegmentWrite16 (PciAddress, *In.Uint16);
        break;
      case S3BootScriptWidthFifoUint16:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%016lx (0x%04x)\n", OriginalPciAddress, (UINTN)*In.Uint16));
        PciSegmentWrite16 (OriginalPciAddress, *In.Uint16);
        break;
      case S3BootScriptWidthFillUint16:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%016lx (0x%04x)\n", PciAddress, (UINTN)*OriginalIn.Uint16));
        PciSegmentWrite16 (PciAddress, *OriginalIn.Uint16);
        break;
      case S3BootScriptWidthUint32:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%016lx (0x%08x)\n", PciAddress, (UINTN)*In.Uint32));
        PciSegmentWrite32 (PciAddress, *In.Uint32);
        break;
      case S3BootScriptWidthFifoUint32:
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%016lx (0x%08x)\n", OriginalPciAddress, (UINTN)*In.Uint32));
        PciSegmentWrite32 (OriginalPciAddress, *In.Uint32);
        break;
      case S3BootScriptWidthFillUint32:
        DEBUG ((EFI_D_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);
}
/**
  Interprete 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 ((EFI_D_INFO, "BootScriptExecutePciCfgWrite - 0x%016lx, 0x%08x, 0x%08x\n", PCI_ADDRESS_ENCODE (0, Address), Count, (UINTN)Width));
  return ScriptPciCfgWrite (Width, Address, Count, Buffer);
}
/**
  Interprete 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 ((EFI_D_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;
}
/**
  Interprete 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 ((EFI_D_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;
}
/**
  Interprete 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 ((EFI_D_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;
}
/**
  Interprete 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 ((EFI_D_INFO, "BootScriptExecuteSmbusExecute - 0x%08x, 0x%08x\n", (UINTN)SmbusExecuteEntry.SmBusAddress, (UINTN)SmbusExecuteEntry.Operation));

  SmBusAddress = (UINTN)SmbusExecuteEntry.SmBusAddress;
  DataSize = (UINTN) SmbusExecuteEntry.DataSize;
  return SmbusExecute (
           SmBusAddress,
           (EFI_SMBUS_OPERATION) SmbusExecuteEntry.Operation,
           &DataSize,
           Script + sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)
           );
}
/**
  Interprete 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 ((EFI_D_INFO, "BootScriptExecuteStall - 0x%08x\n", (UINTN)Stall.Duration));

  MicroSecondDelay ((UINTN) Stall.Duration);
  return EFI_SUCCESS;
}
/**
  Interprete 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 ((EFI_D_INFO, "BootScriptExecuteDispatch - 0x%08x\n", (UINTN)ScriptDispatch.EntryPoint));

  Status    = EntryFunc (NULL, NULL);

  return Status;
}
/**
  Interprete 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 ((EFI_D_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;
}
/**
  Interprete 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 ((EFI_D_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 ((EFI_D_INFO, "BootScriptExecuteInformation - 0x%08x\n", (UINTN) InformationData));

  DEBUG ((EFI_D_INFO, "BootScriptInformation: "));
  for (Index = 0; Index < Information.InformationLength; Index++) {
    DEBUG ((EFI_D_INFO, "%02x ", InformationData[Index]));
  }
  DEBUG ((EFI_D_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 ((EFI_D_INFO, "BootScriptExecuteLabel - 0x%08x\n", (UINTN) InformationData));

  DEBUG ((EFI_D_INFO, "BootScriptLabel: "));
  for (Index = 0; Index < Information.InformationLength; Index++) {
    DEBUG ((EFI_D_INFO, "%02x ", InformationData[Index]));
  }
  DEBUG ((EFI_D_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;
}
/**
  Interprete 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 ((EFI_D_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;
  }
}
/**
  Interprete 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 ((EFI_D_INFO, "BootScriptExecutePciCfg2Write - 0x%016lx, 0x%08x, 0x%08x\n", PCI_ADDRESS_ENCODE (Segment, Address), Count, (UINTN)Width));
  return ScriptPciCfg2Write (Width, Segment, Address, Count, Buffer);
}


/**
  Interprete 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 ((EFI_D_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;
}
/**
  Interprete 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 ((EFI_D_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;
  }
}

/**
  Interprete 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 ((EFI_D_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 ((EFI_D_INFO, "S3BootScriptExecute:\n"));
  if (TableHeader.OpCode != S3_BOOT_SCRIPT_LIB_TABLE_OPCODE) {
    return EFI_UNSUPPORTED;
  }

  DEBUG ((EFI_D_INFO, "TableHeader - 0x%08x\n", Script));

  StartAddress  = (UINTN) Script;
  TableLength   = TableHeader.TableLength;
  Script    =    Script + TableHeader.Length;
  Status        = EFI_SUCCESS;
  AndMask       = 0;
  OrMask        = 0;

  DEBUG ((EFI_D_INFO, "TableHeader.Version - 0x%04x\n", (UINTN)TableHeader.Version));
  DEBUG ((EFI_D_INFO, "TableHeader.TableLength - 0x%08x\n", (UINTN)TableLength));

  while ((UINTN) Script < (UINTN) (StartAddress + TableLength)) {
    DEBUG ((EFI_D_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 ((EFI_D_INFO, "EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE\n"));
      Status = BootScriptExecuteMemoryWrite (Script);
      break;

    case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:
      DEBUG ((EFI_D_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 ((EFI_D_INFO, "EFI_BOOT_SCRIPT_IO_WRITE_OPCODE\n"));
      Status = BootScriptExecuteIoWrite (Script);
      break;

    case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
      DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE\n"));
      Status = BootScriptExecutePciCfgWrite (Script);
      break;

    case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:
      DEBUG ((EFI_D_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 ((EFI_D_INFO, "EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE\n"));
      Status = BootScriptExecutePciCfg2Write (Script);
      break;

    case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:
      DEBUG ((EFI_D_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 ((EFI_D_INFO, "EFI_BOOT_SCRIPT_DISPATCH_OPCODE\n"));
      Status = BootScriptExecuteDispatch (Script);
      break;

    case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:
      DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE\n"));
      Status = BootScriptExecuteDispatch2 (Script);
      break;

    case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:
      DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_INFORMATION_OPCODE\n"));
      BootScriptExecuteInformation (Script);
      break;

    case S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE:
      DEBUG ((EFI_D_INFO, "S3_BOOT_SCRIPT_LIB_TERMINATE_OPCODE\n"));
      DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", EFI_SUCCESS));
      return EFI_SUCCESS;

    case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:
      DEBUG ((EFI_D_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 ((EFI_D_INFO, "EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE\n"));
      Status = BootScriptExecuteSmbusExecute (Script);
      break;

    case EFI_BOOT_SCRIPT_STALL_OPCODE:
      DEBUG ((EFI_D_INFO, "EFI_BOOT_SCRIPT_STALL_OPCODE\n"));
      Status = BootScriptExecuteStall (Script);
      break;

    case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:
      DEBUG ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_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 ((EFI_D_INFO, "S3_BOOT_SCRIPT_LIB_LABEL_OPCODE\n"));
      BootScriptExecuteLabel (Script);
      break;
    default:
      DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", EFI_UNSUPPORTED));
      return EFI_UNSUPPORTED;
    }

    if (EFI_ERROR (Status)) {
      DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", Status));
      return Status;
    }

    Script  = Script + ScriptHeader.Length;
  }

  DEBUG ((EFI_D_INFO, "S3BootScriptDone - %r\n", Status));

  return Status;
}

