]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg: Add ACPI S3 Save State drivers
authorjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 29 Aug 2011 22:19:48 +0000 (22:19 +0000)
committerjljusten <jljusten@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 29 Aug 2011 22:19:48 +0000 (22:19 +0000)
Signed-off-by: jljusten
Reviewed-by: mdkinney
Reviewed-by: rsun3
Reviewed-by: jyao1
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12228 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/MdeModulePkg.dsc
MdeModulePkg/Universal/Acpi/S3SaveStateDxe/InternalS3SaveState.h [new file with mode: 0644]
MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveState.c [new file with mode: 0644]
MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf [new file with mode: 0644]
MdeModulePkg/Universal/Acpi/SmmS3SaveState/InternalSmmSaveState.h [new file with mode: 0644]
MdeModulePkg/Universal/Acpi/SmmS3SaveState/SmmS3SaveState.c [new file with mode: 0644]
MdeModulePkg/Universal/Acpi/SmmS3SaveState/SmmS3SaveState.inf [new file with mode: 0644]

index 1a97ef29e08e09bd4be108787fe87d609254d95c..7a42d12c857074e757f7fa1b7ac8ca19e562961f 100644 (file)
   MdeModulePkg/Library/SmmLockBoxLib/SmmLockBoxPeiLib.inf\r
   MdeModulePkg/Library/SmmCorePlatformHookLibNull/SmmCorePlatformHookLibNull.inf\r
   MdeModulePkg/Universal/Acpi/BootScriptExecutorDxe/BootScriptExecutorDxe.inf\r
+  MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf\r
+  MdeModulePkg/Universal/Acpi/SmmS3SaveState/SmmS3SaveState.inf\r
 \r
