summaryrefslogtreecommitdiff
path: root/Core/EM/S3
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/S3')
-rw-r--r--Core/EM/S3/AcpiPeiS3Func.c141
-rw-r--r--Core/EM/S3/AcpiPeiS3Func.h83
-rw-r--r--Core/EM/S3/AcpiS3Save.c468
-rw-r--r--Core/EM/S3/AcpiS3Save.dxs70
-rw-r--r--Core/EM/S3/AcpiS3Wake.asm339
-rw-r--r--Core/EM/S3/BootScriptExecuter.c1053
-rw-r--r--Core/EM/S3/BootScriptPrivate.h732
-rw-r--r--Core/EM/S3/BootScriptSave.c2540
-rw-r--r--Core/EM/S3/S3Restore.cif15
-rw-r--r--Core/EM/S3/S3Restore.mak88
-rw-r--r--Core/EM/S3/S3Restore.sdl25
-rw-r--r--Core/EM/S3/S3Resume.c582
-rw-r--r--Core/EM/S3/S3Resume.dxs85
-rw-r--r--Core/EM/S3/S3Save.cif14
-rw-r--r--Core/EM/S3/S3Save.mak99
-rw-r--r--Core/EM/S3/S3Save.sdl25
-rw-r--r--Core/EM/S3/S3Support.cif12
-rw-r--r--Core/EM/S3/S3Support.sdl9
-rw-r--r--Core/EM/S3/SmmS3Save.dxs70
19 files changed, 6450 insertions, 0 deletions
diff --git a/Core/EM/S3/AcpiPeiS3Func.c b/Core/EM/S3/AcpiPeiS3Func.c
new file mode 100644
index 0000000..966ddcb
--- /dev/null
+++ b/Core/EM/S3/AcpiPeiS3Func.c
@@ -0,0 +1,141 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.c 2 7/19/11 11:34a Oleksiyy $
+//
+// $Revision: 2 $
+//
+// $Date: 7/19/11 11:34a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.c $
+//
+// 2 7/19/11 11:34a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 1 2/03/11 4:09p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Restore.cif
+// S3Restore.sdl
+// S3Restore.mak
+// S3Resume.dxs
+// AcpiS3Wake.asm
+// S3Resume.c
+// AcpiPeiS3Func.c
+// AcpiPeiS3Func.h
+// BootScriptExecuter.c
+//
+// 7 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 6 4/29/08 4:38p Felixp
+// Bug fix in GetAcpiS3Info: Initialize AcpiVariableSet variable with NULL
+// to make sure there is no junk in the high 4 bytes in x64 mode.
+//
+// 5 4/15/08 9:15p Yakovlevs
+// Functions Headers added
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AcpiPeiS3Func.c
+//
+// Description: ACPI S3 PEI support functions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <EFI.h>
+#include <Pei.h>
+#include <Ppi\ReadOnlyVariable2.h>
+#include <AmiPeiLib.h>
+#include "AcpiS3.h"
+
+CHAR16 gAcpiGlobalVariable[] = ACPI_GLOBAL_VARIABLE;
+EFI_GUID gEfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID;
+
+extern EFI_GUID gEfiPeiReadOnlyVariable2PpiGuid;
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetAcpiS3Info
+//
+// Description:
+// This function reads ACPI_VARIABLE_SET data from NVRAM and returns pointer to it
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices - pointer to pointer to PEI services
+//
+// Output:
+// ACPI_VARIABLE_SET* - pointer to ACPI_VARIABLE_SET structure (NULL if error occured)
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+ACPI_VARIABLE_SET * GetAcpiS3Info(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable;
+ ACPI_VARIABLE_SET *AcpiVariableSet = NULL;
+
+ UINTN VariableSize = sizeof(ACPI_VARIABLE_SET*);
+ EFI_STATUS Status;
+
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0,
+ NULL,
+ &ReadOnlyVariable
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ Status = ReadOnlyVariable->GetVariable(
+ ReadOnlyVariable,
+ gAcpiGlobalVariable,
+ &gEfiAcpiVariableGuid,
+ NULL,
+ &VariableSize,
+ &AcpiVariableSet
+ );
+ if (EFI_ERROR(Status)) return NULL;
+ return AcpiVariableSet;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
diff --git a/Core/EM/S3/AcpiPeiS3Func.h b/Core/EM/S3/AcpiPeiS3Func.h
new file mode 100644
index 0000000..5afbf84
--- /dev/null
+++ b/Core/EM/S3/AcpiPeiS3Func.h
@@ -0,0 +1,83 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.h 1 2/03/11 4:09p Oleksiyy $
+//
+// $Revision: 1 $
+//
+// $Date: 2/03/11 4:09p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiPeiS3Func.h $
+//
+// 1 2/03/11 4:09p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Restore.cif
+// S3Restore.sdl
+// S3Restore.mak
+// S3Resume.dxs
+// AcpiS3Wake.asm
+// S3Resume.c
+// AcpiPeiS3Func.c
+// AcpiPeiS3Func.h
+// BootScriptExecuter.c
+//
+// 3 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 8/22/05 4:06p Markw
+// Removed get cpu info.
+//
+// 1 5/06/05 1:44p Markw
+//
+//**********************************************************************
+
+#ifndef __ACPI_PEI_S3_FUNC_H__
+#define __ACPI_PEI_S3_FUNC_H__
+
+#include <Efi.h>
+#include "AcpiS3.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+ACPI_VARIABLE_SET * GetAcpiS3Info(
+ IN EFI_PEI_SERVICES **PeiServices
+);
+
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/AcpiS3Save.c b/Core/EM/S3/AcpiS3Save.c
new file mode 100644
index 0000000..944c6f5
--- /dev/null
+++ b/Core/EM/S3/AcpiS3Save.c
@@ -0,0 +1,468 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.c 8 7/11/14 11:36a Oleksiyy $
+//
+// $Revision: 8 $
+//
+// $Date: 7/11/14 11:36a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.c $
+//
+// 8 7/11/14 11:36a Oleksiyy
+// [TAG] EIP175962
+// [Category] Improvement
+// [Description] Memory allocation logic made more clear.
+// [Files] AcpiS3Save.c
+//
+// 7 7/01/14 4:13p Oleksiyy
+// [TAG] EIP175962
+// [Category] Improvement
+// [Description] Memory type for AcpiGlobalVariable changed to Reserved to
+// prevent OS from restoring it on thertain scenarious.
+// [Files] AcpiS3Save.c
+//
+// 6 6/05/14 3:22p Oleksiyy
+// [TAG] EIP165196
+// [Category] Improvement
+// [Description] Previous check in updated with better logic.
+// [Files] AcpiS3Save.c
+//
+// 5 6/03/14 6:13p Oleksiyy
+// [TAG] EIP165196
+// [Category] Improvement
+// [Description] Taken care of case when BIOS will be updated with
+// preserved NVRAM and AcpiGlobalVariable will still has runtime attribute
+// [Files] AcpiS3Save.c
+//
+// 4 4/22/14 3:35p Oleksiyy
+// [TAG] EIP165196
+// [Category] Improvement
+// [Description] Runtime attribute removed when setting
+// AcpiGlobalVariable.
+// [Files] AcpiS3Save.c
+//
+// 3 7/19/11 11:32a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 2 4/15/11 5:53p Oleksiyy
+// [TAG] EIP58481
+// [Category] Improvement
+// [Description] AllocatePages used instead of AllocatePool to make
+// AcpiMemoryBase aligned on 4KB boundary
+// [Files] AcpiS3Save.c
+//
+// 1 2/03/11 4:08p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Save.cif
+// S3Save.sdl
+// S3Save.mak
+// AcpiS3.h
+// AcpiS3Save.c
+// BootScriptPrivate.h
+// BootScriptSave.c
+// AcpiS3Save.dxs
+// SmmS3Save.dxs
+//
+// 19 4/28/10 2:49p Oleksiyy
+// EIP 35563 Added logic to handle only ACPI 1.1 case in saving FACS.
+//
+// 18 5/18/09 10:41a Yakovlevs
+// Changed token name from S3_BASE_MEMORY to S3_BASE_MEMORY_SIZE for
+// better token meaning.
+//
+// 17 4/28/09 6:02p Markw
+// EIP #16665 - Unable to allocate enough memory in S3. Added allocation
+// of base + memory per cpu.
+//
+// 16 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 15 10/06/08 2:06p Yakovlevs
+// Added NUM_S3_PAGES_RESERVED token support
+//
+// 14 4/15/08 9:14p Yakovlevs
+// Functions Headers added
+//
+// 13 4/09/08 5:13p Yakovlevs
+// Make S3Save code remember all possible locations of FACS.
+//
+// 12 4/23/07 1:31p Felixp
+// Boot Script related code moved from Core to ACPI module.
+// PEI code added to S3 Resume PPI. DXE code added to AcpiS3Save driver.
+//
+// 11 10/13/06 12:29a Felixp
+// UEFI2.0 compliance: use CreateReadyToBootEvent instead of
+// CreateEvent(READY_TO_BOOT)
+//
+// 10 9/18/06 6:51p Markw
+// Fix AcpiGlobalVariable Size below 4GB.
+//
+// 9 8/24/06 3:00p Felixp
+// x64 support (warnings/errors fixed)
+//
+// 7 8/22/05 4:05p Markw
+// Removed IDT saving to CPU.
+//
+// 6 7/20/05 3:35p Girim
+// Fix for S3 Resume.
+//
+// 5 5/31/05 6:05p Markw
+// Number of pages reported to PEI S3 resume and reserved for windows
+// different. Added a #define, so are the same.
+//
+// 4 5/31/05 10:26a Markw
+// Changed reserving ACPI memory from 32k to 128k.
+//
+// 3 5/04/05 12:24p Markw
+// Moved structure definitions to AcpiS3.h.
+//
+// 2 4/29/05 3:26p Markw
+//
+// 1 4/29/05 12:17p Sivagarn
+//
+// 5 4/22/05 2:45p Markw
+// Only save S3 Resume Info once.
+//
+// 4 3/31/05 11:00a Markw
+// Storing the FACS table for S3 resume is working.
+//
+// 3 3/30/05 2:56p Markw
+// Added getting ACPI FACS table.
+//
+// 2 3/24/05 5:40p Markw
+//
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: AcpiS3Save.c
+//
+// Description: ACPI S3 support functions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Efi.h>
+#include <Dxe.h>
+#include <Hob.h>
+#include <Protocol\BootScriptSave.h>
+#include <Protocol\MpService.h>
+#include <AmiDxeLib.h>
+#include <Acpi20.h>
+#include "AcpiS3.h"
+#include <token.h>
+
+EFI_BOOT_SCRIPT_SAVE_PROTOCOL *gBootScriptSave;
+EFI_MP_SERVICES_PROTOCOL *gMpServices;
+CHAR16 gAcpiGlobalVariable[] = ACPI_GLOBAL_VARIABLE;
+
+EFI_GUID gAcpi20TableGuid = ACPI_20_TABLE_GUID;
+EFI_GUID gAcpi11TAbleGuid = ACPI_10_TABLE_GUID;
+EFI_GUID gEfiBootScriptSaveGuid = EFI_BOOT_SCRIPT_SAVE_GUID;
+EFI_GUID gEfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID;
+EFI_GUID gHobListGuid = HOB_LIST_GUID;
+EFI_GUID gEfiMpServicesGuid = EFI_MP_SERVICES_PROTOCOL_GUID;
+
+//Declaration of Boot Script Save module initializarion routine
+EFI_STATUS InitBootScript(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: GetAcpiFacsTable
+//
+// Description:
+// This function returns address of memory where FACS ACPI table resides
+//
+// Input:
+// VOID
+//
+// Output:
+// EFI_PHYSICAL_ADDRESS - address of FACS table
+//
+// Notes:
+// The routine may fail if the FACS table is in a different location for
+// ACPI 1.0 and ACPI 2.0 (e.g. 1 above 4G and 1 below 4G). WIN98 will read the
+// RSDT, and WINXP will read the XSDT. If the XSDT and RSDT aren't pointing to
+// the same tables, a S3 resume failure will occur.
+// Currently, the variable from Intel only supports one FACS table.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID GetAcpiFacsTable(EFI_PHYSICAL_ADDRESS *FacsTable)
+{
+ RSDT_PTR_20 *RSDP = NULL;
+ RSDT_20 *RSDT = NULL;
+ XSDT_20 *XSDT = NULL;
+ FACP_20 *FADT = 0;
+ UINT32 i;
+ BOOLEAN Ver1 = FALSE;
+
+ // Initialize each pointer to 0
+ for (i = 0; i < 3; i++) FacsTable[i] = 0;
+
+ RSDP = GetEfiConfigurationTable(pST,&gAcpi20TableGuid);
+ if (!RSDP)
+ {
+ RSDP = GetEfiConfigurationTable(pST,&gAcpi11TAbleGuid);
+ Ver1 = TRUE;
+ }
+ if (!RSDP) return;
+
+ RSDT = (RSDT_20*)RSDP->RsdtAddr; // 32-bit pointer table
+ if (!Ver1) XSDT = (XSDT_20*)RSDP->XsdtAddr; // 64-bit pointer table.
+
+ // Get XSDT FACS Pointers
+ if (XSDT) {
+ UINT32 NumPtrs = (XSDT->Header.Length - sizeof(ACPI_HDR)) / 8;
+ for(i = 0; i < NumPtrs; ++i) {
+ if (((ACPI_HDR*)XSDT->Ptrs[i])->Signature == 'PCAF') {
+ FADT = (FACP_20*)XSDT->Ptrs[i];
+ FacsTable[0] = (EFI_PHYSICAL_ADDRESS)FADT->X_FIRMWARE_CTRL;
+ FacsTable[1] = (EFI_PHYSICAL_ADDRESS)FADT->FIRMWARE_CTRL;
+ break;
+ }
+ }
+ }
+
+ // Get RSDT FACS Pointer
+ if (RSDT) {
+ UINT32 NumPtrs = (RSDT->Header.Length - sizeof(ACPI_HDR)) / 4;
+ for(i = 0; i < NumPtrs; ++i) {
+ if (((ACPI_HDR*)RSDT->Ptrs[i])->Signature == 'PCAF') {
+ FADT = (FACP_20*)RSDT->Ptrs[i];
+ FacsTable[2] = (EFI_PHYSICAL_ADDRESS)FADT->FIRMWARE_CTRL;
+ break;
+ }
+ }
+ }
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: CallbackReadyToBoot
+//
+// Description:
+// This function will be called when ReadyToBoot event will be signaled and
+// will update data, needed for S3 resume control flow.
+//
+// Input:
+// IN EFI_EVENT Event - signalled event
+// IN VOID *Context - calling context
+//
+// Output:
+// VOID
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID CallbackReadyToBoot(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+)
+{
+ EFI_HOB_RESOURCE_DESCRIPTOR *ResDescHob;
+ ACPI_VARIABLE_SET *AcpiVariableSet;
+ EFI_PHYSICAL_ADDRESS AcpiMemoryBase;
+ EFI_PHYSICAL_ADDRESS ScriptAddress;
+ UINT64 SystemMemoryLength;
+ VOID *FirstHob;
+ EFI_STATUS Status;
+ UINTN NumCpus = 1;
+ EFI_PHYSICAL_ADDRESS MaxAddress = 0xFFFFFFFF;
+
+ static BOOLEAN S3ResumeInfo = FALSE;
+ if (S3ResumeInfo) return;
+
+ //Get number of CPUs.
+ Status = pBS->LocateProtocol(
+ &gEfiMpServicesGuid,
+ NULL,
+ &gMpServices
+ );
+ ASSERT_EFI_ERROR(Status);
+ if (!EFI_ERROR(Status)) {
+#if PI_SPECIFICATION_VERSION < 0x0001000A || BACKWARD_COMPATIBLE_MODE && defined(NO_PI_MP_SERVICES_SUPPORT)
+ Status = gMpServices->GetGeneralMPInfo(
+ gMpServices, &NumCpus, NULL, NULL, NULL, NULL
+ );
+#else
+ UINTN NumEnCpus;
+ Status = gMpServices->GetNumberOfProcessors(
+ gMpServices, &NumCpus, &NumEnCpus
+ );
+#endif
+
+ ASSERT_EFI_ERROR(Status);
+ }
+
+ Status = pBS->AllocatePages(
+ AllocateMaxAddress,
+ EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES(sizeof(ACPI_VARIABLE_SET)),
+ &MaxAddress
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ AcpiVariableSet = (VOID*)(UINTN)MaxAddress;
+
+ pBS->SetMem(AcpiVariableSet, sizeof(ACPI_VARIABLE_SET),0);
+
+ Status = pBS->LocateProtocol(
+ &gEfiBootScriptSaveGuid,
+ NULL,
+ &gBootScriptSave
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = gBootScriptSave->CloseTable(
+ gBootScriptSave,
+ EFI_ACPI_S3_RESUME_SCRIPT_TABLE,
+ &ScriptAddress);
+ ASSERT_EFI_ERROR(Status);
+
+ // Allocate ACPI reserved memory for S3 resume.
+ Status = pBS->AllocatePages (
+ AllocateAnyPages,
+ EfiACPIMemoryNVS,
+ EFI_SIZE_TO_PAGES(S3_BASE_MEMORY_SIZE + S3_MEMORY_SIZE_PER_CPU * NumCpus),
+ &AcpiMemoryBase
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ // Calculate the system memory length by memory hobs
+ SystemMemoryLength = 0x100000;
+
+ FirstHob = GetEfiConfigurationTable(pST,&gHobListGuid);
+ if (!FirstHob) ASSERT_EFI_ERROR(EFI_NOT_FOUND);
+
+ ResDescHob = (EFI_HOB_RESOURCE_DESCRIPTOR*) FirstHob;
+
+ //Find APIC ID Hob.
+ while (!EFI_ERROR(Status = FindNextHobByType(EFI_HOB_TYPE_RESOURCE_DESCRIPTOR,&ResDescHob)))
+ {
+ if (ResDescHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY)
+ {
+ if (ResDescHob->PhysicalStart >= 0x100000)
+ SystemMemoryLength += ResDescHob->ResourceLength;
+ }
+ }
+ if (SystemMemoryLength == 0x100000) ASSERT_EFI_ERROR(EFI_NOT_FOUND);
+
+ AcpiVariableSet->AcpiReservedMemoryBase = (EFI_PHYSICAL_ADDRESS)AcpiMemoryBase;
+ AcpiVariableSet->AcpiReservedMemorySize = S3_BASE_MEMORY_SIZE + S3_MEMORY_SIZE_PER_CPU * (UINT32)NumCpus;
+ AcpiVariableSet->AcpiBootScriptTable = (EFI_PHYSICAL_ADDRESS) ScriptAddress;
+ AcpiVariableSet->SystemMemoryLength = SystemMemoryLength;
+ GetAcpiFacsTable(&AcpiVariableSet->AcpiFacsTable[0]);
+
+ Status = pRS->SetVariable(
+ gAcpiGlobalVariable,
+ &gEfiAcpiVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(UINT32),
+ &AcpiVariableSet
+ );
+ //In case BIOS was updated with preserved NVRAM and AcpiGlobalVariable still has runtime attribute
+ if (Status == EFI_INVALID_PARAMETER)
+ {
+ Status = pRS->SetVariable(
+ gAcpiGlobalVariable,
+ &gEfiAcpiVariableGuid,
+ 0,
+ 0,
+ NULL
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ Status = pRS->SetVariable(
+ gAcpiGlobalVariable,
+ &gEfiAcpiVariableGuid,
+ EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
+ sizeof(UINT32),
+ &AcpiVariableSet
+ );
+ }
+
+ ASSERT_EFI_ERROR(Status);
+
+ S3ResumeInfo = TRUE;
+}
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: AcpiS3SaveEntryPoint
+//
+// Description:
+// This function is ACPI S3 driver entry point
+//
+// Input:
+// IN EFI_HANDLE ImageHandle - Image handle
+// IN EFI_SYSTEM_TABLE *SystemTable - pointer to system table
+//
+// Output:
+// EFI_SUCCESS - Function executed successfully
+//
+// Notes:
+// This function also creates ReadyToBoot event to save data
+// needed for S3 resume control flow.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS AcpiS3SaveEntryPoint(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ InitAmiLib(ImageHandle,SystemTable);
+
+ //Initialize Boot Script Save module
+ Status = InitBootScript(ImageHandle,SystemTable);
+
+ return Status;
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/AcpiS3Save.dxs b/Core/EM/S3/AcpiS3Save.dxs
new file mode 100644
index 0000000..5aa1806
--- /dev/null
+++ b/Core/EM/S3/AcpiS3Save.dxs
@@ -0,0 +1,70 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.dxs 1 2/03/11 4:08p Oleksiyy $
+//
+// $Revision: 1 $
+//
+// $Date: 2/03/11 4:08p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/AcpiS3Save.dxs $
+//
+// 1 2/03/11 4:08p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Save.cif
+// S3Save.sdl
+// S3Save.mak
+// AcpiS3.h
+// AcpiS3Save.c
+// BootScriptPrivate.h
+// BootScriptSave.c
+// AcpiS3Save.dxs
+// SmmS3Save.dxs
+//
+// 3 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/24/07 6:27p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AcpiS3Save.dxs
+//
+// Description: Dependency expression for the AcpiS3Save component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/S3/AcpiS3Wake.asm b/Core/EM/S3/AcpiS3Wake.asm
new file mode 100644
index 0000000..642e5d5
--- /dev/null
+++ b/Core/EM/S3/AcpiS3Wake.asm
@@ -0,0 +1,339 @@
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
+
+;**********************************************************************
+; $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiS3Wake.asm 1 2/03/11 4:09p Oleksiyy $
+;
+; $Revision: 1 $
+;
+; $Date: 2/03/11 4:09p $
+;**********************************************************************
+; Revision History
+; ----------------
+; $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/AcpiS3Wake.asm $
+;
+; 1 2/03/11 4:09p Oleksiyy
+; [TAG] EIP53402
+; [Category] Improvement
+; [Description] Create new label of ACPI with separate S3 Functionality
+; [Files] S3Restore.cif
+; S3Restore.sdl
+; S3Restore.mak
+; S3Resume.dxs
+; AcpiS3Wake.asm
+; S3Resume.c
+; AcpiPeiS3Func.c
+; AcpiPeiS3Func.h
+; BootScriptExecuter.c
+;
+; 9 3/26/09 4:51p Oleksiyy
+; New ACPI Core implementation - improves logic, execution time and
+; memory usage of ACPI module.
+;
+; 8 4/29/08 5:36p Yakovlevs
+;
+; 7 4/15/08 12:28p Markw
+; Add cs overrides. Option rom may change ds.
+;
+; 6 1/23/07 4:24p Markw
+; Added thunk support for a call for S3 video repost.
+;
+; 5 5/27/05 4:18p Markw
+; Added comment.
+;
+; 4 5/10/05 3:00p Markw
+; Corrected wakeup vector address. Uses 16 bit data selector and adjusts
+; base of data selector to pointer to wake up vector.
+;
+; 3 5/09/05 10:19a Markw
+; Fixed cs and eip backwards. The OS is now given control.
+;
+; 2 5/07/05 11:54p Markw
+; Goes to real mode. But when resuming to windows cs and ip switched.
+; Will fix.
+;
+; 1 5/06/05 1:44p Markw
+;
+;**********************************************************************
+;<AMI_FHDR_START>
+;
+; Name: AcpiS3Wake.asm
+;
+; Description: Provide the thunk S3 resume.
+;
+;<AMI_FHDR_END>
+;**********************************************************************
+
+.586P
+.model small
+include token.equ
+
+ACPI_S3_SEG SEGMENT USE32 'CODE'
+assume DS:ACPI_S3_SEG
+
+public _RealModeThunkStart
+public _RealModeThunkSize
+
+align 16
+;This code may be exexuted
+
+REAL_MODE_BASE equ (MKF_ACPI_THUNK_REAL_MODE_SEGMENT * 16)
+
+;<AMI_PHDR_START>
+;---------------------------------------------------------------------------
+;
+; Procedure: RealModeThunk
+;
+; Description: Switch to 16-bit to jump/call to an address.
+; This may be executed in place for a jump
+; or copied to a location if a call.
+;
+; Input:
+; GdtDesc:DWORD -- pointer descriptors with 16-bit.
+; JmpAddress: DWORD -- Address to jump or call to.
+; IsCall:BYTE -- TRUE - if call. FALSE - if jump.
+;
+;
+; Output: None
+;---------------------------------------------------------------------------
+;<AMI_PHDR_END>
+REAL_MODE_THUNK_START equ $
+RealModeThunk proc C public, GdtDesc:DWORD, JmpAddress: DWORD, IsCall:BYTE
+ pushad
+ call get_base_addr ;push the eip.
+get_base_addr:
+ pop ebx ;ebx = eip.
+ sub ebx, offset get_base_addr - REAL_MODE_THUNK_START ;ebx = Start address
+
+ cmp IsCall, 0
+ je @f
+
+ ;If call, this function will return, so save original state.
+ ;Save 32 bit stack address of this module.
+ ;mov [ebx + offset StackSave - REAL_MODE_THUNK_START], esp
+ db 89h, 0a3h
+ dd offset StackSave - REAL_MODE_THUNK_START
+ ;sgdt fword ptr [ebx + offset GdtSave - REAL_MODE_THUNK_START]
+ db 0fh, 1, 83h
+ dd offset GdtSave - REAL_MODE_THUNK_START
+ ;sidt fword ptr [ebx + offset IdtSave - REAL_MODE_THUNK_START]
+ db 0fh, 1, 8bh
+ dd offset IdtSave - REAL_MODE_THUNK_START
+@@:
+
+;--Switch to real mode--
+ ;lidt fword ptr [ebx + offset LegacyLdtDescriptor - REAL_MODE_THUNK_START]
+ db 0fh, 1, 9bh
+ dd offset LegacyLdtDescriptor - REAL_MODE_THUNK_START
+
+ mov edx, GdtDesc ;Get discriptor table with 16-bit descriptors.
+ mov ecx, [edx + 2] ;ecx = GDT Base
+
+ ;---Set the code selector base address of the memory location
+ ; to jump to 16-bit protected mode above 1MB for execute in place.
+ mov eax, offset Next
+ mov ebx, eax
+ and eax, 00ffffffh ;eax = [23:00] of next
+ shr ebx, 24 ;ebx = [31:24] of next
+
+ or [ecx + 8 + 2], eax ;GDT[1] (Code segment) base [23:00] of next
+ or [ecx + 8 + 7], bl ;GDT[1] base [24:31] of next
+
+ ;---Set the data selector base address of the memory location
+ ; that contains the location to jump to for thunking.
+ ; This is so 16-bit protected mode can read the jump address
+ ; on the caller stack above 1MB. This is needed because the
+ ; jump code will be executed in place.
+ ; For call code, this will not do anything useful.
+ lea edx, JmpAddress
+ mov ebx, edx
+ and edx, 00ffffffh ;edx = [23:00] address of wakeup vector
+ shr ebx, 24 ;ebx = [31:24] address of wakeup vector
+
+ or [ecx + 16 + 2], edx ;GDT[2] (Data segment) base [23:00] of next
+ or [ecx + 16 + 7], bl ;GDT[2] base [24:31] of next
+ ;---
+
+
+ xor esp, esp ;esp will be set to a non-zero if a call.
+ ;This will also to be used to determine
+ ; if call or not call. This is because
+ ; IsCall is not available in 16-bit mode.
+ cmp IsCall, 0
+ je @f
+
+ ;Set real mode stack except the linear stack address.
+ mov esp, REAL_MODE_BASE + MKF_ACPI_THUNK_STACK_TOP
+
+ ;-------------------------------------------------
+ ;Setup the stack to simulate a int xx or call.
+ ;-------------------------------------------------
+
+ mov eax, offset ReturnFromPtr
+ sub eax, REAL_MODE_THUNK_START ;ax = return address.
+
+ ;push the flags and return address to simulate the
+ ; return address on the stack for int xx or call.
+ pushf ;push flags in case intxx
+ push word ptr MKF_ACPI_THUNK_REAL_MODE_SEGMENT
+ push ax ;ax = return ip
+
+ ;push to stack the cs:ip of the address to call to
+ push JmpAddress ;push cs:eip to jump to.
+
+ ;-------------------------------------------------
+ ;Now the stack is setup, so that a retf will jump
+ ;to the address on stack.
+ ;-------------------------------------------------
+
+ ;Adjust the stack address, so it will be relative to ss.
+ sub esp, REAL_MODE_BASE
+@@:
+
+ ;---Switch to 16-bit protected mode---
+ mov edx, GdtDesc
+ lgdt fword ptr [edx]
+
+ ;ITP doesn't display disassembly correctly until jump to 16 bit code.
+ mov ax, 10h ;16 bit data segment
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ mov fs, ax
+ mov gs, ax
+
+ ;jmp 08:next
+ db 0eah
+ dd 0 ;offset of next with new selector
+ dw 08 ;16 bit code selector
+next:
+ ;---16 bit mode. Must use 16 bit instructions from here on.---
+ ;-------------------------------------------------------------
+
+ ;---Switch to real mode---
+ mov eax, cr0
+ and al, 0feh
+ mov cr0, eax ;switch to real mode
+ ;---In real mode---
+
+ db 66h
+ or esp, esp ;IsCall?
+ jnz @f
+
+ ;jmp far ptr [0] ;Jump to the address stored in ds:0.
+ db 0ffh, 2eh ;The descriptor's base is in stack.
+ dw 0
+ ;Does not return.
+@@:
+
+ ; jmp REAL_MODE_SEGMENT:real_mode_adr
+ db 0eah
+ dw offset real_mode_adr - REAL_MODE_THUNK_START
+ dw MKF_ACPI_THUNK_REAL_MODE_SEGMENT
+
+real_mode_adr:
+ db 8ch, 0c8h ;mov ax, cs
+ db 8eh, 0d8h ;mov ds, ax
+ db 8eh, 0c0h ;mov es, ax
+ db 8eh, 0d0h ;mov ss, ax
+ db 8eh, 0e0h ;mov fs, ax
+ db 8eh, 0e8h ;mov gs, ax
+
+ retf ;call JmpAddress on stack.
+
+ReturnFromPtr:
+;--------------End Real Mode operations---------
+
+ ;--Switch to protected mode--
+
+ ;mov esp, cs:[offset StackSave - REAL_MODE_THUNK_START] ;Get original stack back.
+ db 2eh, 66h, 8bh, 26h
+ dw offset StackSave - REAL_MODE_THUNK_START
+
+ ;lgdt fword ptr cs:[offset GdtSave - REAL_MODE_THUNK_START]
+ db 2eh, 66h, 0fh, 1, 16h
+ dw offset GdtSave - REAL_MODE_THUNK_START
+
+ mov eax, cr0
+ or al, 1 ;Set PE bit
+ mov cr0, eax ;Turn on Protected Mode
+
+ ;jmp 10:P32MODE
+ db 66h, 0eah
+ dd REAL_MODE_BASE + offset P32Mode - REAL_MODE_THUNK_START
+ dw 10h
+P32Mode::
+ mov ax, 08
+ mov ds, ax
+ mov es, ax
+ mov ss, ax
+ mov fs, ax
+ mov gs, ax
+
+ ;lidt fword ptr [REAL_MODE_BASE + offset IdtSave - REAL_MODE_THUNK_START]
+ db 0fh, 1, 1dh
+ dd REAL_MODE_BASE + offset IdtSave - REAL_MODE_THUNK_START
+ popad
+ ret
+RealModeThunk endp
+
+align 8
+ public LegacyLdtDescriptor
+LegacyLdtDescriptor label fword
+ dw 3ffh
+ dd 0
+
+;Note: The following below is only used in a call when this is copied to below 1MB.
+;The data below can not be changed when this is executed from ROM.
+
+ public StackSave
+StackSave label dword
+ dd 0
+
+align 8
+ public GdtSave
+GdtSave label fword
+ dw 0
+ dd 0
+
+align 8
+ public IdtSave
+IdtSave label fword
+ dw 0
+ dd 0
+
+REAL_MODE_THUNK_END EQU $
+
+_RealModeThunkStart label dword
+ dd REAL_MODE_THUNK_START
+
+_RealModeThunkSize label dword
+ dd REAL_MODE_THUNK_END - REAL_MODE_THUNK_START
+
+ACPI_S3_SEG ENDS
+end
+
+;**********************************************************************
+;**********************************************************************
+;** **
+;** (C)Copyright 1985-2009, American Megatrends, Inc. **
+;** **
+;** All Rights Reserved. **
+;** **
+;** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+;** **
+;** Phone: (770)-246-8600 **
+;** **
+;**********************************************************************
+;**********************************************************************
diff --git a/Core/EM/S3/BootScriptExecuter.c b/Core/EM/S3/BootScriptExecuter.c
new file mode 100644
index 0000000..35ac423
--- /dev/null
+++ b/Core/EM/S3/BootScriptExecuter.c
@@ -0,0 +1,1053 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptExecuter.c 2 9/17/13 10:02p Thomaschen $
+//
+// $Revision: 2 $
+//
+// $Date: 9/17/13 10:02p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptExecuter.c $
+//
+// 2 9/17/13 10:02p Thomaschen
+// update for ACPI module labeled 47
+//
+// 8 12/13/12 12:03p Oleksiyy
+// [TAG] EIP109290
+// [Category] Improvement
+// [Description] Issues found by CppCheck in ACPI eModule
+// [Files] AcpiCore.c, mptable.c, AmlString.c, BootScriptSave.c and
+// BootScriptExecuter.c
+//
+// 7 9/29/11 5:05p Oleksiyy
+// [TAG] EIP71372
+// [Category] Improvement
+// [Description] EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE added.
+// [Files] BootScriptExecuter.c and BootScriptSave.c
+//
+// 6 7/19/11 11:34a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 5 6/01/11 10:27a Oleksiyy
+// [TAG] EIP56650
+// [Category] New Feature
+// [Description] S3 Save State Protocol and S3 Smm Save State Protocol
+// backward compatibility improved.
+// [Files] BootScriptExecuter.c
+//
+// 4 5/19/11 10:40a Oleksiyy
+// [TAG] EIP60727
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Dispatch opcode invalid
+// [RootCause] Dispatch opcode realization was commented out mistakenly.
+// [Solution] Commented out code restored.
+// [Files] BootScriptExecuter.c
+//
+// 3 5/13/11 3:23p Oleksiyy
+// [TAG] EIP56650
+// [Category] New Feature
+// [Description] S3 Save State Protocol and S3 Smm Save State Protocol
+// functions added. Support for opcodes introduced in PI 1.2 added.
+// [Files] BootScriptCommon.h, BootScriptExecuter.c,
+// BootScriptPrivate.h, BootScriptSave.c and BootScriptSave.h
+//
+// 2 3/18/11 3:51p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Improving backward computability and architecture.
+// [Files] ACPI.mak, AcpiCore.cif, S3Save.cif, S3Save.mak,
+// S3Restore.mak, BootScriptExecutor.c, S3Common.cif, S3SaveState.h,
+// S3smmSaveState.h
+//
+// 2 3/09/11 6:09p Artems
+//
+// 1 3/09/11 6:09p Artems
+//
+// 1 2/03/11 4:09p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Restore.cif
+// S3Restore.sdl
+// S3Restore.mak
+// S3Resume.dxs
+// AcpiS3Wake.asm
+// S3Resume.c
+// AcpiPeiS3Func.c
+// AcpiPeiS3Func.h
+// BootScriptExecuter.c
+//
+// 11 3/04/10 2:06p Oleksiyy
+// EIP 35847: Bug Fix
+//
+// 10 11/05/09 4:00p Oleksiyy
+// EIP 27821 Support for 64 bit operations in Bootscript added. To use
+// this functions AmiLib.h, CpuIo.c, IA32CLib.c, PciCfg.c, x64AsmLib.asm
+// files should be updated also.
+//
+// 9 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 8 10/10/08 8:16p Felixp
+// Performance measurement support added
+//
+// 6 6/06/08 11:54a Felixp
+// Performance measurement support added
+//
+// 5 4/16/08 12:10p Yakovlevs
+// fixed compilation issue
+//
+// 4 4/15/08 9:20p Yakovlevs
+// Functions Headers added; Removed definition of EFI_BOOT_SCRIPT WDTH
+//
+// 3 6/07/07 3:09p Felixp
+//
+// 2 6/05/07 12:17a Felixp
+// Added SmmBus support
+//
+// 1 4/23/07 1:31p Felixp
+//
+// 15 12/26/06 2:56p Markw
+// Add BootScript Polling.
+//
+// 14 11/22/06 4:35p Markw
+// Move certain Mem/Io write trace statments before instead of after the
+// write. This is so if the write causes a hang, it can be seen on serial
+// redirection.
+//
+// 13 9/22/06 6:08p Markw
+// 64-bit fix.
+//
+// 12 3/15/06 2:41p Markw
+//
+// 11 3/15/06 2:37p Markw
+// Fixed bug, used value instead of Mask.
+//
+// 10 3/13/06 9:51a Felixp
+//
+// 9 10/09/05 11:25a Felixp
+// Performance measurements added.
+//
+// 8 6/23/05 5:37p Markw
+// Added defintions from Boot Script Save Protocol.
+//
+// 7 6/15/05 4:20p Markw
+// Modified dispatch function to pass in PeiServices.
+//
+// 6 6/06/05 7:49p Felixp
+//
+// 5 6/06/05 1:26p Felixp
+// Usage of CPU I/O and PCI Cfg changed to match PEI CIS 0.91
+//
+// 4 5/27/05 1:36a Felixp
+//
+// 3 5/16/05 3:03p Markw
+// Added more trace messages.
+//
+// 2 4/04/05 2:38p Markw
+// Fix write to pci register bug.
+// Add temporary trace statements.
+//
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: BootScriptExecuter.c
+//
+// Description: Boot script execution support functions
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Ppi\BootScriptExecuter.h>
+#include <Ppi\CpuIo.h>
+#include <Ppi\PciCfg2.h>
+#if PI_SPECIFICATION_VERSION>=0x10000
+#include <Ppi\Smbus2.h>
+#else
+#include <Ppi\Smbus.h>
+#endif
+#include <Ppi\Stall.h>
+#include "BootScriptPrivate.h"
+#include <AmiPeiLib.h>
+
+#if (CORE_REVISION >= 0x5)
+#include <BootScriptCommon.h>
+#else
+
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+//*******************************************
+// EFI Save State Script Opcode definitions (PI)
+//*******************************************
+
+#define EFI_BOOT_SCRIPT_IO_WRITE_OPCODE 0x00
+#define EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE 0x01
+#define EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE 0x02
+#define EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE 0x03
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE 0x04
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE 0x05
+#define EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE 0x06
+#define EFI_BOOT_SCRIPT_STALL_OPCODE 0x07
+#define EFI_BOOT_SCRIPT_DISPATCH_OPCODE 0x08
+
+#define EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE 0x09
+#define EFI_BOOT_SCRIPT_INFORMATION_OPCODE 0x0A
+#define EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE 0x0B
+#define EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE 0x0C
+#define EFI_BOOT_SCRIPT_IO_POLL_OPCODE 0x0D
+#define EFI_BOOT_SCRIPT_MEM_POLL_OPCODE 0x0E
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE 0x0F
+#define EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE 0x10
+#define EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM 0x83
+
+#else
+//*******************************************
+// EFI Boot Script Opcode definitions (Framework)
+//*******************************************
+
+#define EFI_BOOT_SCRIPT_IO_WRITE_OPCODE 0x00
+#define EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE 0x01
+#define EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE 0x02
+#define EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE 0x03
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE 0x04
+#define EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE 0x05
+#define EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE 0x06
+#define EFI_BOOT_SCRIPT_STALL_OPCODE 0x07
+#define EFI_BOOT_SCRIPT_DISPATCH_OPCODE 0x08
+
+#endif
+//
+// Extensions to boot script definitions
+//
+//OEM
+#ifndef EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM
+#define EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM 0x80
+#endif
+
+#ifndef EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM
+#define EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM 0x81
+#endif
+
+#ifndef EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM
+#define EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM 0x82
+#endif
+
+
+
+#define EFI_BOOT_SCRIPT_TABLE_OPCODE 0xAA
+#define EFI_BOOT_SCRIPT_TERMINATE_OPCODE 0xFF
+
+
+
+//*******************************************
+// EFI_BOOT_SCRIPT_WIDTH
+//*******************************************
+typedef enum {
+ EfiBootScriptWidthUint8,
+ EfiBootScriptWidthUint16,
+ EfiBootScriptWidthUint32,
+ EfiBootScriptWidthUint64,
+ EfiBootScriptWidthFifoUint8,
+ EfiBootScriptWidthFifoUint16,
+ EfiBootScriptWidthFifoUint32,
+ EfiBootScriptWidthFifoUint64,
+ EfiBootScriptWidthFillUint8,
+ EfiBootScriptWidthFillUint16,
+ EfiBootScriptWidthFillUint32,
+ EfiBootScriptWidthFillUint64,
+ EfiBootScriptWidthMaximum
+} EFI_BOOT_SCRIPT_WIDTH;
+
+#endif //#if (CORE_REVISION >= 0x5)
+
+typedef EFI_STATUS (EFIAPI *DISPATCH_ENTRYPOINT_FUNC) (
+ IN EFI_HANDLE ImageHandle,
+ IN VOID* Context
+);
+
+
+EFI_GUID gBootScriptExecuterGuid = EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI_GUID;
+#if PI_SPECIFICATION_VERSION>=0x10000
+EFI_GUID gSmBusGuid = EFI_PEI_SMBUS2_PPI_GUID;
+#else
+EFI_GUID gSmBusGuid = EFI_PEI_SMBUS_PPI_GUID;
+#endif
+EFI_GUID gStallGuid = EFI_PEI_STALL_PPI_GUID;
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: PciRegAdd
+//
+// Description: Increase the Pci register number by a value.
+//
+// Input:
+// IN UINT64 Address - Pci Address
+// IN UINT8 ValueSize - Add value to register.
+//
+// Output:
+// UINT64 New Pci Address.
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get extended register.
+// 2. If extended register, increment it by ValueSize
+// else increment the non-extended register.
+// 3. Return the Address.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+UINT64 PciRegAdd(UINT64 Address,UINT8 ValueSize)
+{
+ UINT32 ExtReg;
+
+ ExtReg = (UINT32) (*((UINT32*)&Address +1));
+ if (ExtReg)
+ (*((UINT32*)&Address + 1)) += ValueSize;
+
+ else (*(UINT8*)&Address) = (*(UINT8*)&Address) + ValueSize;
+
+ return Address;
+}
+#if defined (PI_SPECIFICATION_VERSION) && (PI_SPECIFICATION_VERSION >= 0x0001000A)
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: SwitchPciCfgPpi
+//
+// Description: Serchs for PCI_CFG2_PPI with corresponding Segment
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN UINT16 SegmentSwitchTo
+
+//
+// Output:
+// EFI_PEI_PCI_CFG2_PPI* Pointer to Pci Cfg PPI with Segment wanted
+// NULL if not found
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_PEI_PCI_CFG2_PPI* SwitchPciCfgPpi(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN UINT16 SegmentSwitchTo
+ )
+{
+ UINT32 i = 0;
+ EFI_GUID PciCfg2PpiGuid = EFI_PEI_PCI_CFG2_PPI_GUID;
+ EFI_PEI_PCI_CFG2_PPI *PciCfg2Ppi;
+ EFI_STATUS Status;
+ while (TRUE) {
+
+ Status = (**PeiServices).LocatePpi( PeiServices,
+ &PciCfg2PpiGuid, i, NULL, &PciCfg2Ppi );
+
+ if ( EFI_ERROR( Status ) ) {
+ break;
+ }
+
+ if (PciCfg2Ppi->Segment == SegmentSwitchTo) //We found PPI we need
+ return PciCfg2Ppi; //return pointer
+ i++;
+ }
+ return NULL;
+}
+#endif
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: ExecuteScript
+//
+// Description:
+//
+// Input:
+// IN EFI_PEI_SERVICES **PeiServices
+// IN EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI *This
+// IN EFI_PHYSICAL_ADDRESS Address
+// IN EFI_GUID *FvFile OPTIONAL
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Locate Ppis: CpuIo PciCfg SmBus.
+// 2. If any of the Ppis doesn't exist return EFI_UNSUPPORTED.
+// ---Execute table Script---
+// 3. Read Opcode type:
+// a. EFI_BOOT_SCRIPT_IO_WRITE_OPCODE
+// b. EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE
+// etc.
+// If TABLE_END_OP_CODE, return EFI_SUCCESS.
+// If unknown opcode return EFI_UNSUPPORTED.
+//
+// 4. Copy the Opcode type to its structure. Structure will be aligned.
+// 5. If it has a buffer, get Buffer address in table.
+// 6. Get address of in table for next Opcode.
+// 7. Call appropriate Ppi for OpCode with parameters from the structure.
+//
+// Check BootScript spec for better understanding of code.
+// Note for writes there are EfiBootScriptWidthUintxx,
+// EfiBootScriptWidthFifoUintxx, and EfiBootScriptWidthFillUintxx.
+// xx Denotes 8,16,32,or 64(unsupported).
+//
+// 8. Go to step 3.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS ExecuteScript(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI *This,
+ IN EFI_PHYSICAL_ADDRESS Address,
+ IN EFI_GUID *FvFile OPTIONAL
+ )
+{
+ VOID *TableAddr = (VOID *)(UINTN) Address;
+ BOOT_SCRIPT_DATA BootScript;
+ UINT16 Type;
+ UINT32 AddressCount;
+ UINT8 ValueSize;
+ UINT8 Width;
+ UINT64 Count;
+ VOID *Buffer;
+// UINT32 Value32;
+ UINT64 Value64;
+ UINTN i;
+
+ EFI_STATUS Status;
+
+ EFI_PEI_CPU_IO_PPI *CpuIoPpi;
+
+ EFI_PEI_PCI_CFG2_PPI *PciCfgPpi;
+#if PI_SPECIFICATION_VERSION>=0x1000A
+ BOOLEAN Pi12Spec = FALSE;
+ UINT64 PollDelay;
+#endif
+#if PI_SPECIFICATION_VERSION>=0x10000
+ EFI_PEI_SMBUS2_PPI *SmBusPpi;
+#else
+ EFI_PEI_SMBUS_PPI *SmBusPpi;
+#endif
+ EFI_PEI_STALL_PPI *StallPpi;
+
+ if (FvFile) return EFI_UNSUPPORTED;
+ if (!Address) return EFI_INVALID_PARAMETER;
+
+ CpuIoPpi = (*PeiServices)->CpuIo;
+ PciCfgPpi = (*PeiServices)->PciCfg;
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gSmBusGuid,
+ 0,
+ NULL,
+ &SmBusPpi
+ );
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ Status = (**PeiServices).LocatePpi (
+ PeiServices,
+ &gStallGuid,
+ 0,
+ NULL,
+ &StallPpi
+ );
+ if (EFI_ERROR(Status)) return EFI_UNSUPPORTED;
+
+ for(;;) {
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"UniqueIndex %x\n", ((BOOT_SCRIPT_INFO_STRUCTURE*) TableAddr)->UniqueIndex));
+ TableAddr = (UINT8*) TableAddr + sizeof(BOOT_SCRIPT_INFO_STRUCTURE);
+#endif
+ Type = *(UINT8*) TableAddr + (*((UINT8*) TableAddr + 1) << 8); //In case not aligned if alignment required.
+ switch(Type&0xff) {
+ case EFI_BOOT_SCRIPT_IO_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_WRITE_IO));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_WRITE_IO);
+
+ Width = (UINT8)(BootScript.WrIo.Type >> 8);
+ ValueSize = 1 << (Width & 3);
+ Count = BootScript.WrIo.Count;
+ Buffer = TableAddr;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? (UINT32)Count : 1);
+ TableAddr = (UINT8*)TableAddr + AddressCount;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Io Write %x=", BootScript.WrIo.Port));
+#ifdef EFI_DEBUG
+ switch(ValueSize) {
+ case 1:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT8*)Buffer));
+ break;
+ case 2:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT16*)Buffer));
+ break;
+ case 4:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT32*)Buffer));
+ break;
+ case 8:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%lx\n", *(UINT64*)Buffer));
+ break;
+ default:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Unknown\n"));
+ }
+#endif
+ CpuIoPpi->Io.Write(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.WrIo.Port,
+ (UINTN)Count,
+ Buffer);
+ break;
+ case EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_READ_WRITE_IO));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_READ_WRITE_IO);
+
+ Width = (UINT8)((BootScript.WrIo.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported
+
+ CpuIoPpi->Io.Read(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.RwIo.Port,
+ 1,
+ &Value64);
+
+ Value64 &= BootScript.RwIo.Mask;
+ Value64 |= BootScript.RwIo.Value;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Io R/Write %x=%x\n", BootScript.WrIo.Port,Value64));
+ CpuIoPpi->Io.Write(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.RwIo.Port,
+ 1,
+ &Value64);
+ break;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ case EFI_BOOT_SCRIPT_IO_POLL_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_IO_POLL));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_IO_POLL);
+ PollDelay = Div64(BootScript.IoPoll.Delay, 10, NULL) + 1; // converting x100 ns units to ms, used in stall
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"IO Poll Delay %lx *100ns\n", BootScript.IoPoll.Delay));
+ Pi12Spec = TRUE;
+#endif
+ case EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM:
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (!Pi12Spec)
+#endif
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_POLL_IO));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_POLL_IO);
+ }
+ Width = (UINT8)((BootScript.PollIo.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,
+ "Io Poll: Port = %x, Mask = %lx, Result = %lx\n",
+ BootScript.PollIo.Port,
+ BootScript.PollIo.Mask,
+ BootScript.PollIo.Result
+ ));
+
+ do {
+ CpuIoPpi->Io.Read(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.PollIo.Port,
+ 1,
+ &Value64);
+ Value64 &= BootScript.PollIo.Mask;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ StallPpi->Stall(PeiServices, StallPpi, 1);
+ if (--PollDelay == 0) // delay criteria meet
+ Value64 = BootScript.PollIo.Result; //terminate cycle
+ }
+#endif
+ } while (Value64 != BootScript.PollIo.Result);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ Pi12Spec = FALSE;
+#endif
+ break;
+
+ case EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_WRITE_MEM));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_WRITE_MEM);
+ Buffer = TableAddr;
+
+ Width = (UINT8)(BootScript.WrMem.Type >> 8);
+ ValueSize = 1 << (Width & 3);
+ Count = BootScript.WrMem.Count;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? (UINT32)Count : 1);
+ TableAddr = (UINT8*)TableAddr + AddressCount;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem Write %lx=", BootScript.WrMem.Address));
+#ifdef EFI_DEBUG
+ switch(ValueSize) {
+ case 1:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT8*)Buffer));
+ break;
+ case 2:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT16*)Buffer));
+ break;
+ case 4:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT32*)Buffer));
+ break;
+ case 8:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%lx\n", *(UINT64*)Buffer));
+ break;
+ default:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Unknown\n"));
+ }
+#endif
+ CpuIoPpi->Mem.Write(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.WrMem.Address,
+ (UINTN)Count,
+ Buffer);
+ break;
+ case EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_READ_WRITE_MEM));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_READ_WRITE_MEM);
+
+ Width = (UINT8)((BootScript.WrMem.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported
+
+ CpuIoPpi->Mem.Read(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.RwMem.Address,
+ 1,
+ &Value64);
+
+ Value64 &= BootScript.RwMem.Mask;
+ Value64 |= BootScript.RwMem.Value;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem R/Write %lx=%x\n", BootScript.WrMem.Address,(UINT32)Value64));
+ CpuIoPpi->Mem.Write(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.RwMem.Address,
+ 1,
+ &Value64);
+ break;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_MEM_POLL));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_MEM_POLL);
+ PollDelay = BootScript.MemPoll.LoopTimes + 1;
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem Poll Delay %lx \n", BootScript.MemPoll.Delay));
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Mem Poll Loop Times %lx \n", BootScript.MemPoll.LoopTimes));
+ Pi12Spec = TRUE;
+#endif
+ case EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM:
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (!Pi12Spec)
+#endif
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_POLL_MEM));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_POLL_MEM);
+ }
+ Width = (UINT8)((BootScript.PollMem.Type >> 8) & 3); //Only EfiBootScriptWidthUintxx Supported
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,
+ "Mem Poll: Address = %lx, Mask = %lx, Result = %lx\n",
+ BootScript.PollMem.Address,
+ BootScript.PollMem.Mask,
+ BootScript.PollMem.Result
+ ));
+
+ do {
+ CpuIoPpi->Mem.Read(PeiServices,
+ CpuIoPpi,
+ Width,
+ BootScript.PollMem.Address,
+ 1,
+ &Value64);
+
+ Value64 &= BootScript.PollMem.Mask;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ UINTN Delay = (UINTN)BootScript.MemPoll.Delay;
+
+ StallPpi->Stall(PeiServices, StallPpi, Delay);
+ if (--PollDelay == 0) // delay criteria meet
+ {
+ PEI_TRACE((TRACE_ALWAYS, PeiServices,
+ "Mem Poll: Address = %lx, Mask = %lx, Result = %lx\n",
+ BootScript.PollMem.Address, BootScript.PollMem.Mask, Value64));
+ break;
+ }
+ }
+#endif
+
+ } while (Value64 != BootScript.PollMem.Result);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ Pi12Spec = FALSE;
+#endif
+ break;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ case EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE);
+ if (BootScript.WrPci2.Segment != 0)
+ PciCfgPpi = SwitchPciCfgPpi(PeiServices, BootScript.WrPci2.Segment);
+ if (PciCfgPpi == NULL)
+ {
+ PEI_TRACE((-1,PeiServices,"Can't found PciCfgPpi.Segment %x\n", BootScript.WrPci2.Segment));
+ return EFI_UNSUPPORTED;
+ }
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg2 Write to Segment %x\n = ", BootScript.WrPci2.Segment));
+ Pi12Spec = TRUE;
+
+#endif
+ case EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE:
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (!Pi12Spec)
+#endif
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_WRITE_PCI));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_WRITE_PCI);
+ }
+ Width = (UINT8)(BootScript.WrPci.Type >> 8);
+ ValueSize = 1 << (Width & 3);
+ Count = BootScript.WrPci.Count;
+
+ Buffer = TableAddr;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? (UINT32)Count : 1);
+ TableAddr = (UINT8*)TableAddr + AddressCount;
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Pci Write %lx=", BootScript.WrPci.Address));
+#ifdef EFI_DEBUG
+ switch(ValueSize) {
+ case 1:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT8*)Buffer));
+ break;
+ case 2:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT16*)Buffer));
+ break;
+ case 4:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%x\n", *(UINT32*)Buffer));
+ break;
+ case 8:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"%lx\n", *(UINT64*)Buffer));
+ break;
+ default:
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Unknown\n"));
+ }
+#endif
+ for (i = 0; i < Count; ++i)
+ {
+ Status = PciCfgPpi->Write(PeiServices,
+ PciCfgPpi,
+ Width & 3,
+ BootScript.WrPci.Address,
+ Buffer);
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ switch(Width & ~3)
+ {
+ case EfiBootScriptWidthUint8:
+ Buffer = (UINT8*)Buffer + AddressCount;
+ BootScript.WrPci.Address = PciRegAdd(BootScript.WrPci.Address,ValueSize);
+ break;
+ case EfiBootScriptWidthFifoUint8:
+ Buffer = (UINT8*)Buffer + AddressCount;
+ break;
+ case EfiBootScriptWidthFillUint8:
+ BootScript.WrPci.Address = PciRegAdd(BootScript.WrPci.Address,ValueSize);
+ }
+ }
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ Pi12Spec = FALSE;
+ PciCfgPpi = (*PeiServices)->PciCfg;// restore pointer
+ }
+#endif
+ break;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ case EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE);
+ if (BootScript.RwPci2.Segment != 0)
+ PciCfgPpi = SwitchPciCfgPpi(PeiServices, BootScript.RwPci2.Segment);
+ if (PciCfgPpi == NULL)
+ {
+ PEI_TRACE((-1,PeiServices,"Can't found PciCfgPpi.Segment %x\n", BootScript.RwPci2.Segment));
+ return EFI_UNSUPPORTED;
+ }
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg2 Read/Write to Segment %x\n = ", BootScript.RwPci2.Segment));
+ Pi12Spec = TRUE;
+#endif
+ case EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE:
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (!Pi12Spec)
+#endif
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_READ_WRITE_PCI));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_READ_WRITE_PCI);
+ }
+ Width = (UINT8)((BootScript.RwPci.Type >> 8) & 3);
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"Pci R/Write %x\n", BootScript.RwPci.Address));
+
+ Status = PciCfgPpi->Read(PeiServices,
+ PciCfgPpi,
+ Width,
+ BootScript.RwPci.Address,
+ &Value64
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+
+ Value64 = BootScript.RwPci.Value | (Value64 & BootScript.RwPci.Mask);
+
+ Status = PciCfgPpi->Write(PeiServices,
+ PciCfgPpi,
+ Width,
+ BootScript.RwPci.Address,
+ &Value64
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ Pi12Spec = FALSE;
+ PciCfgPpi = (*PeiServices)->PciCfg;// restore pointer
+ }
+#endif
+ break;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ case EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG2_POLL));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG2_POLL);
+ if (BootScript.PciPoll2.Segment != 0)
+ PciCfgPpi = SwitchPciCfgPpi(PeiServices, BootScript.PciPoll2.Segment);
+ if (PciCfgPpi == NULL)
+ {
+ PEI_TRACE((-1,PeiServices,"Can't found PciCfgPpi.Segment %x\n", BootScript.PciPoll2.Segment));
+ return EFI_UNSUPPORTED;
+ }
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg2 Poll to Segment %x\n = ", BootScript.PciPoll2.Segment));
+ Pi12Spec = TRUE;
+
+ case EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE:
+ if (!Pi12Spec)
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_PCI_CFG_POLL));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_PCI_CFG_POLL);
+ Pi12Spec = TRUE;
+ }
+ PollDelay = Div64(BootScript.PciPoll.Delay, 10, NULL) + 1; // converting x100 ns units to ms, used in stall
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,"PciCfg Poll Delay %lx *100ns\n", BootScript.PciPoll.Delay));
+#endif
+ case EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM:
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (!Pi12Spec)
+#endif
+ {
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_POLL_PCI));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_POLL_PCI);
+ }
+ Width = (UINT8)((BootScript.PollPci.Type >> 8) & 3);
+
+ PEI_TRACE((TRACE_ALWAYS,PeiServices,
+ "PCI Poll: Address = %x, Mask = %lx, Result = %lx\n",
+ BootScript.PollPci.Address,
+ BootScript.PollPci.Mask,
+ BootScript.PollPci.Result
+ ));
+
+ do {
+ PciCfgPpi->Read(PeiServices,
+ PciCfgPpi,
+ Width,
+ BootScript.PollPci.Address,
+ &Value64
+ );
+ Value64 &= BootScript.PollPci.Mask;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ StallPpi->Stall(PeiServices, StallPpi, 1);
+ if (--PollDelay == 0) // delay criteria meet
+ Value64 = BootScript.PollPci.Result; //terminate cycle
+ }
+#endif
+ } while (Value64 != BootScript.PollPci.Result);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (Pi12Spec)
+ {
+ Pi12Spec = FALSE;
+ PciCfgPpi = (*PeiServices)->PciCfg;// restore pointer
+ }
+#endif
+ break;
+
+ case EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_SMBUS_EXECUTE));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_SMBUS_EXECUTE);
+ Buffer = TableAddr;
+ TableAddr = (UINT8*)TableAddr + BootScript.ExecSmbus.Length;
+
+ PEI_TRACE((-1,PeiServices,
+ "Smbus: Address = %x, Command = %x Operation = %x\n",
+ BootScript.ExecSmbus.SlaveAddress,
+ BootScript.ExecSmbus.Command,
+ BootScript.ExecSmbus.Operation
+ ));
+
+ //Note: In specification, the length pointer is a IN/OUT.
+ //However, I do find that its contents updated.
+ SmBusPpi->Execute(
+#if PI_SPECIFICATION_VERSION<0x10000
+ PeiServices,
+#endif
+ SmBusPpi,
+ BootScript.ExecSmbus.SlaveAddress,
+ BootScript.ExecSmbus.Command,
+ BootScript.ExecSmbus.Operation,
+ BootScript.ExecSmbus.PecCheck,
+ (UINTN*)&BootScript.ExecSmbus.Length,
+ Buffer
+ );
+ break;
+
+ case EFI_BOOT_SCRIPT_STALL_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_STALL));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_STALL);
+
+ StallPpi->Stall(PeiServices,
+ StallPpi,
+ (UINTN)BootScript.Stall.Duration);
+ break;
+
+ case EFI_BOOT_SCRIPT_DISPATCH_OPCODE:
+ PEI_TRACE((-1,PeiServices,"Dispatch Opcode.\n"));
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_DISPATCH));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_DISPATCH);
+ ((DISPATCH_ENTRYPOINT_FUNC)(UINTN)BootScript.Dispatch.EntryPoint)(NULL, PeiServices);
+ break;
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+
+ case EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE:
+ MemCpy(&BootScript,TableAddr,sizeof(BOOT_SCRIPT_DISPATCH2));
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_DISPATCH2);
+ ((DISPATCH_ENTRYPOINT_FUNC)(UINTN)BootScript.Dispatch.EntryPoint)(NULL, PeiServices);
+ break;
+
+ case EFI_BOOT_SCRIPT_INFORMATION_OPCODE:
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_INFORMATION);
+ PEI_TRACE((-1,PeiServices,"Skipping Information opcode in Boot Script.\n"));
+ break;
+ case EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM:
+ TableAddr = (UINT8*)TableAddr + sizeof(BOOT_SCRIPT_LABEL)
+ + ((BOOT_SCRIPT_LABEL*)TableAddr)->Size;
+ PEI_TRACE((-1,PeiServices,"Skipping Label opcode in Boot Script.\n"));
+ break;
+
+#endif
+ case TABLE_END_OP_CODE:
+ PEI_TRACE((-1,PeiServices,"Table End Found.\n"));
+ return EFI_SUCCESS;
+
+
+ default:
+ PEI_TRACE((-1,PeiServices,"Boot Script Table Invalid. Type = %x\n", Type));
+ return EFI_UNSUPPORTED;
+ }
+ }
+}
+
+
+EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI gBootScriptExecuterPpi =
+{
+ ExecuteScript
+};
+
+
+EFI_PEI_PPI_DESCRIPTOR gPpiList =
+{
+ (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gBootScriptExecuterGuid,
+ &gBootScriptExecuterPpi
+};
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+//
+// Procedure: InitBootScriptExecuter
+//
+// Description: Increase the Pci register number by a value.
+//
+// Input:
+// IN EFI_FFS_FILE_HEADER *FfsHeader
+// IN EFI_PEI_SERVICES **PeiServices
+//
+// Output:
+// EFI_STATUS
+//
+// Modified:
+//
+// Referrals: InstallPpi
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Install Boot Script Executer Ppi.
+// 2. Return status of InstallPpi.
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitBootScriptExecuter(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ return (**PeiServices).InstallPpi(
+ PeiServices,
+ &gPpiList
+ );
+
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/BootScriptPrivate.h b/Core/EM/S3/BootScriptPrivate.h
new file mode 100644
index 0000000..b3c8c63
--- /dev/null
+++ b/Core/EM/S3/BootScriptPrivate.h
@@ -0,0 +1,732 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptPrivate.h 2 9/17/13 10:02p Thomaschen $
+//
+// $Revision: 2 $
+//
+// $Date: 9/17/13 10:02p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptPrivate.h $
+//
+// 2 9/17/13 10:02p Thomaschen
+// update for ACPI module labeled 47
+//
+// 3 7/01/11 10:03a Oleksiyy
+// [TAG] EIP62200
+// [Category] Improvement
+// [Description] Added #pragma statements to declaration of
+// BOOT_SCRIPT_SMBUS_EXECUTE_32 and BOOT_SCRIPT_SMBUS_EXECUTE structures.
+// [Files] BootScriptPrivate.c
+//
+// 2 5/13/11 3:18p Oleksiyy
+// [TAG] EIP56650
+// [Category] New Feature
+// [Description] S3 Save State Protocol and S3 Smm Save State Protocol
+// functions added. Support for opcodes introduced in PI 1.2 added.
+// [Files] BootScriptCommon.h, BootScriptExecuter.c,
+// BootScriptPrivate.h, BootScriptSave.c and BootScriptSave.h
+//
+// 1 2/03/11 4:08p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Save.cif
+// S3Save.sdl
+// S3Save.mak
+// AcpiS3.h
+// AcpiS3Save.c
+// BootScriptPrivate.h
+// BootScriptSave.c
+// AcpiS3Save.dxs
+// SmmS3Save.dxs
+//
+// 5 11/05/09 4:00p Oleksiyy
+// EIP 27821 Support for 64 bit operations in Bootscript added.
+// To use this functions AmiLib.h, CpuIo.c, IA32CLib.c, PciCfg.c,
+// x64AsmLib.asm files should be updated also.
+//
+// 4 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 3 12/01/08 6:17p Yakovlevs
+// Fixed isue with UINTN SMBUS_ADDRESS in PEI UINTN=32bit; in DXE UINTN
+// for x64 = 64bit.
+//
+// 2 4/15/08 9:16p Yakovlevs
+// Functions Headers added
+//
+// 1 4/23/07 1:31p Felixp
+//
+// 4 12/26/06 2:56p Markw
+// Add BootScript Polling.
+//
+// 3 9/22/06 6:09p Markw
+// 64-bit fix.
+//
+// 2 6/23/05 5:38p Markw
+// Remove include from boot script save protocol.
+//
+// 1 1/21/05 12:01p Felixp
+//
+// 2 1/18/05 3:22p Felixp
+// PrintDebugMessage renamed to Trace
+//
+// 1 12/22/04 6:19p Admin
+//
+// 1 12/22/04 6:18p Admin
+//
+// 3 3/25/04 11:23a Markw
+// Remove lib include.
+//
+// 2 3/23/04 4:57p Felixp
+//
+// 1 3/04/04 3:52p Markw
+//
+//**********************************************************************
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: BootScriptPrivate.h
+//
+// Description: Boot script auxiliary data structures definitions
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#ifndef __BOOT_SCRIPT_PRIVATE__H__
+#define __BOOT_SCRIPT_PRIVATE__H__
+
+#include <efi.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TABLE_TYPE1(OpCode) (OpCode)
+#define TABLE_TYPE2(OpCode, Width) ((OpCode) + ((Width) << 8))
+
+#define TABLE_END_OP_CODE 0xff
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_WRITE_IO
+//
+// Description: Boot script Write IO Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Port UINT16
+// Count UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT16 Port;
+ UINT64 Count;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_WRITE_IO;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_READ_WRITE_IO
+//
+// Description: Boot script Read-Write IO Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Port UINT16
+// Value UINT32
+// Mask UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT16 Port;
+ UINT64 Value;
+ UINT64 Mask;
+} BOOT_SCRIPT_READ_WRITE_IO;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_POLL_IO
+//
+// Description: Boot script Poll IO Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Port UINT16
+// Mask UINT32
+// Result UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT16 Port;
+ UINT64 Mask;
+ UINT64 Result;
+} BOOT_SCRIPT_POLL_IO;
+
+
+//////////////////////////////////////////////////////////////////////////
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_WRITE_MEM
+//
+// Description: Boot script Write memory Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Value UINT8
+// Count UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+// UINT8 Value;
+ UINT64 Count;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_WRITE_MEM;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_READ_WRITE_MEM
+//
+// Description: Boot script Read-Write memory Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Value UINT64
+// Mask UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Value;
+ UINT64 Mask;
+} BOOT_SCRIPT_READ_WRITE_MEM;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_POLL_MEM
+//
+// Description: Boot script Poll memory Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Mask UINT64
+// Result UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Mask;
+ UINT64 Result;
+} BOOT_SCRIPT_POLL_MEM;
+
+//////////////////////////////////////////////////////////////////////////
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_WRITE_PCI
+//
+// Description: Boot script Write PCI Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Count UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Count;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_WRITE_PCI;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_READ_WRITE_PCI
+//
+// Description: Boot script Read-Write PCI Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Value UINT64
+// Mask UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Value;
+ UINT64 Mask;
+} BOOT_SCRIPT_READ_WRITE_PCI;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_POLL_PCI
+//
+// Description: Boot script Poll PCI Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Mask UINT64
+// Result UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Mask;
+ UINT64 Result;
+} BOOT_SCRIPT_POLL_PCI;
+
+#pragma pack(push,1)
+//////////////////////////////////////////////////////////////////////////
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_SMBUS_EXECUTE
+//
+// Description: Boot script SMBUS command Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// SlaveAddress EFI_SMBUS_DEVICE_ADDRESS
+// Command EFI_SMBUS_DEVICE_COMMAND
+// Operation EFI_SMBUS_OPERATION
+// PecCheck BOOLEAN
+// Length UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ EFI_SMBUS_DEVICE_ADDRESS SlaveAddress;
+ EFI_SMBUS_DEVICE_COMMAND Command;
+ EFI_SMBUS_OPERATION Operation;
+ BOOLEAN PecCheck;
+ UINT64 Length;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_SMBUS_EXECUTE;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_SMBUS_EXECUTE_32
+//
+// Description: Boot script SMBUS command Data (32 Bit)
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// SlaveAddress UINT32
+// Command UINT32
+// Operation EFI_SMBUS_OPERATION
+// PecCheck BOOLEAN
+// Length UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT32 SlaveAddress;
+ UINT32 Command;
+ EFI_SMBUS_OPERATION Operation;
+ BOOLEAN PecCheck;
+ UINT64 Length;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_SMBUS_EXECUTE_32;
+#pragma pack(pop)
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_STALL
+//
+// Description: Boot script stall Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Duration UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Duration;
+} BOOT_SCRIPT_STALL;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_DISPATCH
+//
+// Description: Boot script dispatch Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// EntryPoint EFI_PHYSICAL_ADDRESS
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ EFI_PHYSICAL_ADDRESS EntryPoint;
+} BOOT_SCRIPT_DISPATCH;
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_INFORMATION
+//
+// Description: Boot script information Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Size UINT32
+// MessagePtr EFI_PHYSICAL_ADDRESS
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ UINT16 Type;
+ UINT32 Size;
+ EFI_PHYSICAL_ADDRESS MessagePtr;
+} BOOT_SCRIPT_INFORMATION;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_DISPATCH2
+//
+// Description: Boot script Dispatch2 Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// EntryPoint EFI_PHYSICAL_ADDRESS
+// Context EFI_PHYSICAL_ADDRESS
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ UINT16 Type;
+ EFI_PHYSICAL_ADDRESS EntryPoint;
+ EFI_PHYSICAL_ADDRESS Context;
+} BOOT_SCRIPT_DISPATCH2;
+
+//////////////////////////////////////////////////////////////////////////
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_PCI_CFG2_WRITE
+//
+// Description: Boot script Write PCI Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Count UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Count;
+ UINT16 Segment;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_PCI_CFG2_WRITE;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_PCI_CFG2_READ_WRITE
+//
+// Description: Boot script Read-Write PCI Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Value UINT64
+// Mask UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Value;
+ UINT64 Mask;
+ UINT16 Segment;
+} BOOT_SCRIPT_PCI_CFG2_READ_WRITE;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_IO_POLL
+//
+// Description: Boot script Poll IO Data (PI 1.1)
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Port UINT16
+// Mask UINT32
+// Result UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT16 Port;
+ UINT64 Mask;
+ UINT64 Result;
+ UINT64 Delay;
+} BOOT_SCRIPT_IO_POLL;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_MEM_POLL
+//
+// Description: Boot script Poll memory Data (PI 1.1)
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Mask UINT64
+// Result UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Mask;
+ UINT64 Result;
+ UINT64 Delay;
+ UINT64 LoopTimes;
+} BOOT_SCRIPT_MEM_POLL;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_PCI_CFG_POLL
+//
+// Description: Boot script Poll PCI Data (PI 1.1)
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Mask UINT64
+// Result UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Mask;
+ UINT64 Result;
+ UINT64 Delay;
+} BOOT_SCRIPT_PCI_CFG_POLL;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_PCI_CFG2_POLL
+//
+// Description: Boot script Poll PCI Data (PI 1.1)
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Address UINT64
+// Mask UINT64
+// Result UINT64
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+ UINT64 Address;
+ UINT64 Mask;
+ UINT64 Result;
+ UINT64 Delay;
+ UINT16 Segment;
+} BOOT_SCRIPT_PCI_CFG2_POLL;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_LABEL
+//
+// Description: Boot script information Data
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+// Size UINT32
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+typedef struct {
+ UINT16 Type;
+ UINT32 Size;
+ //UINT8 Buffer[];
+} BOOT_SCRIPT_LABEL;
+
+typedef struct {
+ UINT32 UniqueIndex;
+ UINT32 Length;
+} BOOT_SCRIPT_INFO_STRUCTURE;
+#endif
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_TABLE_END
+//
+// Description: Boot script end table marker
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// Type UINT16
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef struct {
+ UINT16 Type;
+} BOOT_SCRIPT_TABLE_END;
+
+//<AMI_THDR_START>
+//----------------------------------------------------------------------------
+// Name: BOOT_SCRIPT_DATA
+//
+// Description: Boot script data union
+//
+// Fields: Name Type Description
+//----------------------------------------------------------------------------
+// WrIo BOOT_SCRIPT_WRITE_IO
+// RwIo BOOT_SCRIPT_READ_WRITE_IO
+// PollIo BOOT_SCRIPT_POLL_IO
+// WrMem BOOT_SCRIPT_WRITE_MEM
+// RwMem BOOT_SCRIPT_READ_WRITE_MEM
+// PollMem BOOT_SCRIPT_POLL_MEM
+// WrPci BOOT_SCRIPT_WRITE_PCI
+// RwPci BOOT_SCRIPT_READ_WRITE_PCI
+// PollPci BOOT_SCRIPT_POLL_PCI
+// ExecSmbus BOOT_SCRIPT_SMBUS_EXECUTE
+// Stall BOOT_SCRIPT_STALL
+// Dispatch BOOT_SCRIPT_DISPATCH
+// End BOOT_SCRIPT_TABLE_END
+//
+//----------------------------------------------------------------------------
+//<AMI_THDR_END>
+
+typedef union {
+ BOOT_SCRIPT_WRITE_IO WrIo;
+ BOOT_SCRIPT_READ_WRITE_IO RwIo;
+ BOOT_SCRIPT_POLL_IO PollIo;
+ BOOT_SCRIPT_WRITE_MEM WrMem;
+ BOOT_SCRIPT_READ_WRITE_MEM RwMem;
+ BOOT_SCRIPT_POLL_MEM PollMem;
+ BOOT_SCRIPT_WRITE_PCI WrPci;
+ BOOT_SCRIPT_READ_WRITE_PCI RwPci;
+ BOOT_SCRIPT_POLL_PCI PollPci;
+ BOOT_SCRIPT_SMBUS_EXECUTE ExecSmbus;
+ BOOT_SCRIPT_STALL Stall;
+ BOOT_SCRIPT_DISPATCH Dispatch;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ BOOT_SCRIPT_INFORMATION Info;
+ BOOT_SCRIPT_DISPATCH2 Dispatch2;
+ BOOT_SCRIPT_PCI_CFG2_WRITE WrPci2;
+ BOOT_SCRIPT_PCI_CFG2_READ_WRITE RwPci2;
+ BOOT_SCRIPT_IO_POLL IoPoll;
+ BOOT_SCRIPT_MEM_POLL MemPoll;
+ BOOT_SCRIPT_PCI_CFG_POLL PciPoll;
+ BOOT_SCRIPT_PCI_CFG2_POLL PciPoll2;
+#endif
+ BOOT_SCRIPT_TABLE_END End;
+} BOOT_SCRIPT_DATA;
+
+VOID CallbackReadyToBoot(
+ IN EFI_EVENT Event,
+ IN VOID *Context
+);
+
+/****** DO NOT WRITE BELOW THIS LINE *******/
+#ifdef __cplusplus
+}
+#endif
+#endif
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/BootScriptSave.c b/Core/EM/S3/BootScriptSave.c
new file mode 100644
index 0000000..46e2bc4
--- /dev/null
+++ b/Core/EM/S3/BootScriptSave.c
@@ -0,0 +1,2540 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptSave.c 5 7/15/14 9:51p Chienhsieh $
+//
+// $Revision: 5 $
+//
+// $Date: 7/15/14 9:51p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/BootScriptSave.c $
+//
+// 5 7/15/14 9:51p Chienhsieh
+// update for ACPI module labeled 49
+//
+// 12 4/14/14 3:10p Oleksiyy
+// [TAG] EIP161916
+// [Category] Improvement
+// [Description] 32 bit typecasting issue fixed.
+// [Files] BootScriptSave.c
+//
+// 4 9/17/13 10:03p Thomaschen
+// update for ACPI module labeled 47
+//
+// 11 8/14/13 12:35p Oleksiyy
+// [TAG] EIP95347
+// [Category] Improvement
+// [Description] Synchronized usage of Allocate/Free memory operations
+// on pool/page basis.
+//
+// [Files] BootScriptSave.c
+//
+// 10 7/05/13 2:32p Oleksiyy
+// [TAG] EIP128054
+// [Category] Improvement
+// [Description] USB ports are disabled after resume from S3 with
+// special steps
+// [Files] BootScriptSave.c
+//
+// 9 12/27/12 4:00p Oleksiyy
+// [TAG] EIP109790
+// [Category] Improvement
+// [Description] Code check result - Possible Null pointer acces.
+// [Files] BootScriptSave.c
+//
+// 8 12/13/12 12:03p Oleksiyy
+// [TAG] EIP109290
+// [Category] Improvement
+// [Description] Issues found by CppCheck in ACPI eModule
+// [Files] AcpiCore.c, mptable.c, AmlString.c, BootScriptSave.c and
+// BootScriptExecuter.c
+//
+// 7 10/31/12 3:49p Oleksiyy
+// [TAG] EIP104782
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] Bug in BootScriptSave.c AllocTableEntry() function
+// [RootCause] Pointer to ACPI_VARIABLE_SET was not initialized.
+// [Solution] Initialize pointer.
+// [Files] BootScriptSave.c
+//
+// 6 12/16/11 4:27p Oleksiyy
+// [TAG] EIP78247
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] BootScriptTable problem
+// [RootCause] TablePointer was updated uncorectly during CloseTable
+// call and any opcodes added after closing was ignored.
+// [Solution] Pointer updated correctly now.
+// [Files] BootScriptSave.c
+//
+// 5 9/29/11 5:05p Oleksiyy
+// [TAG] EIP71372
+// [Category] Improvement
+// [Description] EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE added.
+// [Files] BootScriptExecuter.c and BootScriptSave.c
+//
+// 4 6/16/11 9:57a Felixp
+// Bug fix: EFI_BOOT_SCRIPT_PCI_POLL_OPCODE is replaced with
+// EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE
+//
+// 3 5/13/11 4:59p Oleksiyy
+// [TAG] EIP56650
+// [Category] Improvement
+// [Description] Compatibility with older core fixed.
+// [Files] BootScriptSave.c
+//
+// 2 5/13/11 3:20p Oleksiyy
+// [TAG] EIP56650
+// [Category] New Feature
+// [Description] S3 Save State Protocol and S3 Smm Save State Protocol
+// functions added. Support for opcodes introduced in PI 1.2 added.
+//
+// [Files] BootScriptCommon.h, BootScriptExecuter.c,
+// BootScriptPrivate.h, BootScriptSave.c and BootScriptSave.h
+//
+// 1 2/03/11 4:08p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Save.cif
+// S3Save.sdl
+// S3Save.mak
+// AcpiS3.h
+// AcpiS3Save.c
+// BootScriptPrivate.h
+// BootScriptSave.c
+// AcpiS3Save.dxs
+// SmmS3Save.dxs
+//
+// 8 1/20/11 12:33p Oleksiyy
+// [TAG] EIP48697
+// [Category] Improvement
+// [Description] Functionality modified and after Close table is called
+// - boot script still added to the end of the table.
+// [Files] BootScriptSave.c
+//
+// 7 11/05/09 4:02p Oleksiyy
+// EIP 27821 Support for 64 bit operations in Bootscript added. To use
+// this functions AmiLib.h, CpuIo.c, IA32CLib.c, PciCfg.c, x64AsmLib.asm
+// files should be updated also.
+//
+// 6 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 5 3/26/09 10:10a Oleksiyy
+// EIP 20471 : MAX_TABLE_ENTRIES value increased to 2048.
+//
+// 4 12/01/08 6:52p Yakovlevs
+// Fixed BootScript code to support IA32 and x64 CPU Architecture EIP #
+// 17317
+//
+// 3 4/15/08 9:21p Yakovlevs
+// Functions Headers added
+//
+// 2 6/05/07 12:19a Felixp
+// Added SmmBus support
+//
+// 1 4/23/07 1:31p Felixp
+//
+// 14 3/21/07 10:53a Markw
+// Previous revision over wrote Felix's changes. I put them back.
+//
+// 13 3/19/07 4:13p Markw
+// Update so that PCI functions saving registers 0xfc - 0xff doesn't fail.
+//
+// 12 2/12/07 11:21a Felixp
+// Revision field removed from EFI_BOOT_SCRIPT_SAVE_PROTOCOL structure
+// to match BootScript spec (it was earlier their for Tiano compliance.
+// Tiano header is fixed now).
+//
+// 11 12/26/06 2:57p Markw
+// Add BootScript Polling.
+//
+// 10 9/29/06 6:02p Markw
+// Fix 64-bit bugs.
+//
+// 9 9/22/06 6:09p Markw
+// 64-bit fix.
+//
+// 8 8/24/06 10:11a Felixp
+// x64 support: warning/error fixes
+//
+// 7 3/13/06 5:30p Felixp
+//
+// 6 11/07/05 3:44p Sivagarn
+// Included SMBus.H to resolve SMBus related definition errors
+//
+// 5 6/23/05 5:38p Markw
+// Added include to boot script save protocol. Previously was in
+// bootscriptprivate.h.
+//
+// 4 5/13/05 3:19p Markw
+// UINT32 -> UINT64 sometimes causes sign extend. Clear bits[64:32] for
+// address.
+//
+// 3 3/23/05 2:53p Markw
+// Bug fixes: Pointers, TableLength
+//
+// 2 3/14/05 4:25p Markw
+// Change final memory allocation to Runtime Service Data to ACPI NVS.
+//
+//**********************************************************************
+
+
+//<AMI_FHDR_START>
+//---------------------------------------------------------------------------
+//
+// Name: BootScriptSave.c
+//
+// Description: Save Mem/Io/Pci/Smbus/etc into a table. The script will
+// be executed on a S3 resume.
+//
+//---------------------------------------------------------------------------
+//<AMI_FHDR_END>
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+#include <Protocol\S3SaveState.h>
+#include <Protocol\S3SmmSaveState.h>
+#include <Protocol\SmmBase2.h>
+#endif
+#include <Protocol\BootScriptSave.h>
+#include <Protocol\smbus.h>
+#include "BootScriptPrivate.h"
+#include <AmiDxeLib.h>
+#include "AcpiS3.h"
+//---For Compatibility Reasons---------------------------------------------------
+#ifndef EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM
+#define EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM EFI_BOOT_SCRIPT_IO_POLL_OPCODE
+#define EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM EFI_BOOT_SCRIPT_MEM_POLL_OPCODE
+#define EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE
+#endif
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+// Currently reentrant code could fail if reentered when new table
+// is being created.
+// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+EFI_SMM_SYSTEM_TABLE2 *gSmst2 = NULL;
+EFI_SMM_BASE2_PROTOCOL *mInternalSmmBase2 = NULL;
+EFI_HANDLE mSmmS3SaveHandle = NULL;
+#endif
+
+EFI_EVENT gEvtReadyToBoot;
+
+typedef EFI_STATUS (*GENERIC_OPCODE_FUNC) (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list List
+);
+
+
+#define INIT_TABLE_SIZE 1024
+#define MAX_TABLE_ENTRIES 2048
+#define TBL_VAR_NAME L"S3SS"
+
+
+
+static EFI_GUID gEfiBootScriptSaveGuid = EFI_BOOT_SCRIPT_SAVE_GUID;
+static EFI_GUID gTableDataVarGuid = { 0x4bafc2b4, 0x2dc, 0x4104, 0xb2, 0x36, 0xd6, 0xf1, 0xb9, 0x8d, 0x9e, 0x84};
+
+
+typedef struct {
+ VOID *TableBottom;
+ VOID *TablePtr;
+ UINTN TableSize;
+ UINTN NumTableEntries;
+ BOOLEAN WasClosed;
+} TABLE_INFO;
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+
+typedef struct {
+ BOOLEAN IsItInsert;
+ BOOLEAN BeforeOrAfter;
+ UINTN Position;
+} BOOT_SCRIPT_INSERT_INFO;
+
+BOOT_SCRIPT_INSERT_INFO gInsertInfo = {FALSE, FALSE, 0};
+#define LABEL_MAX_SIZE 0x200
+#endif
+
+TABLE_INFO *gTableInfo = NULL;
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: NewTable
+//
+// Description: Initialize first table.
+//
+// Input:
+// IN UINT16 Table
+//
+// Output:
+// BOOLEAN - TRUE if new table created.
+//
+// Notes:
+// Return True if successful table creation, otherwise return false.
+// Need valid table info even if table fails, because functions may
+// attempt to write to the boot script without a table being created.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+BOOLEAN NewTable()
+{
+ EFI_STATUS Status;
+//--------------------------------
+
+ Status = pBS->AllocatePool(EfiBootServicesData, INIT_TABLE_SIZE*2, &(gTableInfo->TableBottom));
+ if (EFI_ERROR(Status))
+ {
+ gTableInfo->TableBottom = 0;
+ return FALSE;
+ }
+ gTableInfo->TablePtr = gTableInfo->TableBottom;
+ gTableInfo->TableSize = INIT_TABLE_SIZE*2;
+ gTableInfo->NumTableEntries = 0;
+ gTableInfo->WasClosed = FALSE;
+ return TRUE;
+
+}
+
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InitBootScriptStructure
+//
+// Description: Updates Table pointer Before each Write operation.
+//
+// Input:
+// IN UINT16 Table
+//
+// Output:
+// EFI_SATUS - Status of the operation.
+//
+// Notes:
+// Return True if successful table creation, otherwise return false.
+// Need valid table info even if table fails, because functions may
+// attempt to write to the boot script without a table being created.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitBootScriptStructure(BOOLEAN IsItSmm)
+{
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ UINTN sz=sizeof(VOID*);
+#endif
+ EFI_STATUS Status = EFI_SUCCESS;
+
+//--------------------------------
+ if(gTableInfo == NULL)
+ {
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ Status = pRS->GetVariable(L"S3SS", &gTableDataVarGuid, NULL, &sz, &gTableInfo);
+ if(EFI_ERROR(Status) && Status!=EFI_NOT_FOUND && IsItSmm) return EFI_OUT_OF_RESOURCES;
+ if(Status==EFI_NOT_FOUND)
+#endif
+ {
+ EFI_PHYSICAL_ADDRESS MaxAddress = 0xFFFFFFFF;
+ Status = pBS->AllocatePages(AllocateMaxAddress, EfiReservedMemoryType, EFI_SIZE_TO_PAGES(sizeof(TABLE_INFO)),
+ &MaxAddress);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status)) return EFI_OUT_OF_RESOURCES;
+ gTableInfo = (VOID*)(UINTN)MaxAddress;
+ if (!NewTable()) return EFI_OUT_OF_RESOURCES;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ Status = pRS->SetVariable(L"S3SS",&gTableDataVarGuid,
+ (EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS),
+ sz, &gTableInfo);
+ ASSERT_EFI_ERROR(Status);
+ if(EFI_ERROR(Status) && IsItSmm) return EFI_OUT_OF_RESOURCES;
+#endif
+ }
+
+
+ }
+ return Status;
+}
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: InsertPositionInBootScript
+//
+// Description: Found position and, based on Size, allocate space for Entry,
+// that has to be incerted, in table based on parameters in
+// gInsertInfo structure.
+//
+// Input:
+// IN UINTN Size - Size of entry to allocate in table.
+//
+// Output:
+// VOID * - Pointer to allocated entry in table.
+//
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+VOID* InsertPositionInBootScript (UINTN Size)
+{
+ TABLE_INFO *Info = gTableInfo;
+ UINT8 *CopyFrom = Info->TableBottom, *CopyTo;
+ UINTN i = 0, CopySize = (UINT8*)Info->TablePtr - (UINT8*)Info->TableBottom;
+ BOOLEAN Found = FALSE;
+
+ if (gInsertInfo.Position != -1)
+ {
+ for (i=0; i<Info->NumTableEntries; i++)
+ { //Found position with supplied
+ if (((BOOT_SCRIPT_INFO_STRUCTURE*) CopyFrom)->UniqueIndex == gInsertInfo.Position)
+ {
+ Found = TRUE;
+ if (gInsertInfo.BeforeOrAfter == FALSE)
+ CopyFrom += ((BOOT_SCRIPT_INFO_STRUCTURE*) CopyFrom)->Length;
+ break;
+ }
+ CopyFrom += ((BOOT_SCRIPT_INFO_STRUCTURE*) CopyFrom)->Length;
+ }
+ if (!Found) return NULL;
+ }
+ if ((Size != 0) && (i != Info->NumTableEntries))
+ {
+ CopyTo = CopyFrom + Size;
+ CopySize = (UINT8*)Info->TablePtr - CopyFrom;
+ MemCpy(CopyTo, CopyFrom, CopySize);
+ }
+ return CopyFrom;
+
+}
+#endif
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+// Procedure: AllocTableEntry
+//
+// Description: Allocate Entry from table. If not enough space, create
+// larger table and return entry.
+//
+// Input:
+// IN UINTN Size - Size of entry to allocate in table.
+//
+// Output:
+// VOID * - Pointer to allocated entry in table.
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Does the BootScript table exist. If no return 0.
+// 2. Does table contain max entries? If so assert.
+// 3. Enough space in the table for the boot script call? If yes, go to step 8.
+// ---Create table---
+// 4. Get Size of table needed for entry. (A multiple of INIT_TABLE_SIZE.)
+// 5. Allocate new table.
+// 6. Copy old table
+// 7. Free old table.
+// 8. Update gTableInfo data.
+// ------------------
+// 9. Adjust allocation pointer to allocate new space.
+// 10. Return newly allocated space.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+VOID * AllocTableEntry(IN UINTN Size)
+{
+ TABLE_INFO *Info = gTableInfo;
+ VOID *TempBottom;
+ VOID *TempPtr;
+ UINTN TempSize, NewSize;
+ BOOT_SCRIPT_TABLE_END TableEnd;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ //BOOT_SCRIPT_INFO_STRUCTURE BsHeader;
+ Size += sizeof(BOOT_SCRIPT_INFO_STRUCTURE);
+#endif
+ if (Info->TableBottom == NULL) return NULL;
+
+ //Should not fill table. If table becomes full, then an error is causing too many table entries.
+ ASSERT(Info->NumTableEntries < MAX_TABLE_ENTRIES);
+
+ if ((UINTN)Info->TableBottom + Info->TableSize < (UINTN) Info->TablePtr + Size
+ + sizeof(BOOT_SCRIPT_TABLE_END)
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ + sizeof(BOOT_SCRIPT_INFO_STRUCTURE)
+#endif
+ )
+ {
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (gSmst2 != NULL) return NULL; // we can't allocate memory in SMM
+#endif
+ TempSize = Info->TableSize + INIT_TABLE_SIZE * (Size / INIT_TABLE_SIZE + 1);
+
+ if (Info->WasClosed == FALSE) // Use AllocatePool if table was not closed - later it will be copyed under 4 Gb.
+ {
+ if (pBS->AllocatePool(EfiBootServicesData, TempSize, &TempBottom) != EFI_SUCCESS)
+ return NULL;
+
+ NewSize = TempSize;
+ }
+ else // Use AllocatePages if table was closed. We need it under 4 Gb.
+ {
+ EFI_PHYSICAL_ADDRESS MaxAddress = 0xFFFFFFFF;
+
+ if (pBS->AllocatePages(AllocateMaxAddress, EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES(TempSize) + 1, &MaxAddress) != EFI_SUCCESS)
+ return NULL;
+ TempBottom = (VOID*)(UINTN)MaxAddress;
+ NewSize = EFI_PAGES_TO_SIZE(EFI_SIZE_TO_PAGES(TempSize) + 1); // Calculate the sieze of new structure from pages
+ TempSize = EFI_SIZE_TO_PAGES(Info->TableSize); // Save old size in pages to use in FreePages.
+ }
+
+ MemCpy(TempBottom, Info->TableBottom, Info->TableSize);
+
+ Info->TablePtr = (UINT8*)TempBottom + (UINTN)Info->TablePtr - (UINTN)Info->TableBottom;
+ TempPtr = Info->TableBottom; // Save old TableBottom to freememory
+ Info->TableBottom = TempBottom;
+ Info->TableSize = NewSize;
+ if (Info->WasClosed == TRUE)
+ {
+ EFI_STATUS Status;
+ ACPI_VARIABLE_SET *AcpiVariableSet = NULL;
+ CHAR16 AcpiGlobalVariable[] = ACPI_GLOBAL_VARIABLE;
+ EFI_GUID EfiAcpiVariableGuid = EFI_ACPI_VARIABLE_GUID;
+ UINTN VariableSize = sizeof(ACPI_VARIABLE_SET*);
+ Status = pRS->GetVariable(
+ AcpiGlobalVariable,
+ &EfiAcpiVariableGuid,
+ NULL,
+ &VariableSize,
+ &AcpiVariableSet
+ );
+ ASSERT_EFI_ERROR(Status);
+ AcpiVariableSet->AcpiBootScriptTable = (EFI_PHYSICAL_ADDRESS) (UINTN) TempBottom;
+ pBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) TempPtr, TempSize); // If WasClosed == TRUE use FreePages
+ }
+ else pBS->FreePool(TempPtr); // If WasClosed != TRUE use FreePool
+
+ }
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (gInsertInfo.IsItInsert == TRUE)
+ {
+ TempPtr = InsertPositionInBootScript (Size);
+ if (TempPtr == NULL) return TempPtr;
+ }
+ else
+#endif
+ TempPtr = (UINT8*)Info->TablePtr;
+ Info->TablePtr = (UINT8*)Info->TablePtr + Size;
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ ((BOOT_SCRIPT_INFO_STRUCTURE*)TempPtr)->UniqueIndex = (UINT32) Info->NumTableEntries;
+ ((BOOT_SCRIPT_INFO_STRUCTURE*)TempPtr)->Length = (UINT32) Size;
+ TempPtr = (UINT8*) TempPtr + sizeof(BOOT_SCRIPT_INFO_STRUCTURE);
+#endif
+ TableEnd.Type = TABLE_END_OP_CODE;
+ MemCpy((VOID*)((UINTN)Info->TablePtr
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ + sizeof(BOOT_SCRIPT_INFO_STRUCTURE)
+#endif
+ ), &TableEnd, sizeof(BOOT_SCRIPT_TABLE_END));
+ ++(Info->NumTableEntries);
+ return TempPtr;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptIoWrite
+//
+// Description: Write to boot script table an IoWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Add data to end of fixed table.
+// 6. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptIoWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ IN va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+
+ UINT64 Address = va_arg(arglist, UINT64);
+ UINTN Count = va_arg(arglist, UINTN);
+ VOID *Buffer = va_arg(arglist, VOID*);
+
+ BOOT_SCRIPT_WRITE_IO WriteIo;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINTN AddressCount;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1);
+
+ //---Validate Inputs---
+ if (!Count) return EFI_INVALID_PARAMETER;
+ if (Address + AddressCount > 0xffff) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_WRITE_IO) + AddressCount);
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ WriteIo.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_WRITE_OPCODE,Width);
+ WriteIo.Port = (UINT16) Address;
+ WriteIo.Count = Count;
+
+ MemCpy(Ptr, &WriteIo, sizeof(BOOT_SCRIPT_WRITE_IO)); //Use MemCpy to avoid alignment problems.
+ Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_WRITE_IO);
+
+ MemCpy(Ptr, Buffer, AddressCount);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptIoReadWrite
+//
+// Description: Write to boot script table a IoReadWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptIoReadWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataValue = va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_READ_WRITE_IO ReadWriteIo;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Data, Mask;
+
+ Mask = *(UINT64*)DataMask;
+ Data = *(UINT64*)DataValue;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+ if (Address + ValueSize > 0xffff) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_READ_WRITE_IO));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ ReadWriteIo.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_READ_WRITE_OPCODE, Width);
+ ReadWriteIo.Port = (UINT16) Address;
+ ReadWriteIo.Value = Data & BitMask;
+ ReadWriteIo.Mask = Mask & BitMask;
+
+ MemCpy(Ptr, &ReadWriteIo, sizeof(ReadWriteIo)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptMemWrite
+//
+// Description: Write to boot script table an MemWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Add data to end of fixed table.
+// 6. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptMemWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+
+ UINT64 Address = va_arg(arglist, UINT64);
+ UINTN Count = va_arg(arglist, UINTN);
+ VOID *Buffer = va_arg(arglist, VOID*);
+
+ BOOT_SCRIPT_WRITE_MEM WriteMem;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINTN AddressCount;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1);
+
+ //---Validate Inputs---
+ if (!Count) return EFI_INVALID_PARAMETER;
+
+#if defined(EFI64) || defined(EFIx64)
+ if (Address + AddressCount < Address) return EFI_INVALID_PARAMETER; //Overflow
+#else
+ Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends.
+ if (Address + AddressCount > 0xffffffff) return EFI_INVALID_PARAMETER;
+
+#endif
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_WRITE_MEM) + AddressCount);
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ WriteMem.Type = (UINT16)TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_WRITE_OPCODE,Width);
+ WriteMem.Address = (UINT64)Address;
+ WriteMem.Count = Count;
+
+ MemCpy(Ptr, &WriteMem, sizeof(BOOT_SCRIPT_WRITE_MEM)); //Use MemCpy to avoid alignment problems.
+ Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_WRITE_MEM);
+
+ MemCpy(Ptr, Buffer, AddressCount);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptMemReadWrite
+//
+// Description: Write to boot script table an MemReadWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptMemReadWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataValue = va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_READ_WRITE_MEM ReadWriteMem;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Mask, Data;
+
+ Mask = *(UINT64*)DataMask;
+ Data = *(UINT64*)DataValue;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+#if defined(EFI64) || defined(EFIx64)
+ if (Address + ValueSize < Address) return EFI_INVALID_PARAMETER; //Overflow
+#else
+ Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends.
+ if (Address + ValueSize > 0xffffffff) return EFI_INVALID_PARAMETER;
+
+#endif
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_READ_WRITE_MEM));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ ReadWriteMem.Type = (UINT16)TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_READ_WRITE_OPCODE, Width);
+ ReadWriteMem.Address = (UINT64)Address;
+ ReadWriteMem.Value = Data & BitMask;
+ ReadWriteMem.Mask = Mask & BitMask;
+
+ MemCpy(Ptr, &ReadWriteMem, sizeof(BOOT_SCRIPT_READ_WRITE_MEM)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptPciWrite
+//
+// Description: Write to boot script table an PciWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Add data to end of fixed table.
+// 6. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptPciWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+
+ UINT64 Address = va_arg(arglist, UINT64);
+ UINTN Count = va_arg(arglist, UINTN);
+ VOID *Buffer = va_arg(arglist, VOID*);
+
+ BOOT_SCRIPT_WRITE_PCI WritePci;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINTN AddressCount;
+ UINT16 Register;
+ UINT16 RegisterMax;
+ if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1);
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (!Count) return EFI_INVALID_PARAMETER;
+
+ if (Register + AddressCount > RegisterMax) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_WRITE_PCI) + AddressCount);
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ WritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG_WRITE_OPCODE,Width);
+ WritePci.Address = Address;
+ WritePci.Count = Count;
+
+ MemCpy(Ptr, &WritePci, sizeof(BOOT_SCRIPT_WRITE_PCI)); //Use MemCpy to avoid alignment problems.
+ Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_WRITE_PCI);
+
+ MemCpy(Ptr, Buffer, AddressCount);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptPciReadWrite
+//
+// Description: Write to boot script table an PciReadWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptPciReadWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *Data = va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_READ_WRITE_PCI ReadWritePci;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT16 Register;
+ UINT16 RegisterMax;
+ if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_READ_WRITE_PCI));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ ReadWritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG_READ_WRITE_OPCODE, Width);
+ ReadWritePci.Address = Address;
+ ReadWritePci.Value = *(UINT64*) Data & BitMask;
+ ReadWritePci.Mask = *(UINT64*) DataMask & BitMask;
+
+ MemCpy(Ptr, &ReadWritePci, sizeof(BOOT_SCRIPT_READ_WRITE_PCI)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptSmbusExecute
+//
+// Description: Write to boot script table an SmbusExecute.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptSmbusExecute (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ VOID *Ptr;
+ VOID *Buffer;
+
+ BOOT_SCRIPT_SMBUS_EXECUTE_32 Smbus;
+
+ Smbus.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_SMBUS_EXECUTE_OPCODE);
+ Smbus.SlaveAddress = (UINT32)va_arg(arglist, UINTN);
+ Smbus.Command = (UINT32)va_arg(arglist, UINTN);
+ Smbus.Operation = va_arg(arglist, EFI_SMBUS_OPERATION);
+ Smbus.PecCheck = va_arg(arglist, BOOLEAN);
+ Smbus.Length = *(va_arg(arglist, UINTN*));
+
+ Buffer = va_arg(arglist, VOID*);
+
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_SMBUS_EXECUTE_32) + (UINT32)Smbus.Length);
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ MemCpy(Ptr, &Smbus, sizeof(BOOT_SCRIPT_SMBUS_EXECUTE_32)); //Use MemCpy to avoid alignment problems.
+ Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_SMBUS_EXECUTE_32);
+
+ MemCpy(Ptr, Buffer, (UINT32)Smbus.Length);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptStall
+//
+// Description: Write to boot script table an Stall.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptStall (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ VOID *Ptr;
+ BOOT_SCRIPT_STALL Stall;
+
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_STALL));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ Stall.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_STALL_OPCODE);
+ Stall.Duration = va_arg(arglist, UINTN);
+
+ MemCpy(Ptr, &Stall, sizeof(BOOT_SCRIPT_STALL));
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptIoPoll
+//
+// Description: Write to boot script table a IoPoll (OEM specific).
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptIoPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ VOID *DataResult = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_POLL_IO PollIo;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Mask, Result;
+
+ Mask = *(UINT64*)DataMask;
+ Result = *(UINT64*)DataResult;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+ if (Address + ValueSize > 0xffff) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_POLL_IO));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ PollIo.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_POLL_OPCODE_OEM, Width);
+ PollIo.Port = (UINT16) Address;
+ PollIo.Mask = Mask & BitMask;
+ PollIo.Result = Result & BitMask;
+
+ MemCpy(Ptr, &PollIo, sizeof(BOOT_SCRIPT_POLL_IO)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptMemPoll
+//
+// Description: Write to boot script table a MemPoll.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptMemPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ VOID *DataResult = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_POLL_MEM PollMem;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Mask, Result;
+
+ Mask = *(UINT64*)DataMask;
+ Result = *(UINT64*)DataResult;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+#if defined(EFI64) || defined(EFIx64)
+ if (Address + ValueSize < Address) return EFI_INVALID_PARAMETER; //Overflow
+#else
+ Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends.
+ if (Address + ValueSize > 0xffffffff) return EFI_INVALID_PARAMETER;
+#endif
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_POLL_MEM));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ PollMem.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_POLL_OPCODE_OEM, Width);
+ PollMem.Address = (UINT64)Address;
+ PollMem.Mask = Mask & BitMask;
+ PollMem.Result = Result & BitMask;
+
+ MemCpy(Ptr, &PollMem, sizeof(BOOT_SCRIPT_POLL_MEM)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptPciPoll
+//
+// Description: Write to boot script table an PciPoll.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptPciPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ VOID *DataResult= va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_POLL_PCI PollPci;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT16 Register;
+ UINT16 RegisterMax;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER;
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_POLL_PCI));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ PollPci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_POLL_OPCODE_OEM, Width);
+ PollPci.Address = Address;
+ PollPci.Mask = *(UINT64*) DataMask & BitMask;
+ PollPci.Result = *(UINT64*) DataResult & BitMask;
+
+ MemCpy(Ptr, &PollPci, sizeof(BOOT_SCRIPT_POLL_PCI)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: BootScriptDispatch
+//
+// Description: Write to boot script table an Dispatch.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS BootScriptDispatch (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+//---------Unsupported by now------------------------
+
+ VOID *Ptr;
+ BOOT_SCRIPT_DISPATCH Dispatch;
+
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_DISPATCH));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ Dispatch.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_DISPATCH_OPCODE);
+ Dispatch.EntryPoint = va_arg(arglist, EFI_PHYSICAL_ADDRESS);
+
+ MemCpy(Ptr, &Dispatch, sizeof(BOOT_SCRIPT_DISPATCH));
+
+ return EFI_SUCCESS;
+
+// return EFI_UNSUPPORTED;
+}
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateDispatch2
+//
+// Description: Write to boot script table an Dispatch2.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateDispatch2 (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ VOID *Ptr;
+ BOOT_SCRIPT_DISPATCH2 Dispatch2;
+
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_DISPATCH2));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ Dispatch2.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_DISPATCH_2_OPCODE);
+ Dispatch2.EntryPoint = va_arg(arglist, EFI_PHYSICAL_ADDRESS);
+ Dispatch2.Context = va_arg(arglist, EFI_PHYSICAL_ADDRESS);
+
+ MemCpy(Ptr, &Dispatch2, sizeof(BOOT_SCRIPT_DISPATCH2));
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateInformation
+//
+// Description: Write to boot script table an Information entry.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateInformation (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ UINT32 InfoSize = va_arg(arglist, UINT32);
+ EFI_PHYSICAL_ADDRESS InfoBuffer = va_arg(arglist, EFI_PHYSICAL_ADDRESS);
+ BOOT_SCRIPT_INFORMATION Information;
+ VOID *Ptr;
+
+
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_INFORMATION));
+ if (Ptr == NULL) return EFI_OUT_OF_RESOURCES;
+
+ Information.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_INFORMATION_OPCODE);
+ Information.Size = InfoSize;
+ Information.MessagePtr = InfoBuffer;
+
+ MemCpy(Ptr, &Information, sizeof(BOOT_SCRIPT_INFORMATION));
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStatePciCfg2Write
+//
+// Description: Write to boot script table an PciWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Add data to end of fixed table.
+// 6. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStatePciCfg2Write (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT16 Segment = va_arg(arglist, UINT16);
+ UINT64 Address = va_arg(arglist, UINT64);
+ UINTN Count = va_arg(arglist, UINTN);
+ VOID *Buffer = va_arg(arglist, VOID*);
+
+ BOOT_SCRIPT_PCI_CFG2_WRITE WritePci;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINTN AddressCount;
+ UINT16 Register;
+ UINT16 RegisterMax;
+ if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ AddressCount = ValueSize * ( ((Width & ~3) != EfiBootScriptWidthFifoUint8 ) ? Count : 1);
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (!Count) return EFI_INVALID_PARAMETER;
+
+ if (Register + AddressCount > RegisterMax) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry((UINT32)sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE) + AddressCount);
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ WritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG2_WRITE_OPCODE,Width);
+ WritePci.Segment = Segment;
+ WritePci.Address = Address;
+ WritePci.Count = Count;
+
+ MemCpy(Ptr, &WritePci, sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE)); //Use MemCpy to avoid alignment problems.
+ Ptr = (UINT8*) Ptr + sizeof(BOOT_SCRIPT_PCI_CFG2_WRITE);
+
+ MemCpy(Ptr, Buffer, AddressCount);
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStatePciCfg2ReadWrite
+//
+// Description: Write to boot script table an PciReadWrite.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStatePciCfg2ReadWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT16 Segment = va_arg(arglist, UINT16);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *Data = va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+
+ BOOT_SCRIPT_PCI_CFG2_READ_WRITE ReadWritePci;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT16 Register;
+ UINT16 RegisterMax;
+ if (((Width & 3) == EfiBootScriptWidthUint16) && (Address & 0x01))
+ return EFI_INVALID_PARAMETER;
+ if (((Width & 3) >= EfiBootScriptWidthUint32) && (Address & 0x03))
+ return EFI_INVALID_PARAMETER;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ ReadWritePci.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG2_READ_WRITE_OPCODE, Width);
+ ReadWritePci.Segment = Segment;
+ ReadWritePci.Address = Address;
+ ReadWritePci.Value = *(UINT64*) Data & BitMask;
+ ReadWritePci.Mask = *(UINT64*) DataMask & BitMask;
+
+ MemCpy(Ptr, &ReadWritePci, sizeof(BOOT_SCRIPT_PCI_CFG2_READ_WRITE)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateIoPoll
+//
+// Description: Write to boot script table a PI 1.1 IoPoll.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateIoPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataResult = va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ UINT64 Delay = va_arg(arglist, UINT64);
+
+ BOOT_SCRIPT_IO_POLL IoPoll;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Mask, Result;
+
+ Mask = *(UINT64*)DataMask;
+ Result = *(UINT64*)DataResult;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+ if (Address + ValueSize > 0xffff) return EFI_INVALID_PARAMETER;
+
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_IO_POLL));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ IoPoll.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_IO_POLL_OPCODE, Width);
+ IoPoll.Port = (UINT16) Address;
+ IoPoll.Mask = Mask & BitMask;
+ IoPoll.Result = Result & BitMask;
+ IoPoll.Delay = Delay;
+
+ MemCpy(Ptr, &IoPoll, sizeof(BOOT_SCRIPT_IO_POLL)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateMemPoll
+//
+// Description: Write to boot script table a MemPoll (PI 1.1).
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateMemPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ VOID *DataResult = va_arg(arglist, VOID *);
+ UINT64 Delay = va_arg(arglist, UINT64);
+ UINT64 LoopTimes = va_arg(arglist, UINT64);
+
+ BOOT_SCRIPT_MEM_POLL MemPoll;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT64 Mask, Result;
+
+ Mask = *(UINT64*)DataMask;
+ Result = *(UINT64*)DataResult;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+ //---Validate Inputs---
+#if defined(EFI64) || defined(EFIx64)
+ if (Address + ValueSize < Address) return EFI_INVALID_PARAMETER; //Overflow
+#else
+ Address &= 0xffffffff; //When UINT32 -> UINT64, compiler sometimes sign extends.
+ if (Address + ValueSize > 0xffffffff) return EFI_INVALID_PARAMETER;
+#endif
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_MEM_POLL));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ MemPoll.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_MEM_POLL_OPCODE, Width);
+ MemPoll.Address = (UINT64)Address;
+ MemPoll.Mask = Mask & BitMask;
+ MemPoll.Result = Result & BitMask;
+ MemPoll.Delay = Delay;
+ MemPoll.LoopTimes= LoopTimes;
+ MemCpy(Ptr, &MemPoll, sizeof(BOOT_SCRIPT_MEM_POLL)); //Use MemCpy to avoid alignment problems.
+ //TRACE((-1,"SaveState Mem poll Mask %lx\n", MemPoll.Mask));
+ //TRACE((-1,"SaveState Mem poll Result %lx\n", MemPoll.Result));
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStatePciCfgPoll
+//
+// Description: Write to boot script table an PciPoll (PI 1.1).
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStatePciCfgPoll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataResult= va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ UINT64 Delay = va_arg(arglist, UINT64);
+
+ BOOT_SCRIPT_PCI_CFG_POLL PciPoll;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT16 Register;
+ UINT16 RegisterMax;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER;
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_PCI_CFG_POLL));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ PciPoll.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG_POLL_OPCODE, Width);
+ PciPoll.Address = Address;
+ PciPoll.Mask = *(UINT64*) DataMask & BitMask;
+ PciPoll.Result = *(UINT64*) DataResult & BitMask;
+ PciPoll.Delay = Delay;
+
+ MemCpy(Ptr, &PciPoll, sizeof(BOOT_SCRIPT_PCI_CFG_POLL)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStatePciCfg2Poll
+//
+// Description: Write to boot script table an PciPoll Cfg2 (PI 1.1).
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN va_list arglist
+//
+// Output:
+// EFI_STATUS
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Get variable argument list from stack.
+// 2. Validate argument list. If invalid return EFI_INVALID_PARAMETER;
+// 3. Allocate entry from table. If no room in table, return EFI_OUT_OF_RESOURCES.
+// 4. Fill fixed table entries.
+// 5. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStatePciCfg2Poll (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ va_list arglist
+ )
+{
+ EFI_BOOT_SCRIPT_WIDTH Width = va_arg(arglist, EFI_BOOT_SCRIPT_WIDTH);
+ UINT16 Segment = va_arg(arglist, UINT16);
+ UINT64 Address = va_arg(arglist, UINT64);
+ VOID *DataResult= va_arg(arglist, VOID *);
+ VOID *DataMask = va_arg(arglist, VOID *);
+ UINT64 Delay = va_arg(arglist, UINT64);
+
+ BOOT_SCRIPT_PCI_CFG2_POLL PciPoll2;
+ VOID *Ptr;
+ UINT8 ValueSize = (UINT8) (1 << (Width & 3));
+ UINT64 BitMask;
+ UINT16 Register;
+ UINT16 RegisterMax;
+
+ switch(Width&3)
+ {
+ case EfiBootScriptWidthUint8: BitMask = 0x00000000000000ff; break;
+ case EfiBootScriptWidthUint16: BitMask = 0x000000000000ffff; break;
+ case EfiBootScriptWidthUint32: BitMask = 0x00000000ffffffff; break;
+ default: BitMask = 0xffffffffffffffff;
+ }
+
+#if 0 //<-----For PCI-Express
+ if (Address & 0xffffffff00000000) //Extended register?
+ {
+ if (Address & 0xfffff00000000000) return EFI_INVALID_PARAMETER; //Limit 4k
+ Register = (UINT16) (Address >> 16);
+ RegisterMax = 0x1000;
+ } else {
+#else
+ Register = (UINT8) Address;
+ RegisterMax = 0x100;
+#endif
+#if 0
+ }
+#endif
+
+ //---Validate Inputs---
+ if (Register + ValueSize > RegisterMax) return EFI_INVALID_PARAMETER;
+
+ //---Fill and Copy Table---
+ Ptr = AllocTableEntry(sizeof(BOOT_SCRIPT_PCI_CFG2_POLL));
+ if (Ptr == 0) return EFI_OUT_OF_RESOURCES;
+
+ PciPoll2.Type = (UINT16) TABLE_TYPE2(EFI_BOOT_SCRIPT_PCI_CONFIG2_POLL_OPCODE , Width);
+ PciPoll2.Segment = Segment;
+ PciPoll2.Address = Address;
+ PciPoll2.Mask = *(UINT64*) DataMask & BitMask;
+ PciPoll2.Result = *(UINT64*) DataResult & BitMask;
+ PciPoll2.Delay = Delay;
+
+ MemCpy(Ptr, &PciPoll2, sizeof(BOOT_SCRIPT_PCI_CFG2_POLL)); //Use MemCpy to avoid alignment problems.
+
+ return EFI_SUCCESS;
+}
+#endif //#if PI_SPECIFICATION_VERSION>=0x0001000A
+GENERIC_OPCODE_FUNC OpCodeFuncs[] =
+{
+ BootScriptIoWrite, //0
+ BootScriptIoReadWrite, //1
+ BootScriptMemWrite, //2
+ BootScriptMemReadWrite, //3
+ BootScriptPciWrite, //4
+ BootScriptPciReadWrite, //5
+ BootScriptSmbusExecute, //6
+ BootScriptStall, //7
+ BootScriptDispatch, //8
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ SaveStateDispatch2, //9
+ SaveStateInformation, //a ->0xA
+ SaveStatePciCfg2Write, //b ->0xB
+ SaveStatePciCfg2ReadWrite, //c ->0xC
+ SaveStateIoPoll, //d
+ SaveStateMemPoll, //e
+ SaveStatePciCfgPoll, //f
+ SaveStatePciCfg2Poll, //10
+#endif
+//oem
+ BootScriptIoPoll, //0x80 ->
+ BootScriptMemPoll, //0x81 ->
+ BootScriptPciPoll, //0x82 ->
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EfiBootScriptWrite
+//
+// Description: All boot script functions (except close table) call this function.
+// This function passes argument list to appropriate function.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN UINT16 OpCode
+// ...
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EfiBootScriptWrite (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ IN UINT16 TableName,
+ IN UINT16 OpCode,
+ ...
+ )
+{
+ EFI_STATUS Status;
+ va_list arglist;
+ va_start(arglist, OpCode);
+
+ if (TableName != EFI_ACPI_S3_RESUME_SCRIPT_TABLE)
+ return EFI_INVALID_PARAMETER;
+
+ if (OpCode > 0x82) {
+ Status = EFI_INVALID_PARAMETER; goto EXIT_BOOT_SCRIPT_WRITE;
+ }
+
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ if (OpCode > 16 && OpCode < 0x80) {Status = EFI_INVALID_PARAMETER; goto EXIT_BOOT_SCRIPT_WRITE;}
+#else
+ if (OpCode > 8 && OpCode < 0x80) {Status = EFI_INVALID_PARAMETER; goto EXIT_BOOT_SCRIPT_WRITE;}
+#endif
+
+ if (OpCode >= 0x80)
+ {
+ OpCode -= (0x80 - 9);
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ OpCode += 8;
+#endif
+ }
+
+ Status = OpCodeFuncs[OpCode](This, arglist);
+
+EXIT_BOOT_SCRIPT_WRITE:
+ va_end(arglist);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: EfiBootScriptCloseTable
+//
+// Description: Save table in runtime closing table and return pointer to table.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// OUT EFI_PHYSICAL_ADDRESS *Address
+//
+// Output:
+// EFI_STATUS
+//
+// Referrals:
+//
+// Notes:
+// Here is the control flow of this function:
+// 1. Allocate table entry for BOOT_SCRIPT_TABLE_END. If no entry, return EFI_OUT_OF_RESOURCES.
+// 2. Fill table.
+// 3. Allocate space for new table in Runtime.
+// 4. Copy table to new table.
+// 5. Set *Address to Runtime Table.
+// 6. Free old table.
+// 7. Create a initial table to start over if more Scripts are added.
+// 8. Return EFI_SUCCESS.
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS EfiBootScriptCloseTable (
+ IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This,
+ IN UINT16 TableName,
+ OUT EFI_PHYSICAL_ADDRESS *Address
+ )
+{
+ TABLE_INFO *Info = gTableInfo;
+ UINTN TableLength;
+//---------------------------------------
+ if (TableName != EFI_ACPI_S3_RESUME_SCRIPT_TABLE)
+ return EFI_INVALID_PARAMETER;
+ TableLength = (UINTN)Info->TablePtr - (UINTN)Info->TableBottom
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ + sizeof(BOOT_SCRIPT_INFO_STRUCTURE)
+#endif
+ + (UINTN) sizeof(BOOT_SCRIPT_TABLE_END);
+
+ //Copy to new table.
+ *Address = 0xFFFFFFFF;
+ if (pBS->AllocatePages(AllocateMaxAddress, EfiReservedMemoryType,
+ EFI_SIZE_TO_PAGES(TableLength + INIT_TABLE_SIZE) + 1, Address) != EFI_SUCCESS)
+ return EFI_OUT_OF_RESOURCES;
+
+ MemCpy((VOID*)(UINTN)*Address,Info->TableBottom, TableLength);
+ pBS->FreePool(Info->TableBottom);
+
+ //Reasign Table Address;
+ Info->TableBottom = (VOID*)(UINTN)*Address;
+ Info->TablePtr = (VOID*)((UINTN) Info->TableBottom + TableLength
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ - sizeof(BOOT_SCRIPT_INFO_STRUCTURE)
+#endif
+ - (UINTN) sizeof(BOOT_SCRIPT_TABLE_END));
+ Info->TableSize = EFI_PAGES_TO_SIZE(EFI_SIZE_TO_PAGES(TableLength + INIT_TABLE_SIZE) + 1);
+ Info->WasClosed = TRUE;
+
+ return EFI_SUCCESS;
+}
+
+EFI_BOOT_SCRIPT_SAVE_PROTOCOL gBootScriptSaveProtocol =
+{
+ EfiBootScriptWrite,
+ EfiBootScriptCloseTable
+};
+
+
+//PI 1.1 ++
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+
+VOID ClearInsertInfo()
+{
+ gInsertInfo.IsItInsert = FALSE;
+ gInsertInfo.BeforeOrAfter = FALSE;
+ gInsertInfo.Position = -1;
+ return;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateWrite
+//
+// Description: This function is used to store an OpCode to be replayed as part
+// of the S3 resume boot path.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN UINT16 OpCode
+// ...
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateWrite(
+ IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
+ IN UINT16 OpCode,
+ ...)
+{
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINTN OpIndex;
+ va_list arglist;
+ va_start(arglist, OpCode);
+//----------------------------------
+
+ //map SaveState opcodes to the op code table.
+ switch(OpCode){
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 0x9:
+ case 0xA:
+ case 0xB:
+ case 0xC:
+ case 0x0D:
+ case 0x0E:
+ case 0x0F:
+ case 0x10:
+ OpIndex=OpCode;
+ break;
+ case 0x80:
+ case 0x81:
+ case 0x82:
+ OpIndex= OpCode - (0x6F);
+ break;
+ default:
+ Status = EFI_UNSUPPORTED;
+ goto EXIT_BOOT_SCRIPT_WRITE;
+ }
+ Status = OpCodeFuncs[OpIndex](&gBootScriptSaveProtocol, arglist);
+ //TRACE((-1,"SaveState UniqueIndex %x\n", gTableInfo->NumTableEntries -1));
+
+EXIT_BOOT_SCRIPT_WRITE:
+ va_end(arglist);
+ return Status;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateInsert
+//
+// Description: This function is used to store an OpCode to be replayed as part
+// of the S3 resume boot path. The opcode is stored before (TRUE)
+// or after (FALSE) the position in the boot script table specified
+// by Position. If Position is NULL or points to NULL then the new
+// opcode is inserted at the beginning of the table (if TRUE) or end
+// of the table (if FALSE).
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN BOOLEAN BeforeOrAfter
+// IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL
+// IN UINT16 OpCode
+// ...
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateInsert(
+ IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
+ IN BOOLEAN BeforeOrAfter,
+ IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL,
+ IN UINT16 OpCode,
+ ...
+){
+
+ EFI_STATUS Status=EFI_SUCCESS;
+ UINTN OpIndex;
+
+ va_list arglist;
+ va_start(arglist, OpCode);
+//----------------------------------
+
+ //map SaveState opcodes to the op code table.
+ switch(OpCode){
+ case 0:
+ case 1:
+ case 2:
+ case 3:
+ case 4:
+ case 5:
+ case 6:
+ case 7:
+ case 8:
+ case 0x9:
+ case 0xA:
+ case 0xB:
+ case 0xC:
+ case 0x0D:
+ case 0x0E:
+ case 0x0F:
+ case 0x10:
+ OpIndex=OpCode;
+ break;
+ case 0x80:
+ case 0x81:
+ case 0x82:
+ OpIndex= OpCode - (0x6F);
+ break;
+ default:
+ Status = EFI_INVALID_PARAMETER;
+ goto EXIT_BOOT_SCRIPT_WRITE;
+ }
+
+ gInsertInfo.IsItInsert = TRUE;
+ gInsertInfo.BeforeOrAfter = BeforeOrAfter;
+ if (!Position || !*Position)
+ if (BeforeOrAfter) gInsertInfo.Position = -1;
+ else gInsertInfo.IsItInsert = FALSE;
+ else
+ {
+ if ((UINTN) *Position >= gTableInfo->NumTableEntries)
+ {
+ ClearInsertInfo();
+ return EFI_INVALID_PARAMETER;
+ }
+ gInsertInfo.Position = (UINTN)*Position;
+ }
+ Status = OpCodeFuncs[OpIndex](&gBootScriptSaveProtocol, arglist);
+ if (Position) *Position = (VOID*)(gTableInfo->NumTableEntries - 1);
+ ClearInsertInfo();
+EXIT_BOOT_SCRIPT_WRITE:
+ va_end(arglist);
+ return Status;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateLabel
+//
+// Description: Find a label within the boot script table and, if not present,
+// optionally create it.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN BOOLEAN BeforeOrAfter
+// IN BOOLEAN CreateIfNotFound
+// IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL
+// IN CONST CHAR8 *Label
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateLabel(
+ IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
+ IN BOOLEAN BeforeOrAfter,
+ IN BOOLEAN CreateIfNotFound,
+ IN OUT EFI_S3_BOOT_SCRIPT_POSITION *Position OPTIONAL,
+ IN CONST CHAR8 *Label)
+{
+ UINT32 LabelSize, i;
+ UINT8 *TableHdr = gTableInfo->TableBottom, *TableInfo;
+ UINT16 Type;
+ BOOT_SCRIPT_LABEL LabelStr;
+
+ if ((Label == NULL) || (*Label == 0))
+ {
+ TRACE((-1,"First Exit\n"));
+ return EFI_INVALID_PARAMETER;
+ }
+ for(LabelSize=0; LabelSize<= LABEL_MAX_SIZE ; LabelSize++)
+ {
+ if (Label[LabelSize] == 0) break; // We assume label is 0 terminated.
+
+ }
+ if (LabelSize >= LABEL_MAX_SIZE)
+ {
+ TRACE((-1,"2-d Exit\n"));
+ return EFI_INVALID_PARAMETER; // Label is too long or wrong/corrupted pointer
+ }
+ for (i=0; i<=gTableInfo->NumTableEntries; i++)
+ {
+ TableInfo = TableHdr + sizeof(BOOT_SCRIPT_INFO_STRUCTURE);
+ Type = *(UINT8*) TableInfo + (*((UINT8*) TableInfo + 1) << 8); //In case not aligned if alignment required.
+ if (Type == EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM)
+ {
+ if (((BOOT_SCRIPT_LABEL*) TableInfo)->Size == LabelSize &&
+ !MemCmp((VOID*)Label, TableInfo + sizeof(BOOT_SCRIPT_LABEL), LabelSize))
+ {
+ if (Position) *Position = ((VOID*)((BOOT_SCRIPT_INFO_STRUCTURE*) TableHdr)->UniqueIndex);
+ else return EFI_INVALID_PARAMETER; //We found label, but can't return its position
+ return EFI_SUCCESS; // Label found and position returned
+ }
+ }
+ TableHdr += ((BOOT_SCRIPT_INFO_STRUCTURE*) TableHdr)->Length;
+ }
+ //----Label was not found
+
+ if (!CreateIfNotFound) return EFI_NOT_FOUND;
+
+ //----So - lets create it at position
+
+ if (Position && ((UINTN) *Position >= gTableInfo->NumTableEntries))
+ return EFI_INVALID_PARAMETER; // Position is not valid
+
+ //---Filling gInsertInfo based on passed parameters
+
+ gInsertInfo.IsItInsert = TRUE;
+ gInsertInfo.BeforeOrAfter = BeforeOrAfter;
+
+ if (!Position || !*Position)
+ if (BeforeOrAfter) gInsertInfo.Position = -1;
+ else gInsertInfo.IsItInsert = FALSE;
+ else
+ {
+ if ((UINTN) *Position >= gTableInfo->NumTableEntries)
+ {
+ ClearInsertInfo();
+ return EFI_INVALID_PARAMETER;
+ }
+ gInsertInfo.Position = (UINTN)*Position;
+ }
+ TableHdr = AllocTableEntry(sizeof(BOOT_SCRIPT_LABEL) + LabelSize);
+ ClearInsertInfo();
+ if (!TableHdr)
+ return EFI_OUT_OF_RESOURCES;
+ LabelStr.Type = TABLE_TYPE1(EFI_BOOT_SCRIPT_LABEL_OPCODE_OEM);
+ LabelStr.Size = LabelSize;
+ MemCpy(TableHdr, &LabelStr, sizeof(BOOT_SCRIPT_LABEL));
+ TableHdr += sizeof(BOOT_SCRIPT_LABEL);
+ MemCpy(TableHdr, (VOID*)Label, LabelSize);
+ if (Position)
+ *Position = (VOID*)(gTableInfo->NumTableEntries - 1);
+ return EFI_SUCCESS;
+}
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: SaveStateCompare
+//
+// Description: Compare two positions in the boot script table and return their
+// relative position.
+//
+// Input:
+// IN EFI_BOOT_SCRIPT_SAVE_PROTOCOL *This
+// IN EFI_S3_BOOT_SCRIPT_POSITION Position1
+// IN EFI_S3_BOOT_SCRIPT_POSITION Position2
+// OUT UINTN *RelativePosition
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS SaveStateCompare(
+ IN CONST EFI_S3_SAVE_STATE_PROTOCOL *This,
+ IN EFI_S3_BOOT_SCRIPT_POSITION Position1,
+ IN EFI_S3_BOOT_SCRIPT_POSITION Position2,
+ OUT UINTN *RelativePosition)
+{
+ VOID *First, *Second;
+ if (((UINTN) Position1 > gTableInfo->NumTableEntries)
+ || ((UINTN) Position2 > gTableInfo->NumTableEntries))
+ return EFI_INVALID_PARAMETER;
+ gInsertInfo.BeforeOrAfter = TRUE;
+ gInsertInfo.Position = (UINTN)Position1;
+ First = InsertPositionInBootScript (0);
+ if (!First)
+ {
+ ClearInsertInfo();
+ return EFI_INVALID_PARAMETER;
+ }
+ gInsertInfo.Position = (UINTN)Position2;
+ Second = InsertPositionInBootScript (0);
+ if (!Second)
+ {
+ ClearInsertInfo();
+ return EFI_INVALID_PARAMETER;
+ }
+ if (First == Second) *RelativePosition = 0;
+ else
+ if (First < Second) *RelativePosition = -1;
+ else *RelativePosition = 1;
+ ClearInsertInfo();
+ return EFI_SUCCESS;
+}
+
+
+
+EFI_S3_SAVE_STATE_PROTOCOL gS3SaveStateProtocol={
+ SaveStateWrite,
+ SaveStateInsert,
+ SaveStateLabel,
+ SaveStateCompare
+};
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitBootScriptSmm
+//
+// Description: Initialize table, if not done yet, and install protocols in SMM.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+
+EFI_STATUS InitBootScriptSmm(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+//-------------------------------
+ Status=InitAmiSmmLib(ImageHandle, SystemTable);
+ ASSERT_EFI_ERROR (Status);
+ if(EFI_ERROR(Status)) return Status;
+
+ Status=InitBootScriptStructure(TRUE);
+ if(EFI_ERROR(Status)) return Status;
+
+ // We are in SMM, retrieve the pointer to SMM System Table
+ Status=mInternalSmmBase2->GetSmstLocation (mInternalSmmBase2, &gSmst2);
+ ASSERT (gSmst2 != NULL);
+ if( EFI_ERROR(Status) || (gSmst2 == NULL)) return EFI_UNSUPPORTED;
+
+
+ // Install SMM PCI Root Bridge I/O Protocol
+ Status=gSmst2->SmmInstallProtocolInterface(
+ &mSmmS3SaveHandle,
+ &gEfiS3SmmSaveStateProtocolGuid,
+ EFI_NATIVE_INTERFACE,
+ (EFI_S3_SMM_SAVE_STATE_PROTOCOL*)&gS3SaveStateProtocol
+ );
+
+
+
+
+ return Status;
+
+
+}
+
+#endif
+//PI 1.1 --
+
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitBootScriptDxe
+//
+// Description: Initialize table and install protocols outside SMM.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitBootScriptDxe(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = InitBootScriptStructure(FALSE);
+ if(EFI_ERROR(Status)) return Status;
+
+ Status = SystemTable->BootServices->InstallMultipleProtocolInterfaces(
+ &ImageHandle,
+ &gEfiBootScriptSaveGuid, &gBootScriptSaveProtocol,
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ &gEfiS3SaveStateProtocolGuid, &gS3SaveStateProtocol,
+#endif
+ NULL
+ );
+
+ ASSERT_EFI_ERROR(Status);
+
+ Status = CreateReadyToBootEvent(
+ TPL_CALLBACK,
+ CallbackReadyToBoot,
+ NULL,
+ &gEvtReadyToBoot
+ );
+ ASSERT_EFI_ERROR(Status);
+
+ return Status;
+}
+//<AMI_PHDR_START>
+//---------------------------------------------------------------------------
+//
+// Procedure: InitBootScript
+//
+// Description: Initialize table and install protocols.
+// Called twice - in and outside SMM.
+//
+// Input:
+// IN EFI_HANDLE ImageHandle
+// IN EFI_SYSTEM_TABLE *SystemTable
+//
+// Output:
+// EFI_STATUS
+//
+//---------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS InitBootScript(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+#if PI_SPECIFICATION_VERSION>=0x0001000A
+ EFI_STATUS Status;
+ BOOLEAN InSmm=FALSE;
+#endif
+
+//-------
+ InitAmiLib(ImageHandle, SystemTable);
+//PI 1.1 ++
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ // Retrieve SMM Base2 Protocol, Do not use gBS from UefiBootServicesTableLib on purpose
+ // to prevent inclusion of gBS, gST, and gImageHandle from SMM Drivers unless the
+ // SMM driver explicity declares that dependency.
+ Status = SystemTable->BootServices->LocateProtocol (
+ &gEfiSmmBase2ProtocolGuid,
+ NULL,
+ (VOID **)&mInternalSmmBase2
+ );
+ if( EFI_ERROR(Status)){
+ //if we can't find SMM Protocols that's not InSmm initialization
+ if(Status==EFI_NOT_FOUND) InSmm=FALSE;
+ else return EFI_UNSUPPORTED;
+ } else mInternalSmmBase2->InSmm (mInternalSmmBase2, &InSmm);
+
+ // Check to see if we are already in SMM
+ if (!InSmm ) {
+#endif
+ // We are not in SMM, so SMST is not needed
+ return InitBootScriptDxe(ImageHandle,SystemTable);
+//PI 1.1 ++
+#if defined(PI_SPECIFICATION_VERSION)&&(PI_SPECIFICATION_VERSION>=0x0001000A)
+ } else {
+ return InitBootScriptSmm(ImageHandle,SystemTable);
+ }
+#endif
+}
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2011, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/S3Restore.cif b/Core/EM/S3/S3Restore.cif
new file mode 100644
index 0000000..e4c4c83
--- /dev/null
+++ b/Core/EM/S3/S3Restore.cif
@@ -0,0 +1,15 @@
+<component>
+ name = "S3Restore"
+ category = ModulePart
+ LocalRoot = "Core\EM\S3\"
+ RefName = "S3Restore"
+[files]
+"S3Restore.sdl"
+"S3Restore.mak"
+"S3Resume.dxs"
+"AcpiS3Wake.asm"
+"S3Resume.c"
+"AcpiPeiS3Func.c"
+"AcpiPeiS3Func.h"
+"BootScriptExecuter.c"
+<endComponent>
diff --git a/Core/EM/S3/S3Restore.mak b/Core/EM/S3/S3Restore.mak
new file mode 100644
index 0000000..d229d9c
--- /dev/null
+++ b/Core/EM/S3/S3Restore.mak
@@ -0,0 +1,88 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Restore.mak 2 3/18/11 3:51p Oleksiyy $
+#
+# $Revision: 2 $
+#
+# $Date: 3/18/11 3:51p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Restore.mak $
+#
+# 2 3/18/11 3:51p Oleksiyy
+# [TAG] EIP53402
+# [Category] Improvement
+# [Description] Improving backward computability and architecture.
+# [Files] ACPI.mak, AcpiCore.cif, S3Save.cif, S3Save.mak,
+# S3Restore.mak, BootScriptExecutor.c, S3Common.cif, S3SaveState.h,
+# S3smmSaveState.h
+#
+# 1 2/03/11 4:09p Oleksiyy
+# [TAG] EIP53402
+# [Category] Improvement
+# [Description] Create new label of ACPI with separate S3 Functionality
+# [Files] S3Restore.cif
+# S3Restore.sdl
+# S3Restore.mak
+# S3Resume.dxs
+# AcpiS3Wake.asm
+# S3Resume.c
+# AcpiPeiS3Func.c
+# AcpiPeiS3Func.h
+# BootScriptExecuter.c
+#
+# 6 1/13/10 2:13p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: <ComponentName>.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : S3Restore
+
+S3Restore : $(BUILD_DIR)\S3Restore.mak S3RestoreBin
+
+$(BUILD_DIR)\S3Restore.mak : $(S3Restore_DIR)\$(@B).cif $(S3Restore_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(S3Restore_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+S3RestoreBin : $(AMIPEILIB) $(AMICSPLib)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\S3Restore.mak all\
+ GUID=EFD652CC-0E99-40f0-96C0-E08C089070FC \
+ ENTRY_POINT=S3ResumeEntryPoint\
+ "MY_INCLUDES=/I$(ACPI_CORE_DIR)" \
+ DEPEX1=$(S3Restore_DIR)\S3Resume.DXS \
+ DEPEX1_TYPE=EFI_SECTION_PEI_DEPEX \
+ TYPE=PEIM \
+ COMPRESS=0
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
diff --git a/Core/EM/S3/S3Restore.sdl b/Core/EM/S3/S3Restore.sdl
new file mode 100644
index 0000000..baa1165
--- /dev/null
+++ b/Core/EM/S3/S3Restore.sdl
@@ -0,0 +1,25 @@
+TOKEN
+ Name = "S3Restore_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable S3Restore support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "S3Restore_DIR"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\S3Restore.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
+MODULE
+ Help = "Includes S3Restore.mak to Project"
+ File = "S3Restore.mak"
+End
+
diff --git a/Core/EM/S3/S3Resume.c b/Core/EM/S3/S3Resume.c
new file mode 100644
index 0000000..1749cf2
--- /dev/null
+++ b/Core/EM/S3/S3Resume.c
@@ -0,0 +1,582 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/S3Resume.c 3 4/16/14 6:18a Chaseliu $
+//
+// $Revision: 3 $
+//
+// $Date: 4/16/14 6:18a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/Projects/Intel/Haswell/LynxPoint_SharkBay-DT_Crb_1AQQW/Core/EM/S3/S3Resume.c $
+//
+// 3 4/16/14 6:18a Chaseliu
+// sync to ACPI module 48
+//
+// 2 9/18/13 1:04a Thomaschen
+// Fix RHEL6.4 S3 resume issue.
+//
+// 9 3/03/14 5:04p Oleksiyy
+// [TAG] EIP154308
+// [Category] Improvement
+// [Description] Aptio 4: Intel Doc #542550 4h) FirmwarePerformance EFI
+// variable contains address of FPDT ACPI table.
+// [Files] AcpiCore.c and S3Resume.c
+//
+// 8 6/12/12 3:20p Oleksiyy
+// TAG] EIP90322
+// [Category] Improvement
+// [Description] Extern declaradion of gAmiGlobalVariableGuid moved to
+// AmiLib.h.
+// [Files] AmiLib.h, Misc.c, EfiLib.c, AcpiCore.c and S3Resume.c
+//
+// 7 6/12/12 11:18a Oleksiyy
+// [TAG] EIP88889
+// [Category] Improvement
+// [Description] FACP ver 5.0 structure added, FPDT mesurment accuracy
+// improved.
+// [Files] ACPI50.h, ACPI.sdl, AcpiCore.c, S3Resume.c, Image.c,
+// EfiLib.c
+//
+// 6 5/22/12 4:31p Oleksiyy
+// [TAG] EIP90322
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] ChiefRiver SCT Fail, improper variable FPDT_Variable in
+// ACPI module
+// [RootCause] EFI_GLOBAL_VARIABLE guid is used in non EFI defined
+// variable.
+// [Solution] New guig AMI_GLOBAL_VARIABLE_GUID is created and used.
+// [Files] AmiLib.h, Misc.c, EfiLib.c, AcpiCore.c and S3Resume.c
+//
+// 5 5/08/12 6:05p Oleksiyy
+// [TAG] EIP89643
+// [Category] Bug Fix
+// [Severity] Normal
+// [Symptom] S3Resume2 Ppi newer installs
+// [RootCause] EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST incorrect usage in
+// previous Ppi descriptor entree.
+// [Solution] EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LISTremoved.
+// [Files] S3Resume.c
+//
+// 4 11/11/11 5:13p Oleksiyy
+// [TAG] EIP64296
+// [Category] New Feature
+// [Description] Creation and filling of Firmware Performance Data Table
+// is added. FirmPerfDataTab.h renamed to ACPI50.h
+// [Files] AcpiCore.c, EfiLib.c, S3Resume.c and ACPI50.h added.
+//
+// 3 11/08/11 4:45p Oleksiyy
+// [TAG] EIP64296
+// [Category] New Feature
+// [Description] Creation and filling of Firmware Performance Data Table
+// is added.
+// [Files] AcpiCore.c, AmiDxeLib.h, CSM.c, DxeMain.c, EfiLib.c,
+// Image.c, S3Resume.c and FirmPerfDataTab.h
+//
+// 2 7/19/11 11:33a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 1 2/03/11 4:09p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Restore.cif
+// S3Restore.sdl
+// S3Restore.mak
+// S3Resume.dxs
+// AcpiS3Wake.asm
+// S3Resume.c
+// AcpiPeiS3Func.c
+// AcpiPeiS3Func.h
+// BootScriptExecuter.c
+//
+// 25 11/24/09 5:21p Oleksiyy
+// EIP 27605: Added ACPI 4.0 support.
+//
+// 24 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 23 10/03/08 3:20p Felixp
+// Performance measurement support added
+//
+// 19 4/15/08 9:09p Yakovlevs
+// Added support to chech for wake vector in all instances of FACS.
+// EndOfPEIPhase PPI now installed.
+//
+// 18 4/09/08 5:52p Markw
+// Install End of PEI PPI.
+//
+// 17 8/07/07 2:51p Felixp
+// Additional Status Codes added
+//
+// 16 5/18/07 11:11a Markw
+// Reintialize gdt before calling thunk.
+//
+// 15 4/23/07 1:31p Felixp
+// Boot Script related code moved from Core to ACPI module.
+// PEI code added to S3 Resume PPI. DXE code added to AcpiS3Save driver.
+//
+// 14 3/13/07 11:58a Felixp
+// Error reporting updated to use new PEI_ERROR_CODE macro
+//
+// 13 2/07/07 3:08p Markw
+// Add video repost support setup question.
+//
+// 12 1/23/07 4:24p Markw
+// Added thunk support for a call for S3 video repost.
+//
+// 11 4/03/06 4:01p Felixp
+// New Super I/O infrastructure Support
+//
+// 10 12/12/05 9:25p Yakovlevs
+// SIO-specific core surrounded by #ifdefs
+//
+// 9 12/05/05 11:32a Yakovlevs
+// Disabled Generation of SW SMI in order to switch to ACPI mode.
+// System waking up from S3 with SCI_ENABLE bit ON.
+//
+// 8 10/09/05 11:27a Felixp
+// Performance measurements added.
+//
+// 7 5/27/05 4:23p Markw
+// Added Keyboard init.
+//
+// 6 5/10/05 2:50p Markw
+// Use 16bit selectors for data segment.
+//
+// 5 5/07/05 11:53p Markw
+// Store GDT in memory. Give pointer to GDT descripteor base/limit to wake
+// up.
+//
+// 4 5/06/05 5:07p Markw
+// Added 16 bit wakeup support.
+//
+// 3 5/04/05 12:24p Markw
+// Moved structure definitions to AcpiS3.h.
+//
+// 2 4/29/05 3:26p Markw
+//
+// 1 4/29/05 12:17p Sivagarn
+//
+// 5 4/05/05 2:19p Markw
+// Added enable ACPI Mode.
+//
+// 4 3/31/05 11:11a Markw
+// Add wakeup vector support.
+//
+// 3 3/28/05 6:01p Markw
+// Fixed bug. NVRAM variable is address not data.
+//
+// 2 3/27/05 6:36p Markw
+// Execute Boot Script supported added.
+//
+// 1 3/25/05 5:37p Markw
+//
+
+//<AMI_FHDR_START>
+//----------------------------------------------------------------------------
+//
+// Name: S3Resume.c
+//
+// Description: Restore configuration state from S3 resume.
+//
+//----------------------------------------------------------------------------
+//<AMI_FHDR_END>
+
+#include <Pei.h>
+#include <Ppi\S3Resume.h>
+#include <Ppi\S3Resume2.h>
+#include <ppi\BootScriptExecuter.h>
+#include <Ppi\ReadOnlyVariable2.h>
+#include <AmiPeiLib.h>
+#include <token.h>
+#include <setup.h>
+#include "AcpiS3.h"
+#include "AcpiPeiS3Func.h"
+#include "AMICSPLIBInc.H"
+#include <ACPI50.h>
+
+#pragma pack(1)
+typedef struct {
+ UINT16 GdtLimit;
+ UINT64 *GdtBase;
+} PTR_GDT_DESCS;
+#pragma pack()
+
+extern UINT32 RealModeThunkStart;
+extern UINT32 RealModeThunkSize;
+
+EFI_GUID gEfiPeiS3ResumePpiGuid = EFI_PEI_S3_RESUME_PPI_GUID;
+EFI_GUID gEfiPeiBootScriptExecuterPpiGuid = EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI_GUID;
+EFI_GUID gEfiPeiEndOfPeiPhasePpiGuid = EFI_PEI_END_OF_PEI_PHASE_PPI_GUID;
+extern EFI_GUID gEfiPeiReadOnlyVariable2PpiGuid;
+EFI_GUID gEfiSetupGuid = SETUP_GUID;
+
+CHAR16 gSetupVariable[] = L"Setup";
+
+VOID RealModeThunk(PTR_GDT_DESCS *GdtDesc, UINT32 Firmware_Waking_Vector, BOOLEAN UseCall);
+typedef VOID(*REAL_MODE_THUNK_FUNCTION)(PTR_GDT_DESCS*, UINT32, BOOLEAN);
+//Boot Script Executer module initialization routine
+EFI_STATUS InitBootScriptExecuter(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ );
+//S3 Resume PPI routine
+//Defined in this file
+EFI_STATUS S3RestoreConfig(
+ IN EFI_PEI_SERVICES **PeiServices
+);
+EFI_STATUS S3RestoreConfig2(
+ IN EFI_PEI_S3_RESUME2_PPI *This
+);
+//To be copied to memory.
+UINT64 gGDT[] = {
+ 0, //NULL_SEL
+ 0x00009a000000ffff, //CODE_SEL 0x08 16-bit code selector, limit of 4K
+ 0x000093000000ffff //DATA_SEL 0x10, 16-bit data selector Data 0-ffffffff
+};
+
+//PPI to be installed
+EFI_PEI_S3_RESUME_PPI S3ResumePpi = {S3RestoreConfig};
+EFI_PEI_S3_RESUME2_PPI S3ResumePpi2 = {S3RestoreConfig2};
+
+static EFI_PEI_PPI_DESCRIPTOR gPpiList[] = {
+ {EFI_PEI_PPI_DESCRIPTOR_PPI,
+ &gEfiPeiS3ResumePpiGuid,
+ &S3ResumePpi},
+
+ {(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+ &gEfiPeiS3Resume2PpiGuid,
+ &S3ResumePpi2}
+};
+
+static EFI_PEI_PPI_DESCRIPTOR gEndOfPpiList[] = {
+ EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
+ &gEfiPeiEndOfPeiPhasePpiGuid,
+ NULL
+};
+
+VOID InitLongModeExt(
+ IN EFI_PEI_SERVICES **PeiServices,
+ IN VOID *Function,
+ IN VOID *Parameter1,
+ IN VOID *Parameter2,
+ IN UINT8 NumMemBits
+);
+
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: S3RestoreConfig
+//
+// Description: Restore configuration state from S3 resume.
+//
+// Input: EFI_PEI_SERVICES **PeiServices
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS S3RestoreConfig(
+ IN EFI_PEI_SERVICES **PeiServices
+)
+{
+ EFI_STATUS Status;
+ UINT32 i;
+ PTR_GDT_DESCS *GdtDesc;
+ UINT64 *Gdt;
+
+ ACPI_VARIABLE_SET *AcpiVariableSet;
+ EFI_PEI_BOOT_SCRIPT_EXECUTER_PPI *BootScript;
+ EFI_PHYSICAL_ADDRESS BootScriptTable;
+#if S3_VIDEO_REPOST_SUPPORT == 1
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI *ReadOnlyVariable;
+ SETUP_DATA SetupData;
+ BOOLEAN IsSetupDataValid;
+ UINTN VariableSize=sizeof(SETUP_DATA);
+#endif
+ void(*X_Firmware_Waking_Vector)();
+ UINT32 Firmware_Waking_Vector;
+ UINTN VarSize = sizeof(UINT32);
+ EFI_FPDT_STRUCTURE *FpdtVar;
+
+ PEI_PERF_START(PeiServices,S3RESUME_TOK,NULL,0);
+ PEI_PROGRESS_CODE(PeiServices,PEI_S3_STARTED);
+#if S3_VIDEO_REPOST_SUPPORT == 1
+ Status = (*PeiServices)->LocatePpi(
+ PeiServices,
+ &gEfiPeiReadOnlyVariable2PpiGuid,
+ 0, NULL,
+ &ReadOnlyVariable
+ );
+ ASSERT_PEI_ERROR(PeiServices, Status);
+#endif
+
+ Status = (*PeiServices)->LocatePpi (
+ PeiServices,
+ &gEfiPeiBootScriptExecuterPpiGuid,
+ 0,
+ NULL,
+ &BootScript
+ );
+ ASSERT_PEI_ERROR (PeiServices, Status);
+ if (EFI_ERROR(Status)){
+ PEI_ERROR_CODE(PeiServices, PEI_S3_BOOT_SCRIPT_ERROR, EFI_ERROR_MAJOR);
+ return Status;
+ }
+
+ AcpiVariableSet = GetAcpiS3Info(PeiServices);
+ if (!AcpiVariableSet){
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- No Acpi Global Variable\n"));
+ PEI_ERROR_CODE(PeiServices, PEI_S3_RESUME_ERROR, EFI_ERROR_MAJOR);
+ return EFI_NOT_FOUND;
+ }
+
+ BootScriptTable = AcpiVariableSet->AcpiBootScriptTable;
+
+#if S3_VIDEO_REPOST_SUPPORT == 1
+ VariableSize = sizeof(SETUP_DATA);
+ Status = ReadOnlyVariable->GetVariable(
+ ReadOnlyVariable,
+ gSetupVariable, &gEfiSetupGuid,
+ NULL,
+ &VariableSize, &SetupData
+ );
+ IsSetupDataValid = !EFI_ERROR(Status);
+#endif
+
+ PEI_PROGRESS_CODE(PeiServices,PEI_S3_BOOT_SCRIPT);
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Executing Boot Script Table.\n"));
+ Status = BootScript->Execute(
+ PeiServices,
+ BootScript,
+ BootScriptTable,
+ NULL
+ );
+ if (EFI_ERROR(Status))
+ {
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Error executing Boot Script Table.\n"));
+ PEI_ERROR_CODE(PeiServices, PEI_S3_BOOT_SCRIPT_ERROR, EFI_ERROR_MAJOR);
+ }
+
+//for legacy free systems it will be infinite loop
+
+ //keyboard init
+ #define KBC_CMDSTS_PORT 0x64
+ #define KBC_DATA_PORT 0x60
+ #define KBC_IBF 0x02
+ if( IoRead8(KBC_CMDSTS_PORT) != 0xff){
+ IoWrite8(KBC_CMDSTS_PORT, 0xaa);
+ for (;;) {
+ if (!(IoRead8(KBC_CMDSTS_PORT) & KBC_IBF)) {
+ break;
+ }
+ }
+ }
+
+ _asm cli
+
+ //allocate memory for GDT and copy to Thunk to 16-bit.
+ (*PeiServices)->AllocatePool(PeiServices,sizeof(gGDT), &Gdt);
+
+ //Allocate memory for descriptor.
+ (*PeiServices)->AllocatePool(PeiServices,sizeof(PTR_GDT_DESCS), &GdtDesc);
+ GdtDesc->GdtLimit = sizeof(gGDT)-1;
+ GdtDesc->GdtBase = Gdt;
+
+ (*PeiServices)->InstallPpi(PeiServices, gEndOfPpiList);
+
+#if S3_VIDEO_REPOST_SUPPORT == 1
+ if (IsSetupDataValid && SetupData.S3ResumeVideoRepost) {
+ //The following code executes video option ROM at c000:0003.
+ //For the video option ROM, a thunk is needed to 16-bit.
+ //The Thunk and the area for 16-bit stack are located starting at
+ //ACPI_THUNK_REAL_MODE_SEGMENT * 16 with a length ACPI_THUNK_STACK_TOP.
+
+ VOID *RealModeThunkSave;
+
+ PEI_PROGRESS_CODE(PeiServices,PEI_S3_VIDEO_REPOST);
+ //Allocate memory to perserve the the thunk region.
+ Status = (*PeiServices)->AllocatePool(PeiServices, ACPI_THUNK_STACK_TOP, &RealModeThunkSave);
+ ASSERT_PEI_ERROR (PeiServices, Status);
+
+ //Save the thunk and stack region.
+ MemCpy(RealModeThunkSave, (VOID*)(ACPI_THUNK_REAL_MODE_SEGMENT * 16), ACPI_THUNK_STACK_TOP); //Save Region to copy
+ //Copy the thunk code.
+ MemCpy((VOID*)(ACPI_THUNK_REAL_MODE_SEGMENT * 16), (VOID*)RealModeThunkStart, RealModeThunkSize);
+
+ //Open 0xc0000 region--the video option ROM.
+ NBPeiProgramPAMRegisters(
+ PeiServices,
+ 0xc0000,
+ 0x10000,
+ LEGACY_REGION_UNLOCK,
+ NULL
+ );
+
+ //Call video option rom: C000:0003.
+ for(i = 0; i < sizeof(gGDT)/sizeof(UINT64); ++i) Gdt[i] = gGDT[i]; //Set GDT for Thunk to 16-bit
+ ((REAL_MODE_THUNK_FUNCTION)(ACPI_THUNK_REAL_MODE_SEGMENT * 16))(GdtDesc, 0xc0000003, TRUE);
+
+ //Close c000 region
+ NBPeiProgramPAMRegisters(
+ PeiServices,
+ 0xc0000,
+ 0x10000,
+ LEGACY_REGION_LOCK,
+ NULL
+ );
+
+ //Restore region where THUNK and 16-bit stack was copied over.
+ MemCpy((VOID*)(ACPI_THUNK_REAL_MODE_SEGMENT * 16), RealModeThunkSave, ACPI_THUNK_STACK_TOP); //Restore region.
+ }
+#endif
+
+ PEI_TRACE((-1, PeiServices, "Smm S3 resume -- ACPI Mode Enable.\n"));
+ if (!AcpiVariableSet->AcpiFacsTable[0] && \
+ !AcpiVariableSet->AcpiFacsTable[1] && \
+ !AcpiVariableSet->AcpiFacsTable[2])
+ {
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- No ACPI FACS Table\n"));
+ PEI_ERROR_CODE(PeiServices, PEI_S3_RESUME_ERROR, EFI_ERROR_MAJOR);
+ }
+
+ PEI_PERF_END(PeiServices,S3RESUME_TOK,NULL,0);
+ PEI_PERF_SAVE_S3_DATA(PeiServices);
+
+ Status = PeiGetVariable(
+ PeiServices,
+ L"FPDT_Variable_NV", &gAmiGlobalVariableGuid,
+ NULL, &VarSize, &FpdtVar
+
+ );
+ if (!EFI_ERROR (Status))
+ {
+ if (((PERF_TAB_HEADER*)(UINT8*)(FpdtVar->S3Pointer))->Signature == 0x54503353)
+ {
+ BASIC_S3_RESUME_PERF_REC *S3PerRec;
+ UINT64 NanoTime;
+ S3PerRec = (BASIC_S3_RESUME_PERF_REC*)((UINT8*)(FpdtVar->S3Pointer) + sizeof(PERF_TAB_HEADER));
+ if ((FpdtVar->NanoFreq !=0) && (S3PerRec->Header.PerfRecType == 0))
+ {
+ NanoTime = Div64 (Mul64 (GetCpuTimer (), (UINTN)FpdtVar->NanoFreq), 1000000 , NULL);
+
+ S3PerRec->AverageResume = Div64 ((Mul64 (S3PerRec->AverageResume, (UINTN)(S3PerRec->ResumeCount)) + NanoTime),
+ (UINTN)(S3PerRec->ResumeCount + 1), NULL);
+ S3PerRec->FullResume = NanoTime;
+ S3PerRec->ResumeCount++;
+
+ }
+ }
+ }
+
+ //If given control to X_Firmware_Waking_Vector. It will not return.
+ // Search each FACS table for a valid vector
+ for (i = 0; i < 3; i++ ) {
+ if (!AcpiVariableSet->AcpiFacsTable[i]) continue;
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Trying FACS table #%d.\n", i + 1));
+ X_Firmware_Waking_Vector = (void(*)())*(VOID**)((UINT8*)AcpiVariableSet->AcpiFacsTable[i] + 24);
+ if (X_Firmware_Waking_Vector)
+ {
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Waking in protected mode.\n"));
+ PEI_PROGRESS_CODE(PeiServices,PEI_S3_OS_WAKE);
+ PEI_TRACE((-1, PeiServices, "Smm S3 Vector %x.\n", X_Firmware_Waking_Vector));
+ if (((UINT32*)AcpiVariableSet->AcpiFacsTable[i] + 36) && 1)
+ {
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Waking in protected mode 64 bit enable.\n"));
+ InitLongModeExt (PeiServices, X_Firmware_Waking_Vector, NULL, NULL, 12);
+ }
+ else
+ X_Firmware_Waking_Vector(); // Will not return
+ }
+
+ Firmware_Waking_Vector = *(UINT32*)((UINT8*)AcpiVariableSet->AcpiFacsTable[i] + 12);
+ if (Firmware_Waking_Vector)
+ {
+ UINT32 RealModeSegOff;
+
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- Waking in real mode.\n"));
+ PEI_TRACE((-1, PeiServices, "Smm S3 Vector %x.\n", Firmware_Waking_Vector));
+ RealModeSegOff = ((Firmware_Waking_Vector & ~0xf) << 12) + (Firmware_Waking_Vector & 0xf);
+
+ //Execute this thunk from ROM.
+ for(i = 0; i < sizeof(gGDT)/sizeof(UINT64); ++i) Gdt[i] = gGDT[i]; //Set GDT for Thunk to 16-bit
+ PEI_PROGRESS_CODE(PeiServices,PEI_S3_OS_WAKE);
+ RealModeThunk(GdtDesc, RealModeSegOff, FALSE); //Will not return.
+ }
+ }
+
+ PEI_TRACE((-1, PeiServices, "Smm S3 Resume -- No waking vector.\n"));
+ PEI_ERROR_CODE(PeiServices, PEI_S3_OS_WAKE_ERROR, EFI_ERROR_MAJOR);
+
+ return EFI_UNSUPPORTED;
+}
+//<AMI_PHDR_START>
+//----------------------------------------------------------------------------
+// Procedure: S3RestoreConfig2
+//
+// Description: Restore configuration state from S3 resume.
+//
+// Input: EFI_PEI_S3_RESUME2_PPI *This
+//
+// Output: EFI_STATUS
+//
+//----------------------------------------------------------------------------
+//<AMI_PHDR_END>
+EFI_STATUS S3RestoreConfig2(
+ IN EFI_PEI_S3_RESUME2_PPI *This
+)
+{
+ EFI_PEI_SERVICES **PeiServices;
+
+ if (This != &S3ResumePpi2) return EFI_INVALID_PARAMETER;
+
+ PeiServices = GetPeiServicesTablePointer ();
+
+ return S3RestoreConfig(PeiServices);
+
+}
+
+EFI_STATUS S3ResumeEntryPoint(
+ IN EFI_FFS_FILE_HEADER *FfsHeader,
+ IN EFI_PEI_SERVICES **PeiServices
+ )
+{
+ //Initialize Boot Script Executer module
+ InitBootScriptExecuter(FfsHeader,PeiServices);
+ return (*PeiServices)->InstallPpi(PeiServices,gPpiList);
+}
+
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file
diff --git a/Core/EM/S3/S3Resume.dxs b/Core/EM/S3/S3Resume.dxs
new file mode 100644
index 0000000..194ac48
--- /dev/null
+++ b/Core/EM/S3/S3Resume.dxs
@@ -0,0 +1,85 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Resume.dxs 2 7/19/11 11:33a Oleksiyy $
+//
+// $Revision: 2 $
+//
+// $Date: 7/19/11 11:33a $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Restore/S3Resume.dxs $
+//
+// 2 7/19/11 11:33a Oleksiyy
+// [TAG] EIP64108
+// [Category] Improvement
+// [Description] ACPI, convert or update all eModules to be compliant
+// with PI 1.2, and UEFI 2.3.1 specifications.
+// [Files] AcpiCore.c, mptable.c, AcpiS3Save.c, S3Resume.dxs,
+// S3Resume.c, AcpiPeiS3Func.c, BootScriptExecuter.c and DxeIpl.c
+//
+// 1 2/03/11 4:09p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Restore.cif
+// S3Restore.sdl
+// S3Restore.mak
+// S3Resume.dxs
+// AcpiS3Wake.asm
+// S3Resume.c
+// AcpiPeiS3Func.c
+// AcpiPeiS3Func.h
+// BootScriptExecuter.c
+//
+// 3 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/23/07 1:31p Felixp
+// Boot Script related code moved from Core to ACPI module.
+// PEI code added to S3 Resume PPI. DXE code added to AcpiS3Save driver.
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: S3Resume.dxs
+//
+// Description:
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+
+#include <Ppi/ReadOnlyVariable2.h>
+
+DEPENDENCY_START
+ EFI_PEI_READ_ONLY_VARIABLE2_PPI_GUID AND
+ EFI_PEI_PERMANENT_MEMORY_INSTALLED_PPI
+DEPENDENCY_END
+
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
diff --git a/Core/EM/S3/S3Save.cif b/Core/EM/S3/S3Save.cif
new file mode 100644
index 0000000..423bbc2
--- /dev/null
+++ b/Core/EM/S3/S3Save.cif
@@ -0,0 +1,14 @@
+<component>
+ name = "S3Save"
+ category = ModulePart
+ LocalRoot = "Core\EM\S3\"
+ RefName = "S3Save"
+[files]
+"S3Save.sdl"
+"S3Save.mak"
+"AcpiS3Save.c"
+"BootScriptPrivate.h"
+"BootScriptSave.c"
+"AcpiS3Save.dxs"
+"SmmS3Save.dxs"
+<endComponent>
diff --git a/Core/EM/S3/S3Save.mak b/Core/EM/S3/S3Save.mak
new file mode 100644
index 0000000..9bc43e7
--- /dev/null
+++ b/Core/EM/S3/S3Save.mak
@@ -0,0 +1,99 @@
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#**********************************************************************
+
+#**********************************************************************
+# $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/S3Save.mak 2 3/18/11 3:56p Oleksiyy $
+#
+# $Revision: 2 $
+#
+# $Date: 3/18/11 3:56p $
+#**********************************************************************
+# Revision History
+# ----------------
+# $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/S3Save.mak $
+#
+# 2 3/18/11 3:56p Oleksiyy
+# [TAG] EIP53402
+# [Category] Improvement
+# [Description] Improving backward computability and architecture.
+# [Files] ACPI.mak, AcpiCore.cif, S3Save.cif, S3Save.mak,
+# S3Restore.mak, BootScriptExecutor.c, S3Common.cif, S3SaveState.h,
+# S3smmSaveState.h
+#
+# 1 2/03/11 4:08p Oleksiyy
+# [TAG] EIP53402
+# [Category] Improvement
+# [Description] Create new label of ACPI with separate S3 Functionality
+# [Files] S3Save.cif
+# S3Save.sdl
+# S3Save.mak
+# AcpiS3.h
+# AcpiS3Save.c
+# BootScriptPrivate.h
+# BootScriptSave.c
+# AcpiS3Save.dxs
+# SmmS3Save.dxs
+#
+# 6 1/13/10 2:13p Felixp
+#
+#**********************************************************************
+#<AMI_FHDR_START>
+#
+# Name: <ComponentName>.mak
+#
+# Description:
+#
+#<AMI_FHDR_END>
+#**********************************************************************
+all : S3Save
+
+!IFNDEF PI_SPECIFICATION_VERSION
+PI_SPECIFICATION_VERSION = 0
+!ENDIF
+
+S3Save : $(BUILD_DIR)\S3Save.mak S3SaveBin
+
+$(BUILD_DIR)\S3Save.mak : $(S3Save_DIR)\$(@B).cif $(S3Save_DIR)\$(@B).mak $(BUILD_RULES)
+ $(CIF2MAK) $(S3Save_DIR)\$(@B).cif $(CIF2MAK_DEFAULTS)
+
+S3SaveBin : $(AMIDXELIB)
+ $(MAKE) /$(MAKEFLAGS) $(BUILD_DEFAULTS)\
+ /f $(BUILD_DIR)\S3Save.mak all\
+ GUID=26A2481E-4424-46a2-9943-CC4039EAD8F8 \
+ ENTRY_POINT=AcpiS3SaveEntryPoint\
+ "MY_INCLUDES=/I$(ACPI_CORE_DIR)" \
+!IF $(PI_SPECIFICATION_VERSION) >= 0x00001000A
+ TYPE=DXESMM_DRIVER \
+ DEPEX1=$(S3Save_DIR)\SmmS3Save.dxs \
+ DEPEX1_TYPE=EFI_SECTION_SMM_DEPEX \
+ DEPEX2=$(S3Save_DIR)\AcpiS3Save.dxs \
+ DEPEX2_TYPE=EFI_SECTION_DXE_DEPEX \
+!ELSE
+ DEPEX1=$(S3Save_DIR)\AcpiS3Save.dxs \
+ TYPE=BS_DRIVER \
+!ENDIF
+ COMPRESS=1\
+#**********************************************************************
+#**********************************************************************
+#** **
+#** (C)Copyright 1985-2010, American Megatrends, Inc. **
+#** **
+#** All Rights Reserved. **
+#** **
+#** 5555 Oakbrook Parkway, Suite 200, Norcross, GA 30093 **
+#** **
+#** Phone: (770)-246-8600 **
+#** **
+#**********************************************************************
+#********************************************************************** \ No newline at end of file
diff --git a/Core/EM/S3/S3Save.sdl b/Core/EM/S3/S3Save.sdl
new file mode 100644
index 0000000..fc09ec2
--- /dev/null
+++ b/Core/EM/S3/S3Save.sdl
@@ -0,0 +1,25 @@
+TOKEN
+ Name = "S3Save_SUPPORT"
+ Value = "1"
+ Help = "Main switch to enable S3Save Support in Project"
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+End
+
+PATH
+ Name = "S3Save_DIR"
+End
+
+MODULE
+ Help = "Includes S3Save.mak to Project"
+ File = "S3Save.mak"
+End
+
+ELINK
+ Name = "$(BUILD_DIR)\S3Save.ffs"
+ Parent = "FV_MAIN"
+ InvokeOrder = AfterParent
+End
+
diff --git a/Core/EM/S3/S3Support.cif b/Core/EM/S3/S3Support.cif
new file mode 100644
index 0000000..af97bb6
--- /dev/null
+++ b/Core/EM/S3/S3Support.cif
@@ -0,0 +1,12 @@
+<component>
+ name = "S3Support"
+ category = ModulePart
+ LocalRoot = "Core\EM\S3\"
+ RefName = "S3Support"
+[files]
+"S3Support.sdl"
+[parts]
+"S3Save"
+"S3Restore"
+"S3Common"
+<endComponent>
diff --git a/Core/EM/S3/S3Support.sdl b/Core/EM/S3/S3Support.sdl
new file mode 100644
index 0000000..f5a858b
--- /dev/null
+++ b/Core/EM/S3/S3Support.sdl
@@ -0,0 +1,9 @@
+TOKEN
+ Name = S3Support_SUPPORT
+ Value = 1
+ TokenType = Boolean
+ TargetEQU = Yes
+ TargetMAK = Yes
+ Master = Yes
+ Help = "Main switch to enable S3Support support in Project"
+End
diff --git a/Core/EM/S3/SmmS3Save.dxs b/Core/EM/S3/SmmS3Save.dxs
new file mode 100644
index 0000000..abbc621
--- /dev/null
+++ b/Core/EM/S3/SmmS3Save.dxs
@@ -0,0 +1,70 @@
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//**********************************************************************
+
+//**********************************************************************
+// $Header: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/SmmS3Save.dxs 1 2/03/11 4:08p Oleksiyy $
+//
+// $Revision: 1 $
+//
+// $Date: 2/03/11 4:08p $
+//**********************************************************************
+// Revision History
+// ----------------
+// $Log: /Alaska/BIN/Modules/ACPI/Template/S3Support/S3Save/SmmS3Save.dxs $
+//
+// 1 2/03/11 4:08p Oleksiyy
+// [TAG] EIP53402
+// [Category] Improvement
+// [Description] Create new label of ACPI with separate S3 Functionality
+// [Files] S3Save.cif
+// S3Save.sdl
+// S3Save.mak
+// AcpiS3.h
+// AcpiS3Save.c
+// BootScriptPrivate.h
+// BootScriptSave.c
+// AcpiS3Save.dxs
+// SmmS3Save.dxs
+//
+// 3 3/26/09 4:51p Oleksiyy
+// New ACPI Core implementation - improves logic, execution time and
+// memory usage of ACPI module.
+//
+// 2 4/24/07 6:27p Felixp
+//
+//**********************************************************************
+//<AMI_FHDR_START>
+//
+// Name: AcpiS3Save.dxs
+//
+// Description: Dependency expression for the AcpiS3Save component
+//
+//<AMI_FHDR_END>
+//**********************************************************************
+DEPENDENCY_START
+ TRUE
+DEPENDENCY_END
+//**********************************************************************
+//**********************************************************************
+//** **
+//** (C)Copyright 1985-2009, American Megatrends, Inc. **
+//** **
+//** All Rights Reserved. **
+//** **
+//** 5555 Oakbrook Pkwy, Norcross, GA 30093 **
+//** **
+//** Phone: (770)-246-8600 **
+//** **
+//**********************************************************************
+//********************************************************************** \ No newline at end of file