]> git.proxmox.com Git - mirror_edk2.git/blobdiff - UefiCpuPkg/Library/MpInitLib/PeiMpLib.c
UefiCpuPkg/MpInitLib: Remove useless code.
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / PeiMpLib.c
index 9ee5aca57b2bb41aa8dd85793dc9434a247fd338..e6e1b7c57d3d93b2b59d577ee46f0f2e66ed7136 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   MP initialize support functions for PEI phase.\r
 \r
-  Copyright (c) 2016 - 2017, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
   This program and the accompanying materials\r
   are licensed and made available under the terms and conditions of the BSD License\r
   which accompanies this distribution.  The full text of the license may be found at\r
 **/\r
 \r
 #include "MpLib.h"\r
+#include <Library/PeiServicesLib.h>\r
+#include <Guid/S3SmmInitDone.h>\r
+\r
+/**\r
+  S3 SMM Init Done notification function.\r
+\r
+  @param  PeiServices      Indirect reference to the PEI Services Table.\r
+  @param  NotifyDesc       Address of the notification descriptor data structure.\r
+  @param  InvokePpi        Address of the PPI that was invoked.\r
+\r
+  @retval EFI_SUCCESS      The function completes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NotifyOnS3SmmInitDonePpi (\r
+  IN  EFI_PEI_SERVICES                              **PeiServices,\r
+  IN  EFI_PEI_NOTIFY_DESCRIPTOR                     *NotifyDesc,\r
+  IN  VOID                                          *InvokePpi\r
+  );\r
+\r
+\r
+//\r
+// Global function\r
+//\r
+EFI_PEI_NOTIFY_DESCRIPTOR        mS3SmmInitDoneNotifyDesc = {\r
+  EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,\r
+  &gEdkiiS3SmmInitDoneGuid,\r
+  NotifyOnS3SmmInitDonePpi\r
+};\r
+\r
+/**\r
+  S3 SMM Init Done notification function.\r
+\r
+  @param  PeiServices      Indirect reference to the PEI Services Table.\r
+  @param  NotifyDesc       Address of the notification descriptor data structure.\r
+  @param  InvokePpi        Address of the PPI that was invoked.\r
+\r
+  @retval EFI_SUCCESS      The function completes successfully.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+NotifyOnS3SmmInitDonePpi (\r
+  IN  EFI_PEI_SERVICES                              **PeiServices,\r
+  IN  EFI_PEI_NOTIFY_DESCRIPTOR                     *NotifyDesc,\r
+  IN  VOID                                          *InvokePpi\r
+  )\r
+{\r
+  CPU_MP_DATA     *CpuMpData;\r
+\r
+  CpuMpData = GetCpuMpData ();\r
+\r
+  //\r
+  // PiSmmCpuDxeSmm driver hardcode change the loop mode to HLT mode.\r
+  // So in this notify function, code need to check the current loop\r
+  // mode, if it is not HLT mode, code need to change loop mode back\r
+  // to the original mode.\r
+  //\r
+  if (CpuMpData->ApLoopMode != ApInHltLoop) {\r
+    CpuMpData->WakeUpByInitSipiSipi = TRUE;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
 \r
 /**\r
   Enable Debug Agent to support source debugging on AP function.\r
@@ -27,6 +93,8 @@ EnableDebugAgent (
 \r
 /**\r
   Get pointer to CPU MP Data structure.\r
+  For BSP, the pointer is retrieved from HOB.\r
+  For AP, the structure is just after IDT.\r
 \r
   @return  The pointer to CPU MP Data structure.\r
 **/\r
@@ -35,10 +103,18 @@ GetCpuMpData (
   VOID\r
   )\r
 {\r
-  CPU_MP_DATA      *CpuMpData;\r
-\r
-  CpuMpData = GetCpuMpDataFromGuidedHob ();\r
-  ASSERT (CpuMpData != NULL);\r
+  CPU_MP_DATA                  *CpuMpData;\r
+  MSR_IA32_APIC_BASE_REGISTER  ApicBaseMsr;\r
+  IA32_DESCRIPTOR              Idtr;\r
+\r
+  ApicBaseMsr.Uint64 = AsmReadMsr64 (MSR_IA32_APIC_BASE);\r
+  if (ApicBaseMsr.Bits.BSP == 1) {\r
+    CpuMpData = GetCpuMpDataFromGuidedHob ();\r
+    ASSERT (CpuMpData != NULL);\r
+  } else {\r
+    AsmReadIdtr (&Idtr);\r
+    CpuMpData = (CPU_MP_DATA *) (Idtr.Base + Idtr.Limit + 1);\r
+  }\r
   return CpuMpData;\r
 }\r
 \r
