+/**\r
+ Notification for SMM EndOfDxe protocol.\r
+\r
+ @param[in] Protocol Points to the protocol's unique identifier.\r
+ @param[in] Interface Points to the interface instance.\r
+ @param[in] Handle The handle on which the interface was installed.\r
+\r
+ @retval EFI_SUCCESS Notification runs successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmLibInternalEndOfDxeNotify (\r
+ IN CONST EFI_GUID *Protocol,\r
+ IN VOID *Interface,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ UINTN MapKey;\r
+ UINTN MemoryMapSize;\r
+ EFI_MEMORY_DESCRIPTOR *MemoryMap;\r
+ EFI_MEMORY_DESCRIPTOR *MemoryMapStart;\r
+ EFI_MEMORY_DESCRIPTOR *SmmMemoryMapStart;\r
+ UINTN MemoryMapEntryCount;\r
+ UINTN DescriptorSize;\r
+ UINT32 DescriptorVersion;\r
+ UINTN Index;\r
+\r
+ MemoryMapSize = 0;\r
+ MemoryMap = NULL;\r
+ Status = gBS->GetMemoryMap (\r
+ &MemoryMapSize,\r
+ MemoryMap,\r
+ &MapKey,\r
+ &DescriptorSize,\r
+ &DescriptorVersion\r
+ );\r
+ ASSERT (Status == EFI_BUFFER_TOO_SMALL);\r
+\r
+ do {\r
+ Status = gBS->AllocatePool (EfiBootServicesData, MemoryMapSize, (VOID **)&MemoryMap);\r
+ ASSERT (MemoryMap != NULL);\r
+ \r
+ Status = gBS->GetMemoryMap (\r
+ &MemoryMapSize,\r
+ MemoryMap,\r
+ &MapKey,\r
+ &DescriptorSize,\r
+ &DescriptorVersion\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ gBS->FreePool (MemoryMap);\r
+ }\r
+ } while (Status == EFI_BUFFER_TOO_SMALL);\r
+\r
+ //\r
+ // Get Count\r
+ //\r
+ mDescriptorSize = DescriptorSize;\r
+ MemoryMapEntryCount = MemoryMapSize/DescriptorSize;\r
+ MemoryMapStart = MemoryMap;\r
+ mMemoryMapEntryCount = 0;\r
+ for (Index = 0; Index < MemoryMapEntryCount; Index++) {\r
+ switch (MemoryMap->Type) {\r
+ case EfiReservedMemoryType:\r
+ case EfiRuntimeServicesCode:\r
+ case EfiRuntimeServicesData:\r
+ case EfiACPIMemoryNVS:\r
+ mMemoryMapEntryCount++;\r
+ break;\r
+ }\r
+ MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);\r
+ }\r
+ MemoryMap = MemoryMapStart;\r
+ \r
+ //\r
+ // Get Data\r
+ //\r
+ mMemoryMap = AllocatePool (mMemoryMapEntryCount*DescriptorSize);\r
+ ASSERT (mMemoryMap != NULL);\r
+ SmmMemoryMapStart = mMemoryMap;\r
+ for (Index = 0; Index < MemoryMapEntryCount; Index++) {\r
+ switch (MemoryMap->Type) {\r
+ case EfiReservedMemoryType:\r
+ case EfiRuntimeServicesCode:\r
+ case EfiRuntimeServicesData:\r
+ case EfiACPIMemoryNVS:\r
+ CopyMem (mMemoryMap, MemoryMap, DescriptorSize);\r
+ mMemoryMap = NEXT_MEMORY_DESCRIPTOR(mMemoryMap, DescriptorSize);\r
+ break;\r
+ }\r
+ MemoryMap = NEXT_MEMORY_DESCRIPTOR(MemoryMap, DescriptorSize);\r
+ }\r
+ mMemoryMap = SmmMemoryMapStart;\r
+ MemoryMap = MemoryMapStart;\r
+ \r
+ gBS->FreePool (MemoryMap);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r
+/**\r
+ Notification for SMM ReadyToLock protocol.\r
+\r
+ @param[in] Protocol Points to the protocol's unique identifier.\r
+ @param[in] Interface Points to the interface instance.\r
+ @param[in] Handle The handle on which the interface was installed.\r
+\r
+ @retval EFI_SUCCESS Notification runs successfully.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmLibInternalReadyToLockNotify (\r
+ IN CONST EFI_GUID *Protocol,\r
+ IN VOID *Interface,\r
+ IN EFI_HANDLE Handle\r
+ )\r
+{\r
+ mSmmReadyToLock = TRUE;\r
+ return EFI_SUCCESS;\r
+}\r