diff --git a/MdeModulePkg/Universal/Acpi/S3SaveStateDxe/InternalS3SaveState.h b/MdeModulePkg/Universal/Acpi/S3SaveStateDxe/InternalS3SaveState.h
new file mode 100644 (file)
index 0000000..a9b724d
--- /dev/null
@@ -0,0 +1,162 @@
+/** @file\r
+  Internal header file for S3 Boot Script Saver state driver.\r
+\r
+  Copyright (c) 2006 - 2010, 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
+  of the BSD License which accompanies this distribution.  The\r
+  full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#ifndef _INTERNAL_S3_SAVE_STATE_H_\r
+#define _INTERNAL_S3_SAVE_STATE_H_\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/S3SaveState.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/S3BootScriptLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/SmbusLib.h>\r
+#include <IndustryStandard/SmBus.h>\r
+/**\r
+  Adds a record into S3 boot script table.\r
+\r
+  This function is used to store a boot script record into a given boot\r
+  script table. If the table specified by TableName is nonexistent in the \r
+  system, a new table will automatically be created and then the script record \r
+  will be added into the new table. This function is responsible for allocating \r
+  necessary memory for the script.\r
+\r
+  This function has a variable parameter list. The exact parameter list depends on \r
+  the OpCode that is passed into the function. If an unsupported OpCode or illegal \r
+  parameter list is passed in, this function returns EFI_INVALID_PARAMETER.\r
+  If there are not enough resources available for storing more scripts, this function returns\r
+  EFI_OUT_OF_RESOURCES.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  OpCode                The operation code (opcode) number.\r
+  @param  ...                   Argument list that is specific to each opcode. \r
+\r
+  @retval EFI_SUCCESS           The operation succeeded. A record was added into the\r
+                                specified script table.\r
+  @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.\r
+                                If the opcode is unknow or not supported because of the PCD \r
+                                Feature Flags.\r
+  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptWrite (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL      *This,\r
+  IN       UINT16                           OpCode,\r
+  ...\r
+  );\r
+/**\r
+  Insert a record into a specified Framework boot script table.\r
+\r
+  This function is used to store an OpCode to be replayed as part of the S3 resume boot path. It is\r
+  assumed this protocol has platform specific mechanism to store the OpCode set and replay them\r
+  during the S3 resume.\r
+  The opcode is inserted before or after the specified position in the boot script table. If Position is\r
+  NULL then that position is after the last opcode in the table (BeforeOrAfter is FALSE) or before\r
+  the first opcode in the table (BeforeOrAfter is TRUE). The position which is pointed to by\r
+  Position upon return can be used for subsequent insertions.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  BeforeOrAfter         Specifies whether the opcode is stored before (TRUE) or after (FALSE) the position\r
+                                in the boot script table specified by Position. If Position is NULL or points to\r
+                                NULL then the new opcode is inserted at the beginning of the table (if TRUE) or end\r
+                                of the table (if FALSE).\r
+  @param  Position              On entry, specifies the position in the boot script table where the opcode will be\r
+                                inserted, either before or after, depending on BeforeOrAfter. On exit, specifies\r
+                                the position of the inserted opcode in the boot script table.\r
+  @param  OpCode                The operation code (opcode) number.\r
+  @param  ...                   Argument list that is specific to each opcode. \r
+\r
+  @retval EFI_SUCCESS           The operation succeeded. A record was added into the\r
+                                specified script table.\r
+  @retval EFI_INVALID_PARAMETER The Opcode is an invalid opcode value or the Position is not a valid position in the boot script table..\r
+  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptInsert (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL    *This,\r
+  IN       BOOLEAN                          BeforeOrAfter,\r
+  IN OUT   EFI_S3_BOOT_SCRIPT_POSITION     *Position OPTIONAL,\r
+  IN       UINT16                           OpCode,\r
+  ...\r
+  );\r
+/**\r
+  Find a label within the boot script table and, if not present, optionally create it.\r
+\r
+  If the label Label is already exists in the boot script table, then no new label is created, the\r
+  position of the Label is returned in *Position and EFI_SUCCESS is returned.\r
+  If the label Label does not already exist and CreateIfNotFound is TRUE, then it will be\r
+  created before or after the specified position and EFI_SUCCESS is returned.\r
+  If the label Label does not already exist and CreateIfNotFound is FALSE, then\r
+  EFI_NOT_FOUND is returned.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  BeforeOrAfter         Specifies whether the label is stored before (TRUE) or after (FALSE) the position in\r
+                                the boot script table specified by Position. If Position is NULL or points to\r
+                                NULL then the new label is inserted at the beginning of the table (if TRUE) or end of\r
+                                the table (if FALSE).\r
+  @param  CreateIfNotFound      Specifies whether the label will be created if the label does not exists (TRUE) or not\r
+                                (FALSE).\r
+  @param  Position              On entry, specifies the position in the boot script table where the label will be inserted,\r
+                                either before or after, depending on BeforeOrAfter. On exit, specifies the position\r
+                                of the inserted label in the boot script table.\r
+  @param  Label                 Points to the label which will be inserted in the boot script table.\r
+\r
+  @retval EFI_SUCCESS           The label already exists or was inserted.\r
+  @retval EFI_INVALID_PARAMETER The Opcode is an invalid opcode value or the Position is not a valid position in the boot script table..\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptLabel (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL           *This,\r
+  IN       BOOLEAN                               BeforeOrAfter,\r
+  IN       BOOLEAN                               CreateIfNotFound,\r
+  IN OUT   EFI_S3_BOOT_SCRIPT_POSITION          *Position OPTIONAL,\r
+  IN CONST CHAR8                                *Label\r
+  );\r
+/**\r
+  Compare two positions in the boot script table and return their relative position.\r
+  \r
+  This function compares two positions in the boot script table and returns their relative positions. If\r
+  Position1 is before Position2, then -1 is returned. If Position1 is equal to Position2,\r
+  then 0 is returned. If Position1 is after Position2, then 1 is returned.\r
+  \r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  Position1             The positions in the boot script table to compare\r
+  @param  Position2             The positions in the boot script table to compare\r
+  @param  RelativePosition      On return, points to the result of the comparison\r
+\r
+  @retval EFI_SUCCESS           The operation succeeded. \r
+  @retval EFI_INVALID_PARAMETER The Position1 or Position2 is not a valid position in the boot script table.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI \r
+BootScriptCompare (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL      *This,\r
+  IN       EFI_S3_BOOT_SCRIPT_POSITION      Position1,\r
+  IN       EFI_S3_BOOT_SCRIPT_POSITION      Position2,\r
+  OUT      UINTN                           *RelativePosition\r
+  );\r
+  \r
+#endif //_INTERNAL_S3_SAVE_STATE_H_\r
diff --git a/MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveState.c b/MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveState.c
new file mode 100644 (file)
index 0000000..15c4b6b
--- /dev/null
@@ -0,0 +1,901 @@
+/** @file\r
+  Implementation for S3 Boot Script Saver state driver.\r
+\r
+  Copyright (c) 2006 - 2010, 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
+  of the BSD License which accompanies this distribution.  The\r
+  full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#include "InternalS3SaveState.h"\r
+\r
+EFI_HANDLE                    mHandle = NULL;\r
+EFI_S3_SAVE_STATE_PROTOCOL    mS3SaveState = {\r
+  BootScriptWrite,\r
+  BootScriptInsert,\r
+  BootScriptLabel,\r
+  BootScriptCompare\r
+  };\r
+/**\r
+  Internal function to add IO write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteIoWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINTN                 Count;\r
+  UINT8                 *Buffer;\r
+\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Count       = VA_ARG (Marker, UINTN);\r
+  Buffer      = VA_ARG (Marker, UINT8 *);\r
+  \r
+  return S3BootScriptSaveIoWrite (Width, Address, Count, Buffer);\r
+}\r
+/**\r
+  Internal function to add IO read/write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteIoReadWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINT8                 *Data;\r
+  UINT8                 *DataMask;\r
\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Data        = VA_ARG (Marker, UINT8 *);\r
+  DataMask    = VA_ARG (Marker, UINT8 *);\r
+  \r
+  return S3BootScriptSaveIoReadWrite (Width, Address, Data, DataMask);\r
+}\r
+\r
+/**\r
+  Internal function to add memory write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteMemWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINTN                 Count;\r
+  UINT8                 *Buffer;\r
\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Count       = VA_ARG (Marker, UINTN);\r
+  Buffer      = VA_ARG (Marker, UINT8 *);\r
+\r
+  return S3BootScriptSaveMemWrite (Width, Address, Count, Buffer);\r
+}\r
+\r
+/**\r
+  Internal function to add memory read/write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteMemReadWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINT8                 *Data;\r
+  UINT8                 *DataMask;\r
+  \r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Data        = VA_ARG (Marker, UINT8 *);\r
+  DataMask    = VA_ARG (Marker, UINT8 *);\r
+\r
+  return S3BootScriptSaveMemReadWrite (Width, Address, Data, DataMask);\r
+}\r
+\r
+/**\r
+  Internal function to add PciCfg write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciCfgWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINTN                 Count;\r
+  UINT8                 *Buffer;\r
+\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Count       = VA_ARG (Marker, UINTN);\r
+  Buffer      = VA_ARG (Marker, UINT8 *);\r
+\r
+  return S3BootScriptSavePciCfgWrite (Width, Address, Count, Buffer);\r
+}\r
+\r
+/**\r
+  Internal function to PciCfg read/write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciCfgReadWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINT8                 *Data;\r
+  UINT8                 *DataMask;\r
+\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Data        = VA_ARG (Marker, UINT8 *);\r
+  DataMask    = VA_ARG (Marker, UINT8 *);\r
+\r
+  return S3BootScriptSavePciCfgReadWrite (Width, Address, Data, DataMask);\r
+}\r
+/**\r
+  Internal function to add PciCfg2 write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciCfg2Write (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINTN                 Count;\r
+  UINT8                 *Buffer;\r
+  UINT16                Segment;\r
+\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Count       = VA_ARG (Marker, UINTN);\r
+  Buffer      = VA_ARG (Marker, UINT8 *);\r
+  Segment     = VA_ARG (Marker, UINT16);\r
+\r
+  return S3BootScriptSavePciCfg2Write (Width, Segment, Address, Count, Buffer);\r
+}\r
+\r
+/**\r
+  Internal function to PciCfg2 read/write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciCfg2ReadWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT16                Segment;\r
+  UINT64                Address;\r
+  UINT8                 *Data;\r
+  UINT8                 *DataMask;\r
\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Segment     = VA_ARG (Marker, UINT16);\r
+  Data        = VA_ARG (Marker, UINT8 *);\r
+  DataMask    = VA_ARG (Marker, UINT8 *);\r
\r
+  return S3BootScriptSavePciCfg2ReadWrite (Width, Segment, Address, Data, DataMask);\r
+}\r
+/**\r
+  Internal function to add smbus excute opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteSmbusExecute (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress;\r
+  EFI_SMBUS_DEVICE_COMMAND  Command;\r
+  EFI_SMBUS_OPERATION       Operation;\r
+  BOOLEAN                   PecCheck;\r
+  VOID                     *Buffer;\r
+  UINTN                    *DataSize;\r
+  UINTN                     SmBusAddress;\r
+  \r
+  SlaveAddress.SmbusDeviceAddress = VA_ARG (Marker, UINTN);\r
+  Command                         = VA_ARG (Marker, EFI_SMBUS_DEVICE_COMMAND);\r
+  Operation                       = VA_ARG (Marker, EFI_SMBUS_OPERATION);\r
+  PecCheck                        = VA_ARG (Marker, BOOLEAN);\r
+  SmBusAddress                    = SMBUS_LIB_ADDRESS (SlaveAddress.SmbusDeviceAddress,Command,0,PecCheck);\r
+  DataSize                        = VA_ARG (Marker, UINTN *);    \r
+  Buffer                          = VA_ARG (Marker, VOID *);\r
\r
+  return S3BootScriptSaveSmbusExecute (SmBusAddress, Operation, DataSize, Buffer);\r
+}\r
+/**\r
+  Internal function to add stall opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteStall (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  UINT32                Duration;\r
+\r
+  Duration    = VA_ARG (Marker, UINT32);\r
+\r
+  return S3BootScriptSaveStall (Duration);\r
+}\r
+\r
+/**\r
+  Internal function to add Save jmp address according to DISPATCH_OPCODE. \r
+  We ignore "Context" parameter\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteDispatch (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  VOID        *EntryPoint;\r
+\r
+  EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
+  return S3BootScriptSaveDispatch (EntryPoint);\r
+}\r
+\r
+/**\r
+  Internal function to add memory pool operation to the table. \r
\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteMemPoll (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH   Width;                                    \r
+  UINT64                     Address;                                    \r
+  VOID                      *Data;                                    \r
+  VOID                      *DataMask;                                  \r
+  UINTN                     Delay;                                   \r
+                                                                         \r
+  Width    = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);                  \r
+  Address  = VA_ARG (Marker, UINT64);                                    \r
+  Data     = VA_ARG (Marker, VOID *);                                    \r
+  DataMask = VA_ARG (Marker, VOID *);                                    \r
+  Delay    = (UINTN)VA_ARG (Marker, UINT64);                            \r
+  //\r
+  // According to the spec, the interval between 2 pools is 100ns\r
+  //                                                                       \r
+  return S3BootScriptSaveMemPoll (Width, Address, DataMask, Data, 100, Delay); \r
+\r
+}\r
+\r
+/**\r
+  Internal function to add Save jmp address according to DISPATCH_OPCODE2. \r
+  The "Context" parameter is not ignored.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteDispatch2 (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  VOID                  *EntryPoint;\r
+  VOID                  *Context;  \r
+\r
+  EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
+  Context    = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
+\r
+  return S3BootScriptSaveDispatch2 (EntryPoint, Context);\r
+}\r
+/**\r
+  Internal function to add INFORAMTION opcode node to the table\r
+  list.\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enought resource to complete the operations.\r
+  @retval EFI_SUCCESS           The opcode entry is added to the  table\r
+                                successfully.\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteInformation (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  UINT32                InformationLength;\r
+  EFI_PHYSICAL_ADDRESS  Information;  \r
+\r
+  InformationLength = VA_ARG (Marker, UINT32);\r
+  Information = VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
+  return S3BootScriptSaveInformation (InformationLength, (VOID*)(UINTN)Information);\r
+}\r
+/**\r
+  Internal function to add IO poll opcode node  to the table\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enought resource to complete the operations.\r
+  @retval EFI_SUCCESS           The opcode entry is added to the  table\r
+                                successfully.\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteIoPoll (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+   S3_BOOT_SCRIPT_LIB_WIDTH     Width;\r
+   UINT64                     Address;    \r
+   VOID                      *Data;    \r
+   VOID                      *DataMask;   \r
+   UINT64                     Delay;   \r
+   \r
+   Width    = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);  \r
+   Address  = VA_ARG (Marker, UINT64);                    \r
+   Data     = VA_ARG (Marker, VOID *);                   \r
+   DataMask = VA_ARG (Marker, VOID *);                   \r
+   Delay    = (UINT64)VA_ARG (Marker, UINT64);             \r
+   \r
+   return S3BootScriptSaveIoPoll (Width, Address, Data, DataMask, Delay);\r
+}\r
+/**\r
+  Internal function to add PCI config poll opcode node to the table\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enought resource to complete the operations.\r
+  @retval EFI_SUCCESS           The opcode entry is added to the  table\r
+                                successfully.\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciConfigPoll (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+   S3_BOOT_SCRIPT_LIB_WIDTH   Width;\r
+   UINT64                     Address;\r
+   VOID                      *Data;\r
+   VOID                      *DataMask;\r
+   UINT64                     Delay;\r
+\r
+   \r
+   Width    = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);  \r
+   Address  = VA_ARG (Marker, UINT64);                    \r
+   Data     = VA_ARG (Marker, VOID *);                   \r
+   DataMask = VA_ARG (Marker, VOID *);                   \r
+   Delay    = (UINT64)VA_ARG (Marker, UINT64);             \r
+   \r
+   return S3BootScriptSavePciPoll (Width, Address, Data, DataMask, Delay);\r
+}\r
+/**\r
+  Internal function to add PCI config 2 poll opcode node to the table\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enought resource to complete the operations.\r
+  @retval EFI_SUCCESS           The opcode entry is added to the  table\r
+                                successfully.\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciConfig2Poll (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+   S3_BOOT_SCRIPT_LIB_WIDTH      Width;\r
+   UINT16                        Segment;\r
+   UINT64                        Address;\r
+   VOID                         *Data;\r
+   VOID                         *DataMask;\r
+   UINT64                        Delay;\r
+  \r
+   Width    = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);  \r
+   Segment  = VA_ARG (Marker, UINT16);      \r
+   Address  = VA_ARG (Marker, UINT64);                    \r
+   Data     = VA_ARG (Marker, VOID *);                   \r
+   DataMask = VA_ARG (Marker, VOID *);                   \r
+   Delay    = (UINT64)VA_ARG (Marker, UINT64);             \r
+   \r
+   return S3BootScriptSavePci2Poll (Width, Segment, Address, Data, DataMask, Delay);\r
+}\r
+\r
+\r
+/**\r
+  Adds a record into S3 boot script table.\r
+\r
+  This function is used to store a boot script record into a given boot\r
+  script table. If the table specified by TableName is nonexistent in the \r
+  system, a new table will automatically be created and then the script record \r
+  will be added into the new table. This function is responsible for allocating \r
+  necessary memory for the script.\r
+\r
+  This function has a variable parameter list. The exact parameter list depends on \r
+  the OpCode that is passed into the function. If an unsupported OpCode or illegal \r
+  parameter list is passed in, this function returns EFI_INVALID_PARAMETER.\r
+  If there are not enough resources available for storing more scripts, this function returns\r
+  EFI_OUT_OF_RESOURCES.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  OpCode                The operation code (opcode) number.\r
+  @param  ...                   Argument list that is specific to each opcode. \r
+                                \r
+  @retval EFI_SUCCESS           The operation succeeded. A record was added into the\r
+                                specified script table.\r
+  @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.\r
+                                If the opcode is unknow or not supported because of the PCD \r
+                                Feature Flags.\r
+  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptWrite (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL      *This,\r
+  IN       UINT16                           OpCode,\r
+  ...\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  VA_LIST                   Marker;  \r
+  //\r
+  // Build script according to opcode\r
+  //\r
+  switch (OpCode) {\r
+\r
+  case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemWrite (Marker);\r
+    VA_END (Marker); \r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfgWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfgReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteSmbusExecute (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_STALL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteStall (Marker);\r
+    VA_END (Marker);\r
+  \r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteDispatch (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteDispatch2 (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteInformation (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemPoll (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfg2Write (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfg2ReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:  \r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoPoll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+  \r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE: \r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciConfigPoll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+  \r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciConfig2Poll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+\r
+  default:\r
+    Status = EFI_INVALID_PARAMETER;\r
+    break;\r
+  }\r
+\r
+  return Status;\r
+}\r
+/**\r
+  Insert a record into a specified Framework boot script table.\r
+\r
+  This function is used to store an OpCode to be replayed as part of the S3 resume boot path. It is\r
+  assumed this protocol has platform specific mechanism to store the OpCode set and replay them\r
+  during the S3 resume.\r
+  The opcode is inserted before or after the specified position in the boot script table. If Position is\r
+  NULL then that position is after the last opcode in the table (BeforeOrAfter is FALSE) or before\r
+  the first opcode in the table (BeforeOrAfter is TRUE). The position which is pointed to by\r
+  Position upon return can be used for subsequent insertions.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  BeforeOrAfter         Specifies whether the opcode is stored before (TRUE) or after (FALSE) the position\r
+                                in the boot script table specified by Position. If Position is NULL or points to\r
+                                NULL then the new opcode is inserted at the beginning of the table (if TRUE) or end\r
+                                of the table (if FALSE).\r
+  @param  Position              On entry, specifies the position in the boot script table where the opcode will be\r
+                                inserted, either before or after, depending on BeforeOrAfter. On exit, specifies\r
+                                the position of the inserted opcode in the boot script table.\r
+  @param  OpCode                The operation code (opcode) number.\r
+  @param  ...                   Argument list that is specific to each opcode. \r
+\r
+  @retval EFI_SUCCESS           The operation succeeded. A record was added into the\r
+                                specified script table.\r
+  @retval EFI_INVALID_PARAMETER The Opcode is an invalid opcode value or the Position is not a valid position in the boot script table..\r
+  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptInsert (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL     *This,\r
+  IN       BOOLEAN                        BeforeOrAfter,\r
+  IN OUT   EFI_S3_BOOT_SCRIPT_POSITION    *Position OPTIONAL,\r
+  IN       UINT16                         OpCode,\r
+  ...\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  VA_LIST                   Marker;  \r
+  //\r
+  // Build script according to opcode\r
+  //\r
+  switch (OpCode) {\r
+\r
+  case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemWrite (Marker);\r
+    VA_END (Marker); \r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfgWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfgReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteSmbusExecute (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_STALL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteStall (Marker);\r
+    VA_END (Marker);\r
+  \r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteDispatch (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteDispatch2 (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteInformation (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemPoll (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfg2Write (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfg2ReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+    \r
+  case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:  \r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoPoll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+  \r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE: \r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciConfigPoll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+  \r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciConfig2Poll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+\r
+  default:\r
+    Status = EFI_INVALID_PARAMETER;\r
+    break;\r
+  }\r
+  \r
+  if (!EFI_ERROR (Status)) {\r
+   Status = S3BootScriptMoveLastOpcode (BeforeOrAfter, Position);\r
+  }\r
+  return Status;\r
+}\r
+/**\r
+  Find a label within the boot script table and, if not present, optionally create it.\r
+\r
+  If the label Label is already exists in the boot script table, then no new label is created, the\r
+  position of the Label is returned in *Position and EFI_SUCCESS is returned.\r
+  If the label Label does not already exist and CreateIfNotFound is TRUE, then it will be\r
+  created before or after the specified position and EFI_SUCCESS is returned.\r
+  If the label Label does not already exist and CreateIfNotFound is FALSE, then\r
+  EFI_NOT_FOUND is returned.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  BeforeOrAfter         Specifies whether the label is stored before (TRUE) or after (FALSE) the position in\r
+                                the boot script table specified by Position. If Position is NULL or points to\r
+                                NULL then the new label is inserted at the beginning of the table (if TRUE) or end of\r
+                                the table (if FALSE).\r
+  @param  CreateIfNotFound      Specifies whether the label will be created if the label does not exists (TRUE) or not\r
+                                (FALSE).\r
+  @param  Position              On entry, specifies the position in the boot script table where the label will be inserted,\r
+                                either before or after, depending on BeforeOrAfter. On exit, specifies the position\r
+                                of the inserted label in the boot script table.\r
+  @param  Label                 Points to the label which will be inserted in the boot script table.\r
+\r
+  @retval EFI_SUCCESS           The label already exists or was inserted.\r
+  @retval EFI_INVALID_PARAMETER The Opcode is an invalid opcode value or the Position is not a valid position in the boot script table..\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptLabel (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL           *This,\r
+  IN       BOOLEAN                              BeforeOrAfter,\r
+  IN       BOOLEAN                              CreateIfNotFound,\r
+  IN OUT   EFI_S3_BOOT_SCRIPT_POSITION          *Position OPTIONAL,\r
+  IN CONST CHAR8                                *Label\r
+  )\r
+{\r
+       return S3BootScriptLabel (BeforeOrAfter, CreateIfNotFound, Position, Label);\r
+}\r
+/**\r
+  Compare two positions in the boot script table and return their relative position.\r
+  \r
+  This function compares two positions in the boot script table and returns their relative positions. If\r
+  Position1 is before Position2, then -1 is returned. If Position1 is equal to Position2,\r
+  then 0 is returned. If Position1 is after Position2, then 1 is returned.\r
+  \r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  Position1             The positions in the boot script table to compare\r
+  @param  Position2             The positions in the boot script table to compare\r
+  @param  RelativePosition      On return, points to the result of the comparison\r
+\r
+  @retval EFI_SUCCESS           The operation succeeded. \r
+  @retval EFI_INVALID_PARAMETER The Position1 or Position2 is not a valid position in the boot script table.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI \r
+BootScriptCompare (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL      *This,\r
+  IN       EFI_S3_BOOT_SCRIPT_POSITION      Position1,\r
+  IN       EFI_S3_BOOT_SCRIPT_POSITION      Position2,\r
+  OUT      UINTN                           *RelativePosition\r
+  )\r
+{\r
+       return S3BootScriptCompare (Position1, Position2, RelativePosition);\r
+}\r
+/**\r
+  This routine is entry point of ScriptSave driver.\r
+\r
+  @param  ImageHandle           Handle for this drivers loaded image protocol.\r
+  @param  SystemTable           EFI system table.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  No enough resource\r
+  @retval EFI_SUCCESS           Succesfully installed the ScriptSave driver.\r
+  @retval other                 Errors occured.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeS3SaveState (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+\r
+\r
+  return  gBS->InstallProtocolInterface (\r
+                  &mHandle,\r
+                  &gEfiS3SaveStateProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &mS3SaveState\r
+                  );\r
+\r
+}\r
+\r
+\r
diff --git a/MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf b/MdeModulePkg/Universal/Acpi/S3SaveStateDxe/S3SaveStateDxe.inf
new file mode 100644 (file)
index 0000000..9a2cf96
--- /dev/null
@@ -0,0 +1,57 @@
+## @file\r
+# Component description file for ScriptSave module.\r
+#\r
+# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials are\r
+# licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = S3SaveStateDxe\r
+  FILE_GUID                      = BDCE85BB-FBAA-4f4e-9264-501A2C249581\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+\r
+  ENTRY_POINT                    = InitializeS3SaveState\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  S3SaveState.c\r
+  InternalS3SaveState.h\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  PcdLib\r
+  UefiRuntimeServicesTableLib\r
+  UefiBootServicesTableLib\r
+  MemoryAllocationLib\r
+  UefiDriverEntryPoint\r
+  BaseMemoryLib\r
+  DebugLib\r
+  BaseLib\r
+  S3BootScriptLib\r
+\r
+[Protocols]\r
+  gEfiS3SaveStateProtocolGuid                # PROTOCOL ALWAYS_PRODUCED\r
+\r
+\r
+[Depex]\r
+  TRUE        \r
+  
\ No newline at end of file
diff --git a/MdeModulePkg/Universal/Acpi/SmmS3SaveState/InternalSmmSaveState.h b/MdeModulePkg/Universal/Acpi/SmmS3SaveState/InternalSmmSaveState.h
new file mode 100644 (file)
index 0000000..d6263fd
--- /dev/null
@@ -0,0 +1,161 @@
+/** @file\r
+  Internal header file for SMM S3 Boot Script Saver state driver.\r
+\r
+  Copyright (c) 2006 - 2010, 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
+  of the BSD License which accompanies this distribution.  The\r
+  full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#ifndef _INTERNAL_SMM_S3_SAVE_STATE_H_\r
+#define _INTERNAL_SMM_S3_SAVE_STATE_H_\r
+#include <PiDxe.h>\r
+\r
+#include <Protocol/S3SmmSaveState.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiDriverEntryPoint.h>\r
+#include <Library/SmmServicesTableLib.h>\r
+#include <Library/S3BootScriptLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/SmbusLib.h>\r
+#include <IndustryStandard/SmBus.h>\r
+/**\r
+  Adds a record into S3 boot script table.\r
+\r
+  This function is used to store a boot script record into a given boot\r
+  script table. If the table specified by TableName is nonexistent in the \r
+  system, a new table will automatically be created and then the script record \r
+  will be added into the new table. This function is responsible for allocating \r
+  necessary memory for the script.\r
+\r
+  This function has a variable parameter list. The exact parameter list depends on \r
+  the OpCode that is passed into the function. If an unsupported OpCode or illegal \r
+  parameter list is passed in, this function returns EFI_INVALID_PARAMETER.\r
+  If there are not enough resources available for storing more scripts, this function returns\r
+  EFI_OUT_OF_RESOURCES.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  OpCode                The operation code (opcode) number.\r
+  @param  ...                   Argument list that is specific to each opcode. \r
+\r
+  @retval EFI_SUCCESS           The operation succeeded. A record was added into the\r
+                                specified script table.\r
+  @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.\r
+                                If the opcode is unknow or not supported because of the PCD \r
+                                Feature Flags.\r
+  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptWrite (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL      *This,\r
+  IN       UINT16                           OpCode,\r
+  ...\r
+  );\r
+/**\r
+  Insert a record into a specified Framework boot script table.\r
+\r
+  This function is used to store an OpCode to be replayed as part of the S3 resume boot path. It is\r
+  assumed this protocol has platform specific mechanism to store the OpCode set and replay them\r
+  during the S3 resume.\r
+  The opcode is inserted before or after the specified position in the boot script table. If Position is\r
+  NULL then that position is after the last opcode in the table (BeforeOrAfter is FALSE) or before\r
+  the first opcode in the table (BeforeOrAfter is TRUE). The position which is pointed to by\r
+  Position upon return can be used for subsequent insertions.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  BeforeOrAfter         Specifies whether the opcode is stored before (TRUE) or after (FALSE) the position\r
+                                in the boot script table specified by Position. If Position is NULL or points to\r
+                                NULL then the new opcode is inserted at the beginning of the table (if TRUE) or end\r
+                                of the table (if FALSE).\r
+  @param  Position              On entry, specifies the position in the boot script table where the opcode will be\r
+                                inserted, either before or after, depending on BeforeOrAfter. On exit, specifies\r
+                                the position of the inserted opcode in the boot script table.\r
+  @param  OpCode                The operation code (opcode) number.\r
+  @param  ...                   Argument list that is specific to each opcode. \r
+\r
+  @retval EFI_SUCCESS           The operation succeeded. A record was added into the\r
+                                specified script table.\r
+  @retval EFI_INVALID_PARAMETER The Opcode is an invalid opcode value or the Position is not a valid position in the boot script table..\r
+  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptInsert (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL      *This,\r
+  IN       BOOLEAN                          BeforeOrAfter,\r
+  IN OUT   EFI_S3_BOOT_SCRIPT_POSITION     *Position OPTIONAL,\r
+  IN       UINT16                           OpCode,\r
+  ...\r
+  );\r
+/**\r
+  Find a label within the boot script table and, if not present, optionally create it.\r
+\r
+  If the label Label is already exists in the boot script table, then no new label is created, the\r
+  position of the Label is returned in *Position and EFI_SUCCESS is returned.\r
+  If the label Label does not already exist and CreateIfNotFound is TRUE, then it will be\r
+  created before or after the specified position and EFI_SUCCESS is returned.\r
+  If the label Label does not already exist and CreateIfNotFound is FALSE, then\r
+  EFI_NOT_FOUND is returned.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  BeforeOrAfter         Specifies whether the label is stored before (TRUE) or after (FALSE) the position in\r
+                                the boot script table specified by Position. If Position is NULL or points to\r
+                                NULL then the new label is inserted at the beginning of the table (if TRUE) or end of\r
+                                the table (if FALSE).\r
+  @param  CreateIfNotFound      Specifies whether the label will be created if the label does not exists (TRUE) or not\r
+                                (FALSE).\r
+  @param  Position              On entry, specifies the position in the boot script table where the label will be inserted,\r
+                                either before or after, depending on BeforeOrAfter. On exit, specifies the position\r
+                                of the inserted label in the boot script table.\r
+  @param  Label                 Points to the label which will be inserted in the boot script table.\r
+\r
+  @retval EFI_SUCCESS           The label already exists or was inserted.\r
+  @retval EFI_INVALID_PARAMETER The Opcode is an invalid opcode value or the Position is not a valid position in the boot script table..\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptLabel (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL           *This,\r
+  IN       BOOLEAN                               BeforeOrAfter,\r
+  IN       BOOLEAN                               CreateIfNotFound,\r
+  IN OUT   EFI_S3_BOOT_SCRIPT_POSITION          *Position OPTIONAL,\r
+  IN CONST CHAR8                                *Label\r
+  );\r
+/**\r
+  Compare two positions in the boot script table and return their relative position.\r
+  \r
+  This function compares two positions in the boot script table and returns their relative positions. If\r
+  Position1 is before Position2, then -1 is returned. If Position1 is equal to Position2,\r
+  then 0 is returned. If Position1 is after Position2, then 1 is returned.\r
+  \r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  Position1             The positions in the boot script table to compare\r
+  @param  Position2             The positions in the boot script table to compare\r
+  @param  RelativePosition      On return, points to the result of the comparison\r
+\r
+  @retval EFI_SUCCESS           The operation succeeded. \r
+  @retval EFI_INVALID_PARAMETER The Position1 or Position2 is not a valid position in the boot script table.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI \r
+BootScriptCompare (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL      *This,\r
+  IN       EFI_S3_BOOT_SCRIPT_POSITION      Position1,\r
+  IN       EFI_S3_BOOT_SCRIPT_POSITION      Position2,\r
+  OUT      UINTN                           *RelativePosition\r
+  );\r
+  \r
+#endif //_INTERNAL_SMM_S3_SAVE_STATE_H_\r
diff --git a/MdeModulePkg/Universal/Acpi/SmmS3SaveState/SmmS3SaveState.c b/MdeModulePkg/Universal/Acpi/SmmS3SaveState/SmmS3SaveState.c
new file mode 100644 (file)
index 0000000..9879143
--- /dev/null
@@ -0,0 +1,898 @@
+/** @file\r
+  Implementation for S3 SMM Boot Script Saver state driver.\r
+\r
+  Copyright (c) 2010, 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
+  of the BSD License which accompanies this distribution.  The\r
+  full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+#include "InternalSmmSaveState.h"\r
+\r
+EFI_S3_SMM_SAVE_STATE_PROTOCOL    mS3SmmSaveState = {\r
+   BootScriptWrite,\r
+   BootScriptInsert,\r
+   BootScriptLabel,\r
+   BootScriptCompare\r
+  };\r
+/**\r
+  Internal function to add IO write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteIoWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINTN                 Count;\r
+  UINT8                 *Buffer;\r
+\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Count       = VA_ARG (Marker, UINTN);\r
+  Buffer      = VA_ARG (Marker, UINT8 *);\r
+  \r
+  return S3BootScriptSaveIoWrite (Width, Address, Count, Buffer);\r
+}\r
+/**\r
+  Internal function to add IO read/write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteIoReadWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINT8                 *Data;\r
+  UINT8                 *DataMask;\r
\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Data        = VA_ARG (Marker, UINT8 *);\r
+  DataMask    = VA_ARG (Marker, UINT8 *);\r
+  \r
+  return S3BootScriptSaveIoReadWrite (Width, Address, Data, DataMask);\r
+}\r
+\r
+/**\r
+  Internal function to add memory write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteMemWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINTN                 Count;\r
+  UINT8                 *Buffer;\r
\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Count       = VA_ARG (Marker, UINTN);\r
+  Buffer      = VA_ARG (Marker, UINT8 *);\r
+\r
+  return S3BootScriptSaveMemWrite (Width, Address, Count, Buffer);\r
+}\r
+\r
+/**\r
+  Internal function to add memory read/write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteMemReadWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINT8                 *Data;\r
+  UINT8                 *DataMask;\r
+  \r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Data        = VA_ARG (Marker, UINT8 *);\r
+  DataMask    = VA_ARG (Marker, UINT8 *);\r
+\r
+  return S3BootScriptSaveMemReadWrite (Width, Address, Data, DataMask);\r
+}\r
+\r
+/**\r
+  Internal function to add PciCfg write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciCfgWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINTN                 Count;\r
+  UINT8                 *Buffer;\r
+\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Count       = VA_ARG (Marker, UINTN);\r
+  Buffer      = VA_ARG (Marker, UINT8 *);\r
+\r
+  return S3BootScriptSavePciCfgWrite (Width, Address, Count, Buffer);\r
+}\r
+\r
+/**\r
+  Internal function to PciCfg read/write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciCfgReadWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINT8                 *Data;\r
+  UINT8                 *DataMask;\r
+\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Data        = VA_ARG (Marker, UINT8 *);\r
+  DataMask    = VA_ARG (Marker, UINT8 *);\r
+\r
+  return S3BootScriptSavePciCfgReadWrite (Width, Address, Data, DataMask);\r
+}\r
+/**\r
+  Internal function to add PciCfg2 write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciCfg2Write (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT64                Address;\r
+  UINTN                 Count;\r
+  UINT8                 *Buffer;\r
+  UINT16                Segment;\r
+\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Count       = VA_ARG (Marker, UINTN);\r
+  Buffer      = VA_ARG (Marker, UINT8 *);\r
+  Segment     = VA_ARG (Marker, UINT16);\r
+\r
+  return S3BootScriptSavePciCfg2Write (Width, Segment, Address, Count, Buffer);\r
+}\r
+\r
+/**\r
+  Internal function to PciCfg2 read/write opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciCfg2ReadWrite (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH Width;\r
+  UINT16                Segment;\r
+  UINT64                Address;\r
+  UINT8                 *Data;\r
+  UINT8                 *DataMask;\r
\r
+  Width       = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);\r
+  Address     = VA_ARG (Marker, UINT64);\r
+  Segment     = VA_ARG (Marker, UINT16);\r
+  Data        = VA_ARG (Marker, UINT8 *);\r
+  DataMask    = VA_ARG (Marker, UINT8 *);\r
\r
+  return S3BootScriptSavePciCfg2ReadWrite (Width, Segment, Address, Data, DataMask);\r
+}\r
+/**\r
+  Internal function to add smbus excute opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteSmbusExecute (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  EFI_SMBUS_DEVICE_ADDRESS  SlaveAddress;\r
+  EFI_SMBUS_DEVICE_COMMAND  Command;\r
+  EFI_SMBUS_OPERATION       Operation;\r
+  BOOLEAN                   PecCheck;\r
+  VOID                     *Buffer;\r
+  UINTN                    *DataSize;\r
+  UINTN                     SmBusAddress;\r
+  \r
+  SlaveAddress.SmbusDeviceAddress = VA_ARG (Marker, UINTN);\r
+  Command                         = VA_ARG (Marker, EFI_SMBUS_DEVICE_COMMAND);\r
+  Operation                       = VA_ARG (Marker, EFI_SMBUS_OPERATION);\r
+  PecCheck                        = VA_ARG (Marker, BOOLEAN);\r
+  SmBusAddress                    = SMBUS_LIB_ADDRESS (SlaveAddress.SmbusDeviceAddress,Command,0,PecCheck);\r
+  DataSize                        = VA_ARG (Marker, UINTN *);    \r
+  Buffer                          = VA_ARG (Marker, VOID *);\r
\r
+  return S3BootScriptSaveSmbusExecute (SmBusAddress, Operation, DataSize, Buffer);\r
+}\r
+/**\r
+  Internal function to add stall opcode to the table.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteStall (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  UINT32                Duration;\r
+\r
+  Duration    = VA_ARG (Marker, UINT32);\r
+\r
+  return S3BootScriptSaveStall (Duration);\r
+}\r
+\r
+/**\r
+  Internal function to add Save jmp address according to DISPATCH_OPCODE. \r
+  We ignore "Context" parameter\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteDispatch (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  VOID        *EntryPoint;\r
+\r
+  EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
+  return S3BootScriptSaveDispatch (EntryPoint);\r
+}\r
+\r
+/**\r
+  Internal function to add memory pool operation to the table. \r
\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteMemPoll (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  S3_BOOT_SCRIPT_LIB_WIDTH   Width;                                   \r
+  UINT64                     Address;                                    \r
+  VOID                      *Data;                                       \r
+  VOID                      *DataMask;                                   \r
+  UINTN                      Delay;                                       \r
+                                                                         \r
+  Width    = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);                  \r
+  Address  = VA_ARG (Marker, UINT64);                                    \r
+  Data     = VA_ARG (Marker, VOID *);                                    \r
+  DataMask = VA_ARG (Marker, VOID *);                                    \r
+  Delay    = (UINTN)VA_ARG (Marker, UINT64);                            \r
+  //\r
+  // According to the spec, the interval between 2 pools is 100ns\r
+  //                                                                       \r
+  return S3BootScriptSaveMemPoll (Width, Address, DataMask, Data, 100, Delay); \r
+\r
+}\r
+\r
+/**\r
+  Internal function to add Save jmp address according to DISPATCH_OPCODE2. \r
+  The "Context" parameter is not ignored.\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enough resource to do operation.\r
+  @retval EFI_SUCCESS           Opcode is added.\r
+\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteDispatch2 (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  VOID                  *EntryPoint;\r
+  VOID                  *Context;  \r
+\r
+  EntryPoint = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
+  Context    = (VOID*)(UINTN)VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
+\r
+  return S3BootScriptSaveDispatch2 (EntryPoint, Context);\r
+}\r
+/**\r
+  Internal function to add INFORAMTION opcode node to the table\r
+  list.\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enought resource to complete the operations.\r
+  @retval EFI_SUCCESS           The opcode entry is added to the  table\r
+                                successfully.\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteInformation (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+  UINT32                InformationLength;\r
+  EFI_PHYSICAL_ADDRESS  Information;  \r
+\r
+  InformationLength = VA_ARG (Marker, UINT32);\r
+  Information = VA_ARG (Marker, EFI_PHYSICAL_ADDRESS);\r
+  return S3BootScriptSaveInformation (InformationLength, (VOID*)(UINTN)Information);\r
+}\r
+/**\r
+  Internal function to add IO poll opcode node  to the table\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enought resource to complete the operations.\r
+  @retval EFI_SUCCESS           The opcode entry is added to the  table\r
+                                successfully.\r
+**/\r
+EFI_STATUS\r
+BootScriptWriteIoPoll (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+   S3_BOOT_SCRIPT_LIB_WIDTH     Width;  \r
+   UINT64                     Address;    \r
+   VOID                      *Data;       \r
+   VOID                      *DataMask;   \r
+   UINT64                     Delay;       \r
+   \r
+   Width    = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);  \r
+   Address  = VA_ARG (Marker, UINT64);                    \r
+   Data     = VA_ARG (Marker, VOID *);                   \r
+   DataMask = VA_ARG (Marker, VOID *);                   \r
+   Delay    = (UINT64)VA_ARG (Marker, UINT64);             \r
+   \r
+   return S3BootScriptSaveIoPoll (Width, Address, Data, DataMask, Delay);\r
+}\r
+/**\r
+  Internal function to add PCI config poll opcode node to the table\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enought resource to complete the operations.\r
+  @retval EFI_SUCCESS           The opcode entry is added to the  table\r
+                                successfully.\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciConfigPoll (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+   S3_BOOT_SCRIPT_LIB_WIDTH   Width;\r
+   UINT64                     Address;\r
+   VOID                      *Data;\r
+   VOID                      *DataMask;\r
+   UINT64                     Delay;\r
+\r
+   \r
+   Width    = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);  \r
+   Address  = VA_ARG (Marker, UINT64);                    \r
+   Data     = VA_ARG (Marker, VOID *);                   \r
+   DataMask = VA_ARG (Marker, VOID *);                   \r
+   Delay    = (UINT64)VA_ARG (Marker, UINT64);             \r
+   \r
+   return S3BootScriptSavePciPoll (Width, Address, Data, DataMask, Delay);\r
+}\r
+/**\r
+  Internal function to add PCI config 2 poll opcode node to the table\r
+\r
+  @param  Marker                The variable argument list to get the opcode\r
+                                and associated attributes.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  Not enought resource to complete the operations.\r
+  @retval EFI_SUCCESS           The opcode entry is added to the  table\r
+                                successfully.\r
+**/\r
+EFI_STATUS\r
+BootScriptWritePciConfig2Poll (\r
+  IN VA_LIST                       Marker\r
+  )\r
+{\r
+   S3_BOOT_SCRIPT_LIB_WIDTH      Width;\r
+   UINT16                        Segment;\r
+   UINT64                        Address;\r
+   VOID                         *Data;\r
+   VOID                         *DataMask;\r
+   UINT64                        Delay;\r
+  \r
+   Width    = VA_ARG (Marker, S3_BOOT_SCRIPT_LIB_WIDTH);  \r
+   Segment  = VA_ARG (Marker, UINT16);      \r
+   Address  = VA_ARG (Marker, UINT64);                    \r
+   Data     = VA_ARG (Marker, VOID *);                   \r
+   DataMask = VA_ARG (Marker, VOID *);                   \r
+   Delay    = (UINT64)VA_ARG (Marker, UINT64);             \r
+   \r
+   return S3BootScriptSavePci2Poll (Width, Segment, Address, Data, DataMask, Delay);\r
+}\r
+\r
+/**\r
+  Adds a record into S3 boot script table.\r
+\r
+  This function is used to store a boot script record into a given boot\r
+  script table. If the table specified by TableName is nonexistent in the \r
+  system, a new table will automatically be created and then the script record \r
+  will be added into the new table. This function is responsible for allocating \r
+  necessary memory for the script.\r
+\r
+  This function has a variable parameter list. The exact parameter list depends on \r
+  the OpCode that is passed into the function. If an unsupported OpCode or illegal \r
+  parameter list is passed in, this function returns EFI_INVALID_PARAMETER.\r
+  If there are not enough resources available for storing more scripts, this function returns\r
+  EFI_OUT_OF_RESOURCES.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  OpCode                The operation code (opcode) number.\r
+  @param  ...                   Argument list that is specific to each opcode. \r
+  \r
+  @retval EFI_SUCCESS           The operation succeeded. A record was added into the\r
+                                specified script table.\r
+  @retval EFI_INVALID_PARAMETER The parameter is illegal or the given boot script is not supported.\r
+                                If the opcode is unknow or not supported because of the PCD \r
+                                Feature Flags.\r
+  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptWrite (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL         *This,\r
+  IN UINT16                                    OpCode,\r
+  ...\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  VA_LIST                   Marker;  \r
+  //\r
+  // Build script according to opcode\r
+  //\r
+  switch (OpCode) {\r
+\r
+  case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemWrite (Marker);\r
+    VA_END (Marker); \r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfgWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfgReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteSmbusExecute (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_STALL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteStall (Marker);\r
+    VA_END (Marker);\r
+  \r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteDispatch (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteDispatch2 (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteInformation (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemPoll (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfg2Write (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfg2ReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:  \r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoPoll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+  \r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE: \r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciConfigPoll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+  \r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciConfig2Poll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+\r
+  default:\r
+    Status = EFI_INVALID_PARAMETER;\r
+    break;\r
+  }\r
+\r
+  return Status;\r
+}\r
+/**\r
+  Insert a record into a specified Framework boot script table.\r
+\r
+  This function is used to store an OpCode to be replayed as part of the S3 resume boot path. It is\r
+  assumed this protocol has platform specific mechanism to store the OpCode set and replay them\r
+  during the S3 resume.\r
+  The opcode is inserted before or after the specified position in the boot script table. If Position is\r
+  NULL then that position is after the last opcode in the table (BeforeOrAfter is FALSE) or before\r
+  the first opcode in the table (BeforeOrAfter is TRUE). The position which is pointed to by\r
+  Position upon return can be used for subsequent insertions.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  BeforeOrAfter         Specifies whether the opcode is stored before (TRUE) or after (FALSE) the position\r
+                                in the boot script table specified by Position. If Position is NULL or points to\r
+                                NULL then the new opcode is inserted at the beginning of the table (if TRUE) or end\r
+                                of the table (if FALSE).\r
+  @param  Position              On entry, specifies the position in the boot script table where the opcode will be\r
+                                inserted, either before or after, depending on BeforeOrAfter. On exit, specifies\r
+                                the position of the inserted opcode in the boot script table.\r
+  @param  OpCode                The operation code (opcode) number.\r
+  @param  ...                   Argument list that is specific to each opcode. \r
+\r
+  @retval EFI_SUCCESS           The operation succeeded. A record was added into the\r
+                                specified script table.\r
+  @retval EFI_INVALID_PARAMETER The Opcode is an invalid opcode value or the Position is not a valid position in the boot script table..\r
+  @retval EFI_OUT_OF_RESOURCES  There is insufficient memory to store the boot script.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptInsert (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL    *This,\r
+  IN       BOOLEAN                          BeforeOrAfter,\r
+  IN OUT   EFI_S3_BOOT_SCRIPT_POSITION     *Position OPTIONAL,\r
+  IN       UINT16                           OpCode,\r
+  ...\r
+  )\r
+{\r
+  EFI_STATUS                Status;\r
+  VA_LIST                   Marker;  \r
+  //\r
+  // Build script according to opcode\r
+  //\r
+  switch (OpCode) {\r
+\r
+  case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemWrite (Marker);\r
+    VA_END (Marker); \r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfgWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfgReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteSmbusExecute (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_STALL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteStall (Marker);\r
+    VA_END (Marker);\r
+  \r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteDispatch (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteDispatch2 (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteInformation (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteMemPoll (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfg2Write (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+\r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciCfg2ReadWrite (Marker);\r
+    VA_END (Marker);\r
+    break;\r
+    \r
+  case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:  \r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWriteIoPoll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+  \r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE: \r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciConfigPoll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+  \r
+  case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:\r
+    VA_START (Marker, OpCode);\r
+    Status = BootScriptWritePciConfig2Poll (Marker);\r
+    VA_END (Marker);\r
+    break;    \r
+\r
+  default:\r
+    Status = EFI_INVALID_PARAMETER;\r
+    break;\r
+  }\r
+  \r
+  if (!EFI_ERROR (Status)) {\r
+   Status = S3BootScriptMoveLastOpcode (BeforeOrAfter, Position);\r
+  }\r
+  return Status;\r
+}\r
+/**\r
+  Find a label within the boot script table and, if not present, optionally create it.\r
+\r
+  If the label Label is already exists in the boot script table, then no new label is created, the\r
+  position of the Label is returned in *Position and EFI_SUCCESS is returned.\r
+  If the label Label does not already exist and CreateIfNotFound is TRUE, then it will be\r
+  created before or after the specified position and EFI_SUCCESS is returned.\r
+  If the label Label does not already exist and CreateIfNotFound is FALSE, then\r
+  EFI_NOT_FOUND is returned.\r
+\r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  BeforeOrAfter         Specifies whether the label is stored before (TRUE) or after (FALSE) the position in\r
+                                the boot script table specified by Position. If Position is NULL or points to\r
+                                NULL then the new label is inserted at the beginning of the table (if TRUE) or end of\r
+                                the table (if FALSE).\r
+  @param  CreateIfNotFound      Specifies whether the label will be created if the label does not exists (TRUE) or not\r
+                                (FALSE).\r
+  @param  Position              On entry, specifies the position in the boot script table where the label will be inserted,\r
+                                either before or after, depending on BeforeOrAfter. On exit, specifies the position\r
+                                of the inserted label in the boot script table.\r
+  @param  Label                 Points to the label which will be inserted in the boot script table.\r
+\r
+  @retval EFI_SUCCESS           The label already exists or was inserted.\r
+  @retval EFI_INVALID_PARAMETER The Opcode is an invalid opcode value or the Position is not a valid position in the boot script table..\r
+  \r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+BootScriptLabel (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL           *This,\r
+  IN       BOOLEAN                               BeforeOrAfter,\r
+  IN       BOOLEAN                               CreateIfNotFound,\r
+  IN OUT   EFI_S3_BOOT_SCRIPT_POSITION          *Position OPTIONAL,\r
+  IN CONST CHAR8                                *Label\r
+  )\r
+{\r
+       return S3BootScriptLabel (BeforeOrAfter, CreateIfNotFound, Position, Label);\r
+}\r
+/**\r
+  Compare two positions in the boot script table and return their relative position.\r
+  \r
+  This function compares two positions in the boot script table and returns their relative positions. If\r
+  Position1 is before Position2, then -1 is returned. If Position1 is equal to Position2,\r
+  then 0 is returned. If Position1 is after Position2, then 1 is returned.\r
+  \r
+  @param  This                  A pointer to the EFI_S3_SAVE_STATE_PROTOCOL instance.\r
+  @param  Position1             The positions in the boot script table to compare\r
+  @param  Position2             The positions in the boot script table to compare\r
+  @param  RelativePosition      On return, points to the result of the comparison\r
+\r
+  @retval EFI_SUCCESS           The operation succeeded. \r
+  @retval EFI_INVALID_PARAMETER The Position1 or Position2 is not a valid position in the boot script table.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI \r
+BootScriptCompare (\r
+  IN CONST EFI_S3_SAVE_STATE_PROTOCOL      *This,\r
+  IN       EFI_S3_BOOT_SCRIPT_POSITION      Position1,\r
+  IN       EFI_S3_BOOT_SCRIPT_POSITION      Position2,\r
+  OUT      UINTN                           *RelativePosition\r
+  )\r
+{\r
+       return S3BootScriptCompare (Position1, Position2, RelativePosition);\r
+}\r
+/**\r
+  This routine is entry point of ScriptSave driver.\r
+\r
+  @param  ImageHandle           Handle for this drivers loaded image protocol.\r
+  @param  SystemTable           EFI system table.\r
+\r
+  @retval EFI_OUT_OF_RESOURCES  No enough resource\r
+  @retval EFI_SUCCESS           Succesfully installed the ScriptSave driver.\r
+  @retval other                 Errors occured.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+InitializeSmmS3SaveState (\r
+  IN EFI_HANDLE           ImageHandle,\r
+  IN EFI_SYSTEM_TABLE     *SystemTable\r
+  )\r
+{\r
+  EFI_HANDLE   Handle;\r
+  \r
+\r
+  Handle  = NULL;\r
+  return  gSmst->SmmInstallProtocolInterface (\r
+                   &Handle,\r
+                   &gEfiS3SmmSaveStateProtocolGuid,\r
+                   EFI_NATIVE_INTERFACE,\r
+                   &mS3SmmSaveState\r
+                   );\r
+}\r
diff --git a/MdeModulePkg/Universal/Acpi/SmmS3SaveState/SmmS3SaveState.inf b/MdeModulePkg/Universal/Acpi/SmmS3SaveState/SmmS3SaveState.inf
new file mode 100644 (file)
index 0000000..7daa922
--- /dev/null
@@ -0,0 +1,56 @@
+## @file\r
+# Component description file for ScriptSave Lite module.\r
+#\r
+# This is an implementation of the Boot Script Save protocol.\r
+#\r
+# Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+#\r
+# This program and the accompanying materials are\r
+# licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = SmmS3SaveState\r
+  FILE_GUID                      = 2D59F041-53A4-40d0-A6CD-844DC0DFEF17\r
+  MODULE_TYPE                    = DXE_SMM_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  PI_SPECIFICATION_VERSION       = 0x0001000A\r
+  \r
+  ENTRY_POINT                    = InitializeSmmS3SaveState\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  SmmS3SaveState.c\r
+  InternalSmmSaveState.h\r
+\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  SmmServicesTableLib\r
+  UefiDriverEntryPoint\r
+  BaseMemoryLib\r
+  DebugLib\r
+  BaseLib\r
+  S3BootScriptLib\r
+\r
+[Protocols]\r
+  gEfiS3SmmSaveStateProtocolGuid                # PROTOCOL ALWAYS_PRODUCED\r
+\r
+[Depex]\r
+  TRUE\r
+\r