From a7a0f78bd6fa1fe4684bf6de2b3e5ed5d9b5bf1c Mon Sep 17 00:00:00 2001 From: jljusten Date: Mon, 27 Jun 2011 23:32:02 +0000 Subject: EdkCompatibilityPkg: Add AcpiVariableHobOnSmramReserveHobThunk Signed-off-by: jljusten Reviewed-by: mdkinney Reviewed-by: geekboy15a git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11904 6f19259b-4bc3-4df7-8a09-765794883524 --- .../AcpiVariableHobOnSmramReserveHobThunk.c | 249 +++++++++++++++++++++ .../AcpiVariableHobOnSmramReserveHobThunk.inf | 52 +++++ EdkCompatibilityPkg/EdkCompatibilityPkg.dsc | 2 + 3 files changed, 303 insertions(+) create mode 100644 EdkCompatibilityPkg/Compatibility/AcpiVariableHobOnSmramReserveHobThunk/AcpiVariableHobOnSmramReserveHobThunk.c create mode 100644 EdkCompatibilityPkg/Compatibility/AcpiVariableHobOnSmramReserveHobThunk/AcpiVariableHobOnSmramReserveHobThunk.inf (limited to 'EdkCompatibilityPkg') diff --git a/EdkCompatibilityPkg/Compatibility/AcpiVariableHobOnSmramReserveHobThunk/AcpiVariableHobOnSmramReserveHobThunk.c b/EdkCompatibilityPkg/Compatibility/AcpiVariableHobOnSmramReserveHobThunk/AcpiVariableHobOnSmramReserveHobThunk.c new file mode 100644 index 0000000000..05dda263fa --- /dev/null +++ b/EdkCompatibilityPkg/Compatibility/AcpiVariableHobOnSmramReserveHobThunk/AcpiVariableHobOnSmramReserveHobThunk.c @@ -0,0 +1,249 @@ +/** @file + This is the driver that produce AcpiVariable hob and slit SmramReserve hob + for ECP platform. + +Copyright (c) 2010 - 2011, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the BSD License which accompanies this distribution. The +full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include +#include +#include + +#include +#include +#include +#include +#include + +/** + Retrieves the data structure associated witht he GUIDed HOB of type gEfiSmmPeiSmramMemoryReserveGuid + + @retval NULL A HOB of type gEfiSmmPeiSmramMemoryReserveGuid could not be found. + @retval !NULL A pointer to the GUID data from a HIB of type gEfiSmmPeiSmramMemoryReserveGuid + +**/ +EFI_SMRAM_HOB_DESCRIPTOR_BLOCK * +GetSrmamHobData ( + VOID + ) +{ + VOID *GuidHob; + + // + // Search SmramMemoryReserve HOB that describes SMRAM region + // + GuidHob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid); + if (GuidHob == NULL) { + return NULL; + } + return (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)GET_GUID_HOB_DATA (GuidHob); +} + +/** + This routine will split SmramReserve hob to reserve 1 page for SMRAM content in S3 phase + for R9 SMM core. + + @retval EFI_SUCCESS The gEfiSmmPeiSmramMemoryReserveGuid is splited successfully. + @retval EFI_NOT_FOUND The gEfiSmmPeiSmramMemoryReserveGuid is not found. + +**/ +EFI_STATUS +EFIAPI +SplitSmramReserveHob ( + VOID + ) +{ + EFI_HOB_GUID_TYPE *GuidHob; + EFI_PEI_HOB_POINTERS Hob; + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock; + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *NewDescriptorBlock; + UINTN BufferSize; + UINTN SmramRanges; + UINTN Index; + UINTN SubIndex; + + // + // Retrieve the GUID HOB data that contains the set of SMRAM descriptyors + // + GuidHob = GetFirstGuidHob (&gEfiSmmPeiSmramMemoryReserveGuid); + if (GuidHob == NULL) { + return EFI_NOT_FOUND; + } + + DescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)GET_GUID_HOB_DATA (GuidHob); + + // + // Allocate one extra EFI_SMRAM_DESCRIPTOR to describe a page of SMRAM memory that contains a pointer + // to the SMM Services Table that is required on the S3 resume path + // + SmramRanges = DescriptorBlock->NumberOfSmmReservedRegions; + BufferSize = sizeof (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK) + (SmramRanges * sizeof (EFI_SMRAM_DESCRIPTOR)); + + Hob.Raw = BuildGuidHob ( + &gEfiSmmPeiSmramMemoryReserveGuid, + BufferSize + ); + ASSERT (Hob.Raw); + NewDescriptorBlock = (EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *)Hob.Raw; + + // + // Copy old EFI_SMRAM_HOB_DESCRIPTOR_BLOCK to new allocated region + // + CopyMem ((VOID *)Hob.Raw, DescriptorBlock, BufferSize - sizeof(EFI_SMRAM_DESCRIPTOR)); + + // + // Increase the number of SMRAM descriptors by 1 to make room for the ALLOCATED descriptor of size EFI_PAGE_SIZE + // + NewDescriptorBlock->NumberOfSmmReservedRegions = (UINT32)(SmramRanges + 1); + + ASSERT (SmramRanges >= 1); + // + // Copy last entry to the end - we assume TSEG is last entry, which is same assumption as R8 CPU/SMM driver + // + CopyMem (&NewDescriptorBlock->Descriptor[SmramRanges], &NewDescriptorBlock->Descriptor[SmramRanges - 1], sizeof(EFI_SMRAM_DESCRIPTOR)); + + // + // Update the last but 1 entry in the array with a size of EFI_PAGE_SIZE and put into the ALLOCATED state + // + NewDescriptorBlock->Descriptor[SmramRanges - 1].PhysicalSize = EFI_PAGE_SIZE; + NewDescriptorBlock->Descriptor[SmramRanges - 1].RegionState |= EFI_ALLOCATED; + + // + // Reduce the size of the last SMRAM descriptor by EFI_PAGE_SIZE + // + NewDescriptorBlock->Descriptor[SmramRanges].PhysicalStart += EFI_PAGE_SIZE; + NewDescriptorBlock->Descriptor[SmramRanges].CpuStart += EFI_PAGE_SIZE; + NewDescriptorBlock->Descriptor[SmramRanges].PhysicalSize -= EFI_PAGE_SIZE; + + // + // Now, we have created SmramReserve Hob for SmmAccess drive. But the issue is that, R8 SmmAccess will assume there is 2 SmramReserve region only. + // Reporting 3 SmramReserve region will cause buffer overflow. Moreover, we would like to filter AB-SEG or H-SEG to avoid SMM cache-poisoning issue. + // So we uses scan SmmReserve Hob to remove AB-SEG or H-SEG. + // + for (Index = 0; Index <= SmramRanges; Index++) { + if (NewDescriptorBlock->Descriptor[Index].PhysicalSize == 0) { + // + // Skip zero entry + // + continue; + } + if (NewDescriptorBlock->Descriptor[Index].PhysicalStart < BASE_1MB) { + // + // Find AB-SEG or H-SEG + // remove this region + // + for (SubIndex = Index; SubIndex < NewDescriptorBlock->NumberOfSmmReservedRegions - 1; SubIndex++) { + CopyMem (&NewDescriptorBlock->Descriptor[SubIndex], &NewDescriptorBlock->Descriptor[SubIndex + 1], sizeof (EFI_SMRAM_DESCRIPTOR)); + } + // + // Zero last one + // + ZeroMem (&NewDescriptorBlock->Descriptor[SubIndex], sizeof(EFI_SMRAM_DESCRIPTOR)); + // + // Decrease Number + // + NewDescriptorBlock->NumberOfSmmReservedRegions --; + // + // Decrease Index to let it test mew entry + // + Index --; + } + } + + // + // Last step, we can scrub old one + // + ZeroMem (&GuidHob->Name, sizeof(GuidHob->Name)); + + return EFI_SUCCESS; +} + +/** + This routine will create AcpiVariable hob to point the reserved smram in S3 phase + for R9 SMM core. + + @retval EFI_SUCCESS The gEfiAcpiVariableGuid is created successfully. + @retval EFI_NOT_FOUND The gEfiSmmPeiSmramMemoryReserveGuid is not found. + +**/ +EFI_STATUS +EFIAPI +CreateAcpiVariableHob ( + VOID + ) +{ + EFI_PEI_HOB_POINTERS Hob; + EFI_SMRAM_HOB_DESCRIPTOR_BLOCK *DescriptorBlock; + UINTN SmramRanges; + + // + // Retrieve the GUID HOB data that contains the set of SMRAM descriptyors + // + DescriptorBlock = GetSrmamHobData (); + if (DescriptorBlock == NULL) { + return EFI_NOT_FOUND; + } + + Hob.Raw = BuildGuidHob ( + &gEfiAcpiVariableGuid, + sizeof (EFI_SMRAM_DESCRIPTOR) + ); + ASSERT (Hob.Raw); + + // + // It should be already patch, so just copy last but 1 region directly. + // + SmramRanges = DescriptorBlock->NumberOfSmmReservedRegions; + ASSERT (SmramRanges >= 2); + if (SmramRanges >= 2) { + CopyMem ((VOID *)Hob.Raw, &DescriptorBlock->Descriptor[SmramRanges - 2], sizeof (EFI_SMRAM_DESCRIPTOR)); + } + + return EFI_SUCCESS; +} + +/** + Driver Entry for AcpiVariableHobOnSmramReservHob PEIM + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS Success create gEfiAcpiVariableGuid and + split gEfiSmmPeiSmramMemoryReserveGuid. + @retval EFI_NOT_FOUND Can not get gEfiSmmPeiSmramMemoryReserveGuid hob + +**/ +EFI_STATUS +EFIAPI +AcpiVariableHobEntry ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + + // + // Split SmramReserve hob, which is required for R9 SMM Core for S3. + // + Status = SplitSmramReserveHob (); + if (EFI_ERROR (Status)) { + return Status; + } + + // + // Create AcpiVariable hob, which is required for R9 SMM Core for S3. + // + Status = CreateAcpiVariableHob (); + + return Status; +} diff --git a/EdkCompatibilityPkg/Compatibility/AcpiVariableHobOnSmramReserveHobThunk/AcpiVariableHobOnSmramReserveHobThunk.inf b/EdkCompatibilityPkg/Compatibility/AcpiVariableHobOnSmramReserveHobThunk/AcpiVariableHobOnSmramReserveHobThunk.inf new file mode 100644 index 0000000000..447aa77e8c --- /dev/null +++ b/EdkCompatibilityPkg/Compatibility/AcpiVariableHobOnSmramReserveHobThunk/AcpiVariableHobOnSmramReserveHobThunk.inf @@ -0,0 +1,52 @@ +## @file +# Component description file for AcpiVariableHob on SmramReservedHob Thunk driver. +# +# Copyright (c) 2010, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions +# of the BSD License which accompanies this distribution. The +# full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = AcpiVariableHobOnSmramReserveHobThunk + FILE_GUID = 49B7F3E1-6C08-4a5b-911C-E9E397ED4178 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + ENTRY_POINT = AcpiVariableHobEntry + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 +# + +[Sources] + AcpiVariableHobOnSmramReserveHobThunk.c + +[Packages] + MdePkg/MdePkg.dec + IntelFrameworkPkg/IntelFrameworkPkg.dec + IntelFrameworkModulePkg/IntelFrameworkModulePkg.dec + +[LibraryClasses] + PeimEntryPoint + MemoryAllocationLib + DebugLib + HobLib + PeiServicesLib + BaseMemoryLib + +[Guids] + gEfiSmmPeiSmramMemoryReserveGuid # ALWAYS_CONSUMED + gEfiAcpiVariableGuid # ALWAYS_CONSUMED + +[Depex] + gEfiPeiMemoryDiscoveredPpiGuid diff --git a/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc b/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc index ebb26f1c04..cf8243d2b8 100644 --- a/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc +++ b/EdkCompatibilityPkg/EdkCompatibilityPkg.dsc @@ -74,6 +74,7 @@ define GCC_MACRO = -DEFI_SPECIFICATION_VERSION=0x00020000 -DPI_S [LibraryClasses.common.PEIM] MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf + HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf [LibraryClasses.common.DXE_DRIVER,LibraryClasses.common.DXE_RUNTIME_DRIVER] MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf @@ -279,6 +280,7 @@ define GCC_MACRO = -DEFI_SPECIFICATION_VERSION=0x00020000 -DPI_S EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/PeiServicesTablePointerLibMm7/PeiServicesTablePointerLibMm7.inf EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/DxePerformanceLib/DxePerformanceLib.inf # Use IA32/X64 specific AsmReadTsc (). EdkCompatibilityPkg/Foundation/Library/EdkIIGlueLib/Library/PeiPerformanceLib/PeiPerformanceLib.inf # Use IA32/X64 specific AsmReadTsc (). + EdkCompatibilityPkg/Compatibility/AcpiVariableHobOnSmramReserveHobThunk/AcpiVariableHobOnSmramReserveHobThunk.inf EdkCompatibilityPkg/Compatibility/MpServicesOnFrameworkMpServicesThunk/MpServicesOnFrameworkMpServicesThunk.inf EdkCompatibilityPkg/Compatibility/SmmBaseOnSmmBase2Thunk/SmmBaseOnSmmBase2Thunk.inf EdkCompatibilityPkg/Compatibility/SmmBaseHelper/SmmBaseHelper.inf -- cgit v1.2.3