#include <Library/DebugLib.h>\r
#include <Library/MemoryAllocationLib.h>\r
#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/DxeServicesTableLib.h>\r
#include <Library/SmmServicesTableLib.h>\r
#include <Library/HobLib.h>\r
#include <Protocol/SmmAccess2.h>\r
#include <Protocol/SmmReadyToLock.h>\r
#include <Protocol/SmmEndOfDxe.h>\r
\r
+//\r
+// attributes for reserved memory before it is promoted to system memory\r
+//\r
+#define EFI_MEMORY_PRESENT 0x0100000000000000ULL\r
+#define EFI_MEMORY_INITIALIZED 0x0200000000000000ULL\r
+#define EFI_MEMORY_TESTED 0x0400000000000000ULL\r
+\r
#define NEXT_MEMORY_DESCRIPTOR(MemoryDescriptor, Size) \\r
((EFI_MEMORY_DESCRIPTOR *)((UINT8 *)(MemoryDescriptor) + (Size)))\r
\r
EFI_MEMORY_DESCRIPTOR *mMemoryMap;\r
UINTN mDescriptorSize;\r
\r
+EFI_GCD_MEMORY_SPACE_DESCRIPTOR *mSmmMemLibGcdMemSpace = NULL;\r
+UINTN mSmmMemLibGcdMemNumberOfDesc = 0;\r
+\r
VOID *mRegistrationEndOfDxe;\r
VOID *mRegistrationReadyToLock;\r
\r
-BOOLEAN mSmmReadyToLock = FALSE;\r
+BOOLEAN mSmmMemLibSmmReadyToLock = FALSE;\r
\r
/**\r
Calculate and save the maximum support address.\r
//\r
// Check override for Valid Communication Region\r
//\r
- if (mSmmReadyToLock) {\r
+ if (mSmmMemLibSmmReadyToLock) {\r
EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
BOOLEAN InValidCommunicationRegion;\r
\r
if (!InValidCommunicationRegion) {\r
DEBUG ((\r
EFI_D_ERROR,\r
- "SmmIsBufferOutsideSmmValid: Not in ValidCommunicationRegion: Buffer (0x%lx) - Length (0x%lx), ",\r
+ "SmmIsBufferOutsideSmmValid: Not in ValidCommunicationRegion: Buffer (0x%lx) - Length (0x%lx)\n",\r
Buffer,\r
Length\r
));\r
return FALSE;\r
}\r
+\r
+ //\r
+ // Check untested memory as invalid communication buffer.\r
+ //\r
+ for (Index = 0; Index < mSmmMemLibGcdMemNumberOfDesc; Index++) {\r
+ if (((Buffer >= mSmmMemLibGcdMemSpace[Index].BaseAddress) && (Buffer < mSmmMemLibGcdMemSpace[Index].BaseAddress + mSmmMemLibGcdMemSpace[Index].Length)) ||\r
+ ((mSmmMemLibGcdMemSpace[Index].BaseAddress >= Buffer) && (mSmmMemLibGcdMemSpace[Index].BaseAddress < Buffer + Length))) {\r
+ DEBUG ((\r
+ EFI_D_ERROR,\r
+ "SmmIsBufferOutsideSmmValid: In Untested Memory Region: Buffer (0x%lx) - Length (0x%lx)\n",\r
+ Buffer,\r
+ Length\r
+ ));\r
+ return FALSE;\r
+ }\r
+ }\r
}\r
return TRUE;\r
}\r
return EFI_SUCCESS;\r
}\r
\r
+/**\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
/**\r
Notification for SMM EndOfDxe protocol.\r
\r
\r
gBS->FreePool (MemoryMap);\r
\r
+ //\r
+ // Get additional information from GCD memory map.\r
+ //\r
+ SmmMemLibInternalGetGcdMemoryMap ();\r
+\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Notification for SMM ReadyToLock protocol.\r
\r
IN EFI_HANDLE Handle\r
)\r
{\r
- mSmmReadyToLock = TRUE;\r
+ mSmmMemLibSmmReadyToLock = TRUE;\r
return EFI_SUCCESS;\r
}\r
/**\r