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;
 | |
| }
 | |
| 
 |