summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmMemLib/ArmStandaloneMmMemLibInternal.c42
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c11
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLibInternal.h33
-rw-r--r--StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c199
4 files changed, 284 insertions, 1 deletions
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/ArmStandaloneMmMemLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmMemLib/ArmStandaloneMmMemLibInternal.c
index f1e1ec3103..c3fa8b1674 100644
--- a/StandaloneMmPkg/Library/StandaloneMmMemLib/ArmStandaloneMmMemLibInternal.c
+++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/ArmStandaloneMmMemLibInternal.c
@@ -59,3 +59,45 @@ MmMemLibInternalFreeMmramRanges (
{
// Not implemented for AARCH64.
}
+
+/**
+ Initialize valid non-Mmram Ranges from Resource HOB.
+
+**/
+VOID
+MmMemLibInitializeValidNonMmramRanges (
+ VOID
+ )
+{
+ // Not implemented for AARCH64.
+}
+
+/**
+ Deinitialize cached non-Mmram Ranges.
+
+**/
+VOID
+MmMemLibFreeValidNonMmramRanges (
+ VOID
+ )
+{
+ // Not implemented for AARCH64.
+}
+
+/**
+ This function check if the buffer is valid non-MMRAM memory range.
+
+ @param[in] Buffer The buffer start address to be checked.
+ @param[in] Length The buffer length to be checked.
+
+ @retval TRUE This buffer is valid non-MMRAM memory range.
+ @retval FALSE This buffer is not valid non-MMRAM memory range.
+**/
+BOOLEAN
+MmMemLibIsValidNonMmramRange (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ )
+{
+ return TRUE;
+}
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c
index e8b50c5a59..0f5d6d1b10 100644
--- a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c
+++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c
@@ -84,7 +84,7 @@ MmIsBufferOutsideMmValid (
}
}
- return TRUE;
+ return MmMemLibIsValidNonMmramRange (Buffer, Length);
}
/**
@@ -262,6 +262,11 @@ MemLibConstructor (
MmMemLibCalculateMaximumSupportAddress ();
//
+ // Initialize valid non-Mmram Ranges from Resource HOB.
+ //
+ MmMemLibInitializeValidNonMmramRanges ();
+
+ //
// Initialize cached Mmram Ranges from HOB.
//
Status = MmMemLibInternalPopulateMmramRanges ();
@@ -290,5 +295,9 @@ MemLibDestructor (
//
MmMemLibInternalFreeMmramRanges ();
+ //
+ // Deinitialize cached non-Mmram Ranges.
+ //
+ MmMemLibFreeValidNonMmramRanges ();
return EFI_SUCCESS;
}
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLibInternal.h b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLibInternal.h
index d2fba8f909..527f1ac9c4 100644
--- a/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLibInternal.h
+++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLibInternal.h
@@ -45,4 +45,37 @@ MmMemLibInternalFreeMmramRanges (
VOID
);
+/**
+ Initialize valid non-Mmram Ranges from Resource HOB.
+
+**/
+VOID
+MmMemLibInitializeValidNonMmramRanges (
+ VOID
+ );
+
+/**
+ Deinitialize cached non-Mmram Ranges.
+
+**/
+VOID
+MmMemLibFreeValidNonMmramRanges (
+ VOID
+ );
+
+/**
+ This function check if the buffer is valid non-MMRAM memory range.
+
+ @param[in] Buffer The buffer start address to be checked.
+ @param[in] Length The buffer length to be checked.
+
+ @retval TRUE This buffer is valid non-MMRAM memory range.
+ @retval FALSE This buffer is not valid non-MMRAM memory range.
+**/
+BOOLEAN
+MmMemLibIsValidNonMmramRange (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ );
+
#endif
diff --git a/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c b/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c
index 81b959230f..8f87e7803d 100644
--- a/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c
+++ b/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c
@@ -20,6 +20,14 @@
#include <Guid/MmramMemoryReserve.h>
+typedef struct {
+ EFI_PHYSICAL_ADDRESS Base;
+ UINT64 Length;
+} NON_MM_MEMORY_RANGE;
+
+NON_MM_MEMORY_RANGE *mValidNonMmramRanges;
+UINTN mValidNonMmramCount;
+
//
// Maximum support address used to check input buffer
//
@@ -135,3 +143,194 @@ MmMemLibInternalFreeMmramRanges (
FreePool (mMmMemLibInternalMmramRanges);
}
}
+
+/**
+ Merge the overlapped or continuous ranges in input MemoryRange. This function is to optimize
+ the process of checking whether a buffer range belongs to the range reported by resource HOB,
+ since the buffer to be checked may be covered by multi resource HOB.
+
+ @param[in, out] MemoryRange A pointer to the NonMmramRanges reported by resource HOB.
+ @param[in, out] MemoryRangeSize A pointer to the size, in bytes, of the MemoryRange buffer.
+ On input, it is the size of the current memory map.
+ On output, it is the size of new memory map after merge.
+**/
+STATIC
+VOID
+MergeOverlappedOrContinuousRanges (
+ IN OUT NON_MM_MEMORY_RANGE *MemoryRange,
+ IN OUT UINTN *MemoryRangeSize
+ )
+{
+ NON_MM_MEMORY_RANGE *MemoryRangeEntry;
+ NON_MM_MEMORY_RANGE *MemoryRangeEnd;
+ NON_MM_MEMORY_RANGE *NewMemoryRangeEntry;
+ NON_MM_MEMORY_RANGE *NextMemoryRangeEntry;
+ EFI_PHYSICAL_ADDRESS End;
+
+ MemoryRangeEntry = MemoryRange;
+ NewMemoryRangeEntry = MemoryRange;
+ MemoryRangeEnd = (NON_MM_MEMORY_RANGE *)((UINT8 *)MemoryRange + *MemoryRangeSize);
+ while ((UINTN)MemoryRangeEntry < (UINTN)MemoryRangeEnd) {
+ NextMemoryRangeEntry = MemoryRangeEntry + 1;
+
+ do {
+ if (((UINTN)NextMemoryRangeEntry < (UINTN)MemoryRangeEnd) &&
+ ((MemoryRangeEntry->Base + MemoryRangeEntry->Length) >= NextMemoryRangeEntry->Base))
+ {
+ //
+ // Merge the overlapped or continuous ranges.
+ //
+ End = MAX (
+ MemoryRangeEntry->Base + MemoryRangeEntry->Length,
+ NextMemoryRangeEntry->Base + NextMemoryRangeEntry->Length
+ );
+ MemoryRangeEntry->Length = End - MemoryRangeEntry->Base;
+
+ NextMemoryRangeEntry++;
+ continue;
+ } else {
+ //
+ // Copy the processed independent range to the new index location.
+ //
+ CopyMem (NewMemoryRangeEntry, MemoryRangeEntry, sizeof (NON_MM_MEMORY_RANGE));
+ break;
+ }
+ } while (TRUE);
+
+ MemoryRangeEntry = NextMemoryRangeEntry;
+ NewMemoryRangeEntry++;
+ }
+
+ *MemoryRangeSize = (UINTN)NewMemoryRangeEntry - (UINTN)MemoryRange;
+}
+
+/**
+ Function to compare 2 NON_MM_MEMORY_RANGE pointer based on Base.
+
+ @param[in] Buffer1 pointer to NON_MM_MEMORY_RANGE pointer to compare
+ @param[in] Buffer2 pointer to second NON_MM_MEMORY_RANGE pointer to compare
+
+ @retval 0 Buffer1 equal to Buffer2
+ @retval <0 Buffer1 is less than Buffer2
+ @retval >0 Buffer1 is greater than Buffer2
+**/
+INTN
+EFIAPI
+NonMmMapCompare (
+ IN CONST VOID *Buffer1,
+ IN CONST VOID *Buffer2
+ )
+{
+ if (((NON_MM_MEMORY_RANGE *)Buffer1)->Base > ((NON_MM_MEMORY_RANGE *)Buffer2)->Base) {
+ return 1;
+ } else if (((NON_MM_MEMORY_RANGE *)Buffer1)->Base < ((NON_MM_MEMORY_RANGE *)Buffer2)->Base) {
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ Initialize valid non-Mmram Ranges from Resource HOB.
+
+**/
+VOID
+MmMemLibInitializeValidNonMmramRanges (
+ VOID
+ )
+{
+ EFI_PEI_HOB_POINTERS Hob;
+ UINTN Count;
+ UINTN Index;
+ UINTN RangeSize;
+ NON_MM_MEMORY_RANGE SortBuffer;
+
+ mValidNonMmramRanges = NULL;
+ mValidNonMmramCount = 0;
+
+ Count = 0;
+ Index = 0;
+ RangeSize = 0;
+
+ //
+ // 1. Get the count.
+ //
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+ while (Hob.Raw != NULL) {
+ Count++;
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
+ }
+
+ //
+ // 2. Store the initial data.
+ //
+ RangeSize = sizeof (NON_MM_MEMORY_RANGE) * Count;
+ mValidNonMmramRanges = (NON_MM_MEMORY_RANGE *)AllocateZeroPool (RangeSize);
+ ASSERT (mValidNonMmramRanges != NULL);
+
+ Hob.Raw = GetFirstHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR);
+ while (Hob.Raw != NULL) {
+ mValidNonMmramRanges[Index].Base = Hob.ResourceDescriptor->PhysicalStart;
+ mValidNonMmramRanges[Index].Length = Hob.ResourceDescriptor->ResourceLength;
+ Index++;
+
+ Hob.Raw = GET_NEXT_HOB (Hob);
+ Hob.Raw = GetNextHob (EFI_HOB_TYPE_RESOURCE_DESCRIPTOR, Hob.Raw);
+ }
+
+ ASSERT (Index == Count);
+
+ //
+ // 3. Sort the data.
+ //
+ QuickSort (mValidNonMmramRanges, Count, sizeof (NON_MM_MEMORY_RANGE), (BASE_SORT_COMPARE)NonMmMapCompare, &SortBuffer);
+
+ //
+ // 4. Merge the overlapped or continuous ranges.
+ //
+ MergeOverlappedOrContinuousRanges (mValidNonMmramRanges, &RangeSize);
+ mValidNonMmramCount = RangeSize/sizeof (NON_MM_MEMORY_RANGE);
+}
+
+/**
+ Deinitialize cached non-Mmram Ranges.
+
+**/
+VOID
+MmMemLibFreeValidNonMmramRanges (
+ VOID
+ )
+{
+ if (mValidNonMmramRanges != NULL) {
+ FreePool (mValidNonMmramRanges);
+ }
+}
+
+/**
+ This function check if the buffer is valid non-MMRAM memory range.
+
+ @param[in] Buffer The buffer start address to be checked.
+ @param[in] Length The buffer length to be checked.
+
+ @retval TRUE This buffer is valid non-MMRAM memory range.
+ @retval FALSE This buffer is not valid non-MMRAM memory range.
+**/
+BOOLEAN
+MmMemLibIsValidNonMmramRange (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ )
+{
+ UINTN Index;
+
+ for (Index = 0; Index < mValidNonMmramCount; Index++) {
+ if ((Buffer >= mValidNonMmramRanges[Index].Base) &&
+ (Buffer + Length <= mValidNonMmramRanges[Index].Base + mValidNonMmramRanges[Index].Length))
+ {
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}