summaryrefslogtreecommitdiff
path: root/Core/EM/S3/AcpiS3Save.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/EM/S3/AcpiS3Save.c')
-rw-r--r--Core/EM/S3/AcpiS3Save.c468
1 files changed, 468 insertions, 0 deletions
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 **
+//** **
+//**********************************************************************
+//**********************************************************************