+/**\r
+ Get GCD memory map.\r
+ Only record untested memory as invalid communication buffer.\r
+**/\r
+VOID\r
+SmmMemLibInternalGetGcdMemoryMap (\r
+ VOID\r
+ )\r
+{\r
+ UINTN NumberOfDescriptors;\r
+ EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemSpaceMap;\r
+ EFI_STATUS Status;\r
+ UINTN Index;\r
+\r
+ Status = gDS->GetMemorySpaceMap (&NumberOfDescriptors, &MemSpaceMap);\r
+ if (EFI_ERROR (Status)) {\r
+ return ;\r
+ }\r
+\r
+ mSmmMemLibGcdMemNumberOfDesc = 0;\r
+ for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
+ if (MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved &&\r
+ (MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==\r
+ (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)\r
+ ) {\r
+ mSmmMemLibGcdMemNumberOfDesc++;\r
+ }\r
+ }\r
+\r
+ mSmmMemLibGcdMemSpace = AllocateZeroPool (mSmmMemLibGcdMemNumberOfDesc * sizeof (EFI_GCD_MEMORY_SPACE_DESCRIPTOR));\r
+ ASSERT (mSmmMemLibGcdMemSpace != NULL);\r
+ if (mSmmMemLibGcdMemSpace == NULL) {\r
+ mSmmMemLibGcdMemNumberOfDesc = 0;\r
+ gBS->FreePool (MemSpaceMap);\r
+ return ;\r
+ }\r
+\r
+ mSmmMemLibGcdMemNumberOfDesc = 0;\r
+ for (Index = 0; Index < NumberOfDescriptors; Index++) {\r
+ if (MemSpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeReserved &&\r
+ (MemSpaceMap[Index].Capabilities & (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED | EFI_MEMORY_TESTED)) ==\r
+ (EFI_MEMORY_PRESENT | EFI_MEMORY_INITIALIZED)\r
+ ) {\r
+ CopyMem (\r
+ &mSmmMemLibGcdMemSpace[mSmmMemLibGcdMemNumberOfDesc],\r
+ &MemSpaceMap[Index],\r
+ sizeof(EFI_GCD_MEMORY_SPACE_DESCRIPTOR)\r
+ );\r
+ mSmmMemLibGcdMemNumberOfDesc++;\r
+ }\r
+ }\r
+\r
+ gBS->FreePool (MemSpaceMap);\r
+}\r
+\r