/** @file\r
Save the S3 data to S3 boot script. \r
\r
- Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2006 - 2015, Intel Corporation. All rights reserved.<BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions\r
This is an internal function to add a terminate node the entry, recalculate the table \r
length and fill into the table. \r
\r
- @return the base address of the boot script tble. \r
+ @return the base address of the boot script table. \r
**/\r
UINT8*\r
S3BootScriptInternalCloseTable (\r
run time phase.\r
\r
@param Event Pointer to this event\r
- @param Context Event hanlder private data \r
+ @param Context Event handler private data \r
**/\r
VOID\r
EFIAPI\r
ScriptTableInfo = (EFI_BOOT_SCRIPT_TABLE_HEADER*)(UINTN)S3TableBase;\r
ScriptTableInfo->OpCode = S3_BOOT_SCRIPT_LIB_TABLE_OPCODE;\r
ScriptTableInfo->Length = (UINT8) sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);\r
+ ScriptTableInfo->Version = BOOT_SCRIPT_TABLE_VERSION;\r
ScriptTableInfo->TableLength = 0; // will be calculate at CloseTable\r
mS3BootScriptTablePtr->TableLength = sizeof (EFI_BOOT_SCRIPT_TABLE_HEADER);\r
mS3BootScriptTablePtr->TableBase = (UINT8*)(UINTN)S3TableBase;\r
how to get the script to run on an S3 resume because the boot script maintained by the lib will be \r
destroyed.\r
\r
- @return the base address of the new copy of the boot script tble. \r
+ @return the base address of the new copy of the boot script table. \r
@note this function could only called in boot time phase\r
\r
**/\r
\r
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.\r
@retval RETURN_SUCCESS Opcode is added.\r
+ @note A known Limitations in the implementation which is 64bits operations are not supported.\r
+\r
**/\r
RETURN_STATUS\r
EFIAPI\r
UINT8 WidthInByte;\r
EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE ScriptPciWrite;\r
\r
+ if (Width == S3BootScriptWidthUint64 ||\r
+ Width == S3BootScriptWidthFifoUint64 ||\r
+ Width == S3BootScriptWidthFillUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
WidthInByte = (UINT8) (0x01 << (Width & 0x03));\r
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE) + (WidthInByte * Count));\r
\r
\r
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.\r
@retval RETURN__SUCCESS Opcode is added.\r
+ @note A known Limitations in the implementation which is 64bits operations are not supported.\r
+\r
**/\r
RETURN_STATUS\r
EFIAPI\r
UINT8 WidthInByte;\r
EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE ScriptPciReadWrite;\r
\r
+ if (Width == S3BootScriptWidthUint64 ||\r
+ Width == S3BootScriptWidthFifoUint64 ||\r
+ Width == S3BootScriptWidthFillUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
WidthInByte = (UINT8) (0x01 << (Width & 0x03));\r
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE) + (WidthInByte * 2));\r
\r
\r
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.\r
@retval RETURN_SUCCESS Opcode is added.\r
+ @note A known Limitations in the implementation which is non-zero Segment and 64bits operations are not supported.\r
+\r
**/\r
RETURN_STATUS\r
EFIAPI\r
UINT8 *Script;\r
UINT8 WidthInByte;\r
EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE ScriptPciWrite2;\r
- \r
+\r
+ if (Segment != 0 ||\r
+ Width == S3BootScriptWidthUint64 ||\r
+ Width == S3BootScriptWidthFifoUint64 ||\r
+ Width == S3BootScriptWidthFillUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
WidthInByte = (UINT8) (0x01 << (Width & 0x03));\r
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE) + (WidthInByte * Count));\r
\r
\r
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.\r
@retval RETURN_SUCCESS Opcode is added.\r
+ @note A known Limitations in the implementation which is non-zero Segment and 64bits operations are not supported.\r
+\r
**/\r
RETURN_STATUS\r
EFIAPI\r
UINT8 *Script;\r
UINT8 WidthInByte;\r
EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE ScriptPciReadWrite2;\r
+\r
+ if (Segment != 0 ||\r
+ Width == S3BootScriptWidthUint64 ||\r
+ Width == S3BootScriptWidthFifoUint64 ||\r
+ Width == S3BootScriptWidthFillUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
\r
WidthInByte = (UINT8) (0x01 << (Width & 0x03));\r
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE) + (WidthInByte * 2));\r
\r
return RETURN_SUCCESS;\r
}\r
+\r
+/**\r
+ Checks the parameter of S3BootScriptSaveSmbusExecute().\r
+\r
+ This function checks the input parameters of SmbusExecute(). If the input parameters are valid\r
+ for certain SMBus bus protocol, it will return EFI_SUCCESS; otherwise, it will return certain\r
+ error code based on the input SMBus bus protocol.\r
+\r
+ @param SmBusAddress Address that encodes the SMBUS Slave Address, SMBUS Command, SMBUS Data Length, \r
+ and PEC.\r
+ @param Operation Signifies which particular SMBus hardware protocol instance that\r
+ it will use to execute the SMBus transactions. This SMBus\r
+ hardware protocol is defined by the SMBus Specification and is\r
+ not related to EFI.\r
+ @param Length Signifies the number of bytes that this operation will do. The\r
+ maximum number of bytes can be revision specific and operation\r
+ specific. This field will contain the actual number of bytes that\r
+ are executed for this operation. Not all operations require this\r
+ argument.\r
+ @param Buffer Contains the value of data to execute to the SMBus slave device.\r
+ Not all operations require this argument. The length of this\r
+ buffer is identified by Length.\r
+\r
+ @retval EFI_SUCCESS All the parameters are valid for the corresponding SMBus bus\r
+ protocol. \r
+ @retval EFI_INVALID_PARAMETER Operation is not defined in EFI_SMBUS_OPERATION.\r
+ @retval EFI_INVALID_PARAMETER Length/Buffer is NULL for operations except for EfiSmbusQuickRead\r
+ and EfiSmbusQuickWrite. Length is outside the range of valid\r
+ values.\r
+ @retval EFI_UNSUPPORTED The SMBus operation or PEC is not supported.\r
+ @retval EFI_BUFFER_TOO_SMALL Buffer is not sufficient for this operation.\r
+\r
+**/\r
+EFI_STATUS\r
+CheckParameters (\r
+ IN UINTN SmBusAddress,\r
+ IN EFI_SMBUS_OPERATION Operation,\r
+ IN OUT UINTN *Length,\r
+ IN VOID *Buffer\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN RequiredLen;\r
+ EFI_SMBUS_DEVICE_COMMAND Command;\r
+ BOOLEAN PecCheck;\r
+ \r
+ Command = SMBUS_LIB_COMMAND (SmBusAddress);\r
+ PecCheck = SMBUS_LIB_PEC (SmBusAddress);\r
+ //\r
+ // Set default value to be 2:\r
+ // for SmbusReadWord, SmbusWriteWord and SmbusProcessCall. \r
+ //\r
+ RequiredLen = 2;\r
+ Status = EFI_SUCCESS;\r
+ switch (Operation) {\r
+ case EfiSmbusQuickRead:\r
+ case EfiSmbusQuickWrite:\r
+ if (PecCheck || Command != 0) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ break;\r
+ case EfiSmbusReceiveByte:\r
+ case EfiSmbusSendByte:\r
+ if (Command != 0) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+ //\r
+ // Cascade to check length parameter.\r
+ //\r
+ case EfiSmbusReadByte:\r
+ case EfiSmbusWriteByte:\r
+ RequiredLen = 1;\r
+ //\r
+ // Cascade to check length parameter.\r
+ //\r
+ case EfiSmbusReadWord:\r
+ case EfiSmbusWriteWord:\r
+ case EfiSmbusProcessCall:\r
+ if (Buffer == NULL || Length == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ } else if (*Length < RequiredLen) {\r
+ Status = EFI_BUFFER_TOO_SMALL;\r
+ }\r
+ *Length = RequiredLen;\r
+ break;\r
+ case EfiSmbusReadBlock:\r
+ case EfiSmbusWriteBlock:\r
+ case EfiSmbusBWBRProcessCall:\r
+ if ((Buffer == NULL) || \r
+ (Length == NULL) || \r
+ (*Length < MIN_SMBUS_BLOCK_LEN) ||\r
+ (*Length > MAX_SMBUS_BLOCK_LEN)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ break;\r
+ default:\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ return Status;\r
+}\r
+\r
/**\r
Adds a record for an SMBus command execution into a specified boot script table.\r
\r
IN VOID *Buffer\r
)\r
{\r
+ EFI_STATUS Status;\r
+ UINTN BufferLength;\r
UINT8 DataSize;\r
UINT8 *Script;\r
EFI_BOOT_SCRIPT_SMBUS_EXECUTE ScriptSmbusExecute;\r
\r
- DataSize = (UINT8)(sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE) + (*Length));\r
+ if (Length == NULL) {\r
+ BufferLength = 0;\r
+ } else {\r
+ BufferLength = *Length;\r
+ }\r
+\r
+ Status = CheckParameters (SmBusAddress, Operation, &BufferLength, Buffer);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ DataSize = (UINT8)(sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE) + BufferLength);\r
\r
Script = S3BootScriptGetEntryAddAddress (DataSize);\r
if (Script == NULL) {\r
ScriptSmbusExecute.Length = DataSize;\r
ScriptSmbusExecute.SmBusAddress = (UINT64) SmBusAddress;\r
ScriptSmbusExecute.Operation = Operation;\r
- ScriptSmbusExecute.DataSize = (UINT32) *Length;\r
+ ScriptSmbusExecute.DataSize = (UINT32) BufferLength;\r
\r
CopyMem ((VOID*)Script, (VOID*)&ScriptSmbusExecute, sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE));\r
CopyMem (\r
(VOID*)(Script + sizeof (EFI_BOOT_SCRIPT_SMBUS_EXECUTE)),\r
Buffer,\r
- (*Length)\r
+ BufferLength\r
);\r
\r
SyncBootScript (Script);\r
/**\r
Adds a record for memory reads of the memory location and continues when the exit criteria is\r
satisfied or after a defined duration.\r
- \r
+\r
+ Please aware, below interface is different with PI specification, Vol 5:\r
+ EFI_S3_SAVE_STATE_PROTOCOL.Write() for EFI_BOOT_SCRIPT_MEM_POLL_OPCODE.\r
+ "Duration" below is microseconds, while "Delay" in PI specification means\r
+ the number of 100ns units to poll.\r
+\r
@param Width The width of the memory operations.\r
@param Address The base address of the memory operations.\r
@param BitMask A pointer to the bit mask to be AND-ed with the data read from the register.\r
\r
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.\r
@retval RETURN_SUCCESS Opcode is added.\r
+ @note A known Limitations in the implementation which is 64bits operations are not supported.\r
\r
**/\r
RETURN_STATUS\r
UINT8 Length;\r
EFI_BOOT_SCRIPT_PCI_CONFIG_POLL ScriptPciPoll;\r
\r
+ if (Width == S3BootScriptWidthUint64 ||\r
+ Width == S3BootScriptWidthFifoUint64 ||\r
+ Width == S3BootScriptWidthFillUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
WidthInByte = (UINT8) (0x01 << (Width & 0x03));\r
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG_POLL) + (WidthInByte * 2));\r
\r
\r
@retval RETURN_OUT_OF_RESOURCES Not enough memory for the table do operation.\r
@retval RETURN_SUCCESS Opcode is added.\r
- @note A known Limitations in the implementation: When interpreting the opcode EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE\r
- EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE and EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE, the 'Segment' parameter is assumed as \r
- Zero, or else, assert.\r
+ @note A known Limitations in the implementation which is non-zero Segment and 64bits operations are not supported.\r
+\r
**/\r
RETURN_STATUS\r
EFIAPI\r
UINT8 *Script;\r
UINT8 Length;\r
EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL ScriptPci2Poll;\r
- \r
+\r
+ if (Segment != 0 ||\r
+ Width == S3BootScriptWidthUint64 ||\r
+ Width == S3BootScriptWidthFifoUint64 ||\r
+ Width == S3BootScriptWidthFillUint64) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
WidthInByte = (UINT8) (0x01 << (Width & 0x03));\r
Length = (UINT8)(sizeof (EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL) + (WidthInByte * 2));\r
\r