summaryrefslogtreecommitdiff
path: root/MdeModulePkg/Core/PiSmmCore/Pool.c
diff options
context:
space:
mode:
Diffstat (limited to 'MdeModulePkg/Core/PiSmmCore/Pool.c')
-rw-r--r--MdeModulePkg/Core/PiSmmCore/Pool.c44
1 files changed, 42 insertions, 2 deletions
diff --git a/MdeModulePkg/Core/PiSmmCore/Pool.c b/MdeModulePkg/Core/PiSmmCore/Pool.c
index d7f80f4f8c..10a85c47ab 100644
--- a/MdeModulePkg/Core/PiSmmCore/Pool.c
+++ b/MdeModulePkg/Core/PiSmmCore/Pool.c
@@ -42,6 +42,11 @@ typedef struct {
} FREE_POOL_HEADER;
LIST_ENTRY mSmmPoolLists[MAX_POOL_INDEX];
+//
+// To cache the SMRAM base since when Loading modules At fixed address feature is enabled,
+// all module is assigned an offset relative the SMRAM base in build time.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PHYSICAL_ADDRESS gLoadModuleAtFixAddressSmramBase = 0;
/**
Called to initialize the memory service.
@@ -56,7 +61,10 @@ SmmInitializeMemoryServices (
IN EFI_SMRAM_DESCRIPTOR *SmramRanges
)
{
- UINTN Index;
+ UINTN Index;
+ UINT64 SmmCodeSize;
+ UINTN CurrentSmramRangesIndex;
+ UINT64 MaxSize;
//
// Initialize Pool list
@@ -64,7 +72,38 @@ SmmInitializeMemoryServices (
for (Index = sizeof (mSmmPoolLists) / sizeof (*mSmmPoolLists); Index > 0;) {
InitializeListHead (&mSmmPoolLists[--Index]);
}
-
+ CurrentSmramRangesIndex = 0;
+ //
+ // If Loadding Module At fixed Address feature is enabled, cache the SMRAM base here
+ //
+ if (PcdGet64(PcdLoadModuleAtFixAddressEnable) != 0) {
+ //
+ // Build tool will calculate the smm code size and then patch the PcdLoadFixAddressSmmCodePageNumber
+ //
+ SmmCodeSize = LShiftU64 (PcdGet32(PcdLoadFixAddressSmmCodePageNumber), EFI_PAGE_SHIFT);
+
+ //
+ // Find the largest SMRAM range between 1MB and 4GB that is at least 256KB - 4K in size
+ //
+ for (Index = 0, MaxSize = SIZE_256KB - EFI_PAGE_SIZE; Index < SmramRangeCount; Index++) {
+ if (SmramRanges[Index].CpuStart >= BASE_1MB) {
+ if ((SmramRanges[Index].CpuStart + SmramRanges[Index].PhysicalSize) <= BASE_4GB) {
+ if (SmramRanges[Index].PhysicalSize >= MaxSize) {
+ MaxSize = SmramRanges[Index].PhysicalSize;
+ CurrentSmramRangesIndex = Index;
+ }
+ }
+ }
+ }
+ gLoadModuleAtFixAddressSmramBase = SmramRanges[CurrentSmramRangesIndex].CpuStart;
+
+ //
+ // cut out a memory range from this SMRAM range with the size SmmCodeSize to hold SMM driver code
+ // A notable thing is that SMM core is already loaded into this range.
+ //
+ SmramRanges[CurrentSmramRangesIndex].CpuStart = SmramRanges[CurrentSmramRangesIndex].CpuStart + SmmCodeSize;
+ SmramRanges[CurrentSmramRangesIndex].PhysicalSize = SmramRanges[CurrentSmramRangesIndex].PhysicalSize - SmmCodeSize;
+ }
//
// Initialize free SMRAM regions
//
@@ -76,6 +115,7 @@ SmmInitializeMemoryServices (
SmramRanges[Index].RegionState
);
}
+
}
/**