+/**\r
+ Software SMI handler that is called when the EndOfDxe event is signalled.\r
+ This function installs the SMM EndOfDxe Protocol so SMM Drivers are informed that\r
+ platform code will invoke 3rd part code.\r
+\r
+ @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
+ @param Context Points to an optional handler context which was specified when the handler was registered.\r
+ @param CommBuffer A pointer to a collection of data in memory that will\r
+ be conveyed from a non-SMM environment into an SMM environment.\r
+ @param CommBufferSize The size of the CommBuffer.\r
+\r
+ @return Status Code\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmEndOfDxeHandler (\r
+ IN EFI_HANDLE DispatchHandle,\r
+ IN CONST VOID *Context, OPTIONAL\r
+ IN OUT VOID *CommBuffer, OPTIONAL\r
+ IN OUT UINTN *CommBufferSize OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE SmmHandle;\r
+ EFI_SMM_SX_DISPATCH2_PROTOCOL *SxDispatch;\r
+ EFI_SMM_SX_REGISTER_CONTEXT EntryRegisterContext;\r
+ EFI_HANDLE S3EntryHandle;\r
+\r
+ DEBUG ((EFI_D_INFO, "SmmEndOfDxeHandler\n"));\r
+\r
+ //\r
+ // Install SMM EndOfDxe protocol\r
+ //\r
+ SmmHandle = NULL;\r
+ Status = SmmInstallProtocolInterface (\r
+ &SmmHandle,\r
+ &gEfiSmmEndOfDxeProtocolGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ NULL\r
+ );\r
+\r
+ //\r
+ // Locate SmmSxDispatch2 protocol.\r
+ //\r
+ Status = SmmLocateProtocol (\r
+ &gEfiSmmSxDispatch2ProtocolGuid,\r
+ NULL,\r
+ (VOID **)&SxDispatch\r
+ );\r
+ if (!EFI_ERROR (Status) && (SxDispatch != NULL)) {\r
+ //\r
+ // Register a S3 entry callback function to\r
+ // determine if it will be during S3 resume.\r
+ //\r
+ EntryRegisterContext.Type = SxS3;\r
+ EntryRegisterContext.Phase = SxEntry;\r
+ Status = SxDispatch->Register (\r
+ SxDispatch,\r
+ SmmS3EntryCallBack,\r
+ &EntryRegisterContext,\r
+ &S3EntryHandle\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+ Software SMI handler that is called when the S3SmmInitDone signal is triggered.\r
+ This function installs the SMM S3SmmInitDone Protocol so SMM Drivers are informed that\r
+ S3 SMM initialization has been done.\r
+\r
+ @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
+ @param Context Points to an optional handler context which was specified when the handler was registered.\r
+ @param CommBuffer A pointer to a collection of data in memory that will\r
+ be conveyed from a non-SMM environment into an SMM environment.\r
+ @param CommBufferSize The size of the CommBuffer.\r
+\r
+ @return Status Code\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmS3SmmInitDoneHandler (\r
+ IN EFI_HANDLE DispatchHandle,\r
+ IN CONST VOID *Context, OPTIONAL\r
+ IN OUT VOID *CommBuffer, OPTIONAL\r
+ IN OUT UINTN *CommBufferSize OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE SmmHandle;\r
+\r
+ DEBUG ((DEBUG_INFO, "SmmS3SmmInitDoneHandler\n"));\r
+\r
+ if (!mDuringS3Resume) {\r
+ DEBUG ((DEBUG_ERROR, "It is not during S3 resume\n"));\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Install SMM S3SmmInitDone protocol\r
+ //\r
+ SmmHandle = NULL;\r
+ Status = SmmInstallProtocolInterface (\r
+ &SmmHandle,\r
+ &gEdkiiS3SmmInitDoneGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Uninstall the protocol here because the comsumer just hook the\r
+ // installation event.\r
+ //\r
+ Status = SmmUninstallProtocolInterface (\r
+ SmmHandle,\r
+ &gEdkiiS3SmmInitDoneGuid,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Software SMI handler that is called when the EndOfS3Resume signal is triggered.\r
+ This function installs the SMM EndOfS3Resume Protocol so SMM Drivers are informed that\r
+ S3 resume has finished.\r
+\r
+ @param DispatchHandle The unique handle assigned to this handler by SmiHandlerRegister().\r
+ @param Context Points to an optional handler context which was specified when the handler was registered.\r
+ @param CommBuffer A pointer to a collection of data in memory that will\r
+ be conveyed from a non-SMM environment into an SMM environment.\r
+ @param CommBufferSize The size of the CommBuffer.\r
+\r
+ @return Status Code\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmEndOfS3ResumeHandler (\r
+ IN EFI_HANDLE DispatchHandle,\r
+ IN CONST VOID *Context, OPTIONAL\r
+ IN OUT VOID *CommBuffer, OPTIONAL\r
+ IN OUT UINTN *CommBufferSize OPTIONAL\r
+ )\r
+{\r
+ EFI_STATUS Status;\r
+ EFI_HANDLE SmmHandle;\r
+\r
+ DEBUG ((DEBUG_INFO, "SmmEndOfS3ResumeHandler\n"));\r
+\r
+ if (!mDuringS3Resume) {\r
+ DEBUG ((DEBUG_ERROR, "It is not during S3 resume\n"));\r
+ return EFI_SUCCESS;\r
+ }\r
+\r
+ //\r
+ // Install SMM EndOfS3Resume protocol\r
+ //\r
+ SmmHandle = NULL;\r
+ Status = SmmInstallProtocolInterface (\r
+ &SmmHandle,\r
+ &gEdkiiEndOfS3ResumeGuid,\r
+ EFI_NATIVE_INTERFACE,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ //\r
+ // Uninstall the protocol here because the comsumer just hook the\r
+ // installation event.\r
+ //\r
+ Status = SmmUninstallProtocolInterface (\r
+ SmmHandle,\r
+ &gEdkiiEndOfS3ResumeGuid,\r
+ NULL\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ mDuringS3Resume = FALSE;\r
+ return Status;\r
+}\r
+\r
+/**\r
+ Determine if two buffers overlap in memory.\r
+\r
+ @param[in] Buff1 Pointer to first buffer\r
+ @param[in] Size1 Size of Buff1\r
+ @param[in] Buff2 Pointer to second buffer\r
+ @param[in] Size2 Size of Buff2\r
+\r
+ @retval TRUE Buffers overlap in memory.\r
+ @retval FALSE Buffer doesn't overlap.\r
+\r
+**/\r
+BOOLEAN\r
+InternalIsBufferOverlapped (\r
+ IN UINT8 *Buff1,\r
+ IN UINTN Size1,\r
+ IN UINT8 *Buff2,\r
+ IN UINTN Size2\r
+ )\r
+{\r
+ //\r
+ // If buff1's end is less than the start of buff2, then it's ok.\r
+ // Also, if buff1's start is beyond buff2's end, then it's ok.\r
+ //\r
+ if (((Buff1 + Size1) <= Buff2) || (Buff1 >= (Buff2 + Size2))) {\r
+ return FALSE;\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r