* [PATCH v4 1/5] StandaloneMmPkg: Add StandaloneMmIplPei driver.
@ 2023-06-19 7:46 Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 2/5] " Zhang, Hongbin1
` (3 more replies)
0 siblings, 4 replies; 5+ messages in thread
From: Zhang, Hongbin1 @ 2023-06-19 7:46 UTC (permalink / raw)
To: devel
Cc: Zhang, Hongbin1, Jiewen Yao, Ray Ni, Star Zeng, Jiaxin Wu,
Sami Mujawar, Ard Biesheuvel, Supreeth Venkatesh
Add StandaloneMmIplPei IA32/X64 driver at PEI stage.
FSP will use this driver to load Standalone MM code
to dispatch other Standalone MM drivers.
And this is the 1st patch to implement the entrypoint
to find the correct SMRAM range and dump it
Signed-off-by: Hongbin1 Zhang <hongbin1.zhang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Supreeth Venkatesh <supreeth.venkatesh@arm.com>
---
StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c | 266 ++++++++++++++++++++
StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf | 54 ++++
StandaloneMmPkg/StandaloneMmPkg.dsc | 15 +-
3 files changed, 333 insertions(+), 2 deletions(-)
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
new file mode 100644
index 0000000000..16e7d59d0e
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
@@ -0,0 +1,266 @@
+/** @file
+ SMM IPL that load the SMM Core into SMRAM at PEI stage
+
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <Ppi/SmmAccess.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PeiServicesTablePointerLib.h>
+#include <Library/PeiServicesLib.h>
+#include <Library/HobLib.h>
+#include <Guid/MmCoreData.h>
+
+//
+// MM Core Private Data structure that contains the data shared between
+// the SMM IPL and the Standalone MM Core.
+//
+MM_CORE_PRIVATE_DATA mMmCorePrivateData = {
+ MM_CORE_PRIVATE_DATA_SIGNATURE, // Signature
+ 0, // MmramRangeCount
+ 0, // MmramRanges
+ 0, // MmEntryPoint
+ FALSE, // MmEntryPointRegistered
+ FALSE, // InMm
+ 0, // Mmst
+ 0, // CommunicationBuffer
+ 0, // BufferSize
+ EFI_SUCCESS, // ReturnStatus
+ 0, // MmCoreImageBase
+ 0, // MmCoreImageSize
+ 0, // MmCoreEntryPoint
+ 0, // StandaloneBfvAddress
+};
+
+//
+// Global pointer used to access mMmCorePrivateData from outside and inside SMM
+//
+MM_CORE_PRIVATE_DATA *gMmCorePrivate;
+
+//
+// SMM IPL global variables
+//
+PEI_SMM_ACCESS_PPI *mSmmAccess;
+EFI_SMRAM_DESCRIPTOR *mCurrentSmramRange;
+EFI_PHYSICAL_ADDRESS mSmramCacheBase;
+UINT64 mSmramCacheSize;
+UINTN mSmramRangeCount;
+
+/**
+ Find the maximum SMRAM cache range that covers the range specified by SmramRange.
+
+ This function searches and joins all adjacent ranges of SmramRange into a range to be cached.
+
+ @param SmramRange The SMRAM range to search from.
+ @param SmramCacheBase The returned cache range base.
+ @param SmramCacheSize The returned cache range size.
+**/
+VOID
+GetSmramCacheRange (
+ IN EFI_SMRAM_DESCRIPTOR *SmramRange,
+ OUT EFI_PHYSICAL_ADDRESS *SmramCacheBase,
+ OUT UINT64 *SmramCacheSize
+ )
+{
+ UINTN Index;
+ EFI_PHYSICAL_ADDRESS RangeCpuStart;
+ UINT64 RangePhysicalSize;
+ BOOLEAN FoundAdjacentRange;
+ EFI_SMRAM_DESCRIPTOR *SmramRanges;
+
+ *SmramCacheBase = SmramRange->CpuStart;
+ *SmramCacheSize = SmramRange->PhysicalSize;
+
+ SmramRanges = (EFI_SMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->MmramRanges;
+ do {
+ FoundAdjacentRange = FALSE;
+ for (Index = 0; Index < gMmCorePrivate->MmramRangeCount; Index++) {
+ RangeCpuStart = SmramRanges[Index].CpuStart;
+ RangePhysicalSize = SmramRanges[Index].PhysicalSize;
+ if ((RangeCpuStart < *SmramCacheBase) && (*SmramCacheBase == (RangeCpuStart + RangePhysicalSize))) {
+ *SmramCacheBase = RangeCpuStart;
+ *SmramCacheSize += RangePhysicalSize;
+ FoundAdjacentRange = TRUE;
+ } else if (((*SmramCacheBase + *SmramCacheSize) == RangeCpuStart) && (RangePhysicalSize > 0)) {
+ *SmramCacheSize += RangePhysicalSize;
+ FoundAdjacentRange = TRUE;
+ }
+ }
+ } while (FoundAdjacentRange);
+}
+
+/**
+ Get full SMRAM ranges.
+
+ It will get SMRAM ranges from SmmAccess PPI. It will also reserve one entry
+ for SMM core.
+
+ @param[in] PeiServices Describes the list of possible PEI Services.
+ @param[out] FullSmramRangeCount Output pointer to full SMRAM range count.
+
+ @return Pointer to full SMRAM ranges.
+
+**/
+EFI_SMRAM_DESCRIPTOR *
+GetFullSmramRanges (
+ IN CONST EFI_PEI_SERVICES **PeiServices,
+ OUT UINTN *FullSmramRangeCount
+ )
+{
+ EFI_STATUS Status;
+ UINTN Size;
+ EFI_SMRAM_DESCRIPTOR *FullSmramRanges;
+ UINTN AdditionSmramRangeCount;
+
+ //
+ // Get SMRAM information.
+ //
+ Size = 0;
+ Status = mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, &Size, NULL);
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);
+
+ mSmramRangeCount = Size / sizeof (EFI_SMRAM_DESCRIPTOR);
+
+ //
+ // Reserve one entry SMM Core in the full SMRAM ranges.
+ //
+ AdditionSmramRangeCount = 1;
+
+ *FullSmramRangeCount = mSmramRangeCount + AdditionSmramRangeCount;
+ Size = (*FullSmramRangeCount) * sizeof (EFI_SMRAM_DESCRIPTOR);
+ FullSmramRanges = (EFI_SMRAM_DESCRIPTOR *)AllocateZeroPool (Size);
+ ASSERT (FullSmramRanges != NULL);
+ if (FullSmramRanges == NULL) {
+ return NULL;
+ }
+
+ Status = mSmmAccess->GetCapabilities ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, &Size, FullSmramRanges);
+
+ ASSERT_EFI_ERROR (Status);
+
+ return FullSmramRanges;
+}
+
+/**
+ The Entry Point for SMM IPL at PEI stage
+
+ Load SMM Core into SMRAM.
+
+ @param FileHandle Handle of the file being invoked.
+ @param PeiServices Describes the list of possible PEI Services.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval Other Some error occurred when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+StandaloneMmIplPeiEntry (
+ IN EFI_PEI_FILE_HANDLE FileHandle,
+ IN CONST EFI_PEI_SERVICES **PeiServices
+ )
+{
+ EFI_STATUS Status;
+ UINTN Index;
+ UINT64 MaxSize;
+ MM_CORE_DATA_HOB_DATA SmmCoreDataHobData;
+ EFI_SMRAM_DESCRIPTOR *MmramRanges;
+
+ //
+ // Build Hob for SMM and DXE phase
+ //
+ SmmCoreDataHobData.Address = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateRuntimePages (EFI_SIZE_TO_PAGES (sizeof (mMmCorePrivateData)));
+ ASSERT (SmmCoreDataHobData.Address != 0);
+ gMmCorePrivate = (VOID *)(UINTN)SmmCoreDataHobData.Address;
+ CopyMem ((VOID *)(UINTN)SmmCoreDataHobData.Address, &mMmCorePrivateData, sizeof (mMmCorePrivateData));
+ DEBUG ((DEBUG_INFO, "gMmCorePrivate - 0x%x\n", gMmCorePrivate));
+
+ BuildGuidDataHob (
+ &gMmCoreDataHobGuid,
+ (VOID *)&SmmCoreDataHobData,
+ sizeof (SmmCoreDataHobData)
+ );
+
+ //
+ // Get SMM Access PPI
+ //
+ Status = PeiServicesLocatePpi (&gPeiSmmAccessPpiGuid, 0, NULL, (VOID **)&mSmmAccess);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Get SMRAM information
+ //
+ gMmCorePrivate->MmramRanges = (EFI_PHYSICAL_ADDRESS)(UINTN)GetFullSmramRanges (PeiServices, (UINTN *)&gMmCorePrivate->MmramRangeCount);
+ ASSERT (gMmCorePrivate->MmramRanges != 0);
+ if (gMmCorePrivate->MmramRanges == 0) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Open all SMRAM ranges
+ //
+ for (Index = 0; Index < mSmramRangeCount; Index++) {
+ Status = mSmmAccess->Open ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index);
+ ASSERT_EFI_ERROR (Status);
+ }
+
+ //
+ // Print debug message that the SMRAM window is now open.
+ //
+ DEBUG ((DEBUG_INFO, "SMM IPL opened SMRAM window\n"));
+
+ //
+ // Find the largest SMRAM range between 1MB and 4GB that is at least 256KB - 4K in size
+ //
+ mCurrentSmramRange = NULL;
+ MmramRanges = (EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->MmramRanges;
+ if (MmramRanges == NULL) {
+ DEBUG ((DEBUG_ERROR, "Fail to retrieve MmramRanges\n"));
+ return EFI_UNSUPPORTED;
+ }
+
+ for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < gMmCorePrivate->MmramRangeCount; Index++) {
+ //
+ // Skip any SMRAM region that is already allocated, needs testing, or needs ECC initialization
+ //
+ if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) {
+ continue;
+ }
+
+ if (MmramRanges[Index].CpuStart >= BASE_1MB) {
+ if ((MmramRanges[Index].CpuStart + MmramRanges[Index].PhysicalSize) <= BASE_4GB) {
+ if (MmramRanges[Index].PhysicalSize >= MaxSize) {
+ MaxSize = MmramRanges[Index].PhysicalSize;
+ mCurrentSmramRange = &MmramRanges[Index];
+ }
+ }
+ }
+ }
+
+ if (mCurrentSmramRange != NULL) {
+ //
+ // Print debug message showing SMRAM window that will be used by SMM IPL and SMM Core
+ //
+ DEBUG ((
+ DEBUG_INFO,
+ "SMM IPL found SMRAM window %p - %p\n",
+ (VOID *)(UINTN)mCurrentSmramRange->CpuStart,
+ (VOID *)(UINTN)(mCurrentSmramRange->CpuStart + mCurrentSmramRange->PhysicalSize - 1)
+ ));
+
+ GetSmramCacheRange (mCurrentSmramRange, &mSmramCacheBase, &mSmramCacheSize);
+ } else {
+ //
+ // Print error message that there are not enough SMRAM resources to load the SMM Core.
+ //
+ DEBUG ((DEBUG_ERROR, "SMM IPL could not find a large enough SMRAM region to load SMM Core\n"));
+ }
+
+ return EFI_SUCCESS;
+}
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
new file mode 100644
index 0000000000..372c59c1fa
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
@@ -0,0 +1,54 @@
+## @file
+# This module provide a Standalone SMM compliant implementation of SMM IPL PEIM.
+#
+# Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = StandaloneMmIplPei
+ FILE_GUID = 578A0D17-2DC0-4C7D-A121-D8D771923BB0
+ MODULE_TYPE = PEIM
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x0001000A
+ ENTRY_POINT = StandaloneMmIplPeiEntry
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64
+#
+
+[Sources]
+ StandaloneMmIplPei.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+ PeimEntryPoint
+ PeiServicesTablePointerLib
+ PeiServicesLib
+ BaseLib
+ BaseMemoryLib
+ MemoryAllocationLib
+ DebugLib
+ HobLib
+ IntrinsicLib
+
+[Guids]
+ gMmCoreDataHobGuid
+
+[Ppis]
+ gPeiSmmAccessPpiGuid ## CONSUMES
+
+[Pcd]
+
+[Depex]
+ gPeiSmmAccessPpiGuid
+
diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc
index 8012f93b7d..d88471fe82 100644
--- a/StandaloneMmPkg/StandaloneMmPkg.dsc
+++ b/StandaloneMmPkg/StandaloneMmPkg.dsc
@@ -20,7 +20,7 @@
PLATFORM_VERSION = 1.0
DSC_SPECIFICATION = 0x00010011
OUTPUT_DIRECTORY = Build/StandaloneMm
- SUPPORTED_ARCHITECTURES = AARCH64|X64|ARM
+ SUPPORTED_ARCHITECTURES = AARCH64|X64|ARM|IA32
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
@@ -60,6 +60,14 @@
StandaloneMmDriverEntryPoint|MdePkg/Library/StandaloneMmDriverEntryPoint/StandaloneMmDriverEntryPoint.inf
VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf
+[LibraryClasses.common.PEIM]
+ HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
+ PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
+ MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
+ PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
+ PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
+ IntrinsicLib|CryptoPkg/Library/IntrinsicLib/IntrinsicLib.inf
+
[LibraryClasses.AARCH64, LibraryClasses.ARM]
ArmLib|ArmPkg/Library/ArmLib/ArmBaseLib.inf
StandaloneMmMmuLib|ArmPkg/Library/StandaloneMmMmuLib/ArmMmuStandaloneMmLib.inf
@@ -104,7 +112,7 @@
# generated for it, but the binary will not be put into any firmware volume.
#
###################################################################################################
-[Components.common]
+[Components.AARCH64, Components.ARM, Components.X64]
#
# MM Core
#
@@ -122,6 +130,9 @@
StandaloneMmPkg/Drivers/StandaloneMmCpu/StandaloneMmCpu.inf
StandaloneMmPkg/Library/StandaloneMmPeCoffExtraActionLib/StandaloneMmPeCoffExtraActionLib.inf
+[Components.X64, Components.IA32]
+ StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
+
###################################################################################################
#
# BuildOptions Section - Define the module specific tool chain flags that should be used as
--
2.37.0.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 2/5] StandaloneMmPkg: Add StandaloneMmIplPei driver.
2023-06-19 7:46 [PATCH v4 1/5] StandaloneMmPkg: Add StandaloneMmIplPei driver Zhang, Hongbin1
@ 2023-06-19 7:46 ` Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 3/5] " Zhang, Hongbin1
` (2 subsequent siblings)
3 siblings, 0 replies; 5+ messages in thread
From: Zhang, Hongbin1 @ 2023-06-19 7:46 UTC (permalink / raw)
To: devel
Cc: Zhang, Hongbin1, Jiewen Yao, Ray Ni, Star Zeng, Jiaxin Wu,
Sami Mujawar, Ard Biesheuvel, Supreeth Venkatesh
Add StandaloneMmIplPei IA32/X64 driver at PEI stage.
FSP will use this driver to load Standalone MM code
to dispatch other Standalone MM drivers.
Signed-off-by: Hongbin1 Zhang <hongbin1.zhang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Supreeth Venkatesh <supreeth.venkatesh@arm.com>
---
StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c | 343 ++++++++++++++++++++
StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf | 2 +
2 files changed, 345 insertions(+)
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
index 16e7d59d0e..e043fcdb65 100644
--- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
@@ -7,9 +7,13 @@
**/
#include <PiPei.h>
+#include <PiSmm.h>
+#include <StandaloneMm.h>
#include <Ppi/SmmAccess.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
+#include <Library/PeCoffLib.h>
+#include <Library/CacheMaintenanceLib.h>
#include <Library/MemoryAllocationLib.h>
#include <Library/DebugLib.h>
#include <Library/PeiServicesTablePointerLib.h>
@@ -95,6 +99,329 @@ GetSmramCacheRange (
} while (FoundAdjacentRange);
}
+/**
+ Load SMM core to dispatch other Standalone MM drivers.
+
+ @param Entry Entry of Standalone MM Foundation.
+ @param Context1 A pointer to the context to pass into the EntryPoint
+ function.
+ @retval EFI_SUCCESS Successfully loaded SMM core.
+ @retval Others Failed to load SMM core.
+**/
+EFI_STATUS
+LoadSmmCore (
+ IN EFI_PHYSICAL_ADDRESS Entry,
+ IN VOID *Context1
+ )
+{
+ STANDALONE_MM_FOUNDATION_ENTRY_POINT EntryPoint;
+
+ EntryPoint = (STANDALONE_MM_FOUNDATION_ENTRY_POINT)(UINTN)Entry;
+ return EntryPoint (Context1);
+}
+
+/**
+ Get the fixed loading address from image header assigned by build tool. This function only be called
+ when Loading module at Fixed address feature enabled.
+
+ @param ImageContext Pointer to the image context structure that describes the PE/COFF
+ image that needs to be examined by this function.
+ @retval EFI_SUCCESS An fixed loading address is assigned to this image by build tools .
+ @retval EFI_NOT_FOUND The image has no assigned fixed loading address.
+**/
+EFI_STATUS
+GetPeCoffImageFixLoadingAssignedAddress (
+ IN OUT PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
+ )
+{
+ UINTN SectionHeaderOffset;
+ EFI_STATUS Status;
+ EFI_IMAGE_SECTION_HEADER SectionHeader;
+ EFI_IMAGE_OPTIONAL_HEADER_UNION *ImgHdr;
+ EFI_PHYSICAL_ADDRESS FixLoadingAddress;
+ UINT16 Index;
+ UINTN Size;
+ UINT16 NumberOfSections;
+ EFI_PHYSICAL_ADDRESS SmramBase;
+ UINT64 ValueInSectionHeader;
+
+ FixLoadingAddress = 0;
+ Status = EFI_NOT_FOUND;
+ SmramBase = mCurrentSmramRange->CpuStart;
+ //
+ // Get PeHeader pointer
+ //
+ ImgHdr = (EFI_IMAGE_OPTIONAL_HEADER_UNION *)((CHAR8 *)ImageContext->Handle + ImageContext->PeCoffHeaderOffset);
+ SectionHeaderOffset = (UINTN)(
+ ImageContext->PeCoffHeaderOffset +
+ sizeof (UINT32) +
+ sizeof (EFI_IMAGE_FILE_HEADER) +
+ ImgHdr->Pe32.FileHeader.SizeOfOptionalHeader
+ );
+ NumberOfSections = ImgHdr->Pe32.FileHeader.NumberOfSections;
+
+ //
+ // Get base address from the first section header that doesn't point to code section.
+ //
+ for (Index = 0; Index < NumberOfSections; Index++) {
+ //
+ // Read section header from file
+ //
+ Size = sizeof (EFI_IMAGE_SECTION_HEADER);
+ Status = ImageContext->ImageRead (
+ ImageContext->Handle,
+ SectionHeaderOffset,
+ &Size,
+ &SectionHeader
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ Status = EFI_NOT_FOUND;
+
+ if ((SectionHeader.Characteristics & EFI_IMAGE_SCN_CNT_CODE) == 0) {
+ //
+ // Build tool saves the offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields in the
+ // first section header that doesn't point to code section in image header. And there is an assumption that when the
+ // feature is enabled, if a module is assigned a loading address by tools, PointerToRelocations & PointerToLineNumbers
+ // fields should NOT be Zero, or else, these 2 fields should be set to Zero
+ //
+ ValueInSectionHeader = ReadUnaligned64 ((UINT64 *)&SectionHeader.PointerToRelocations);
+ if (ValueInSectionHeader != 0) {
+ //
+ // Found first section header that doesn't point to code section in which build tool saves the
+ // offset to SMRAM base as image base in PointerToRelocations & PointerToLineNumbers fields
+ //
+ FixLoadingAddress = (EFI_PHYSICAL_ADDRESS)(SmramBase + (INT64)ValueInSectionHeader);
+
+ if ((SmramBase > FixLoadingAddress) && (SmramBase <= FixLoadingAddress)) {
+ //
+ // The assigned address is valid. Return the specified loading address
+ //
+ ImageContext->ImageAddress = FixLoadingAddress;
+ Status = EFI_SUCCESS;
+ }
+ }
+
+ break;
+ }
+
+ SectionHeaderOffset += sizeof (EFI_IMAGE_SECTION_HEADER);
+ }
+
+ DEBUG ((DEBUG_INFO|DEBUG_LOAD, "LOADING MODULE FIXED INFO: Loading module at fixed address %x, Status = %r \n", FixLoadingAddress, Status));
+ return Status;
+}
+
+/**
+ Search all the available firmware volumes for SMM Core driver
+
+ @param MmFvBaseAddress Base address of FV which included SMM Core driver.
+ @param MmCoreImageAddress Image address of SMM Core driver.
+
+ @retval EFI_SUCCESS The specified FFS section was returned.
+ @retval EFI_NOT_FOUND The specified FFS section could not be found.
+
+**/
+EFI_STATUS
+LocateMmFvForMmCore (
+ OUT EFI_PHYSICAL_ADDRESS *MmFvBaseAddress,
+ OUT VOID **MmCoreImageAddress
+ )
+{
+ EFI_STATUS Status;
+ UINTN FvIndex;
+ EFI_PEI_FV_HANDLE VolumeHandle;
+ EFI_PEI_FILE_HANDLE FileHandle;
+ EFI_PE32_SECTION *SectionData;
+ EFI_FV_INFO VolumeInfo;
+
+ //
+ // Search all FV
+ //
+ VolumeHandle = NULL;
+ for (FvIndex = 0; ; FvIndex++) {
+ Status = PeiServicesFfsFindNextVolume (FvIndex, &VolumeHandle);
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+
+ //
+ // Search PEIM FFS
+ //
+ FileHandle = NULL;
+ Status = PeiServicesFfsFindNextFile (EFI_FV_FILETYPE_MM_CORE_STANDALONE, VolumeHandle, &FileHandle);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Search Section
+ //
+ Status = PeiServicesFfsFindSectionData (EFI_SECTION_PE32, FileHandle, MmCoreImageAddress);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Great!
+ //
+ SectionData = (EFI_PE32_SECTION *)((UINT8 *)*MmCoreImageAddress - sizeof (EFI_PE32_SECTION));
+ ASSERT (SectionData->Type == EFI_SECTION_PE32);
+
+ //
+ // This is SMM BFV
+ //
+ Status = PeiServicesFfsGetVolumeInfo (VolumeHandle, &VolumeInfo);
+ if (!EFI_ERROR (Status)) {
+ *MmFvBaseAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)VolumeInfo.FvStart;
+ }
+
+ return EFI_SUCCESS;
+ }
+
+ return EFI_NOT_FOUND;
+}
+
+/**
+ Load the SMM Core image into SMRAM and executes the SMM Core from SMRAM.
+
+ @param[in, out] SmramRange Descriptor for the range of SMRAM to reload the
+ currently executing image, the rang of SMRAM to
+ hold SMM Core will be excluded.
+ @param[in, out] SmramRangeSmmCore Descriptor for the range of SMRAM to hold SMM Core.
+
+ @param[in] Context Context to pass into SMM Core
+
+ @return EFI_STATUS
+
+**/
+EFI_STATUS
+ExecuteSmmCoreFromSmram (
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramRange,
+ IN OUT EFI_SMRAM_DESCRIPTOR *SmramRangeSmmCore,
+ IN VOID *Context
+ )
+{
+ EFI_STATUS Status;
+ VOID *SourceBuffer;
+ PE_COFF_LOADER_IMAGE_CONTEXT ImageContext;
+ UINTN PageCount;
+ VOID *HobList;
+ EFI_PHYSICAL_ADDRESS SourceFvBaseAddress;
+
+ Status = PeiServicesGetHobList (&HobList);
+ ASSERT_EFI_ERROR (Status);
+
+ //
+ // Search all Firmware Volumes for a PE/COFF image in a file of type SMM_CORE
+ //
+ Status = LocateMmFvForMmCore (&SourceFvBaseAddress, &SourceBuffer);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ gMmCorePrivate->StandaloneBfvAddress = SourceFvBaseAddress;
+
+ //
+ // Initialize ImageContext
+ //
+ ImageContext.Handle = SourceBuffer;
+ ImageContext.ImageRead = PeCoffLoaderImageReadFromMemory;
+
+ //
+ // Get information about the image being loaded
+ //
+ Status = PeCoffLoaderGetImageInfo (&ImageContext);
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Allocate memory for the image being loaded from the EFI_SRAM_DESCRIPTOR
+ // specified by SmramRange
+ //
+ PageCount = (UINTN)EFI_SIZE_TO_PAGES ((UINTN)ImageContext.ImageSize + ImageContext.SectionAlignment);
+
+ ASSERT ((SmramRange->PhysicalSize & EFI_PAGE_MASK) == 0);
+ ASSERT (SmramRange->PhysicalSize > EFI_PAGES_TO_SIZE (PageCount));
+
+ SmramRange->PhysicalSize -= EFI_PAGES_TO_SIZE (PageCount);
+ SmramRangeSmmCore->CpuStart = SmramRange->CpuStart + SmramRange->PhysicalSize;
+ SmramRangeSmmCore->PhysicalStart = SmramRange->PhysicalStart + SmramRange->PhysicalSize;
+ SmramRangeSmmCore->RegionState = SmramRange->RegionState | EFI_ALLOCATED;
+ SmramRangeSmmCore->PhysicalSize = EFI_PAGES_TO_SIZE (PageCount);
+
+ //
+ // Align buffer on section boundary
+ //
+ ImageContext.ImageAddress = SmramRangeSmmCore->CpuStart;
+
+ ImageContext.ImageAddress += ImageContext.SectionAlignment - 1;
+ ImageContext.ImageAddress &= ~((EFI_PHYSICAL_ADDRESS)ImageContext.SectionAlignment - 1);
+
+ //
+ // Print debug message showing SMM Core load address.
+ //
+ DEBUG ((DEBUG_INFO, "SMM IPL loading SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.ImageAddress));
+
+ //
+ // Load the image to our new buffer
+ //
+ Status = PeCoffLoaderLoadImage (&ImageContext);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Relocate the image in our new buffer
+ //
+ Status = PeCoffLoaderRelocateImage (&ImageContext);
+ if (!EFI_ERROR (Status)) {
+ //
+ // Flush the instruction cache so the image data are written before we execute it
+ //
+ InvalidateInstructionCacheRange ((VOID *)(UINTN)ImageContext.ImageAddress, (UINTN)ImageContext.ImageSize);
+
+ //
+ // Print debug message showing SMM Core entry point address.
+ //
+ DEBUG ((DEBUG_INFO, "SMM IPL calling SMM Core at SMRAM address %p\n", (VOID *)(UINTN)ImageContext.EntryPoint));
+
+ gMmCorePrivate->MmCoreImageBase = ImageContext.ImageAddress;
+ gMmCorePrivate->MmCoreImageSize = ImageContext.ImageSize;
+ DEBUG ((DEBUG_INFO, "SmmCoreImageBase - 0x%016lx\n", gMmCorePrivate->MmCoreImageBase));
+ DEBUG ((DEBUG_INFO, "SmmCoreImageSize - 0x%016lx\n", gMmCorePrivate->MmCoreImageSize));
+
+ gMmCorePrivate->MmCoreEntryPoint = ImageContext.EntryPoint;
+
+ //
+ // Print debug message showing Standalone MM Core entry point address.
+ //
+ DEBUG ((DEBUG_INFO, "SMM IPL calling Standalone MM Core at SMRAM address - 0x%016lx\n", gMmCorePrivate->MmCoreEntryPoint));
+
+ //
+ // Execute image
+ //
+ LoadSmmCore (ImageContext.EntryPoint, HobList);
+ }
+ }
+
+ //
+ // If the load operation, relocate operation, or the image execution return an
+ // error, then free memory allocated from the EFI_SRAM_DESCRIPTOR specified by
+ // SmramRange
+ //
+ if (EFI_ERROR (Status)) {
+ SmramRange->PhysicalSize += EFI_PAGES_TO_SIZE (PageCount);
+ }
+
+ //
+ // Always free memory allocated by GetFileBufferByFilePath ()
+ //
+ FreePool (SourceBuffer);
+
+ return Status;
+}
+
/**
Get full SMRAM ranges.
@@ -255,6 +582,22 @@ StandaloneMmIplPeiEntry (
));
GetSmramCacheRange (mCurrentSmramRange, &mSmramCacheBase, &mSmramCacheSize);
+
+ //
+ // Load SMM Core into SMRAM and execute it from SMRAM
+ // Note: SmramRanges specific for SMM Core will put in the gMmCorePrivate->MmramRangeCount - 1.
+ //
+ Status = ExecuteSmmCoreFromSmram (
+ mCurrentSmramRange,
+ &(((EFI_MMRAM_DESCRIPTOR *)(UINTN)gMmCorePrivate->MmramRanges)[gMmCorePrivate->MmramRangeCount - 1]),
+ gMmCorePrivate
+ );
+ if (EFI_ERROR (Status)) {
+ //
+ // Print error message that the SMM Core failed to be loaded and executed.
+ //
+ DEBUG ((DEBUG_ERROR, "SMM IPL could not load and execute SMM Core from SMRAM\n"));
+ }
} else {
//
// Print error message that there are not enough SMRAM resources to load the SMM Core.
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
index 372c59c1fa..668d3afbf4 100644
--- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
@@ -36,6 +36,8 @@
PeiServicesLib
BaseLib
BaseMemoryLib
+ PeCoffLib
+ CacheMaintenanceLib
MemoryAllocationLib
DebugLib
HobLib
--
2.37.0.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 3/5] StandaloneMmPkg: Add StandaloneMmIplPei driver.
2023-06-19 7:46 [PATCH v4 1/5] StandaloneMmPkg: Add StandaloneMmIplPei driver Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 2/5] " Zhang, Hongbin1
@ 2023-06-19 7:46 ` Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 4/5] " Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 5/5] " Zhang, Hongbin1
3 siblings, 0 replies; 5+ messages in thread
From: Zhang, Hongbin1 @ 2023-06-19 7:46 UTC (permalink / raw)
To: devel
Cc: Zhang, Hongbin1, Jiewen Yao, Ray Ni, Star Zeng, Jiaxin Wu,
Sami Mujawar, Ard Biesheuvel, Supreeth Venkatesh
Add StandaloneMmIplPei IA32/X64 driver at PEI stage.
FSP will use this driver to load Standalone MM code
to dispatch other Standalone MM drivers.
Signed-off-by: Hongbin1 Zhang <hongbin1.zhang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Supreeth Venkatesh <supreeth.venkatesh@arm.com>
---
StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c | 456 ++++++++++++++++++++
StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c | 18 +-
StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c | 29 ++
StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm | 148 +++++++
StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h | 47 ++
StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf | 11 +
StandaloneMmPkg/StandaloneMmPkg.ci.yaml | 4 +-
7 files changed, 709 insertions(+), 4 deletions(-)
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c
new file mode 100644
index 0000000000..2d43807a88
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/LoadSmmCore.c
@@ -0,0 +1,456 @@
+/** @file
+ SMM IPL that load the SMM Core into SMRAM
+
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <PiSmm.h>
+#include <StandaloneMm.h>
+#include <Library/HobLib.h>
+#include <Library/DebugLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <StandaloneMmIplPei.h>
+
+#pragma pack(1)
+
+//
+// Page-Map Level-4 Offset (PML4) and
+// Page-Directory-Pointer Offset (PDPE) entries 4K & 2MB
+//
+
+typedef union {
+ struct {
+ UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory
+ UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching
+ UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)
+ UINT64 Reserved : 1; // Reserved
+ UINT64 MustBeZero : 2; // Must Be Zero
+ UINT64 Available : 3; // Available for use by system software
+ UINT64 PageTableBaseAddress : 40; // Page Table Base Address
+ UINT64 AvailableHigh : 11; // Available for use by system software
+ UINT64 Nx : 1; // No Execute bit
+ } Bits;
+ UINT64 Uint64;
+} PAGE_MAP_AND_DIRECTORY_POINTER;
+
+//
+// Page Table Entry 2MB
+//
+typedef union {
+ struct {
+ UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory
+ UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching
+ UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)
+ UINT64 Dirty : 1; // 0 = Not Dirty, 1 = written by processor on access to page
+ UINT64 MustBe1 : 1; // Must be 1
+ UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
+ UINT64 Available : 3; // Available for use by system software
+ UINT64 Pat : 1; //
+ UINT64 MustBeZero : 8; // Must be zero
+ UINT64 PageTableBaseAddress : 31; // Page Table Base Address
+ UINT64 AvailableHigh : 11; // Available for use by system software
+ UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution
+ } Bits;
+ UINT64 Uint64;
+} PAGE_TABLE_ENTRY;
+
+//
+// Page Table Entry 1GB
+//
+typedef union {
+ struct {
+ UINT64 Present : 1; // 0 = Not present in memory, 1 = Present in memory
+ UINT64 ReadWrite : 1; // 0 = Read-Only, 1= Read/Write
+ UINT64 UserSupervisor : 1; // 0 = Supervisor, 1=User
+ UINT64 WriteThrough : 1; // 0 = Write-Back caching, 1=Write-Through caching
+ UINT64 CacheDisabled : 1; // 0 = Cached, 1=Non-Cached
+ UINT64 Accessed : 1; // 0 = Not accessed, 1 = Accessed (set by CPU)
+ UINT64 Dirty : 1; // 0 = Not Dirty, 1 = written by processor on access to page
+ UINT64 MustBe1 : 1; // Must be 1
+ UINT64 Global : 1; // 0 = Not global page, 1 = global page TLB not cleared on CR3 write
+ UINT64 Available : 3; // Available for use by system software
+ UINT64 Pat : 1; //
+ UINT64 MustBeZero : 17; // Must be zero;
+ UINT64 PageTableBaseAddress : 22; // Page Table Base Address
+ UINT64 AvailableHigh : 11; // Available for use by system software
+ UINT64 Nx : 1; // 0 = Execute Code, 1 = No Code Execution
+ } Bits;
+ UINT64 Uint64;
+} PAGE_TABLE_1G_ENTRY;
+
+#pragma pack()
+
+//
+// Global Descriptor Table (GDT)
+//
+GLOBAL_REMOVE_IF_UNREFERENCED IA32_SEGMENT_DESCRIPTOR mGdtEntries[] = {
+ /* selector { Global Segment Descriptor } */
+ /* 0x00 */ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ }, // null descriptor
+ /* 0x08 */ {
+ { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
+ }, // linear data segment descriptor
+ /* 0x10 */ {
+ { 0xffff, 0, 0, 0xf, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
+ }, // linear code segment descriptor
+ /* 0x18 */ {
+ { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
+ }, // system data segment descriptor
+ /* 0x20 */ {
+ { 0xffff, 0, 0, 0xb, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
+ }, // system code segment descriptor
+ /* 0x28 */ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ }, // spare segment descriptor
+ /* 0x30 */ {
+ { 0xffff, 0, 0, 0x3, 1, 0, 1, 0xf, 0, 0, 1, 1, 0 }
+ }, // system data segment descriptor
+ /* 0x38 */ {
+ { 0xffff, 0, 0, 0xb, 1, 0, 1, 0xf, 0, 1, 0, 1, 0 }
+ }, // system code segment descriptor
+ /* 0x40 */ {
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
+ }, // spare segment descriptor
+};
+
+//
+// IA32 Gdt register
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST IA32_DESCRIPTOR mGdt = {
+ sizeof (mGdtEntries) - 1,
+ (UINTN)mGdtEntries
+};
+
+/**
+ Calculate the total size of page table.
+
+ @return The size of page table.
+
+**/
+UINTN
+CalculatePageTableSize (
+ VOID
+ )
+{
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINTN TotalPagesNum;
+ UINT8 PhysicalAddressBits;
+ VOID *Hob;
+ UINT32 NumberOfPml4EntriesNeeded;
+ UINT32 NumberOfPdpEntriesNeeded;
+ BOOLEAN Page1GSupport;
+
+ Page1GSupport = FALSE;
+ if (PcdGetBool (PcdUse1GPageTable)) {
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000001) {
+ AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT26) != 0) {
+ Page1GSupport = TRUE;
+ }
+ }
+ }
+
+ //
+ // Get physical address bits supported.
+ //
+ Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
+ if (Hob != NULL) {
+ PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
+ } else {
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000008) {
+ AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+ PhysicalAddressBits = (UINT8)RegEax;
+ } else {
+ PhysicalAddressBits = 36;
+ }
+ }
+
+ //
+ // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
+ //
+ ASSERT (PhysicalAddressBits <= 52);
+ if (PhysicalAddressBits > 48) {
+ PhysicalAddressBits = 48;
+ }
+
+ //
+ // Calculate the table entries needed.
+ //
+ if (PhysicalAddressBits <= 39 ) {
+ NumberOfPml4EntriesNeeded = 1;
+ NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
+ } else {
+ NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));
+ NumberOfPdpEntriesNeeded = 512;
+ }
+
+ if (!Page1GSupport) {
+ TotalPagesNum = (NumberOfPdpEntriesNeeded + 1) * NumberOfPml4EntriesNeeded + 1;
+ } else {
+ TotalPagesNum = NumberOfPml4EntriesNeeded + 1;
+ }
+
+ return EFI_PAGES_TO_SIZE (TotalPagesNum);
+}
+
+/**
+ Allocates and fills in the Page Directory and Page Table Entries to
+ establish a 1:1 Virtual to Physical mapping.
+
+ @param[in] PageTablesAddress The base address of page table.
+
+**/
+VOID
+CreateIdentityMappingPageTables (
+ IN EFI_PHYSICAL_ADDRESS PageTablesAddress
+ )
+{
+ UINT32 RegEax;
+ UINT32 RegEdx;
+ UINT8 PhysicalAddressBits;
+ EFI_PHYSICAL_ADDRESS PageAddress;
+ UINTN IndexOfPml4Entries;
+ UINTN IndexOfPdpEntries;
+ UINTN IndexOfPageDirectoryEntries;
+ UINT32 NumberOfPml4EntriesNeeded;
+ UINT32 NumberOfPdpEntriesNeeded;
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageMapLevel4Entry;
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageMap;
+ PAGE_MAP_AND_DIRECTORY_POINTER *PageDirectoryPointerEntry;
+ PAGE_TABLE_ENTRY *PageDirectoryEntry;
+ UINTN BigPageAddress;
+ VOID *Hob;
+ BOOLEAN Page1GSupport;
+ PAGE_TABLE_1G_ENTRY *PageDirectory1GEntry;
+
+ Page1GSupport = FALSE;
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000001) {
+ AsmCpuid (0x80000001, NULL, NULL, NULL, &RegEdx);
+ if ((RegEdx & BIT26) != 0) {
+ Page1GSupport = TRUE;
+ }
+ }
+
+ //
+ // Get physical address bits supported.
+ //
+ Hob = GetFirstHob (EFI_HOB_TYPE_CPU);
+ if (Hob != NULL) {
+ PhysicalAddressBits = ((EFI_HOB_CPU *)Hob)->SizeOfMemorySpace;
+ } else {
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);
+ if (RegEax >= 0x80000008) {
+ AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);
+ PhysicalAddressBits = (UINT8)RegEax;
+ } else {
+ PhysicalAddressBits = 36;
+ }
+ }
+
+ //
+ // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.
+ //
+ ASSERT (PhysicalAddressBits <= 52);
+ if (PhysicalAddressBits > 48) {
+ PhysicalAddressBits = 48;
+ }
+
+ //
+ // Calculate the table entries needed.
+ //
+ if (PhysicalAddressBits <= 39 ) {
+ NumberOfPml4EntriesNeeded = 1;
+ NumberOfPdpEntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 30));
+ } else {
+ NumberOfPml4EntriesNeeded = (UINT32)LShiftU64 (1, (PhysicalAddressBits - 39));
+ NumberOfPdpEntriesNeeded = 512;
+ }
+
+ //
+ // Pre-allocate big pages to avoid later allocations.
+ //
+ BigPageAddress = (UINTN)PageTablesAddress;
+
+ //
+ // By architecture only one PageMapLevel4 exists - so lets allocate storage for it.
+ //
+ PageMap = (VOID *)BigPageAddress;
+ BigPageAddress += SIZE_4KB;
+
+ PageMapLevel4Entry = PageMap;
+ PageAddress = 0;
+ for (IndexOfPml4Entries = 0; IndexOfPml4Entries < NumberOfPml4EntriesNeeded; IndexOfPml4Entries++, PageMapLevel4Entry++) {
+ //
+ // Each PML4 entry points to a page of Page Directory Pointer entires.
+ // So lets allocate space for them and fill them in in the IndexOfPdpEntries loop.
+ //
+ PageDirectoryPointerEntry = (VOID *)BigPageAddress;
+ BigPageAddress += SIZE_4KB;
+
+ //
+ // Make a PML4 Entry
+ //
+ PageMapLevel4Entry->Uint64 = (UINT64)(UINTN)PageDirectoryPointerEntry;
+ PageMapLevel4Entry->Bits.ReadWrite = 1;
+ PageMapLevel4Entry->Bits.Present = 1;
+
+ if (Page1GSupport) {
+ PageDirectory1GEntry = (VOID *)PageDirectoryPointerEntry;
+
+ for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectory1GEntry++, PageAddress += SIZE_1GB) {
+ //
+ // Fill in the Page Directory entries
+ //
+ PageDirectory1GEntry->Uint64 = (UINT64)PageAddress;
+ PageDirectory1GEntry->Bits.ReadWrite = 1;
+ PageDirectory1GEntry->Bits.Present = 1;
+ PageDirectory1GEntry->Bits.MustBe1 = 1;
+ }
+ } else {
+ for (IndexOfPdpEntries = 0; IndexOfPdpEntries < NumberOfPdpEntriesNeeded; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
+ //
+ // Each Directory Pointer entries points to a page of Page Directory entires.
+ // So allocate space for them and fill them in in the IndexOfPageDirectoryEntries loop.
+ //
+ PageDirectoryEntry = (VOID *)BigPageAddress;
+ BigPageAddress += SIZE_4KB;
+
+ //
+ // Fill in a Page Directory Pointer Entries
+ //
+ PageDirectoryPointerEntry->Uint64 = (UINT64)(UINTN)PageDirectoryEntry;
+ PageDirectoryPointerEntry->Bits.ReadWrite = 1;
+ PageDirectoryPointerEntry->Bits.Present = 1;
+
+ for (IndexOfPageDirectoryEntries = 0; IndexOfPageDirectoryEntries < 512; IndexOfPageDirectoryEntries++, PageDirectoryEntry++, PageAddress += SIZE_2MB) {
+ //
+ // Fill in the Page Directory entries
+ //
+ PageDirectoryEntry->Uint64 = (UINT64)PageAddress;
+ PageDirectoryEntry->Bits.ReadWrite = 1;
+ PageDirectoryEntry->Bits.Present = 1;
+ PageDirectoryEntry->Bits.MustBe1 = 1;
+ }
+ }
+
+ for ( ; IndexOfPdpEntries < 512; IndexOfPdpEntries++, PageDirectoryPointerEntry++) {
+ ZeroMem (
+ PageDirectoryPointerEntry,
+ sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
+ );
+ }
+ }
+ }
+
+ //
+ // For the PML4 entries we are not using fill in a null entry.
+ //
+ for ( ; IndexOfPml4Entries < 512; IndexOfPml4Entries++, PageMapLevel4Entry++) {
+ ZeroMem (
+ PageMapLevel4Entry,
+ sizeof (PAGE_MAP_AND_DIRECTORY_POINTER)
+ );
+ }
+}
+
+/**
+ If in 32 bit protection mode, and coalesce image is of X64, switch to long mode.
+
+ @param Entry Entry of Standalone MM Foundation.
+ @param Context1 A pointer to the context to pass into the EntryPoint
+ function.
+ @param Context2 A pointer to the context to pass into the EntryPoint
+ function.
+ @retval EFI_SUCCESS Successfully switched to long mode and execute coalesce.
+ @retval Others Failed to execute coalesce in long mode.
+
+**/
+EFI_STATUS
+ModeSwitch (
+ IN EFI_PHYSICAL_ADDRESS Entry,
+ IN VOID *Context1,
+ IN VOID *Context2
+ )
+{
+ UINTN PageTableAddress;
+ UINTN PageTableSize;
+ EFI_STATUS Status;
+ IA32_DESCRIPTOR Gdtr;
+
+ DEBUG ((DEBUG_INFO, "ModeSwitch\n"));
+
+ //
+ // Save IA32 GDTR
+ //
+ AsmReadGdtr (&Gdtr);
+
+ //
+ // Set X64 GDTR
+ //
+ AsmWriteGdtr (&mGdt);
+
+ PageTableAddress = AsmReadCr3 () & 0xFFFFF000;
+
+ //
+ // If page table was created, no need to create
+ //
+ if (PageTableAddress == 0) {
+ PageTableSize = CalculatePageTableSize ();
+
+ PageTableAddress = (UINTN)AllocatePages (EFI_SIZE_TO_PAGES (PageTableSize));
+ ASSERT (PageTableAddress != 0);
+
+ CreateIdentityMappingPageTables (PageTableAddress);
+
+ AsmWriteCr3 ((UINTN)PageTableAddress);
+ }
+
+ DEBUG ((DEBUG_INFO, "AsmExecute64BitCode ...\n"));
+
+ Status = AsmExecute64BitCode (Entry, (UINT64)(UINTN)Context1, (UINT64)(UINTN)Context2, NULL);
+ if (Status != 0) {
+ Status = Status | MAX_BIT;
+ }
+
+ DEBUG ((DEBUG_INFO, "AsmExecute64BitCode - %r\n", Status));
+
+ //
+ // Restore IA32 GDTR
+ //
+ AsmWriteGdtr (&Gdtr);
+
+ return Status;
+}
+
+/**
+ Load SMM core to dispatch other Standalone MM drivers after IA32 mode to X64 mode.
+
+ @param Entry Entry of Standalone MM Foundation.
+ @param Context1 A pointer to the context to pass into the EntryPoint
+ function.
+ @retval EFI_SUCCESS Successfully loaded SMM core.
+ @retval Others Failed to load SMM core.
+**/
+EFI_STATUS
+LoadSmmCoreIA32ToX64 (
+ IN EFI_PHYSICAL_ADDRESS Entry,
+ IN VOID *Context1
+ )
+{
+ return ModeSwitch (Entry, Context1, NULL);
+}
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
index e043fcdb65..47cc18ecbd 100644
--- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
@@ -20,6 +20,7 @@
#include <Library/PeiServicesLib.h>
#include <Library/HobLib.h>
#include <Guid/MmCoreData.h>
+#include <StandaloneMmIplPei.h>
//
// MM Core Private Data structure that contains the data shared between
@@ -43,7 +44,7 @@ MM_CORE_PRIVATE_DATA mMmCorePrivateData = {
};
//
-// Global pointer used to access mMmCorePrivateData from outside and inside SMM
+// Global pointer used to access mMmCorePrivateData from outside and inside SMM.
//
MM_CORE_PRIVATE_DATA *gMmCorePrivate;
@@ -399,9 +400,20 @@ ExecuteSmmCoreFromSmram (
DEBUG ((DEBUG_INFO, "SMM IPL calling Standalone MM Core at SMRAM address - 0x%016lx\n", gMmCorePrivate->MmCoreEntryPoint));
//
- // Execute image
+ // If StandaloneMmIpl driver is IA32 image, but Standalone MM core is X64 image
+ // Switch 32 bit protect mode to X64 mode and load SMM core
//
- LoadSmmCore (ImageContext.EntryPoint, HobList);
+ if ((sizeof (UINTN) == sizeof (UINT32)) && (ImageContext.Machine == EFI_IMAGE_MACHINE_X64)) {
+ //
+ // Switch to X64 mode and load SMM core
+ //
+ LoadSmmCoreIA32ToX64 (ImageContext.EntryPoint, HobList);
+ } else {
+ //
+ // Execute image
+ //
+ LoadSmmCore (ImageContext.EntryPoint, HobList);
+ }
}
}
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c
new file mode 100644
index 0000000000..9cd0636c4b
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/X64/LoadSmmCore.c
@@ -0,0 +1,29 @@
+/** @file
+ SMM IPL that load the SMM Core into SMRAM
+
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#include <PiPei.h>
+#include <PiSmm.h>
+#include <StandaloneMm.h>
+
+/**
+ Load SMM core to dispatch other Standalone MM drivers after IA32 mode to X64 mode.
+
+ @param Entry Entry of Standalone MM Foundation.
+ @param Context1 A pointer to the context to pass into the EntryPoint
+ function.
+ @retval EFI_SUCCESS Successfully loaded SMM core.
+ @retval Others Failed to load SMM core.
+**/
+EFI_STATUS
+LoadSmmCoreIA32ToX64 (
+ IN EFI_PHYSICAL_ADDRESS Entry,
+ IN VOID *Context1
+ )
+{
+ return EFI_SUCCESS;
+}
\ No newline at end of file
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm
new file mode 100644
index 0000000000..7f887eb77d
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm
@@ -0,0 +1,148 @@
+;------------------------------------------------------------------------------
+;
+; Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+; SPDX-License-Identifier: BSD-2-Clause-Patent
+;
+; Module Name:
+;
+; Thunk32To64.nasm
+;
+; Abstract:
+;
+; This is the assembly code to transition from long mode to compatibility
+; mode to execute 32-bit code and then transit back to long mode.
+;
+;------------------------------------------------------------------------------
+
+ SECTION .text
+
+;------------------------------------------------------------------------------
+; Procedure: AsmExecute64BitCode
+;
+; Input: None
+;
+; Output: None
+;
+; Prototype: UINT32
+; AsmExecute64BitCode (
+; IN UINT64 Function,
+; IN UINT64 Param1,
+; IN UINT64 Param2,
+; IN IA32_DESCRIPTOR *InternalGdtr
+; );
+;
+;
+; Description: A thunk function to execute 32-bit code in long mode.
+;
+;------------------------------------------------------------------------------
+global ASM_PFX(AsmExecute64BitCode)
+ASM_PFX(AsmExecute64BitCode):
+;
+; +---------+
+; | EIP(64) |
+; +---------+
+; | CS (64) |
+; +---------+
+; | EIP(32) |
+; +---------+
+; | CS (32) |<-ESP (16 bytes aligned)
+; +---------+
+; | ... |
+; +---------+
+; | ebx |<-EBP
+; +---------+
+; | ebp |<-EBP + 4
+; +---------+
+; | esi |<-EBP + 8
+; +---------+
+; | edi |<-EBP + 12
+; +---------+
+; | RFlags |<-EBP + 16
+; +---------+
+; | RetAddr |<-EBP (org)
+; +---------+
+; | Func |<-EBP + 24
+; | Func |
+; +---------+
+; | Param1 |<-EBP + 32
+; | Param1 |
+; +---------+
+; | Param2 |<-EBP + 40
+; | Param2 |
+; +---------+
+; | Gdtr |
+; +---------+
+;
+ ;
+ ; Save general purpose register and RFlags register
+ ;
+ pushfd
+ push edi
+ push esi
+ push ebp
+ push ebx
+ mov ebp, esp
+
+ and esp, 0FFFFFFF0h
+
+ push 010h ; protected mode selector on stack
+ mov eax, Compatible ; offset for LongMode
+ push eax ; offset on stack
+
+ push 038h ; long mode selector on stack
+ mov eax, LongMode ; offset for LongMode
+ push eax ; offset on stack
+
+ mov eax, cr4
+ or al, 020h
+ mov cr4, eax ; enable PAE
+ mov ecx, 0c0000080h
+ rdmsr
+ or ah, 1 ; set LME
+ wrmsr
+ mov eax, cr0
+ bts eax, 31 ; set PG
+ mov cr0, eax ; enable paging
+ retf ; topmost 2 dwords hold the address
+LongMode: ; long mode starts here
+
+ ; Call long mode function
+ DB 67h, 48h ; 32-bit address size, 64-bit operand size
+ mov eax, [ebp + 24] ; mov rbx, [ebp + 24]
+ DB 67h, 48h
+ mov ecx, [ebp + 24 + 8] ; mov rcx, [ebp + 24 + 8]
+ DB 67h, 48h
+ mov edx, [ebp + 24 + 16] ; mov rdx, [ebp + 24 + 16]
+
+ DB 48h
+ add esp, -20h ; add rsp, -20h
+ call eax ; call rax
+ DB 48h
+ add esp, 20h ; add rsp, 20h
+
+ ; after long mode function call
+ mov ebx, eax
+
+ retf
+Compatible:
+ mov ecx, cr0
+ btc ecx, 31 ; clear PG
+ mov cr0, ecx ; disable paging
+ mov ecx, 0C0000080h
+ rdmsr
+ btc eax, 8 ; clear LME
+ wrmsr
+
+ ;
+ ; Restore C register and eax hold the return status from 32-bit function.
+ ; Note: Do not touch rax from now which hold the return value from IA32 function
+ ;
+ mov eax, ebx ; put return status to EAX
+ mov esp, ebp ; restore stack pointer
+ pop ebx
+ pop ebp
+ pop esi
+ pop edi
+ popfd
+
+ ret
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h
new file mode 100644
index 0000000000..170a6c9e40
--- /dev/null
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.h
@@ -0,0 +1,47 @@
+/** @file
+ Private header with declarations and definitions specific to the Standalone
+ MM IPL PEI driver
+
+ Copyright (c) 2023, Intel Corporation. All rights reserved.<BR>
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+#ifndef STANDALONE_MM_IPL_PEI_H_
+#define STANDALONE_MM_IPL_PEI_H_
+
+/**
+ Assembly function to transition from long mode to compatibility mode to
+ execute 32-bit code and then transit back to long mode.
+
+ @param[in] Function The 32bit code entry to be executed.
+ @param[in] Param1 The first parameter to pass to 32bit code
+ @param[in] Param2 The second parameter to pass to 32bit code
+ @param[in] InternalGdtr The GDT and GDT descriptor used by this library
+
+ @retval status.
+**/
+UINT32
+AsmExecute64BitCode (
+ IN UINT64 Function,
+ IN UINT64 Param1,
+ IN UINT64 Param2,
+ IN IA32_DESCRIPTOR *InternalGdtr
+ );
+
+/**
+ Load SMM core to dispatch other Standalone MM drivers after IA32 mode to X64 mode.
+
+ @param Entry Entry of Standalone MM Foundation.
+ @param Context1 A pointer to the context to pass into the EntryPoint
+ function.
+ @retval EFI_SUCCESS Successfully loaded SMM core.
+ @retval Others Failed to load SMM core.
+**/
+EFI_STATUS
+LoadSmmCoreIA32ToX64 (
+ IN EFI_PHYSICAL_ADDRESS Entry,
+ IN VOID *Context1
+ );
+
+#endif
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
index 668d3afbf4..b9851c072f 100644
--- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.inf
@@ -23,8 +23,16 @@
#
[Sources]
+ StandaloneMmIplPei.h
StandaloneMmIplPei.c
+[Sources.Ia32]
+ Ia32/LoadSmmCore.c
+ Ia32/Thunk32To64.nasm
+
+[Sources.X64]
+ X64/LoadSmmCore.c
+
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
@@ -49,6 +57,9 @@
[Ppis]
gPeiSmmAccessPpiGuid ## CONSUMES
+[Pcd.IA32]
+ gEfiMdeModulePkgTokenSpaceGuid.PcdUse1GPageTable ## SOMETIMES_CONSUMES
+
[Pcd]
[Depex]
diff --git a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml b/StandaloneMmPkg/StandaloneMmPkg.ci.yaml
index 4777532a7e..872f7958be 100644
--- a/StandaloneMmPkg/StandaloneMmPkg.ci.yaml
+++ b/StandaloneMmPkg/StandaloneMmPkg.ci.yaml
@@ -78,7 +78,9 @@
## options defined .pytool/Plugin/SpellCheck
"SpellCheck": {
"AuditOnly": False,
- "IgnoreFiles": [], # use gitignore syntax to ignore errors
+ "IgnoreFiles": [
+ "Drivers/StandaloneMmIplPei/Ia32/Thunk32To64.nasm"
+ ], # use gitignore syntax to ignore errors
# in matching files
"ExtendWords": [
"Bsymbolic",
--
2.37.0.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 4/5] StandaloneMmPkg: Add StandaloneMmIplPei driver.
2023-06-19 7:46 [PATCH v4 1/5] StandaloneMmPkg: Add StandaloneMmIplPei driver Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 2/5] " Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 3/5] " Zhang, Hongbin1
@ 2023-06-19 7:46 ` Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 5/5] " Zhang, Hongbin1
3 siblings, 0 replies; 5+ messages in thread
From: Zhang, Hongbin1 @ 2023-06-19 7:46 UTC (permalink / raw)
To: devel
Cc: Zhang, Hongbin1, Jiewen Yao, Ray Ni, Star Zeng, Jiaxin Wu,
Sami Mujawar, Ard Biesheuvel, Supreeth Venkatesh
Add StandaloneMmIplPei IA32/X64 driver at PEI stage.
FSP will use this driver to load Standalone MM code
to dispatch other Standalone MM drivers.
Signed-off-by: Hongbin1 Zhang <hongbin1.zhang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Supreeth Venkatesh <supreeth.venkatesh@arm.com>
---
StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
index 47cc18ecbd..0d0c678f90 100644
--- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
@@ -400,8 +400,17 @@ ExecuteSmmCoreFromSmram (
DEBUG ((DEBUG_INFO, "SMM IPL calling Standalone MM Core at SMRAM address - 0x%016lx\n", gMmCorePrivate->MmCoreEntryPoint));
//
- // If StandaloneMmIpl driver is IA32 image, but Standalone MM core is X64 image
- // Switch 32 bit protect mode to X64 mode and load SMM core
+ // If StandaloneMmIpl driver is X64 image, but Standalone MM core is IA32 image
+ // This case is not supported
+ //
+ if ((sizeof (UINTN) == sizeof (UINT64)) && (ImageContext.Machine == EFI_IMAGE_MACHINE_IA32)) {
+ DEBUG ((DEBUG_ERROR, "X64 SMM IPL call IA32 MM core is not supported !\n"));
+ CpuDeadLoop ();
+ }
+
+ //
+ // If StandaloneMmIpl driver is IA32 image, but Standalone MM core is X64 image,
+ // Switch 32 bit protect mode to X64 mode and load SMM core.
//
if ((sizeof (UINTN) == sizeof (UINT32)) && (ImageContext.Machine == EFI_IMAGE_MACHINE_X64)) {
//
--
2.37.0.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v4 5/5] StandaloneMmPkg: Add StandaloneMmIplPei driver.
2023-06-19 7:46 [PATCH v4 1/5] StandaloneMmPkg: Add StandaloneMmIplPei driver Zhang, Hongbin1
` (2 preceding siblings ...)
2023-06-19 7:46 ` [PATCH v4 4/5] " Zhang, Hongbin1
@ 2023-06-19 7:46 ` Zhang, Hongbin1
3 siblings, 0 replies; 5+ messages in thread
From: Zhang, Hongbin1 @ 2023-06-19 7:46 UTC (permalink / raw)
To: devel
Cc: Zhang, Hongbin1, Jiewen Yao, Ray Ni, Star Zeng, Jiaxin Wu,
Sami Mujawar, Ard Biesheuvel, Supreeth Venkatesh
Add StandaloneMmIplPei IA32/X64 driver at PEI stage.
FSP will use this driver to load Standalone MM code
to dispatch other Standalone MM drivers.
Signed-off-by: Hongbin1 Zhang <hongbin1.zhang@intel.com>
Cc: Jiewen Yao <jiewen.yao@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Star Zeng <star.zeng@intel.com>
Cc: Jiaxin Wu <jiaxin.wu@intel.com>
Cc: Sami Mujawar <sami.mujawar@arm.com>
Cc: Ard Biesheuvel <ardb+tianocore@kernel.org>
Cc: Supreeth Venkatesh <supreeth.venkatesh@arm.com>
---
StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
index 0d0c678f90..78939faeea 100644
--- a/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
+++ b/StandaloneMmPkg/Drivers/StandaloneMmIplPei/StandaloneMmIplPei.c
@@ -626,5 +626,16 @@ StandaloneMmIplPeiEntry (
DEBUG ((DEBUG_ERROR, "SMM IPL could not find a large enough SMRAM region to load SMM Core\n"));
}
+ //
+ // Close and lock all SMRAM ranges.
+ //
+ for (Index = 0; Index < mSmramRangeCount; Index++) {
+ Status = mSmmAccess->Close ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index);
+ ASSERT_EFI_ERROR (Status);
+
+ Status = mSmmAccess->Lock ((EFI_PEI_SERVICES **)PeiServices, mSmmAccess, Index);
+ ASSERT_EFI_ERROR (Status);
+ }
+
return EFI_SUCCESS;
}
--
2.37.0.windows.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2023-06-19 7:47 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-19 7:46 [PATCH v4 1/5] StandaloneMmPkg: Add StandaloneMmIplPei driver Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 2/5] " Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 3/5] " Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 4/5] " Zhang, Hongbin1
2023-06-19 7:46 ` [PATCH v4 5/5] " Zhang, Hongbin1
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox