Revision: 18014
          http://sourceforge.net/p/edk2/code/18014
Author:   vanjeff
Date:     2015-07-15 03:46:13 +0000 (Wed, 15 Jul 2015)
Log Message:
-----------
UefiCpuPkg/CpuMpPei: Register callback on End Of Pei PPI

Add CpuMpEndOfPeiCallback () to restore wakeup buffer data on S3 path and flag
flag wakeup buffer to be un-used type on normal boot path. Set one EndOfPei
flag save/restore wakeup buffer when wakeup APs every time.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <[email protected]>
Reviewed-by: Feng Tian <[email protected]>
Reviewed-by: Jiewen Yao <[email protected]>

Modified Paths:
--------------
    trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.c
    trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.h
    trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
    trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.c

Modified: trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.c
===================================================================
--- trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.c   2015-07-15 03:45:45 UTC (rev 
18013)
+++ trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.c   2015-07-15 03:46:13 UTC (rev 
18014)
@@ -38,6 +38,12 @@
   (UINTN) mGdtEntries
   };
 
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
+  (EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | 
EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
+  &gEfiEndOfPeiSignalPpiGuid,
+  CpuMpEndOfPeiCallback
+};
+
 /**
   Sort the APIC ID of all processors.
 
@@ -317,7 +323,21 @@
     PeiCpuMpData->AddressMap.RendezvousFunnelSize
     );
 }
+
 /**
+  Restore wakeup buffer data.
+
+  @param PeiCpuMpData        Pointer to PEI CPU MP Data
+**/
+VOID
+RestoreWakeupBuffer(
+  IN PEI_CPU_MP_DATA         *PeiCpuMpData
+  )
+{
+  CopyMem ((VOID *) PeiCpuMpData->WakeupBuffer, (VOID *) 
PeiCpuMpData->BackupBuffer, PeiCpuMpData->BackupBufferSize);
+}
+
+/**
   This function will get CPU count in the system.
 
   @param PeiCpuMpData        Pointer to PEI CPU MP Data
@@ -381,6 +401,7 @@
   AsmGetAddressMap (&AddressMap);
   WakeupBufferSize = AddressMap.RendezvousFunnelSize + sizeof 
(MP_CPU_EXCHANGE_INFO);
   WakeupBuffer     = GetWakeupBuffer ((WakeupBufferSize + SIZE_4KB - 1) & 
~(SIZE_4KB - 1));
+  ASSERT (WakeupBuffer != (UINTN) -1);
   DEBUG ((EFI_D_INFO, "CpuMpPei: WakeupBuffer = 0x%x\n", WakeupBuffer));
 
   //
@@ -409,6 +430,7 @@
   PeiCpuMpData->CpuData                  = (PEI_CPU_DATA *) 
(PeiCpuMpData->MpCpuExchangeInfo + 1);
   PeiCpuMpData->CpuData[0].ApicId        = GetInitialApicId ();
   PeiCpuMpData->CpuData[0].Health.Uint32 = 0;
+  PeiCpuMpData->EndOfPeiFlag             = FALSE;
   CopyMem (&PeiCpuMpData->AddressMap, &AddressMap, sizeof 
(MP_ASSEMBLY_ADDRESS_MAP));
 
   //
@@ -418,7 +440,71 @@
 
   return PeiCpuMpData;
 }
+
 /**
+  Notify function on End Of Pei PPI.
+
+  On S3 boot, this function will restore wakeup buffer data.
+  On normal boot, this function will flag wakeup buffer to be un-used type.
+
+  @param  PeiServices        The pointer to the PEI Services Table.
+  @param  NotifyDescriptor   Address of the notification descriptor data 
structure.
+  @param  Ppi                Address of the PPI that was installed.
+
+  @retval EFI_SUCCESS        When everything is OK.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMpEndOfPeiCallback (
+  IN      EFI_PEI_SERVICES        **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR    *NotifyDescriptor,
+  IN VOID                         *Ppi
+  )
+{
+  EFI_STATUS                Status;
+  EFI_BOOT_MODE             BootMode;
+  PEI_CPU_MP_DATA           *PeiCpuMpData;
+  EFI_PEI_HOB_POINTERS      Hob;
+  EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
+
+  DEBUG ((EFI_D_INFO, "CpuMpPei: CpuMpEndOfPeiCallback () invokded\n"));
+
+  Status = PeiServicesGetBootMode (&BootMode);
+  ASSERT_EFI_ERROR (Status);
+
+  PeiCpuMpData = GetMpHobData ();
+  ASSERT (PeiCpuMpData != NULL);
+
+  if (BootMode != BOOT_ON_S3_RESUME) {
+    //
+    // Get the HOB list for processing
+    //
+    Hob.Raw = GetHobList ();
+    //
+    // Collect memory ranges
+    //
+    while (!END_OF_HOB_LIST (Hob)) {
+      if (Hob.Header->HobType == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
+        MemoryHob = Hob.MemoryAllocation;
+        if(MemoryHob->AllocDescriptor.MemoryBaseAddress == 
PeiCpuMpData->WakeupBuffer) {
+          //
+          // Flag this HOB type to un-used
+          //
+          GET_HOB_TYPE (Hob) = EFI_HOB_TYPE_UNUSED;
+          break;
+        }
+      }
+      Hob.Raw = GET_NEXT_HOB (Hob);
+    }
+  } else {
+    RestoreWakeupBuffer (PeiCpuMpData);
+    PeiCpuMpData->EndOfPeiFlag = TRUE;
+  }
+  return EFI_SUCCESS;
+}
+
+/**
   The Entry point of the MP CPU PEIM.
 
   This function will wakeup APs and collect CPU AP count and install the
@@ -466,6 +552,11 @@
   //
   CollectBistDataFromPpi (PeiServices, PeiCpuMpData);
   //
+  // register an event for EndOfPei
+  //
+  Status  = PeiServicesNotifyPpi (&mNotifyList);
+  ASSERT_EFI_ERROR (Status);
+  //
   // Install CPU MP PPI
   //
   Status = PeiServicesInstallPpi(&mPeiCpuMpPpiDesc);

Modified: trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.h
===================================================================
--- trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.h   2015-07-15 03:45:45 UTC (rev 
18013)
+++ trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.h   2015-07-15 03:46:13 UTC (rev 
18014)
@@ -20,6 +20,7 @@
 #include <Ppi/MpServices.h>
 #include <Ppi/SecPlatformInformation.h>
 #include <Ppi/SecPlatformInformation2.h>
+#include <Ppi/EndOfPeiPhase.h>
 
 #include <Register/LocalApic.h>
 
@@ -133,6 +134,7 @@
   UINTN                          ApFunction;
   UINTN                          ApFunctionArgument;
   volatile UINT32                FinishedCount;
+  BOOLEAN                        EndOfPeiFlag;
   BOOLEAN                        InitFlag;
   CPU_EXCHANGE_ROLE_INFO         BSPInfo;
   CPU_EXCHANGE_ROLE_INFO         APInfo;
@@ -177,6 +179,47 @@
   );
 
 /**
+  Get available system memory below 1MB by specified size.
+
+  @param PeiCpuMpData        Pointer to PEI CPU MP Data
+**/
+VOID
+BackupAndPrepareWakeupBuffer(
+  IN PEI_CPU_MP_DATA         *PeiCpuMpData
+  );
+
+/**
+  Restore wakeup buffer data.
+
+  @param PeiCpuMpData        Pointer to PEI CPU MP Data
+**/
+VOID
+RestoreWakeupBuffer(
+  IN PEI_CPU_MP_DATA         *PeiCpuMpData
+  );
+
+/**
+  Notify function on End Of Pei PPI.
+
+  On S3 boot, this function will restore wakeup buffer data.
+  On normal boot, this function will flag wakeup buffer to be un-used type.
+
+  @param  PeiServices        The pointer to the PEI Services Table.
+  @param  NotifyDescriptor   Address of the notification descriptor data 
structure.
+  @param  Ppi                Address of the PPI that was installed.
+
+  @retval EFI_SUCCESS        When everything is OK.
+
+**/
+EFI_STATUS
+EFIAPI
+CpuMpEndOfPeiCallback (
+  IN      EFI_PEI_SERVICES        **PeiServices,
+  IN EFI_PEI_NOTIFY_DESCRIPTOR    *NotifyDescriptor,
+  IN VOID                         *Ppi
+  );
+
+/**
   This function will be called by BSP to wakeup AP.
 
   @param PeiCpuMpData       Pointer to PEI CPU MP Data

Modified: trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
===================================================================
--- trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.inf 2015-07-15 03:45:45 UTC (rev 
18013)
+++ trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.inf 2015-07-15 03:46:13 UTC (rev 
18014)
@@ -69,6 +69,7 @@
 
 [Ppis]
   gEfiPeiMpServicesPpiGuid                      ## PRODUCES
+  gEfiEndOfPeiSignalPpiGuid                     ## NOTIFY
   gEfiSecPlatformInformationPpiGuid             ## SOMETIMES_CONSUMES
   ## SOMETIMES_CONSUMES
   ## SOMETIMES_PRODUCES

Modified: trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.c
===================================================================
--- trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.c      2015-07-15 03:45:45 UTC 
(rev 18013)
+++ trunk/edk2/UefiCpuPkg/CpuMpPei/PeiMpServices.c      2015-07-15 03:46:13 UTC 
(rev 18014)
@@ -480,6 +480,13 @@
     return EFI_NOT_READY;
   }
 
+  if (PeiCpuMpData->EndOfPeiFlag) {
+    //
+    // Backup original data and copy AP reset vector in it
+    //
+    BackupAndPrepareWakeupBuffer(PeiCpuMpData);
+  }
+
   WaitCountNumber = TimeoutInMicroSeconds / CPU_CHECK_AP_INTERVAL + 1;
   WaitCountIndex = 0;
   FinishedCount = &PeiCpuMpData->FinishedCount;
@@ -531,6 +538,13 @@
     }
   }
 
+  if (PeiCpuMpData->EndOfPeiFlag) {
+    //
+    // Restore original data
+    //
+    RestoreWakeupBuffer(PeiCpuMpData);
+  }
+
   return Status;
 }
 
@@ -626,6 +640,13 @@
     return EFI_INVALID_PARAMETER;
   }
 
+  if (PeiCpuMpData->EndOfPeiFlag) {
+    //
+    // Backup original data and copy AP reset vector in it
+    //
+    BackupAndPrepareWakeupBuffer(PeiCpuMpData);
+  }
+
   WaitCountNumber = TimeoutInMicroseconds / CPU_CHECK_AP_INTERVAL + 1;
   WaitCountIndex = 0;
   FinishedCount = &PeiCpuMpData->FinishedCount;
@@ -651,6 +672,13 @@
     }
   }
 
+  if (PeiCpuMpData->EndOfPeiFlag) {
+    //
+    // Backup original data and copy AP reset vector in it
+    //
+    RestoreWakeupBuffer(PeiCpuMpData);
+  }
+
   return Status;
 }
 
@@ -749,6 +777,13 @@
   PeiCpuMpData->BSPInfo.State = CPU_SWITCH_STATE_IDLE;
   PeiCpuMpData->APInfo.State  = CPU_SWITCH_STATE_IDLE;
 
+  if (PeiCpuMpData->EndOfPeiFlag) {
+    //
+    // Backup original data and copy AP reset vector in it
+    //
+    BackupAndPrepareWakeupBuffer(PeiCpuMpData);
+  }
+
   //
   // Need to wakeUp AP (future BSP).
   //
@@ -756,6 +791,13 @@
 
   AsmExchangeRole (&PeiCpuMpData->BSPInfo, &PeiCpuMpData->APInfo);
 
+  if (PeiCpuMpData->EndOfPeiFlag) {
+    //
+    // Backup original data and copy AP reset vector in it
+    //
+    RestoreWakeupBuffer(PeiCpuMpData);
+  }
+
   //
   // Set the BSP bit of MSR_IA32_APIC_BASE on new BSP
   //


------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to