--- /dev/null
+/** @file\r
+ Internal ARCH Specific file of MM memory check library.\r
+\r
+ MM memory check library implementation. This library consumes MM_ACCESS_PROTOCOL\r
+ to get MMRAM information. In order to use this library instance, the platform should produce\r
+ all MMRAM range via MM_ACCESS_PROTOCOL, including the range for firmware (like MM Core\r
+ and MM driver) and/or specific dedicated hardware.\r
+\r
+ Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
+ Copyright (c) 2016 - 2018, ARM Limited. All rights reserved.<BR>\r
+ Copyright (c) Microsoft Corporation.\r
+\r
+ SPDX-License-Identifier: BSD-2-Clause-Patent\r
+\r
+**/\r
+#include <PiMm.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/HobLib.h>\r
+\r
+#include <Guid/MmCoreData.h>\r
+#include <Guid/MmramMemoryReserve.h>\r
+\r
+//\r
+// Maximum support address used to check input buffer\r
+//\r
+extern EFI_PHYSICAL_ADDRESS mMmMemLibInternalMaximumSupportAddress;\r
+extern EFI_MMRAM_DESCRIPTOR *mMmMemLibInternalMmramRanges;\r
+extern UINTN mMmMemLibInternalMmramCount;\r
+\r
+/**\r
+ Calculate and save the maximum support address.\r
+\r
+**/\r
+VOID\r
+MmMemLibInternalCalculateMaximumSupportAddress (\r
+ VOID\r
+ )\r
+{\r
+ VOID *Hob;\r
+ UINT32 RegEax;\r
+ UINT8 PhysicalAddressBits;\r
+\r
+ //\r
+ // Get physical address bits supported.\r
+ //\r
+ Hob = GetFirstHob (EFI_HOB_TYPE_CPU);\r
+ if (Hob != NULL) {\r
+ PhysicalAddressBits = ((EFI_HOB_CPU *) Hob)->SizeOfMemorySpace;\r
+ } else {\r
+ AsmCpuid (0x80000000, &RegEax, NULL, NULL, NULL);\r
+ if (RegEax >= 0x80000008) {\r
+ AsmCpuid (0x80000008, &RegEax, NULL, NULL, NULL);\r
+ PhysicalAddressBits = (UINT8) RegEax;\r
+ } else {\r
+ PhysicalAddressBits = 36;\r
+ }\r
+ }\r
+ //\r
+ // IA-32e paging translates 48-bit linear addresses to 52-bit physical addresses.\r
+ //\r
+ ASSERT (PhysicalAddressBits <= 52);\r
+ if (PhysicalAddressBits > 48) {\r
+ PhysicalAddressBits = 48;\r
+ }\r
+\r
+ //\r
+ // Save the maximum support address in one global variable\r
+ //\r
+ mMmMemLibInternalMaximumSupportAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)(LShiftU64 (1, PhysicalAddressBits) - 1);\r
+ DEBUG ((DEBUG_INFO, "mMmMemLibInternalMaximumSupportAddress = 0x%lx\n", mMmMemLibInternalMaximumSupportAddress));\r
+}\r
+\r
+/**\r
+ Initialize cached Mmram Ranges from HOB.\r
+\r
+ @retval EFI_UNSUPPORTED The routine is unable to extract MMRAM information.\r
+ @retval EFI_SUCCESS MmRanges are populated successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+MmMemLibInternalPopulateMmramRanges (\r
+ VOID\r
+ )\r
+{\r
+ VOID *HobStart;\r
+ EFI_HOB_GUID_TYPE *GuidHob;\r
+ MM_CORE_DATA_HOB_DATA *DataInHob;\r
+ MM_CORE_PRIVATE_DATA *MmCorePrivateData;\r
+ EFI_HOB_GUID_TYPE *MmramRangesHob;\r
+ EFI_MMRAM_HOB_DESCRIPTOR_BLOCK *MmramRangesHobData;\r
+ EFI_MMRAM_DESCRIPTOR *MmramDescriptors;\r
+\r
+ HobStart = GetHobList ();\r
+ DEBUG ((DEBUG_INFO, "%a - 0x%x\n", __FUNCTION__, HobStart));\r
+\r
+ //\r
+ // Extract MM Core Private context from the Hob. If absent search for\r
+ // a Hob containing the MMRAM ranges\r
+ //\r
+ GuidHob = GetNextGuidHob (&gMmCoreDataHobGuid, HobStart);\r
+ if (GuidHob == NULL) {\r
+ MmramRangesHob = GetFirstGuidHob (&gEfiMmPeiMmramMemoryReserveGuid);\r
+ if (MmramRangesHob == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ MmramRangesHobData = GET_GUID_HOB_DATA (MmramRangesHob);\r
+ if (MmramRangesHobData == NULL || MmramRangesHobData->Descriptor == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ mMmMemLibInternalMmramCount = MmramRangesHobData->NumberOfMmReservedRegions;\r
+ MmramDescriptors = MmramRangesHobData->Descriptor;\r
+ } else {\r
+ DataInHob = GET_GUID_HOB_DATA (GuidHob);\r
+ if (DataInHob == NULL) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ MmCorePrivateData = (MM_CORE_PRIVATE_DATA *) (UINTN) DataInHob->Address;\r
+ if (MmCorePrivateData == NULL || MmCorePrivateData->MmramRanges == 0) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ mMmMemLibInternalMmramCount = (UINTN) MmCorePrivateData->MmramRangeCount;\r
+ MmramDescriptors = (EFI_MMRAM_DESCRIPTOR *) (UINTN) MmCorePrivateData->MmramRanges;\r
+ }\r
+\r
+ mMmMemLibInternalMmramRanges = AllocatePool (mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR));\r
+ if (mMmMemLibInternalMmramRanges) {\r
+ CopyMem (mMmMemLibInternalMmramRanges,\r
+ MmramDescriptors,\r
+ mMmMemLibInternalMmramCount * sizeof (EFI_MMRAM_DESCRIPTOR));\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Deinitialize cached Mmram Ranges.\r
+\r
+**/\r
+VOID\r
+MmMemLibInternalFreeMmramRanges (\r
+ VOID\r
+ )\r
+{\r
+ if (mMmMemLibInternalMmramRanges != NULL) {\r
+ FreePool (mMmMemLibInternalMmramRanges);\r
+ }\r
+}\r
+\r