* [PATCH v3] StandaloneMmPkg: Add StandaloneMmIplPei driver.
@ 2023-06-13 2:29 Zhang, Hongbin1
0 siblings, 0 replies; only message in thread
From: Zhang, Hongbin1 @ 2023-06-13 2:29 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] only message in thread
only message in thread, other threads:[~2023-06-13 2:29 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-06-13 2:29 [PATCH v3] StandaloneMmPkg: Add StandaloneMmIplPei driver Zhang, Hongbin1
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox