+++ /dev/null
-/** @file\r
- This is an implementation of the AcpiVariable platform field for ECP platform.\r
-\r
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
-\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-==\r
-\r
-typedef struct {\r
- EFI_PHYSICAL_ADDRESS AcpiReservedMemoryBase; <<===\r
- UINT32 AcpiReservedMemorySize; <<===\r
- EFI_PHYSICAL_ADDRESS S3ReservedLowMemoryBase;\r
- EFI_PHYSICAL_ADDRESS AcpiBootScriptTable;\r
- EFI_PHYSICAL_ADDRESS RuntimeScriptTableBase;\r
- EFI_PHYSICAL_ADDRESS AcpiFacsTable;\r
- UINT64 SystemMemoryLength; <<===\r
- ACPI_CPU_DATA_COMPATIBILITY AcpiCpuData;\r
- EFI_PHYSICAL_ADDRESS VideoOpromAddress;\r
- UINT32 VideoOpromSize;\r
- EFI_PHYSICAL_ADDRESS S3DebugBufferAddress;\r
- EFI_PHYSICAL_ADDRESS S3ResumeNvsEntryPoint;\r
-} ACPI_VARIABLE_SET_COMPATIBILITY;\r
-\r
-**/\r
-\r
-#include <FrameworkDxe.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-#include <Library/UefiBootServicesTableLib.h>\r
-#include <Library/UefiRuntimeServicesTableLib.h>\r
-#include <Library/HobLib.h>\r
-#include <Library/PcdLib.h>\r
-#include <Library/DebugLib.h>\r
-#include <Library/UefiLib.h>\r
-#include <Protocol/FrameworkMpService.h>\r
-#include <Protocol/VariableLock.h>\r
-#include <Guid/AcpiVariableCompatibility.h>\r
-\r
-GLOBAL_REMOVE_IF_UNREFERENCED\r
-ACPI_VARIABLE_SET_COMPATIBILITY *mAcpiVariableSetCompatibility = NULL;\r
-\r
-/**\r
- Allocate memory below 4G memory address.\r
-\r
- This function allocates memory below 4G memory address.\r
-\r
- @param MemoryType Memory type of memory to allocate.\r
- @param Size Size of memory to allocate.\r
-\r
- @return Allocated address for output.\r
-\r
-**/\r
-VOID*\r
-AllocateMemoryBelow4G (\r
- IN EFI_MEMORY_TYPE MemoryType,\r
- IN UINTN Size\r
- );\r
-\r
-/**\r
- Hook point for AcpiVariableThunkPlatform for S3Ready.\r
-\r
-**/\r
-VOID\r
-S3ReadyThunkPlatform (\r
- VOID\r
- )\r
-{\r
- EFI_PHYSICAL_ADDRESS AcpiMemoryBase;\r
- UINT32 AcpiMemorySize;\r
- EFI_PEI_HOB_POINTERS Hob;\r
- UINT64 MemoryLength;\r
-\r
- DEBUG ((EFI_D_INFO, "S3ReadyThunkPlatform\n"));\r
-\r
- if (mAcpiVariableSetCompatibility == NULL) {\r
- return;\r
- }\r
-\r
- //\r
- // Allocate ACPI reserved memory under 4G\r
- //\r
- AcpiMemoryBase = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateMemoryBelow4G (EfiReservedMemoryType, PcdGet32 (PcdS3AcpiReservedMemorySize));\r
- ASSERT (AcpiMemoryBase != 0);\r
- AcpiMemorySize = PcdGet32 (PcdS3AcpiReservedMemorySize);\r
-\r
- //\r
- // Calculate the system memory length by memory hobs\r
- //\r
- MemoryLength = 0x100000;\r
- Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);\r
- ASSERT (Hob.Raw != NULL);\r
- while ((Hob.Raw != NULL) && (!END_OF_HOB_LIST (Hob))) {\r
- if (Hob.ResourceDescriptor->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) {\r
- //\r
- // Skip the memory region below 1MB\r
- //\r
- if (Hob.ResourceDescriptor->PhysicalStart >= 0x100000) {\r
- MemoryLength += Hob.ResourceDescriptor->ResourceLength;\r
- }\r
- }\r
- Hob.Raw = GET_NEXT_HOB (Hob);\r
- Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);\r
- }\r
-\r
- mAcpiVariableSetCompatibility->AcpiReservedMemoryBase = AcpiMemoryBase;\r
- mAcpiVariableSetCompatibility->AcpiReservedMemorySize = AcpiMemorySize;\r
- mAcpiVariableSetCompatibility->SystemMemoryLength = MemoryLength;\r
-\r
- DEBUG((EFI_D_INFO, "AcpiVariableThunkPlatform: AcpiMemoryBase is 0x%8x\n", mAcpiVariableSetCompatibility->AcpiReservedMemoryBase));\r
- DEBUG((EFI_D_INFO, "AcpiVariableThunkPlatform: AcpiMemorySize is 0x%8x\n", mAcpiVariableSetCompatibility->AcpiReservedMemorySize));\r
- DEBUG((EFI_D_INFO, "AcpiVariableThunkPlatform: SystemMemoryLength is 0x%8x\n", mAcpiVariableSetCompatibility->SystemMemoryLength));\r
-\r
- return ;\r
-}\r
-\r
-/**\r
- Register callback function upon VariableLockProtocol\r
- to lock ACPI_GLOBAL_VARIABLE variable to avoid malicious code to update it.\r
-\r
- @param[in] Event Event whose notification function is being invoked.\r
- @param[in] Context Pointer to the notification function's context.\r
-**/\r
-VOID\r
-EFIAPI\r
-VariableLockAcpiGlobalVariable (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EDKII_VARIABLE_LOCK_PROTOCOL *VariableLock;\r
- //\r
- // Mark ACPI_GLOBAL_VARIABLE variable to read-only if the Variable Lock protocol exists\r
- //\r
- Status = gBS->LocateProtocol (&gEdkiiVariableLockProtocolGuid, NULL, (VOID **) &VariableLock);\r
- if (!EFI_ERROR (Status)) {\r
- Status = VariableLock->RequestToLock (VariableLock, ACPI_GLOBAL_VARIABLE, &gEfiAcpiVariableCompatiblityGuid);\r
- ASSERT_EFI_ERROR (Status);\r
- }\r
-}\r
-\r
-/**\r
- Hook point for AcpiVariableThunkPlatform for InstallAcpiS3Save.\r
-**/\r
-VOID\r
-InstallAcpiS3SaveThunk (\r
- VOID\r
- )\r
-{\r
- EFI_STATUS Status;\r
- FRAMEWORK_EFI_MP_SERVICES_PROTOCOL *FrameworkMpService;\r
- UINTN VarSize;\r
- VOID *Registration;\r
-\r
- Status = gBS->LocateProtocol (\r
- &gFrameworkEfiMpServiceProtocolGuid,\r
- NULL,\r
- (VOID**) &FrameworkMpService\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // On ECP platform, if framework CPU drivers are in use, The compatible version of ACPI variable set\r
- // should be produced by CPU driver.\r
- //\r
- VarSize = sizeof (mAcpiVariableSetCompatibility);\r
- Status = gRT->GetVariable (\r
- ACPI_GLOBAL_VARIABLE,\r
- &gEfiAcpiVariableCompatiblityGuid,\r
- NULL,\r
- &VarSize,\r
- &mAcpiVariableSetCompatibility\r
- );\r
- if (EFI_ERROR (Status) || (VarSize != sizeof (mAcpiVariableSetCompatibility))) {\r
- DEBUG ((EFI_D_ERROR, "FATAL ERROR: AcpiVariableSetCompatibility was not saved by CPU driver correctly. OS S3 may fail!\n"));\r
- mAcpiVariableSetCompatibility = NULL;\r
- }\r
- } else {\r
- //\r
- // Allocate/initialize the compatible version of Acpi Variable Set since Framework chipset/platform\r
- // driver need this variable. ACPI_GLOBAL_VARIABLE variable is not used in runtime phase,\r
- // so RT attribute is not needed for it.\r
- //\r
- mAcpiVariableSetCompatibility = AllocateMemoryBelow4G (EfiACPIMemoryNVS, sizeof(ACPI_VARIABLE_SET_COMPATIBILITY));\r
- Status = gRT->SetVariable (\r
- ACPI_GLOBAL_VARIABLE,\r
- &gEfiAcpiVariableCompatiblityGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- sizeof(mAcpiVariableSetCompatibility),\r
- &mAcpiVariableSetCompatibility\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- //\r
- // Register callback function upon VariableLockProtocol\r
- // to lock ACPI_GLOBAL_VARIABLE variable to avoid malicious code to update it.\r
- //\r
- EfiCreateProtocolNotifyEvent (\r
- &gEdkiiVariableLockProtocolGuid,\r
- TPL_CALLBACK,\r
- VariableLockAcpiGlobalVariable,\r
- NULL,\r
- &Registration\r
- );\r
- } else {\r
- DEBUG ((EFI_D_ERROR, "FATAL ERROR: AcpiVariableSetCompatibility cannot be saved: %r. OS S3 may fail!\n", Status));\r
- gBS->FreePages (\r
- (EFI_PHYSICAL_ADDRESS) (UINTN) mAcpiVariableSetCompatibility,\r
- EFI_SIZE_TO_PAGES (sizeof (ACPI_VARIABLE_SET_COMPATIBILITY))\r
- );\r
- mAcpiVariableSetCompatibility = NULL;\r
- }\r
- }\r
-\r
- DEBUG((EFI_D_INFO, "AcpiVariableSetCompatibility is 0x%8x\n", mAcpiVariableSetCompatibility));\r
-}\r