Get AP wakeup buffer and copy AP reset code into it. Allocate APs' stack and CPU
MP data buffer. Fill CPU MP data fields accordingly.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <jeff....@intel.com>
CC: Feng Tian <feng.t...@intel.com>
CC: Jiewen Yao <jiewen....@intel.com>
CC: Michael Kinney <michael.d.kin...@intel.com>
---
 UefiCpuPkg/CpuMpPei/CpuMpPei.c   | 87 ++++++++++++++++++++++++++++++++++++++++
 UefiCpuPkg/CpuMpPei/CpuMpPei.h   | 41 ++++++++++++++++++-
 UefiCpuPkg/CpuMpPei/CpuMpPei.inf |  9 ++++-
 3 files changed, 135 insertions(+), 2 deletions(-)

diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.c b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
index 0e34f26..45243d8 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.c
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.c
@@ -111,6 +111,88 @@ GetWakeupBuffer (
 }
 
 /**
+  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
+  )
+{
+  CopyMem (
+    (VOID *) PeiCpuMpData->BackupBuffer,
+    (VOID *) PeiCpuMpData->WakeupBuffer,
+    PeiCpuMpData->BackupBufferSize
+    );
+  CopyMem (
+    (VOID *) PeiCpuMpData->WakeupBuffer,
+    (VOID *) PeiCpuMpData->AddressMap.RendezvousFunnelAddress,
+    PeiCpuMpData->AddressMap.RendezvousFunnelSize
+    );
+}
+/**
+  Prepare for AP wakeup buffer and copy AP reset code into it.
+
+  Get wakeup buffer below 1MB. Allocate memory for CPU MP Data and APs Stack.
+
+  @return   Pointer to PEI CPU MP Data
+**/
+PEI_CPU_MP_DATA *
+PrepareAPStartupVector (
+  VOID
+  )
+{
+  EFI_STATUS                    Status;
+  UINT32                        MaxCpuCount;
+  PEI_CPU_MP_DATA               *PeiCpuMpData;
+  EFI_PHYSICAL_ADDRESS          Buffer;
+  UINTN                         BufferSize;
+  UINTN                         WakeupBuffer;
+  UINTN                         WakeupBufferSize;
+  MP_ASSEMBLY_ADDRESS_MAP       AddressMap;
+
+  AsmGetAddressMap (&AddressMap);
+  WakeupBufferSize = AddressMap.RendezvousFunnelSize + sizeof 
(MP_CPU_EXCHANGE_INFO);
+  WakeupBuffer     = GetWakeupBuffer ((WakeupBufferSize + SIZE_4KB - 1) & 
~(SIZE_4KB - 1));
+  DEBUG ((EFI_D_INFO, "CpuMpPei: WakeupBuffer = 0x%x\n", WakeupBuffer));
+
+  //
+  // Allocate Pages for APs stack, CPU MP Data and backup buffer for wakeup 
buffer
+  //
+  MaxCpuCount = PcdGet32(PcdCpuMaxLogicalProcessorNumber);
+  BufferSize  = PcdGet32 (PcdCpuApStackSize) * MaxCpuCount + sizeof 
(PEI_CPU_MP_DATA)
+                  + WakeupBufferSize + sizeof (PEI_CPU_DATA) * MaxCpuCount;
+  Status = PeiServicesAllocatePages (
+             EfiBootServicesData,
+             EFI_SIZE_TO_PAGES (BufferSize),
+             &Buffer
+             );
+  ASSERT_EFI_ERROR (Status);
+
+  PeiCpuMpData = (PEI_CPU_MP_DATA *) (UINTN) (Buffer + PcdGet32 
(PcdCpuApStackSize) * MaxCpuCount);
+  PeiCpuMpData->Buffer            = (UINTN) Buffer;
+  PeiCpuMpData->CpuApStackSize    = PcdGet32 (PcdCpuApStackSize);
+  PeiCpuMpData->WakeupBuffer      = WakeupBuffer;
+  PeiCpuMpData->BackupBuffer      = (UINTN)PeiCpuMpData + sizeof 
(PEI_CPU_MP_DATA);
+  PeiCpuMpData->BackupBufferSize  = WakeupBufferSize;
+  PeiCpuMpData->MpCpuExchangeInfo = (MP_CPU_EXCHANGE_INFO *) (UINTN) 
(WakeupBuffer + AddressMap.RendezvousFunnelSize);
+
+  PeiCpuMpData->CpuCount                 = 1;
+  PeiCpuMpData->BspNumber                = 0;
+  PeiCpuMpData->CpuData                  = (PEI_CPU_DATA *) 
(PeiCpuMpData->MpCpuExchangeInfo + 1);
+  PeiCpuMpData->CpuData[0].ApicId        = GetInitialApicId ();
+  PeiCpuMpData->CpuData[0].Health.Uint32 = 0;
+  CopyMem (&PeiCpuMpData->AddressMap, &AddressMap, sizeof 
(MP_ASSEMBLY_ADDRESS_MAP));
+
+  //
+  // Backup original data and copy AP reset code in it
+  //
+  BackupAndPrepareWakeupBuffer(PeiCpuMpData);
+
+  return PeiCpuMpData;
+}
+/**
   The Entry point of the MP CPU PEIM.
 
   This function will wakeup APs and collect CPU AP count and install the
@@ -130,11 +212,16 @@ CpuMpPeimInit (
   )
 {
 
+  PEI_CPU_MP_DATA      *PeiCpuMpData;
 
   //
   // Load new GDT table on BSP
   //
   AsmInitializeGdt (&mGdt);
+  //
+  // Get wakeup buffer and copy AP reset code in it
+  //
+  PeiCpuMpData = PrepareAPStartupVector ();
 
   return EFI_SUCCESS;
 }
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.h b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
index 7c96084..1219e4e 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.h
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.h
@@ -17,11 +17,25 @@
 
 #include <PiPei.h>
 
+#include <Ppi/SecPlatformInformation.h>
 
 #include <Library/BaseLib.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
 #include <Library/HobLib.h>
+#include <Library/LocalApicLib.h>
+#include <Library/PcdLib.h>
 #include <Library/PeimEntryPoint.h>
+#include <Library/PeiServicesLib.h>
 #include <Library/UefiCpuLib.h>
+//
+// AP state
+//
+typedef enum {
+  CpuStateIdle,
+  CpuStateBusy,
+  CpuStateDisabled
+} CPU_STATE;
 
 //
 // AP reset code information
@@ -33,7 +47,9 @@ typedef struct {
   UINTN             RendezvousFunnelSize;
 } MP_ASSEMBLY_ADDRESS_MAP;
 
-#pragma pack(1)
+typedef struct _PEI_CPU_MP_DATA  PEI_CPU_MP_DATA;
+
+#pragma pack()
 
 typedef union {
   struct {
@@ -73,6 +89,29 @@ typedef struct {
 
 #pragma pack()
 
+typedef struct {
+  UINT32                         ApicId;
+  EFI_HEALTH_FLAGS               Health;
+  CPU_STATE                      State;
+  BOOLEAN                        CpuHealthy;
+} PEI_CPU_DATA;
+
+//
+// PEI CPU MP Data save in memory
+//
+struct _PEI_CPU_MP_DATA {
+  UINT32                         CpuCount;
+  UINT32                         BspNumber;
+  UINTN                          Buffer;
+  UINTN                          CpuApStackSize;
+  MP_ASSEMBLY_ADDRESS_MAP        AddressMap;
+  UINTN                          WakeupBuffer;
+  UINTN                          BackupBuffer;
+  UINTN                          BackupBufferSize;
+  PEI_CPU_DATA                   *CpuData;
+  volatile MP_CPU_EXCHANGE_INFO  *MpCpuExchangeInfo;
+};
+
 /**
   Assembly code to get starting address and size of the rendezvous entry for 
APs.
   Information for fixing a jump instruction in the code is also returned.
diff --git a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
index 9fb9e94..a04556f 100644
--- a/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
+++ b/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
@@ -49,12 +49,19 @@
 
 [LibraryClasses]
   BaseLib
+  BaseMemoryLib
+  DebugLib
   HobLib
+  LocalApicLib
+  PcdLib
   PeimEntryPoint
+  PeiServicesLib
   UefiCpuLib
 
 
-
+[Pcd]
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
 
 [Depex]
   gEfiPeiMemoryDiscoveredPpiGuid
-- 
1.9.5.msysgit.0


------------------------------------------------------------------------------
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-devel mailing list
edk2-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/edk2-devel

Reply via email to