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