@@ -75,15 +151,15 @@ SaveCpuMpData (
 **/\r
 BOOLEAN\r
 CheckOverlapWithAllocatedBuffer (\r
-  IN UINT               WakeupBufferStart,\r
-  IN UINT               WakeupBufferEnd\r
+  IN UINT64               WakeupBufferStart,\r
+  IN UINT64               WakeupBufferEnd\r
   )\r
 {\r
   EFI_PEI_HOB_POINTERS      Hob;\r
   EFI_HOB_MEMORY_ALLOCATION *MemoryHob;\r
   BOOLEAN                   Overlapped;\r
-  UINT                    MemoryStart;\r
-  UINT                    MemoryEnd;\r
+  UINT64                    MemoryStart;\r
+  UINT64                    MemoryEnd;\r
 \r
   Overlapped = FALSE;\r
   //\r
@@ -96,9 +172,8 @@ CheckOverlapWithAllocatedBuffer (
   while (!END_OF_HOB_LIST (Hob)) {\r
     if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {\r
       MemoryHob   = Hob.MemoryAllocation;\r
-      MemoryStart = (UINTN) MemoryHob->AllocDescriptor.MemoryBaseAddress;\r
-      MemoryEnd   = (UINTN) (MemoryHob->AllocDescriptor.MemoryBaseAddress +\r
-                             MemoryHob->AllocDescriptor.MemoryLength);\r
+      MemoryStart = MemoryHob->AllocDescriptor.MemoryBaseAddress;\r
+      MemoryEnd   = MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength;\r
       if (!((WakeupBufferStart >= MemoryEnd) || (WakeupBufferEnd <= MemoryStart))) {\r
         Overlapped = TRUE;\r
         break;\r
@@ -123,8 +198,8 @@ GetWakeupBuffer (
   )\r
 {\r
   EFI_PEI_HOB_POINTERS    Hob;\r
-  UINT                  WakeupBufferStart;\r
-  UINT                  WakeupBufferEnd;\r
+  UINT64                  WakeupBufferStart;\r
+  UINT64                  WakeupBufferEnd;\r
 \r
   WakeupBufferSize = (WakeupBufferSize + SIZE_4KB - 1) & ~(SIZE_4KB - 1);\r
 \r
@@ -149,7 +224,7 @@ GetWakeupBuffer (
         //\r
         // Need memory under 1MB to be collected here\r
         //\r
-        WakeupBufferEnd = (UINTN) (Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength);\r
+        WakeupBufferEnd = Hob.ResourceDescriptor->PhysicalStart + Hob.ResourceDescriptor->ResourceLength;\r
         if (WakeupBufferEnd > BASE_1MB) {\r
           //\r
           // Wakeup buffer should be under 1MB\r
@@ -174,7 +249,7 @@ GetWakeupBuffer (
           }\r
           DEBUG ((DEBUG_INFO, "WakeupBufferStart = %x, WakeupBufferSize = %x\n",\r
                                WakeupBufferStart, WakeupBufferSize));\r
-          return WakeupBufferStart;\r
+          return (UINTN)WakeupBufferStart;\r
         }\r
       }\r
     }\r
@@ -188,39 +263,26 @@ GetWakeupBuffer (
 }\r
 \r
 /**\r
-  Allocate reset vector buffer.\r
+  Get available EfiBootServicesCode memory below 4GB by specified size.\r
 \r
-  @param[in, out]  CpuMpData  The pointer to CPU MP Data structure.\r
-**/\r
-VOID\r
-AllocateResetVector (\r
-  IN OUT CPU_MP_DATA          *CpuMpData\r
-  )\r
-{\r
-  UINTN           ApResetVectorSize;\r
+  This buffer is required to safely transfer AP from real address mode to\r
+  protected mode or long mode, due to the fact that the buffer returned by\r
+  GetWakeupBuffer() may be marked as non-executable.\r
 \r
-  if (CpuMpData->WakeupBuffer == (UINTN) -1) {\r
-    ApResetVectorSize = CpuMpData->AddressMap.RendezvousFunnelSize +\r
-                          sizeof (MP_CPU_EXCHANGE_INFO);\r
+  @param[in] BufferSize   Wakeup transition buffer size.\r
 \r
-    CpuMpData->WakeupBuffer      = GetWakeupBuffer (ApResetVectorSize);\r
-    CpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN)\r
-                    (CpuMpData->WakeupBuffer + CpuMpData->AddressMap.RendezvousFunnelSize);\r
-  }\r
-  BackupAndPrepareWakeupBuffer (CpuMpData);\r
-}\r
-\r
-/**\r
-  Free AP reset vector buffer.\r
-\r
-  @param[in]  CpuMpData  The pointer to CPU MP Data structure.\r
+  @retval other   Return wakeup transition buffer address below 4GB.\r
+  @retval 0       Cannot find free memory below 4GB.\r
 **/\r
-VOID\r
-FreeResetVector (\r
-  IN CPU_MP_DATA              *CpuMpData\r
+UINTN\r
+GetModeTransitionBuffer (\r
+  IN UINTN                BufferSize\r
   )\r
 {\r
-  RestoreWakeupBuffer (CpuMpData);\r
+  //\r
+  // PEI phase doesn't need to do such transition. So simply return 0.\r
+  //\r
+  return 0;\r
 }\r
 \r
 /**\r
@@ -244,7 +306,15 @@ InitMpGlobalData (
   IN CPU_MP_DATA               *CpuMpData\r
   )\r
 {\r
+  EFI_STATUS  Status;\r
+\r
   SaveCpuMpData (CpuMpData);\r
+\r
+  ///\r
+  /// Install Notify\r
+  ///\r
+  Status = PeiServicesNotifyPpi (&mS3SmmInitDoneNotifyDesc);\r
+  ASSERT_EFI_ERROR (Status);\r
 }\r
 \r
 /**\r