summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-11 08:17:27 +0000
commitf215e02bf85f68d3a6106c2a1f4f7f063f819064 (patch)
tree6bb5b92c046312c4e95ac2620b10ddf482d3fa8b /src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib
parentInitial commit. (diff)
downloadvirtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.tar.xz
virtualbox-f215e02bf85f68d3a6106c2a1f4f7f063f819064.zip
Adding upstream version 7.0.14-dfsg.upstream/7.0.14-dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib')
-rw-r--r--src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c70
-rw-r--r--src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c315
-rw-r--r--src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf55
-rw-r--r--src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c155
4 files changed, 595 insertions, 0 deletions
diff --git a/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c b/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c
new file mode 100644
index 00000000..8f92a997
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/AArch64/StandaloneMmMemLibInternal.c
@@ -0,0 +1,70 @@
+/** @file
+ Internal ARCH Specific file of MM memory check library.
+
+ MM memory check library implementation. This library consumes MM_ACCESS_PROTOCOL
+ to get MMRAM information. In order to use this library instance, the platform should produce
+ all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core
+ and MM driver) and/or specific dedicated hardware.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+//
+// Maximum support address used to check input buffer
+//
+extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress;
+
+/**
+ Calculate and save the maximum support address.
+
+**/
+VOID
+MmMemLibInternalCalculateMaximumSupportAddress (
+ VOID
+ )
+{
+ UINT8 PhysicalAddressBits;
+
+ PhysicalAddressBits = 36;
+
+ //
+ // Save the maximum support address in one global variable
+ //
+ mMmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1);
+ DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress));
+}
+
+/**
+ Initialize cached Mmram Ranges from HOB.
+
+ @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.
+ @retval EFI_SUCCESS MmRanges are populated successfully.
+
+**/
+EFI_STATUS
+MmMemLibInternalPopulateMmramRanges (
+ VOID
+ )
+{
+ // Not implemented for AARCH64.
+ return EFI_SUCCESS;
+}
+
+/**
+ Deinitialize cached Mmram Ranges.
+
+**/
+VOID
+MmMemLibInternalFreeMmramRanges (
+ VOID
+ )
+{
+ // Not implemented for AARCH64.
+}
+
diff --git a/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c b/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c
new file mode 100644
index 00000000..38117ea6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.c
@@ -0,0 +1,315 @@
+/** @file
+ Instance of MM memory check library.
+
+ MM memory check library library implementation. This library consumes MM_ACCESS_PROTOCOL
+ to get MMRAM information. In order to use this library instance, the platform should produce
+ all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core
+ and MM driver) and/or specific dedicated hardware.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include <PiMm.h>
+
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+
+EFI_MMRAM_DESCRIPTOR *mMmMemLibInternalMmramRanges;
+UINTN mMmMemLibInternalMmramCount;
+
+//
+// Maximum support address used to check input buffer
+//
+EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress = 0;
+
+/**
+ Calculate and save the maximum support address.
+
+**/
+VOID
+MmMemLibInternalCalculateMaximumSupportAddress (
+ VOID
+ );
+
+/**
+ Initialize cached Mmram Ranges from HOB.
+
+ @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.
+ @retval EFI_SUCCESS MmRanges are populated successfully.
+
+**/
+EFI_STATUS
+MmMemLibInternalPopulateMmramRanges (
+ VOID
+ );
+
+/**
+ Deinitialize cached Mmram Ranges.
+
+**/
+VOID
+MmMemLibInternalFreeMmramRanges (
+ VOID
+ );
+
+/**
+ This function check if the buffer is valid per processor architecture and not overlap with MMRAM.
+
+ @param Buffer The buffer start address to be checked.
+ @param Length The buffer length to be checked.
+
+ @retval TRUE This buffer is valid per processor architecture and not overlap with MMRAM.
+ @retval FALSE This buffer is not valid per processor architecture or overlap with MMRAM.
+**/
+BOOLEAN
+EFIAPI
+MmIsBufferOutsideMmValid (
+ IN EFI_PHYSICAL_ADDRESS Buffer,
+ IN UINT64 Length
+ )
+{
+ UINTN Index;
+
+ //
+ // Check override.
+ // NOTE: (B:0->L:4G) is invalid for IA32, but (B:1->L:4G-1)/(B:4G-1->L:1) is valid.
+ //
+ if ((Length > mMmMemLibInternalMaximumSupportAddress) ||
+ (Buffer > mMmMemLibInternalMaximumSupportAddress) ||
+ ((Length != 0) && (Buffer > (mMmMemLibInternalMaximumSupportAddress - (Length - 1)))) ) {
+ //
+ // Overflow happen
+ //
+ DEBUG ((
+ DEBUG_ERROR,
+ "MmIsBufferOutsideMmValid: Overflow: Buffer (0x%lx) - Length (0x%lx), MaximumSupportAddress (0x%lx)\n",
+ Buffer,
+ Length,
+ mMmMemLibInternalMaximumSupportAddress
+ ));
+ return FALSE;
+ }
+
+ for (Index = 0; Index < mMmMemLibInternalMmramCount; Index ++) {
+ if (((Buffer >= mMmMemLibInternalMmramRanges[Index].CpuStart) &&
+ (Buffer < mMmMemLibInternalMmramRanges[Index].CpuStart + mMmMemLibInternalMmramRanges[Index].PhysicalSize)) ||
+ ((mMmMemLibInternalMmramRanges[Index].CpuStart >= Buffer) &&
+ (mMmMemLibInternalMmramRanges[Index].CpuStart < Buffer + Length))) {
+ DEBUG ((
+ DEBUG_ERROR,
+ "MmIsBufferOutsideMmValid: Overlap: Buffer (0x%lx) - Length (0x%lx), ",
+ Buffer,
+ Length
+ ));
+ DEBUG ((
+ DEBUG_ERROR,
+ "CpuStart (0x%lx) - PhysicalSize (0x%lx)\n",
+ mMmMemLibInternalMmramRanges[Index].CpuStart,
+ mMmMemLibInternalMmramRanges[Index].PhysicalSize
+ ));
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+/**
+ Copies a source buffer (non-MMRAM) to a destination buffer (MMRAM).
+
+ This function copies a source buffer (non-MMRAM) to a destination buffer (MMRAM).
+ It checks if source buffer is valid per processor architecture and not overlap with MMRAM.
+ If the check passes, it copies memory and returns EFI_SUCCESS.
+ If the check fails, it return EFI_SECURITY_VIOLATION.
+ The implementation must be reentrant.
+
+ @param DestinationBuffer The pointer to the destination buffer of the memory copy.
+ @param SourceBuffer The pointer to the source buffer of the memory copy.
+ @param Length The number of bytes to copy from SourceBuffer to DestinationBuffer.
+
+ @retval EFI_SECURITY_VIOLATION The SourceBuffer is invalid per processor architecture or overlap with MMRAM.
+ @retval EFI_SUCCESS Memory is copied.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCopyMemToMmram (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ if (!MmIsBufferOutsideMmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)SourceBuffer, Length)) {
+ DEBUG ((DEBUG_ERROR, "MmCopyMemToMmram: Security Violation: Source (0x%x), Length (0x%x)\n", SourceBuffer, Length));
+ return EFI_SECURITY_VIOLATION;
+ }
+ CopyMem (DestinationBuffer, SourceBuffer, Length);
+ return EFI_SUCCESS;
+}
+
+/**
+ Copies a source buffer (MMRAM) to a destination buffer (NON-MMRAM).
+
+ This function copies a source buffer (non-MMRAM) to a destination buffer (MMRAM).
+ It checks if destination buffer is valid per processor architecture and not overlap with MMRAM.
+ If the check passes, it copies memory and returns EFI_SUCCESS.
+ If the check fails, it returns EFI_SECURITY_VIOLATION.
+ The implementation must be reentrant.
+
+ @param DestinationBuffer The pointer to the destination buffer of the memory copy.
+ @param SourceBuffer The pointer to the source buffer of the memory copy.
+ @param Length The number of bytes to copy from SourceBuffer to DestinationBuffer.
+
+ @retval EFI_SECURITY_VIOLATION The DestinationBuffer is invalid per processor architecture or overlap with MMRAM.
+ @retval EFI_SUCCESS Memory is copied.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCopyMemFromMmram (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ if (!MmIsBufferOutsideMmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)DestinationBuffer, Length)) {
+ DEBUG ((DEBUG_ERROR, "MmCopyMemFromMmram: Security Violation: Destination (0x%x), Length (0x%x)\n",
+ DestinationBuffer, Length));
+ return EFI_SECURITY_VIOLATION;
+ }
+ CopyMem (DestinationBuffer, SourceBuffer, Length);
+ return EFI_SUCCESS;
+}
+
+/**
+ Copies a source buffer (NON-MMRAM) to a destination buffer (NON-MMRAM).
+
+ This function copies a source buffer (non-MMRAM) to a destination buffer (MMRAM).
+ It checks if source buffer and destination buffer are valid per processor architecture and not overlap with MMRAM.
+ If the check passes, it copies memory and returns EFI_SUCCESS.
+ If the check fails, it returns EFI_SECURITY_VIOLATION.
+ The implementation must be reentrant, and it must handle the case where source buffer overlaps destination buffer.
+
+ @param DestinationBuffer The pointer to the destination buffer of the memory copy.
+ @param SourceBuffer The pointer to the source buffer of the memory copy.
+ @param Length The number of bytes to copy from SourceBuffer to DestinationBuffer.
+
+ @retval EFI_SECURITY_VIOLATION The DestinationBuffer is invalid per processor architecture or overlap with MMRAM.
+ @retval EFI_SECURITY_VIOLATION The SourceBuffer is invalid per processor architecture or overlap with MMRAM.
+ @retval EFI_SUCCESS Memory is copied.
+
+**/
+EFI_STATUS
+EFIAPI
+MmCopyMem (
+ OUT VOID *DestinationBuffer,
+ IN CONST VOID *SourceBuffer,
+ IN UINTN Length
+ )
+{
+ if (!MmIsBufferOutsideMmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)DestinationBuffer, Length)) {
+ DEBUG ((DEBUG_ERROR, "MmCopyMem: Security Violation: Destination (0x%x), Length (0x%x)\n",
+ DestinationBuffer, Length));
+ return EFI_SECURITY_VIOLATION;
+ }
+ if (!MmIsBufferOutsideMmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)SourceBuffer, Length)) {
+ DEBUG ((DEBUG_ERROR, "MmCopyMem: Security Violation: Source (0x%x), Length (0x%x)\n", SourceBuffer, Length));
+ return EFI_SECURITY_VIOLATION;
+ }
+ CopyMem (DestinationBuffer, SourceBuffer, Length);
+ return EFI_SUCCESS;
+}
+
+/**
+ Fills a target buffer (NON-MMRAM) with a byte value.
+
+ This function fills a target buffer (non-MMRAM) with a byte value.
+ It checks if target buffer is valid per processor architecture and not overlap with MMRAM.
+ If the check passes, it fills memory and returns EFI_SUCCESS.
+ If the check fails, it returns EFI_SECURITY_VIOLATION.
+
+ @param Buffer The memory to set.
+ @param Length The number of bytes to set.
+ @param Value The value with which to fill Length bytes of Buffer.
+
+ @retval EFI_SECURITY_VIOLATION The Buffer is invalid per processor architecture or overlap with MMRAM.
+ @retval EFI_SUCCESS Memory is set.
+
+**/
+EFI_STATUS
+EFIAPI
+MmSetMem (
+ OUT VOID *Buffer,
+ IN UINTN Length,
+ IN UINT8 Value
+ )
+{
+ if (!MmIsBufferOutsideMmValid ((EFI_PHYSICAL_ADDRESS)(UINTN)Buffer, Length)) {
+ DEBUG ((DEBUG_ERROR, "MmSetMem: Security Violation: Source (0x%x), Length (0x%x)\n", Buffer, Length));
+ return EFI_SECURITY_VIOLATION;
+ }
+ SetMem (Buffer, Length, Value);
+ return EFI_SUCCESS;
+}
+
+/**
+ The constructor function initializes the Mm Mem library
+
+ @param [in] ImageHandle The firmware allocated handle for the EFI image.
+ @param [in] MmSystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+MemLibConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *MmSystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Calculate and save maximum support address
+ //
+ MmMemLibInternalCalculateMaximumSupportAddress ();
+
+ //
+ // Initialize cached Mmram Ranges from HOB.
+ //
+ Status = MmMemLibInternalPopulateMmramRanges ();
+
+ return Status;
+}
+
+/**
+ Destructor for Mm Mem library.
+
+ @param ImageHandle The image handle of the process.
+ @param MmSystemTable The EFI System Table pointer.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+MemLibDestructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_MM_SYSTEM_TABLE *MmSystemTable
+ )
+{
+
+ //
+ // Deinitialize cached Mmram Ranges.
+ //
+ MmMemLibInternalFreeMmramRanges ();
+
+ return EFI_SUCCESS;
+}
diff --git a/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf b/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
new file mode 100644
index 00000000..bc2f3eea
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/StandaloneMmMemLib.inf
@@ -0,0 +1,55 @@
+## @file
+# Instance of MM memory check library.
+#
+# MM memory check library library implementation. This library consumes MM_ACCESS_PROTOCOL
+# to get MMRAM information. In order to use this library instance, the platform should produce
+# all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core
+# and MM driver) and/or specific dedicated hardware.
+#
+# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+# Copyright (c) Microsoft Corporation.
+#
+# SPDX-License-Identifier: BSD-2-Clause-Patent
+#
+##
+
+[Defines]
+ INF_VERSION = 0x0001001A
+ BASE_NAME = MemLib
+ FILE_GUID = EA355F14-6409-4716-829F-37B3BC7C7F26
+ MODULE_TYPE = MM_STANDALONE
+ VERSION_STRING = 1.0
+ PI_SPECIFICATION_VERSION = 0x00010032
+ LIBRARY_CLASS = MemLib|MM_STANDALONE MM_CORE_STANDALONE
+ CONSTRUCTOR = MemLibConstructor
+ DESTRUCTOR = MemLibDestructor
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 AARCH64
+#
+
+[Sources.Common]
+ StandaloneMmMemLib.c
+
+[Sources.IA32, Sources.X64]
+ X86StandaloneMmMemLibInternal.c
+
+[Sources.AARCH64]
+ AArch64/StandaloneMmMemLibInternal.c
+
+[Packages]
+ MdePkg/MdePkg.dec
+ StandaloneMmPkg/StandaloneMmPkg.dec
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ HobLib
+ MemoryAllocationLib
+
+[Guids]
+ gMmCoreDataHobGuid ## SOMETIMES_CONSUMES ## HOB
+ gEfiMmPeiMmramMemoryReserveGuid ## SOMETIMES_CONSUMES ## HOB
diff --git a/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c b/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c
new file mode 100644
index 00000000..530105a6
--- /dev/null
+++ b/src/VBox/Devices/EFI/Firmware/StandaloneMmPkg/Library/StandaloneMmMemLib/X86StandaloneMmMemLibInternal.c
@@ -0,0 +1,155 @@
+/** @file
+ Internal ARCH Specific file of MM memory check library.
+
+ MM memory check library implementation. This library consumes MM_ACCESS_PROTOCOL
+ to get MMRAM information. In order to use this library instance, the platform should produce
+ all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core
+ and MM driver) and/or specific dedicated hardware.
+
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>
+ Copyright (c) Microsoft Corporation.
+
+ SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+#include <PiMm.h>
+#include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/DebugLib.h>
+#include <Library/HobLib.h>
+
+#include <Guid/MmCoreData.h>
+#include <Guid/MmramMemoryReserve.h>
+
+//
+// Maximum support address used to check input buffer
+//
+extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress;
+extern EFI_MMRAM_DESCRIPTOR *mMmMemLibInternalMmramRanges;
+extern UINTN mMmMemLibInternalMmramCount;
+
+/**
+ Calculate and save the maximum support address.
+
+**/
+VOID
+MmMemLibInternalCalculateMaximumSupportAddress (
+ VOID
+ )
+{
+ VOID *Hob;
+ UINT32 RegEax;
+ UINT8 PhysicalAddressBits;
+
+ //
+ // 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;
+ }
+
+ //
+ // Save the maximum support address in one global variable
+ //
+ mMmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1);
+ DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress));
+}
+
+/**
+ Initialize cached Mmram Ranges from HOB.
+
+ @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.
+ @retval EFI_SUCCESS MmRanges are populated successfully.
+
+**/
+EFI_STATUS
+MmMemLibInternalPopulateMmramRanges (
+ VOID
+ )
+{
+ VOID *HobStart;
+ EFI_HOB_GUID_TYPE *GuidHob;
+ MM_CORE_DATA_HOB_DATA *DataInHob;
+ MM_CORE_PRIVATE_DATA *MmCorePrivateData;
+ EFI_HOB_GUID_TYPE *MmramRangesHob;
+ EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData;
+ EFI_MMRAM_DESCRIPTOR *MmramDescriptors;
+
+ HobStart = GetHobList ();
+ DEBUG ((DEBUG_INFO, "%a - 0x%x\n", __FUNCTION__, HobStart));
+
+ //
+ // Extract MM Core Private context from the Hob. If absent search for
+ // a Hob containing the MMRAM ranges
+ //
+ GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart);
+ if (GuidHob == NULL) {
+ MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid);
+ if (MmramRangesHob == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);
+ if (MmramRangesHobData == NULL || MmramRangesHobData->Descriptor == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ mMmMemLibInternalMmramCount = MmramRangesHobData->NumberOfMmReservedRegions;
+ MmramDescriptors = MmramRangesHobData->Descriptor;
+ } else {
+ DataInHob = GET_GUID_HOB_DATA (GuidHob);
+ if (DataInHob == NULL) {
+ return EFI_UNSUPPORTED;
+ }
+
+ MmCorePrivateData = (MM_CORE_PRIVATE_DATA *) (UINTN) DataInHob->Address;
+ if (MmCorePrivateData == NULL || MmCorePrivateData->MmramRanges == 0) {
+ return EFI_UNSUPPORTED;
+ }
+
+ mMmMemLibInternalMmramCount = (UINTN) MmCorePrivateData->MmramRangeCount;
+ MmramDescriptors = (EFI_MMRAM_DESCRIPTOR *) (UINTN) MmCorePrivateData->MmramRanges;
+ }
+
+ mMmMemLibInternalMmramRanges = AllocatePool (mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR));
+ if (mMmMemLibInternalMmramRanges) {
+ CopyMem (mMmMemLibInternalMmramRanges,
+ MmramDescriptors,
+ mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR));
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Deinitialize cached Mmram Ranges.
+
+**/
+VOID
+MmMemLibInternalFreeMmramRanges (
+ VOID
+ )
+{
+ if (mMmMemLibInternalMmramRanges != NULL) {
+ FreePool (mMmMemLibInternalMmramRanges);
+ }
+}
+