diff --git a/StandaloneMmPkg/Core/Dispatcher.c b/StandaloneMmPkg/Core/Dispatcher.c index 462a4abd8a..b9fe323846 100644 --- a/StandaloneMmPkg/Core/Dispatcher.c +++ b/StandaloneMmPkg/Core/Dispatcher.c @@ -759,6 +759,8 @@ MmDriverDispatchHandler ( } } + MmCoreInitializeMemoryAttributesTable (); + MmiHandlerUnRegister (DispatchHandle); return EFI_SUCCESS; diff --git a/StandaloneMmPkg/Core/MemoryAttributesTable.c b/StandaloneMmPkg/Core/MemoryAttributesTable.c new file mode 100644 index 0000000000..bf001899ae --- /dev/null +++ b/StandaloneMmPkg/Core/MemoryAttributesTable.c @@ -0,0 +1,493 @@ +/** @file + PI SMM MemoryAttributes support + +Copyright (c) 2024, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "StandaloneMmCore.h" + +#define PREVIOUS_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ + ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) - (Size))) + +#define IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE SIGNATURE_32 ('I','P','P','D') + +typedef struct { + UINT32 Signature; + UINTN ImageRecordCount; + UINTN CodeSegmentCountMax; + LIST_ENTRY ImageRecordList; +} IMAGE_PROPERTIES_PRIVATE_DATA; + +IMAGE_PROPERTIES_PRIVATE_DATA mImagePropertiesPrivateData = { + IMAGE_PROPERTIES_PRIVATE_DATA_SIGNATURE, + 0, + 0, + INITIALIZE_LIST_HEAD_VARIABLE (mImagePropertiesPrivateData.ImageRecordList) +}; + +#define EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA BIT0 + +UINT64 mMemoryProtectionAttribute = EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA; + +// +// Below functions are for MemoryMap +// + +/** + Merge continuous memory map entries whose have same attributes. + + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the current memory map. On output, + it is the size of new memory map after merge. + @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. +**/ +STATIC +VOID +MergeMemoryMap ( + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN OUT UINTN *MemoryMapSize, + IN UINTN DescriptorSize + ) +{ + EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; + UINT64 MemoryBlockLength; + EFI_MEMORY_DESCRIPTOR *NewMemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *NextMemoryMapEntry; + + MemoryMapEntry = MemoryMap; + NewMemoryMapEntry = MemoryMap; + MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + *MemoryMapSize); + while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { + CopyMem (NewMemoryMapEntry, MemoryMapEntry, sizeof (EFI_MEMORY_DESCRIPTOR)); + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + + do { + MemoryBlockLength = LShiftU64 (MemoryMapEntry->NumberOfPages, EFI_PAGE_SHIFT); + if (((UINTN)NextMemoryMapEntry < (UINTN)MemoryMapEnd) && + (MemoryMapEntry->Type == NextMemoryMapEntry->Type) && + (MemoryMapEntry->Attribute == NextMemoryMapEntry->Attribute) && + ((MemoryMapEntry->PhysicalStart + MemoryBlockLength) == NextMemoryMapEntry->PhysicalStart)) + { + MemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; + if (NewMemoryMapEntry != MemoryMapEntry) { + NewMemoryMapEntry->NumberOfPages += NextMemoryMapEntry->NumberOfPages; + } + + NextMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); + continue; + } else { + MemoryMapEntry = PREVIOUS_MEMORY_DESCRIPTOR (NextMemoryMapEntry, DescriptorSize); + break; + } + } while (TRUE); + + MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + NewMemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (NewMemoryMapEntry, DescriptorSize); + } + + *MemoryMapSize = (UINTN)NewMemoryMapEntry - (UINTN)MemoryMap; + + return; +} + +/** + Enforce memory map attributes. + This function will set EfiRuntimeServicesData/EfiMemoryMappedIO/EfiMemoryMappedIOPortSpace to be EFI_MEMORY_XP. + + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[in] MemoryMapSize Size, in bytes, of the MemoryMap buffer. + @param[in] DescriptorSize Size, in bytes, of an individual EFI_MEMORY_DESCRIPTOR. +**/ +STATIC +VOID +EnforceMemoryMapAttribute ( + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + IN UINTN MemoryMapSize, + IN UINTN DescriptorSize + ) +{ + EFI_MEMORY_DESCRIPTOR *MemoryMapEntry; + EFI_MEMORY_DESCRIPTOR *MemoryMapEnd; + + MemoryMapEntry = MemoryMap; + MemoryMapEnd = (EFI_MEMORY_DESCRIPTOR *)((UINT8 *)MemoryMap + MemoryMapSize); + while ((UINTN)MemoryMapEntry < (UINTN)MemoryMapEnd) { + if (MemoryMapEntry->Attribute != 0) { + // It is PE image, the attribute is already set. + } else { + switch (MemoryMapEntry->Type) { + case EfiRuntimeServicesCode: + MemoryMapEntry->Attribute = EFI_MEMORY_RO; + break; + case EfiRuntimeServicesData: + default: + MemoryMapEntry->Attribute |= EFI_MEMORY_XP; + break; + } + } + + MemoryMapEntry = NEXT_MEMORY_DESCRIPTOR (MemoryMapEntry, DescriptorSize); + } + + return; +} + +/** + This function for GetMemoryMap() with memory attributes table. + + It calls original GetMemoryMap() to get the original memory map information. Then + plus the additional memory map entries for PE Code/Data separation. + + @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the buffer allocated by the caller. On output, + it is the size of the buffer returned by the + firmware if the buffer was large enough, or the + size of the buffer needed to contain the map if + the buffer was too small. + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[out] MapKey A pointer to the location in which firmware + returns the key for the current memory map. + @param[out] DescriptorSize A pointer to the location in which firmware + returns the size, in bytes, of an individual + EFI_MEMORY_DESCRIPTOR. + @param[out] DescriptorVersion A pointer to the location in which firmware + returns the version number associated with the + EFI_MEMORY_DESCRIPTOR. + + @retval EFI_SUCCESS The memory map was returned in the MemoryMap + buffer. + @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current + buffer size needed to hold the memory map is + returned in MemoryMapSize. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +STATIC +EFI_STATUS +EFIAPI +MmCoreGetMemoryMapMemoryAttributesTable ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ) +{ + EFI_STATUS Status; + UINTN OldMemoryMapSize; + UINTN AdditionalRecordCount; + + // + // If PE code/data is not aligned, just return. + // + if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) { + return MmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); + } + + if (MemoryMapSize == NULL) { + return EFI_INVALID_PARAMETER; + } + + AdditionalRecordCount = (2 * mImagePropertiesPrivateData.CodeSegmentCountMax + 3) * mImagePropertiesPrivateData.ImageRecordCount; + + OldMemoryMapSize = *MemoryMapSize; + Status = MmCoreGetMemoryMap (MemoryMapSize, MemoryMap, MapKey, DescriptorSize, DescriptorVersion); + if (Status == EFI_BUFFER_TOO_SMALL) { + *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount; + } else if (Status == EFI_SUCCESS) { + if (OldMemoryMapSize - *MemoryMapSize < (*DescriptorSize) * AdditionalRecordCount) { + *MemoryMapSize = *MemoryMapSize + (*DescriptorSize) * AdditionalRecordCount; + // + // Need update status to buffer too small + // + Status = EFI_BUFFER_TOO_SMALL; + } else { + // + // Split PE code/data + // + ASSERT (MemoryMap != NULL); + SplitTable (MemoryMapSize, MemoryMap, *DescriptorSize, &mImagePropertiesPrivateData.ImageRecordList, AdditionalRecordCount); + + // + // Set RuntimeData to XP + // + EnforceMemoryMapAttribute (MemoryMap, *MemoryMapSize, *DescriptorSize); + + // + // Merge same type to save entry size + // + MergeMemoryMap (MemoryMap, MemoryMapSize, *DescriptorSize); + } + } + + return Status; +} + +// +// Below functions are for ImageRecord +// + +/** + Insert image record. + + @param[in] DriverEntry Driver information +**/ +VOID +MmInsertImageRecord ( + IN EFI_MM_DRIVER_ENTRY *DriverEntry + ) +{ + EFI_STATUS Status; + IMAGE_PROPERTIES_RECORD *ImageRecord; + CHAR8 *PdbPointer; + UINT32 RequiredAlignment; + + DEBUG ((DEBUG_VERBOSE, "MM InsertImageRecord - 0x%x\n", DriverEntry)); + + ImageRecord = AllocatePool (sizeof (*ImageRecord)); + if (ImageRecord == NULL) { + return; + } + + InitializeListHead (&ImageRecord->Link); + InitializeListHead (&ImageRecord->CodeSegmentList); + + PdbPointer = PeCoffLoaderGetPdbPointer ((VOID *)(UINTN)DriverEntry->ImageBuffer); + if (PdbPointer != NULL) { + DEBUG ((DEBUG_VERBOSE, "MM Image - %a\n", PdbPointer)); + } + + RequiredAlignment = RUNTIME_PAGE_ALLOCATION_GRANULARITY; + Status = CreateImagePropertiesRecord ( + (VOID *)(UINTN)DriverEntry->ImageBuffer, + LShiftU64 (DriverEntry->NumberOfPage, EFI_PAGE_SHIFT), + &RequiredAlignment, + ImageRecord + ); + + if (EFI_ERROR (Status)) { + if (Status == EFI_ABORTED) { + mMemoryProtectionAttribute &= + ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); + } + + goto Finish; + } + + if (ImageRecord->CodeSegmentCount == 0) { + mMemoryProtectionAttribute &= + ~((UINT64)EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA); + DEBUG ((DEBUG_ERROR, "MM !!!!!!!! InsertImageRecord - CodeSegmentCount is 0 !!!!!!!!\n")); + if (PdbPointer != NULL) { + DEBUG ((DEBUG_ERROR, "MM !!!!!!!! Image - %a !!!!!!!!\n", PdbPointer)); + } + + Status = EFI_ABORTED; + goto Finish; + } + + // + // Check overlap all section in ImageBase/Size + // + if (!IsImageRecordCodeSectionValid (ImageRecord)) { + DEBUG ((DEBUG_ERROR, "MM IsImageRecordCodeSectionValid - FAIL\n")); + Status = EFI_ABORTED; + goto Finish; + } + + InsertTailList (&mImagePropertiesPrivateData.ImageRecordList, &ImageRecord->Link); + mImagePropertiesPrivateData.ImageRecordCount++; + + if (mImagePropertiesPrivateData.CodeSegmentCountMax < ImageRecord->CodeSegmentCount) { + mImagePropertiesPrivateData.CodeSegmentCountMax = ImageRecord->CodeSegmentCount; + } + + SortImageRecord (&mImagePropertiesPrivateData.ImageRecordList); + +Finish: + if (EFI_ERROR (Status) && (ImageRecord != NULL)) { + DeleteImagePropertiesRecord (ImageRecord); + } + + return; +} + +/** + Publish MemoryAttributesTable to MM configuration table. +**/ +VOID +PublishMemoryAttributesTable ( + VOID + ) +{ + UINTN MemoryMapSize; + EFI_MEMORY_DESCRIPTOR *MemoryMap; + UINTN MapKey; + UINTN DescriptorSize; + UINT32 DescriptorVersion; + UINTN Index; + EFI_STATUS Status; + UINTN RuntimeEntryCount; + EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE *MemoryAttributesTable; + EFI_MEMORY_DESCRIPTOR *MemoryAttributesEntry; + UINTN MemoryAttributesTableSize; + + MemoryMapSize = 0; + MemoryMap = NULL; + Status = MmCoreGetMemoryMapMemoryAttributesTable ( + &MemoryMapSize, + MemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + ASSERT (Status == EFI_BUFFER_TOO_SMALL); + + do { + DEBUG ((DEBUG_VERBOSE, "MemoryMapSize - 0x%x\n", MemoryMapSize)); + MemoryMap = AllocatePool (MemoryMapSize); + ASSERT (MemoryMap != NULL); + DEBUG ((DEBUG_VERBOSE, "MemoryMap - 0x%x\n", MemoryMap)); + + Status = MmCoreGetMemoryMapMemoryAttributesTable ( + &MemoryMapSize, + MemoryMap, + &MapKey, + &DescriptorSize, + &DescriptorVersion + ); + if (EFI_ERROR (Status)) { + FreePool (MemoryMap); + } + } while (Status == EFI_BUFFER_TOO_SMALL); + + // + // Allocate MemoryAttributesTable + // + RuntimeEntryCount = MemoryMapSize/DescriptorSize; + MemoryAttributesTableSize = sizeof (EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount; + MemoryAttributesTable = AllocatePool (sizeof (EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE) + DescriptorSize * RuntimeEntryCount); + ASSERT (MemoryAttributesTable != NULL); + if (MemoryAttributesTable == NULL) { + return; + } + + MemoryAttributesTable->Version = EDKII_PI_SMM_MEMORY_ATTRIBUTES_TABLE_VERSION; + MemoryAttributesTable->NumberOfEntries = (UINT32)RuntimeEntryCount; + MemoryAttributesTable->DescriptorSize = (UINT32)DescriptorSize; + MemoryAttributesTable->Reserved = 0; + DEBUG ((DEBUG_VERBOSE, "MemoryAttributesTable:\n")); + DEBUG ((DEBUG_VERBOSE, " Version - 0x%08x\n", MemoryAttributesTable->Version)); + DEBUG ((DEBUG_VERBOSE, " NumberOfEntries - 0x%08x\n", MemoryAttributesTable->NumberOfEntries)); + DEBUG ((DEBUG_VERBOSE, " DescriptorSize - 0x%08x\n", MemoryAttributesTable->DescriptorSize)); + MemoryAttributesEntry = (EFI_MEMORY_DESCRIPTOR *)(MemoryAttributesTable + 1); + for (Index = 0; Index < MemoryMapSize/DescriptorSize; Index++) { + CopyMem (MemoryAttributesEntry, MemoryMap, DescriptorSize); + DEBUG ((DEBUG_VERBOSE, "Entry (0x%x)\n", MemoryAttributesEntry)); + DEBUG ((DEBUG_VERBOSE, " Type - 0x%x\n", MemoryAttributesEntry->Type)); + DEBUG ((DEBUG_VERBOSE, " PhysicalStart - 0x%016lx\n", MemoryAttributesEntry->PhysicalStart)); + DEBUG ((DEBUG_VERBOSE, " VirtualStart - 0x%016lx\n", MemoryAttributesEntry->VirtualStart)); + DEBUG ((DEBUG_VERBOSE, " NumberOfPages - 0x%016lx\n", MemoryAttributesEntry->NumberOfPages)); + DEBUG ((DEBUG_VERBOSE, " Attribute - 0x%016lx\n", MemoryAttributesEntry->Attribute)); + MemoryAttributesEntry = NEXT_MEMORY_DESCRIPTOR (MemoryAttributesEntry, DescriptorSize); + + MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, DescriptorSize); + } + + Status = MmInstallConfigurationTable (&gMmCoreMmst, &gEdkiiPiSmmMemoryAttributesTableGuid, MemoryAttributesTable, MemoryAttributesTableSize); + ASSERT_EFI_ERROR (Status); +} + +/** + This function installs all MM image record information. +**/ +VOID +MmInstallImageRecord ( + VOID + ) +{ + EFI_STATUS Status; + UINTN NoHandles; + EFI_HANDLE *HandleBuffer; + EFI_LOADED_IMAGE_PROTOCOL *LoadedImage; + UINTN Index; + EFI_MM_DRIVER_ENTRY DriverEntry; + + Status = MmLocateHandleBuffer ( + ByProtocol, + &gEfiLoadedImageProtocolGuid, + NULL, + &NoHandles, + &HandleBuffer + ); + if (EFI_ERROR (Status)) { + return; + } + + for (Index = 0; Index < NoHandles; Index++) { + Status = MmHandleProtocol ( + HandleBuffer[Index], + &gEfiLoadedImageProtocolGuid, + (VOID **)&LoadedImage + ); + if (EFI_ERROR (Status)) { + continue; + } + + DEBUG ((DEBUG_VERBOSE, "LoadedImage - 0x%x 0x%x ", LoadedImage->ImageBase, LoadedImage->ImageSize)); + { + VOID *PdbPointer; + PdbPointer = PeCoffLoaderGetPdbPointer (LoadedImage->ImageBase); + if (PdbPointer != NULL) { + DEBUG ((DEBUG_VERBOSE, "(%a) ", PdbPointer)); + } + } + DEBUG ((DEBUG_VERBOSE, "\n")); + ZeroMem (&DriverEntry, sizeof (DriverEntry)); + DriverEntry.ImageBuffer = (UINTN)LoadedImage->ImageBase; + DriverEntry.NumberOfPage = EFI_SIZE_TO_PAGES ((UINTN)LoadedImage->ImageSize); + MmInsertImageRecord (&DriverEntry); + } + + FreePool (HandleBuffer); +} + +/** + Initialize MemoryAttributesTable support. + +**/ +VOID +EFIAPI +MmCoreInitializeMemoryAttributesTable ( + VOID + ) +{ + MmInstallImageRecord (); + + DEBUG ((DEBUG_VERBOSE, "MM MemoryProtectionAttribute - 0x%016lx\n", mMemoryProtectionAttribute)); + if ((mMemoryProtectionAttribute & EFI_MEMORY_ATTRIBUTES_RUNTIME_MEMORY_PROTECTION_NON_EXECUTABLE_PE_DATA) == 0) { + return; + } + + DEBUG_CODE_BEGIN (); + if ( mImagePropertiesPrivateData.ImageRecordCount > 0) { + DEBUG ((DEBUG_INFO, "MM - Total Runtime Image Count - 0x%x\n", mImagePropertiesPrivateData.ImageRecordCount)); + DEBUG ((DEBUG_INFO, "MM - Dump Runtime Image Records:\n")); + DumpImageRecords (&mImagePropertiesPrivateData.ImageRecordList); + } + + DEBUG_CODE_END (); + + PublishMemoryAttributesTable (); + + return; +} diff --git a/StandaloneMmPkg/Core/Page.c b/StandaloneMmPkg/Core/Page.c index 8ee85d19db..5b94876b82 100644 --- a/StandaloneMmPkg/Core/Page.c +++ b/StandaloneMmPkg/Core/Page.c @@ -9,15 +9,447 @@ #include "StandaloneMmCore.h" -#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ - ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size))) - #define TRUNCATE_TO_PAGES(a) ((a) >> EFI_PAGE_SHIFT) LIST_ENTRY mMmMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (mMmMemoryMap); UINTN mMapKey; +// +// For GetMemoryMap() +// + +#define MEMORY_MAP_SIGNATURE SIGNATURE_32('m','m','a','p') +typedef struct { + UINTN Signature; + LIST_ENTRY Link; + + BOOLEAN FromStack; + EFI_MEMORY_TYPE Type; + UINT64 Start; + UINT64 End; +} MEMORY_MAP; + +LIST_ENTRY gMemoryMap = INITIALIZE_LIST_HEAD_VARIABLE (gMemoryMap); + +#define MAX_MAP_DEPTH 6 + +/// +/// mMapDepth - depth of new descriptor stack +/// +UINTN mMapDepth = 0; +/// +/// mMapStack - space to use as temp storage to build new map descriptors +/// +MEMORY_MAP mMapStack[MAX_MAP_DEPTH]; +UINTN mFreeMapStack = 0; +/// +/// This list maintain the free memory map list +/// +LIST_ENTRY mFreeMemoryMapEntryList = INITIALIZE_LIST_HEAD_VARIABLE (mFreeMemoryMapEntryList); + +/** + Allocates pages from the memory map. + + @param[in] Type The type of allocation to perform. + @param[in] MemoryType The type of memory to turn the allocated pages + into. + @param[in] NumberOfPages The number of pages to allocate. + @param[out] Memory A pointer to receive the base allocated memory + address. + @param[in] AddRegion If this memory is new added region. + + @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. + @retval EFI_NOT_FOUND Could not allocate pages match the requirement. + @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. + @retval EFI_SUCCESS Pages successfully allocated. + +**/ +EFI_STATUS +MmInternalAllocatePagesEx ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + OUT EFI_PHYSICAL_ADDRESS *Memory, + IN BOOLEAN AddRegion + ); + +/** + Internal function. Deque a descriptor entry from the mFreeMemoryMapEntryList. + If the list is empty, then allocate a new page to refuel the list. + Please Note this algorithm to allocate the memory map descriptor has a property + that the memory allocated for memory entries always grows, and will never really be freed. + + @return The Memory map descriptor dequeued from the mFreeMemoryMapEntryList + +**/ +MEMORY_MAP * +AllocateMemoryMapEntry ( + VOID + ) +{ + EFI_PHYSICAL_ADDRESS Mem; + EFI_STATUS Status; + MEMORY_MAP *FreeDescriptorEntries; + MEMORY_MAP *Entry; + UINTN Index; + + // DEBUG((DEBUG_INFO, "AllocateMemoryMapEntry\n")); + + if (IsListEmpty (&mFreeMemoryMapEntryList)) { + // DEBUG((DEBUG_INFO, "mFreeMemoryMapEntryList is empty\n")); + // + // The list is empty, to allocate one page to refuel the list + // + Status = MmInternalAllocatePagesEx ( + AllocateAnyPages, + EfiRuntimeServicesData, + EFI_SIZE_TO_PAGES (RUNTIME_PAGE_ALLOCATION_GRANULARITY), + &Mem, + TRUE + ); + ASSERT_EFI_ERROR (Status); + if (!EFI_ERROR (Status)) { + FreeDescriptorEntries = (MEMORY_MAP *)(UINTN)Mem; + // DEBUG((DEBUG_INFO, "New FreeDescriptorEntries - 0x%x\n", FreeDescriptorEntries)); + // + // Enqueue the free memory map entries into the list + // + for (Index = 0; Index < RUNTIME_PAGE_ALLOCATION_GRANULARITY / sizeof (MEMORY_MAP); Index++) { + FreeDescriptorEntries[Index].Signature = MEMORY_MAP_SIGNATURE; + InsertTailList (&mFreeMemoryMapEntryList, &FreeDescriptorEntries[Index].Link); + } + } else { + return NULL; + } + } + + // + // dequeue the first descriptor from the list + // + Entry = CR (mFreeMemoryMapEntryList.ForwardLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + RemoveEntryList (&Entry->Link); + + return Entry; +} + +/** + Internal function. Moves any memory descriptors that are on the + temporary descriptor stack to heap. + +**/ +VOID +CoreFreeMemoryMapStack ( + VOID + ) +{ + MEMORY_MAP *Entry; + + // + // If already freeing the map stack, then return + // + if (mFreeMapStack != 0) { + ASSERT (FALSE); + return; + } + + // + // Move the temporary memory descriptor stack into pool + // + mFreeMapStack += 1; + + while (mMapDepth != 0) { + // + // Deque an memory map entry from mFreeMemoryMapEntryList + // + Entry = AllocateMemoryMapEntry (); + ASSERT (Entry); + if (Entry == NULL) { + return; + } + + // + // Update to proper entry + // + mMapDepth -= 1; + + if (mMapStack[mMapDepth].Link.ForwardLink != NULL) { + CopyMem (Entry, &mMapStack[mMapDepth], sizeof (MEMORY_MAP)); + Entry->FromStack = FALSE; + + // + // Move this entry to general memory + // + InsertTailList (&mMapStack[mMapDepth].Link, &Entry->Link); + RemoveEntryList (&mMapStack[mMapDepth].Link); + mMapStack[mMapDepth].Link.ForwardLink = NULL; + } + } + + mFreeMapStack -= 1; +} + +/** + Insert new entry from memory map. + + @param[in] Link The old memory map entry to be linked. + @param[in] Start The start address of new memory map entry. + @param[in] End The end address of new memory map entry. + @param[in] Type The type of new memory map entry. + @param[in] Next If new entry is inserted to the next of old entry. + @param[in] AddRegion If this memory is new added region. +**/ +VOID +InsertNewEntry ( + IN LIST_ENTRY *Link, + IN UINT64 Start, + IN UINT64 End, + IN EFI_MEMORY_TYPE Type, + IN BOOLEAN Next, + IN BOOLEAN AddRegion + ) +{ + MEMORY_MAP *Entry; + + Entry = &mMapStack[mMapDepth]; + mMapDepth += 1; + ASSERT (mMapDepth < MAX_MAP_DEPTH); + Entry->FromStack = TRUE; + + Entry->Signature = MEMORY_MAP_SIGNATURE; + Entry->Type = Type; + Entry->Start = Start; + Entry->End = End; + if (Next) { + InsertHeadList (Link, &Entry->Link); + } else { + InsertTailList (Link, &Entry->Link); + } +} + +/** + Remove old entry from memory map. + + @param[in] Entry Memory map entry to be removed. +**/ +VOID +RemoveOldEntry ( + IN MEMORY_MAP *Entry + ) +{ + RemoveEntryList (&Entry->Link); + Entry->Link.ForwardLink = NULL; + + if (!Entry->FromStack) { + InsertTailList (&mFreeMemoryMapEntryList, &Entry->Link); + } +} + +/** + Update MM memory map entry. + + @param[in] Type The type of allocation to perform. + @param[in] Memory The base of memory address. + @param[in] NumberOfPages The number of pages to allocate. + @param[in] AddRegion If this memory is new added region. +**/ +VOID +ConvertMmMemoryMapEntry ( + IN EFI_MEMORY_TYPE Type, + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages, + IN BOOLEAN AddRegion + ) +{ + LIST_ENTRY *Link; + MEMORY_MAP *Entry; + MEMORY_MAP *NextEntry; + LIST_ENTRY *NextLink; + MEMORY_MAP *PreviousEntry; + LIST_ENTRY *PreviousLink; + EFI_PHYSICAL_ADDRESS Start; + EFI_PHYSICAL_ADDRESS End; + + Start = Memory; + End = Memory + EFI_PAGES_TO_SIZE (NumberOfPages) - 1; + + // + // Exclude memory region + // + Link = gMemoryMap.ForwardLink; + while (Link != &gMemoryMap) { + Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + Link = Link->ForwardLink; + + // + // --------------------------------------------------- + // | +----------+ +------+ +------+ +------+ | + // ---|gMemoryMep|---|Entry1|---|Entry2|---|Entry3|--- + // +----------+ ^ +------+ +------+ +------+ + // | + // +------+ + // |EntryX| + // +------+ + // + if (Entry->Start > End) { + if ((Entry->Start == End + 1) && (Entry->Type == Type)) { + Entry->Start = Start; + return; + } + + InsertNewEntry ( + &Entry->Link, + Start, + End, + Type, + FALSE, + AddRegion + ); + return; + } + + if ((Entry->Start <= Start) && (Entry->End >= End)) { + if (Entry->Type != Type) { + if (Entry->Start < Start) { + // + // --------------------------------------------------- + // | +----------+ +------+ +------+ +------+ | + // ---|gMemoryMep|---|Entry1|---|EntryX|---|Entry3|--- + // +----------+ +------+ ^ +------+ +------+ + // | + // +------+ + // |EntryA| + // +------+ + // + InsertNewEntry ( + &Entry->Link, + Entry->Start, + Start - 1, + Entry->Type, + FALSE, + AddRegion + ); + } + + if (Entry->End > End) { + // + // --------------------------------------------------- + // | +----------+ +------+ +------+ +------+ | + // ---|gMemoryMep|---|Entry1|---|EntryX|---|Entry3|--- + // +----------+ +------+ +------+ ^ +------+ + // | + // +------+ + // |EntryZ| + // +------+ + // + InsertNewEntry ( + &Entry->Link, + End + 1, + Entry->End, + Entry->Type, + TRUE, + AddRegion + ); + } + + // + // Update this node + // + Entry->Start = Start; + Entry->End = End; + Entry->Type = Type; + + // + // Check adjacent + // + NextLink = Entry->Link.ForwardLink; + if (NextLink != &gMemoryMap) { + NextEntry = CR (NextLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + // + // --------------------------------------------------- + // | +----------+ +------+ +-----------------+ | + // ---|gMemoryMep|---|Entry1|---|EntryX Entry3|--- + // +----------+ +------+ +-----------------+ + // + if ((Entry->Type == NextEntry->Type) && (Entry->End + 1 == NextEntry->Start)) { + Entry->End = NextEntry->End; + RemoveOldEntry (NextEntry); + } + } + + PreviousLink = Entry->Link.BackLink; + if (PreviousLink != &gMemoryMap) { + PreviousEntry = CR (PreviousLink, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + // + // --------------------------------------------------- + // | +----------+ +-----------------+ +------+ | + // ---|gMemoryMep|---|Entry1 EntryX|---|Entry3|--- + // +----------+ +-----------------+ +------+ + // + if ((PreviousEntry->Type == Entry->Type) && (PreviousEntry->End + 1 == Entry->Start)) { + PreviousEntry->End = Entry->End; + RemoveOldEntry (Entry); + } + } + } + + return; + } + } + + // + // --------------------------------------------------- + // | +----------+ +------+ +------+ +------+ | + // ---|gMemoryMep|---|Entry1|---|Entry2|---|Entry3|--- + // +----------+ +------+ +------+ +------+ ^ + // | + // +------+ + // |EntryX| + // +------+ + // + Link = gMemoryMap.BackLink; + if (Link != &gMemoryMap) { + Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + if ((Entry->End + 1 == Start) && (Entry->Type == Type)) { + Entry->End = End; + return; + } + } + + InsertNewEntry ( + &gMemoryMap, + Start, + End, + Type, + FALSE, + AddRegion + ); + return; +} + +/** + Return the count of Mm memory map entry. + + @return The count of Mm memory map entry. +**/ +UINTN +GetMmMemoryMapEntryCount ( + VOID + ) +{ + LIST_ENTRY *Link; + UINTN Count; + + Count = 0; + Link = gMemoryMap.ForwardLink; + while (Link != &gMemoryMap) { + Link = Link->ForwardLink; + Count++; + } + + return Count; +} + /** Internal Function. Allocate n pages from given free page node. @@ -136,12 +568,13 @@ InternalAllocAddress ( /** Allocates pages from the memory map. - @param Type The type of allocation to perform. - @param MemoryType The type of memory to turn the allocated pages - into. - @param NumberOfPages The number of pages to allocate. - @param Memory A pointer to receive the base allocated memory - address. + @param[in] Type The type of allocation to perform. + @param[in] MemoryType The type of memory to turn the allocated pages + into. + @param[in] NumberOfPages The number of pages to allocate. + @param[out] Memory A pointer to receive the base allocated memory + address. + @param[in] AddRegion If this memory is new added region. @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. @retval EFI_NOT_FOUND Could not allocate pages match the requirement. @@ -150,12 +583,12 @@ InternalAllocAddress ( **/ EFI_STATUS -EFIAPI -MmInternalAllocatePages ( +MmInternalAllocatePagesEx ( IN EFI_ALLOCATE_TYPE Type, IN EFI_MEMORY_TYPE MemoryType, IN UINTN NumberOfPages, - OUT EFI_PHYSICAL_ADDRESS *Memory + OUT EFI_PHYSICAL_ADDRESS *Memory, + IN BOOLEAN AddRegion ) { UINTN RequestedAddress; @@ -203,9 +636,51 @@ MmInternalAllocatePages ( return EFI_INVALID_PARAMETER; } + // + // Update MmMemoryMap here. + // + ConvertMmMemoryMapEntry (MemoryType, *Memory, NumberOfPages, AddRegion); + if (!AddRegion) { + CoreFreeMemoryMapStack (); + } + return EFI_SUCCESS; } +/** + Allocates pages from the memory map. + + @param[in] Type The type of allocation to perform. + @param[in] MemoryType The type of memory to turn the allocated pages + into. + @param[in] NumberOfPages The number of pages to allocate. + @param[out] Memory A pointer to receive the base allocated memory + address. + + @retval EFI_INVALID_PARAMETER Parameters violate checking rules defined in spec. + @retval EFI_NOT_FOUND Could not allocate pages match the requirement. + @retval EFI_OUT_OF_RESOURCES No enough pages to allocate. + @retval EFI_SUCCESS Pages successfully allocated. + +**/ +EFI_STATUS +EFIAPI +MmInternalAllocatePages ( + IN EFI_ALLOCATE_TYPE Type, + IN EFI_MEMORY_TYPE MemoryType, + IN UINTN NumberOfPages, + OUT EFI_PHYSICAL_ADDRESS *Memory + ) +{ + return MmInternalAllocatePagesEx ( + Type, + MemoryType, + NumberOfPages, + Memory, + FALSE + ); +} + /** Allocates pages from the memory map. @@ -269,19 +744,20 @@ InternalMergeNodes ( /** Frees previous allocated pages. - @param Memory Base address of memory being freed. - @param NumberOfPages The number of pages to free. + @param[in] Memory Base address of memory being freed. + @param[in] NumberOfPages The number of pages to free. + @param[in] AddRegion If this memory is new added region. @retval EFI_NOT_FOUND Could not find the entry that covers the range. - @retval EFI_INVALID_PARAMETER Address not aligned. + @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. @return EFI_SUCCESS Pages successfully freed. **/ EFI_STATUS -EFIAPI -MmInternalFreePages ( +MmInternalFreePagesEx ( IN EFI_PHYSICAL_ADDRESS Memory, - IN UINTN NumberOfPages + IN UINTN NumberOfPages, + IN BOOLEAN AddRegion ) { LIST_ENTRY *Node; @@ -329,9 +805,38 @@ MmInternalFreePages ( InternalMergeNodes (Pages); } + // + // Update MmMemoryMap here. + // + ConvertMmMemoryMapEntry (EfiConventionalMemory, Memory, NumberOfPages, AddRegion); + if (!AddRegion) { + CoreFreeMemoryMapStack (); + } + return EFI_SUCCESS; } +/** + Frees previous allocated pages. + + @param[in] Memory Base address of memory being freed. + @param[in] NumberOfPages The number of pages to free. + + @retval EFI_NOT_FOUND Could not find the entry that covers the range. + @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. + @return EFI_SUCCESS Pages successfully freed. + +**/ +EFI_STATUS +EFIAPI +MmInternalFreePages ( + IN EFI_PHYSICAL_ADDRESS Memory, + IN UINTN NumberOfPages + ) +{ + return MmInternalFreePagesEx (Memory, NumberOfPages, FALSE); +} + /** Frees previous allocated pages. @@ -339,7 +844,7 @@ MmInternalFreePages ( @param NumberOfPages The number of pages to free. @retval EFI_NOT_FOUND Could not find the entry that covers the range. - @retval EFI_INVALID_PARAMETER Address not aligned. + @retval EFI_INVALID_PARAMETER Address not aligned, Address is zero or NumberOfPages is zero. @return EFI_SUCCESS Pages successfully freed. **/ @@ -376,10 +881,12 @@ MmAddMemoryRegion ( UINTN AlignedMemBase; // - // Do not add memory regions that is already allocated, needs testing, or needs ECC initialization + // Add EfiRuntimeServicesData for memory regions that is already allocated, needs testing, or needs ECC initialization // if ((Attributes & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { - return; + Type = EfiRuntimeServicesData; + } else { + Type = EfiConventionalMemory; } // @@ -387,5 +894,102 @@ MmAddMemoryRegion ( // AlignedMemBase = (UINTN)(MemBase + EFI_PAGE_MASK) & ~EFI_PAGE_MASK; MemLength -= AlignedMemBase - MemBase; - MmFreePages (AlignedMemBase, TRUNCATE_TO_PAGES ((UINTN)MemLength)); + if (Type == EfiConventionalMemory) { + MmInternalFreePagesEx (AlignedMemBase, TRUNCATE_TO_PAGES ((UINTN)MemLength), TRUE); + } else { + ConvertMmMemoryMapEntry (EfiRuntimeServicesData, AlignedMemBase, TRUNCATE_TO_PAGES ((UINTN)MemLength), TRUE); + } + + CoreFreeMemoryMapStack (); +} + +/** + This function returns a copy of the current memory map. The map is an array of + memory descriptors, each of which describes a contiguous block of memory. + + @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the buffer allocated by the caller. On output, + it is the size of the buffer returned by the + firmware if the buffer was large enough, or the + size of the buffer needed to contain the map if + the buffer was too small. + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[out] MapKey A pointer to the location in which firmware + returns the key for the current memory map. + @param[out] DescriptorSize A pointer to the location in which firmware + returns the size, in bytes, of an individual + EFI_MEMORY_DESCRIPTOR. + @param[out] DescriptorVersion A pointer to the location in which firmware + returns the version number associated with the + EFI_MEMORY_DESCRIPTOR. + + @retval EFI_SUCCESS The memory map was returned in the MemoryMap + buffer. + @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current + buffer size needed to hold the memory map is + returned in MemoryMapSize. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +MmCoreGetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ) +{ + UINTN Count; + LIST_ENTRY *Link; + MEMORY_MAP *Entry; + UINTN Size; + UINTN BufferSize; + + Size = sizeof (EFI_MEMORY_DESCRIPTOR); + + // + // Make sure Size != sizeof(EFI_MEMORY_DESCRIPTOR). This will + // prevent people from having pointer math bugs in their code. + // now you have to use *DescriptorSize to make things work. + // + Size += sizeof (UINT64) - (Size % sizeof (UINT64)); + + if (DescriptorSize != NULL) { + *DescriptorSize = Size; + } + + if (DescriptorVersion != NULL) { + *DescriptorVersion = EFI_MEMORY_DESCRIPTOR_VERSION; + } + + Count = GetMmMemoryMapEntryCount (); + BufferSize = Size * Count; + if (*MemoryMapSize < BufferSize) { + *MemoryMapSize = BufferSize; + return EFI_BUFFER_TOO_SMALL; + } + + *MemoryMapSize = BufferSize; + if (MemoryMap == NULL) { + return EFI_INVALID_PARAMETER; + } + + ZeroMem (MemoryMap, BufferSize); + Link = gMemoryMap.ForwardLink; + while (Link != &gMemoryMap) { + Entry = CR (Link, MEMORY_MAP, Link, MEMORY_MAP_SIGNATURE); + Link = Link->ForwardLink; + + MemoryMap->Type = Entry->Type; + MemoryMap->PhysicalStart = Entry->Start; + MemoryMap->NumberOfPages = RShiftU64 (Entry->End - Entry->Start + 1, EFI_PAGE_SHIFT); + + MemoryMap = NEXT_MEMORY_DESCRIPTOR (MemoryMap, Size); + } + + return EFI_SUCCESS; } diff --git a/StandaloneMmPkg/Core/Pool.c b/StandaloneMmPkg/Core/Pool.c index 282caa9869..80a879c15b 100644 --- a/StandaloneMmPkg/Core/Pool.c +++ b/StandaloneMmPkg/Core/Pool.c @@ -40,6 +40,7 @@ MmInitializeMemoryServices ( // // Initialize free MMRAM regions + // Need add Free memory at first, to let mMmMemoryMap record data // for (Index = 0; Index < MmramRangeCount; Index++) { // @@ -49,6 +50,10 @@ MmInitializeMemoryServices ( continue; } + if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) != 0) { + continue; + } + DEBUG (( DEBUG_INFO, "MmAddMemoryRegion %d : 0x%016lx - 0x%016lx\n", @@ -63,6 +68,26 @@ MmInitializeMemoryServices ( MmramRanges[Index].RegionState ); } + + for (Index = 0; Index < MmramRangeCount; Index++) { + // + // BUGBUG: Add legacy MMRAM region is buggy. + // + if (MmramRanges[Index].CpuStart < BASE_1MB) { + continue; + } + + if ((MmramRanges[Index].RegionState & (EFI_ALLOCATED | EFI_NEEDS_TESTING | EFI_NEEDS_ECC_INITIALIZATION)) == 0) { + continue; + } + + MmAddMemoryRegion ( + MmramRanges[Index].CpuStart, + MmramRanges[Index].PhysicalSize, + EfiConventionalMemory, + MmramRanges[Index].RegionState + ); + } } /** diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.h b/StandaloneMmPkg/Core/StandaloneMmCore.h index 632ded9b27..093a35fb56 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.h +++ b/StandaloneMmPkg/Core/StandaloneMmCore.h @@ -31,6 +31,7 @@ #include #include #include +#include #include #include @@ -42,6 +43,8 @@ #include #include #include +#include +#include #include #include @@ -514,6 +517,38 @@ MmLocateHandle ( OUT EFI_HANDLE *Buffer ); +/** + Function returns an array of handles that support the requested protocol + in a buffer allocated from pool. This is a version of MmLocateHandle() + that allocates a buffer for the caller. + + @param SearchType Specifies which handle(s) are to be returned. + @param Protocol Provides the protocol to search by. This + parameter is only valid for SearchType + ByProtocol. + @param SearchKey Supplies the search key depending on the + SearchType. + @param NumberHandles The number of handles returned in Buffer. + @param Buffer A pointer to the buffer to return the requested + array of handles that support Protocol. + + @retval EFI_SUCCESS The result array of handles was returned. + @retval EFI_NOT_FOUND No handles match the search. + @retval EFI_OUT_OF_RESOURCES There is not enough pool memory to store the + matching results. + @retval EFI_INVALID_PARAMETER One or more parameters are not valid. + +**/ +EFI_STATUS +EFIAPI +MmLocateHandleBuffer ( + IN EFI_LOCATE_SEARCH_TYPE SearchType, + IN EFI_GUID *Protocol OPTIONAL, + IN VOID *SearchKey OPTIONAL, + IN OUT UINTN *NumberHandles, + OUT EFI_HANDLE **Buffer + ); + /** Return the first Protocol Interface that matches the Protocol GUID. If Registration is passed in return a Protocol Instance that was just add @@ -895,7 +930,56 @@ MmCoreFfsFindMmDriver ( IN UINT32 Depth ); -extern UINTN mMmramRangeCount; -extern EFI_MMRAM_DESCRIPTOR *mMmramRanges; +#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \ + ((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size))) + +/** + Initialize MemoryAttributesTable support. +**/ +VOID +EFIAPI +MmCoreInitializeMemoryAttributesTable ( + VOID + ); + +/** + This function returns a copy of the current memory map. The map is an array of + memory descriptors, each of which describes a contiguous block of memory. + + @param[in, out] MemoryMapSize A pointer to the size, in bytes, of the + MemoryMap buffer. On input, this is the size of + the buffer allocated by the caller. On output, + it is the size of the buffer returned by the + firmware if the buffer was large enough, or the + size of the buffer needed to contain the map if + the buffer was too small. + @param[in, out] MemoryMap A pointer to the buffer in which firmware places + the current memory map. + @param[out] MapKey A pointer to the location in which firmware + returns the key for the current memory map. + @param[out] DescriptorSize A pointer to the location in which firmware + returns the size, in bytes, of an individual + EFI_MEMORY_DESCRIPTOR. + @param[out] DescriptorVersion A pointer to the location in which firmware + returns the version number associated with the + EFI_MEMORY_DESCRIPTOR. + + @retval EFI_SUCCESS The memory map was returned in the MemoryMap + buffer. + @retval EFI_BUFFER_TOO_SMALL The MemoryMap buffer was too small. The current + buffer size needed to hold the memory map is + returned in MemoryMapSize. + @retval EFI_INVALID_PARAMETER One of the parameters has an invalid value. + +**/ +EFI_STATUS +EFIAPI +MmCoreGetMemoryMap ( + IN OUT UINTN *MemoryMapSize, + IN OUT EFI_MEMORY_DESCRIPTOR *MemoryMap, + OUT UINTN *MapKey, + OUT UINTN *DescriptorSize, + OUT UINT32 *DescriptorVersion + ); #endif diff --git a/StandaloneMmPkg/Core/StandaloneMmCore.inf b/StandaloneMmPkg/Core/StandaloneMmCore.inf index 58c3bdee03..f5ecda3a06 100644 --- a/StandaloneMmPkg/Core/StandaloneMmCore.inf +++ b/StandaloneMmPkg/Core/StandaloneMmCore.inf @@ -33,6 +33,7 @@ Mmi.c InstallConfigurationTable.c FwVol.c + MemoryAttributesTable.c [Packages] MdePkg/MdePkg.dec @@ -53,6 +54,7 @@ ReportStatusCodeLib StandaloneMmCoreEntryPoint HobPrintLib + ImagePropertiesRecordLib [Protocols] gEfiDxeMmReadyToLockProtocolGuid ## UNDEFINED # SmiHandlerRegister @@ -78,6 +80,7 @@ gEfiEventReadyToBootGuid gMmCommBufferHobGuid gEfiSmmSmramMemoryGuid + gEdkiiPiSmmMemoryAttributesTableGuid [Pcd] gStandaloneMmPkgTokenSpaceGuid.PcdFwVolMmMaxEncapsulationDepth ##CONSUMES diff --git a/StandaloneMmPkg/StandaloneMmPkg.dsc b/StandaloneMmPkg/StandaloneMmPkg.dsc index a2410f37d3..02ab3d749e 100644 --- a/StandaloneMmPkg/StandaloneMmPkg.dsc +++ b/StandaloneMmPkg/StandaloneMmPkg.dsc @@ -61,6 +61,8 @@ VariableMmDependency|StandaloneMmPkg/Library/VariableMmDependency/VariableMmDependency.inf HobPrintLib|MdeModulePkg/Library/HobPrintLib/HobPrintLib.inf MmPlatformHobProducerLib|StandaloneMmPkg/Library/MmPlatformHobProducerLibNull/MmPlatformHobProducerLibNull.inf + ImagePropertiesRecordLib|MdeModulePkg/Library/ImagePropertiesRecordLib/ImagePropertiesRecordLib.inf + PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf [LibraryClasses.common.PEIM] HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf