Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Jiewen Yao <jiewen.yao@intel.com> git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@17166 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1793 lines
		
	
	
		
			63 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1793 lines
		
	
	
		
			63 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  Interpret and execute the S3 data in S3 boot script. 
 | 
						|
 | 
						|
  Copyright (c) 2006 - 2015, 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 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 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
 | 
						|
ScriptPciCfgRead (
 | 
						|
  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;
 | 
						|
  UINTN       PciAddress;
 | 
						|
 | 
						|
  Out.Buf = (UINT8 *) Buffer;
 | 
						|
 | 
						|
  PciAddress = PCI_ADDRESS_ENCODE (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%08x\n", PciAddress));
 | 
						|
      *Out.Uint8 = PciRead8 (PciAddress);
 | 
						|
      break;
 | 
						|
    case S3BootScriptWidthFifoUint8:
 | 
						|
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x\n", PciAddress));
 | 
						|
      *Out.Uint8 = PciRead8 (PciAddress);
 | 
						|
      break;
 | 
						|
    case S3BootScriptWidthFillUint8:
 | 
						|
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x\n", PciAddress));
 | 
						|
      *Out.Uint8 = PciRead8 (PciAddress);
 | 
						|
      break;
 | 
						|
 | 
						|
    case S3BootScriptWidthUint16:
 | 
						|
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x\n", PciAddress));
 | 
						|
      *Out.Uint16 = PciRead16 (PciAddress);
 | 
						|
      break;
 | 
						|
    case S3BootScriptWidthFifoUint16:
 | 
						|
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x\n", PciAddress));
 | 
						|
      *Out.Uint16 = PciRead16 (PciAddress);
 | 
						|
      break;
 | 
						|
    case S3BootScriptWidthFillUint16:
 | 
						|
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x\n", PciAddress));
 | 
						|
      *Out.Uint16 = PciRead16 (PciAddress);
 | 
						|
      break;
 | 
						|
 | 
						|
    case S3BootScriptWidthUint32:
 | 
						|
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x\n", PciAddress));
 | 
						|
      *Out.Uint32 = PciRead32 (PciAddress);
 | 
						|
      break;
 | 
						|
    case S3BootScriptWidthFifoUint32:
 | 
						|
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x\n", PciAddress));
 | 
						|
      *Out.Uint32 = PciRead32 (PciAddress);
 | 
						|
      break;
 | 
						|
    case S3BootScriptWidthFillUint32:
 | 
						|
      DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x\n", PciAddress));
 | 
						|
      *Out.Uint32 = PciRead32 (PciAddress);
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      return EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
/**
 | 
						|
  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 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
 | 
						|
ScriptPciCfgWrite (
 | 
						|
  IN  S3_BOOT_SCRIPT_LIB_WIDTH     Width,
 | 
						|
  IN  UINT64                       Address,
 | 
						|
  IN  UINTN                        Count,
 | 
						|
  IN  VOID                         *Buffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  UINTN       AddressStride;
 | 
						|
  UINTN       BufferStride;
 | 
						|
  UINTN       OriginalPciAddress;
 | 
						|
  PTR         In;
 | 
						|
  PTR         OriginalIn;
 | 
						|
  UINTN       PciAddress;
 | 
						|
 | 
						|
  In.Buf = (UINT8 *) Buffer;
 | 
						|
 | 
						|
  PciAddress = PCI_ADDRESS_ENCODE (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%08x (0x%02x)\n", PciAddress, (UINTN)*In.Uint8));
 | 
						|
        PciWrite8 (PciAddress, *In.Uint8);
 | 
						|
        break;      
 | 
						|
      case S3BootScriptWidthFifoUint8:
 | 
						|
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint8 - 0x%08x (0x%02x)\n", OriginalPciAddress, (UINTN)*In.Uint8));
 | 
						|
        PciWrite8 (OriginalPciAddress, *In.Uint8);
 | 
						|
        break;      
 | 
						|
      case S3BootScriptWidthFillUint8:
 | 
						|
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint8 - 0x%08x (0x%02x)\n", PciAddress, (UINTN)*OriginalIn.Uint8));
 | 
						|
        PciWrite8 (PciAddress, *OriginalIn.Uint8);
 | 
						|
        break;
 | 
						|
      case S3BootScriptWidthUint16:
 | 
						|
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint16 - 0x%08x (0x%04x)\n", PciAddress, (UINTN)*In.Uint16));
 | 
						|
        PciWrite16 (PciAddress, *In.Uint16);
 | 
						|
        break;      
 | 
						|
      case S3BootScriptWidthFifoUint16:
 | 
						|
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint16 - 0x%08x (0x%04x)\n", OriginalPciAddress, (UINTN)*In.Uint16));
 | 
						|
        PciWrite16 (OriginalPciAddress, *In.Uint16);
 | 
						|
        break;      
 | 
						|
      case S3BootScriptWidthFillUint16:
 | 
						|
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint16 - 0x%08x (0x%04x)\n", PciAddress, (UINTN)*OriginalIn.Uint16));
 | 
						|
        PciWrite16 (PciAddress, *OriginalIn.Uint16);
 | 
						|
        break;
 | 
						|
      case S3BootScriptWidthUint32:
 | 
						|
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthUint32 - 0x%08x (0x%08x)\n", PciAddress, (UINTN)*In.Uint32));
 | 
						|
        PciWrite32 (PciAddress, *In.Uint32);
 | 
						|
        break;      
 | 
						|
      case S3BootScriptWidthFifoUint32:
 | 
						|
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFifoUint32 - 0x%08x (0x%08x)\n", OriginalPciAddress, (UINTN)*In.Uint32));
 | 
						|
        PciWrite32 (OriginalPciAddress, *In.Uint32);
 | 
						|
        break;      
 | 
						|
      case S3BootScriptWidthFillUint32:
 | 
						|
        DEBUG ((EFI_D_INFO, "S3BootScriptWidthFillUint32 - 0x%08x (0x%08x)\n", (UINTN)PciAddress, (UINTN)*OriginalIn.Uint32));
 | 
						|
        PciWrite32 (PciAddress, *OriginalIn.Uint32);
 | 
						|
        break;
 | 
						|
      default:
 | 
						|
        return EFI_INVALID_PARAMETER;
 | 
						|
    }
 | 
						|
  }
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
/**
 | 
						|
  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 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.
 | 
						|
  @note  A known Limitations in the implementation which is the 'Segment' parameter is assumed as 
 | 
						|
         Zero, or else, assert.
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
ScriptPciCfg2Read (
 | 
						|
  IN  S3_BOOT_SCRIPT_LIB_WIDTH    Width,
 | 
						|
  IN  UINT16                   Segment,  
 | 
						|
  IN  UINT64                   Address,
 | 
						|
  IN  UINTN                    Count,
 | 
						|
  OUT VOID                     *Buffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (Segment==0);
 | 
						|
  
 | 
						|
  return ScriptPciCfgRead (Width, Address, Count, Buffer);
 | 
						|
}
 | 
						|
/**
 | 
						|
  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 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.
 | 
						|
  @note  A known Limitations in the implementation which is the 'Segment' parameter is assumed as 
 | 
						|
         Zero, or else, assert.
 | 
						|
                                
 | 
						|
**/
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
ScriptPciCfg2Write (
 | 
						|
  IN  S3_BOOT_SCRIPT_LIB_WIDTH    Width,
 | 
						|
  IN  UINT16                   Segment,  
 | 
						|
  IN  UINT64                   Address,
 | 
						|
  IN  UINTN                    Count,
 | 
						|
  IN  VOID                     *Buffer
 | 
						|
  )
 | 
						|
{
 | 
						|
  ASSERT (Segment==0);
 | 
						|
  return ScriptPciCfgWrite (Width, 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%08x, 0x%08x, 0x%08x\n", PCI_ADDRESS_ENCODE (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%08x, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (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%04x, 0x%08x, 0x%08x, 0x%08x\n", Segment, PCI_ADDRESS_ENCODE (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%04x, 0x%08x, 0x%016lx, 0x%016lx\n", PciCfg2ReadWrite.Segment, PCI_ADDRESS_ENCODE (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%08x, 0x%016lx, 0x%016lx\n", PCI_ADDRESS_ENCODE (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%04x, 0x%08x, 0x%016lx, 0x%016lx\n", PciCfg2Poll.Segment, PCI_ADDRESS_ENCODE (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.  
 | 
						|
  
 | 
						|
  @note  A known Limitations in the implementation: When interpreting the opcode  EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE
 | 
						|
         EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE and EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE, the 'Segment' parameter is assumed as 
 | 
						|
         Zero, or else, assert.
 | 
						|
**/
 | 
						|
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;
 | 
						|
}
 | 
						|
 |