]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Core/PiSmmCore/PiSmmCore.c
MdeModulePkg/PiSmmCore: fix GCC build error
[mirror_edk2.git] / MdeModulePkg / Core / PiSmmCore / PiSmmCore.c
index 9e4390e15a1cbe69d44d57b0221ed8faaa297ac4..1ccb9c7787ad8b7e57edba1ab9f2bccbf6caa115 100644 (file)
@@ -71,17 +71,24 @@ EFI_SMM_SYSTEM_TABLE2  gSmmCoreSmst = {
 //\r
 BOOLEAN  mInLegacyBoot = FALSE;\r
 \r
+//\r
+// Flag to determine if it is during S3 resume.\r
+// It will be set in S3 entry callback and cleared at EndOfS3Resume.\r
+//\r
+BOOLEAN  mDuringS3Resume = FALSE;\r
+\r
 //\r
 // Table of SMI Handlers that are registered by the SMM Core when it is initialized\r
 //\r
 SMM_CORE_SMI_HANDLERS  mSmmCoreSmiHandlers[] = {\r
-  { SmmDriverDispatchHandler,   &gEfiEventDxeDispatchGuid,          NULL, TRUE  },\r
-  { SmmReadyToLockHandler,      &gEfiDxeSmmReadyToLockProtocolGuid, NULL, TRUE }, \r
-  { SmmLegacyBootHandler,       &gEfiEventLegacyBootGuid,           NULL, FALSE },\r
-  { SmmExitBootServicesHandler, &gEfiEventExitBootServicesGuid,     NULL, FALSE },\r
-  { SmmReadyToBootHandler,      &gEfiEventReadyToBootGuid,          NULL, FALSE },\r
-  { SmmEndOfDxeHandler,         &gEfiEndOfDxeEventGroupGuid,        NULL, TRUE },\r
-  { NULL,                       NULL,                               NULL, FALSE }\r
+  { SmmDriverDispatchHandler,   &gEfiEventDxeDispatchGuid,           NULL, TRUE  },\r
+  { SmmReadyToLockHandler,      &gEfiDxeSmmReadyToLockProtocolGuid,  NULL, TRUE }, \r
+  { SmmLegacyBootHandler,       &gEfiEventLegacyBootGuid,            NULL, FALSE },\r
+  { SmmExitBootServicesHandler, &gEfiEventExitBootServicesGuid,      NULL, FALSE },\r
+  { SmmReadyToBootHandler,      &gEfiEventReadyToBootGuid,           NULL, FALSE },\r
+  { SmmEndOfDxeHandler,         &gEfiEndOfDxeEventGroupGuid,         NULL, TRUE },\r
+  { SmmEndOfS3ResumeHandler,    &gEdkiiEndOfS3ResumeGuid,            NULL, FALSE },\r
+  { NULL,                       NULL,                                NULL, FALSE }\r
 };\r
 \r
 UINTN                           mFullSmramRangeCount;\r
@@ -150,6 +157,7 @@ SmmLegacyBootHandler (
 {\r
   EFI_STATUS    Status;\r
   EFI_HANDLE    SmmHandle;\r
+  UINTN         Index;\r
 \r
   //\r
   // Install SMM Legacy Boot protocol.\r
@@ -166,6 +174,16 @@ SmmLegacyBootHandler (
 \r
   SmiHandlerUnRegister (DispatchHandle);\r
 \r
+  //\r
+  // It is legacy boot, unregister ExitBootService SMI handler.\r
+  //\r
+  for (Index = 0; mSmmCoreSmiHandlers[Index].HandlerType != NULL; Index++) {\r
+    if (CompareGuid (mSmmCoreSmiHandlers[Index].HandlerType, &gEfiEventExitBootServicesGuid)) {\r
+      SmiHandlerUnRegister (mSmmCoreSmiHandlers[Index].DispatchHandle);\r
+      break;\r
+    }\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -194,6 +212,7 @@ SmmExitBootServicesHandler (
 {\r
   EFI_STATUS    Status;\r
   EFI_HANDLE    SmmHandle;\r
+  UINTN         Index;\r
 \r
   //\r
   // Install SMM Exit Boot Services protocol.\r
@@ -208,9 +227,50 @@ SmmExitBootServicesHandler (
 \r
   SmiHandlerUnRegister (DispatchHandle);\r
 \r
+  //\r
+  // It is UEFI boot, unregister LegacyBoot SMI handler.\r
+  //\r
+  for (Index = 0; mSmmCoreSmiHandlers[Index].HandlerType != NULL; Index++) {\r
+    if (CompareGuid (mSmmCoreSmiHandlers[Index].HandlerType, &gEfiEventLegacyBootGuid)) {\r
+      SmiHandlerUnRegister (mSmmCoreSmiHandlers[Index].DispatchHandle);\r
+      break;\r
+    }\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
+/**\r
+  Main entry point for an SMM handler dispatch or communicate-based callback.\r
+\r
+  @param[in]     DispatchHandle  The unique handle assigned to this handler by SmiHandlerRegister().\r
+  @param[in]     Context         Points to an optional handler context which was specified when the\r
+                                 handler was registered.\r
+  @param[in,out] 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[in,out] CommBufferSize  The size of the CommBuffer.\r
+\r
+  @retval EFI_SUCCESS                         The interrupt was handled and quiesced. No other handlers\r
+                                              should still be called.\r
+  @retval EFI_WARN_INTERRUPT_SOURCE_QUIESCED  The interrupt has been quiesced but other handlers should\r
+                                              still be called.\r
+  @retval EFI_WARN_INTERRUPT_SOURCE_PENDING   The interrupt is still pending and other handlers should still\r
+                                              be called.\r
+  @retval EFI_INTERRUPT_PENDING               The interrupt could not be quiesced.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+SmmS3EntryCallBack (\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
+  mDuringS3Resume = TRUE;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 /**\r
   Software SMI handler that is called when an Ready To Boot event is signalled.\r
   Then the SMM Core also install SMM Ready To Boot protocol to notify SMM driver\r
@@ -234,8 +294,11 @@ SmmReadyToBootHandler (
   IN OUT UINTN       *CommBufferSize  OPTIONAL\r
   )\r
 {\r
-  EFI_STATUS    Status;\r
-  EFI_HANDLE    SmmHandle;\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
   //\r
   // Install SMM Ready To Boot protocol.\r
@@ -250,7 +313,31 @@ SmmReadyToBootHandler (
 \r
   SmiHandlerUnRegister (DispatchHandle);\r
 \r
-  return Status;\r
+  //\r
+  // Locate SmmSxDispatch2 protocol.\r
+  //\r
+  Status = SmmLocateProtocol (\r
+             &gEfiSmmSxDispatch2ProtocolGuid,\r
+             NULL,\r
+             (VOID **)&SxDispatch\r
+             );\r
+  if (!EFI_ERROR (Status)) {\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
@@ -382,6 +469,67 @@ SmmEndOfDxeHandler (
   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
+\r
+  return Status;\r
+}\r
+\r
 /**\r
   Determine if two buffers overlap in memory.\r
 \r
@@ -451,6 +599,11 @@ SmmEntryPoint (
   //\r
   PlatformHookBeforeSmmDispatch ();\r
 \r
+  //\r
+  // Call memory management hook function\r
+  //\r
+  SmmEntryPointMemoryManagementHook ();\r
+\r
   //\r
   // If a legacy boot has occured, then make sure gSmmCorePrivate is not accessed\r
   //\r
@@ -484,7 +637,7 @@ SmmEntryPoint (
         // return EFI_INVALID_PARAMETER\r
         //\r
         gSmmCorePrivate->CommunicationBuffer = NULL;\r
-        gSmmCorePrivate->ReturnStatus = EFI_INVALID_PARAMETER;\r
+        gSmmCorePrivate->ReturnStatus = EFI_ACCESS_DENIED;\r
       } else {\r
         CommunicateHeader = (EFI_SMM_COMMUNICATE_HEADER *)CommunicationBuffer;\r
         BufferSize -= OFFSET_OF (EFI_SMM_COMMUNICATE_HEADER, Data);\r
@@ -644,7 +797,7 @@ SmmMain (
   //\r
   gSmmCorePrivate->Smst          = &gSmmCoreSmst;\r
   gSmmCorePrivate->SmmEntryPoint = SmmEntryPoint;\r
-  \r
+\r
   //\r
   // No need to initialize memory service.\r
   // It is done in constructor of PiSmmCoreMemoryAllocationLib(),\r