public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "duntan" <dun.tan@intel.com>
To: devel@edk2.groups.io
Cc: Eric Dong <eric.dong@intel.com>, Ray Ni <ray.ni@intel.com>,
	Rahul Kumar <rahul1.kumar@intel.com>
Subject: [edk2-devel] [Patch V2 4/5] UefiCpuPkg/PiSmmCpuDxe: code refinement for CpuS3.c
Date: Mon, 21 Aug 2023 10:09:46 +0800	[thread overview]
Message-ID: <20230821020947.346-5-dun.tan@intel.com> (raw)
In-Reply-To: <20230821020947.346-1-dun.tan@intel.com>

This commit is code logic refinement for s3 boot flow
in CpuS3.c. It doesn't change any code functionality.
This commit implementes InitializeAp and InitializeBsp
as a single function since they are doing almost the
same thing. Then both BSP and AP will execute the same
function InitializeCpuProcedure to do CPU initialization.
This can make the code logic easier to understand.

Signed-off-by: Dun Tan <dun.tan@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
---
 UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c | 272 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------------------------------------------------------------------------------------------------------------------
 1 file changed, 144 insertions(+), 128 deletions(-)

diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
index 0f7ee0372d..a6adf46af7 100644
--- a/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
+++ b/UefiCpuPkg/PiSmmCpuDxeSmm/CpuS3.c
@@ -539,44 +539,155 @@ SetRegister (
 }
 
 /**
-  AP initialization before then after SMBASE relocation in the S3 boot path.
+  The function is invoked before SMBASE relocation in S3 path to restores CPU status.
+
+  The function is invoked before SMBASE relocation in S3 path. It does first time microcode load
+  and restores MTRRs for both BSP and APs.
+
+  @param   IsBsp   The CPU this function executes on is BSP or not.
+
 **/
 VOID
-InitializeAp (
-  VOID
+InitializeCpuBeforeRebase (
+  IN BOOLEAN  IsBsp
   )
 {
-  UINTN  TopOfStack;
-  UINT8  Stack[128];
-
   LoadMtrrData (mAcpiCpuData.MtrrTable);
 
   SetRegister (TRUE);
 
+  ProgramVirtualWireMode ();
   //
   // Count down the number with lock mechanism.
   //
   InterlockedDecrement (&mNumberToFinish);
 
+  if (IsBsp) {
+    //
+    // Bsp wait here till all AP finish the initialization before rebase
+    //
+    while (mNumberToFinish > 0) {
+      CpuPause ();
+    }
+  } else {
+    //
+    // AP Wait for BSP to signal SMM Base relocation done.
+    //
+    while (!mInitApsAfterSmmBaseReloc) {
+      CpuPause ();
+    }
+  }
+}
+
+/**
+  The function is invoked after SMBASE relocation in S3 path to restores CPU status.
+
+  The function is invoked after SMBASE relocation in S3 path. It restores configuration according to
+  data saved by normal boot path for both BSP and APs.
+
+  @param   IsBsp   The CPU this function executes on is BSP or not.
+
+**/
+VOID
+InitializeCpuAfterRebase (
+  IN BOOLEAN  IsBsp
+  )
+{
+  UINTN  TopOfStack;
+  UINT8  Stack[128];
+
+  if (IsBsp) {
+    mNumberToFinish = (UINT32)(mNumberOfCpus - 1);
+
+    //
+    // Signal that SMM base relocation is complete and to continue initialization for all APs.
+    //
+    mInitApsAfterSmmBaseReloc = TRUE;
+
+    //
+    // Must begin set register after all APs have continue their initialization.
+    // This is a requirement to support semaphore mechanism in register table.
+    // Because if semaphore's dependence type is package type, semaphore will wait
+    // for all Aps in one package finishing their tasks before set next register
+    // for all APs. If the Aps not begin its task during BSP doing its task, the
+    // BSP thread will hang because it is waiting for other Aps in the same
+    // package finishing their task.
+    //
+    SetRegister (FALSE);
+
+    while (mNumberToFinish > 0) {
+      CpuPause ();
+    }
+  } else {
+    DisableLvtInterrupts ();
+
+    SetRegister (FALSE);
+
+    //
+    // Place AP into the safe code, count down the number with lock mechanism in the safe code.
+    //
+    TopOfStack  = (UINTN)Stack + sizeof (Stack);
+    TopOfStack &= ~(UINTN)(CPU_STACK_ALIGNMENT - 1);
+    CopyMem ((VOID *)(UINTN)mApHltLoopCode, mApHltLoopCodeTemplate, sizeof (mApHltLoopCodeTemplate));
+    TransferApToSafeState ((UINTN)mApHltLoopCode, TopOfStack, (UINTN)&mNumberToFinish);
+  }
+}
+
+/**
+  Cpu initialization procedure.
+
+  @param[in,out] Buffer  The pointer to private data buffer.
+
+**/
+VOID
+EFIAPI
+InitializeCpuProcedure (
+  IN OUT VOID  *Buffer
+  )
+{
+  BOOLEAN  IsBsp;
+
+  IsBsp =  (BOOLEAN)(mBspApicId == GetApicId ());
+
   //
-  // Wait for BSP to signal SMM Base relocation done.
+  // Skip initialization if mAcpiCpuData is not valid
   //
-  while (!mInitApsAfterSmmBaseReloc) {
-    CpuPause ();
+  if (mAcpiCpuData.NumberOfCpus > 0) {
+    //
+    // First time microcode load and restore MTRRs
+    //
+    InitializeCpuBeforeRebase (IsBsp);
   }
 
-  ProgramVirtualWireMode ();
-  DisableLvtInterrupts ();
+  if (IsBsp) {
+    DEBUG ((DEBUG_INFO, "SmmRestoreCpu: mSmmRelocated is %d\n", mSmmRelocated));
 
-  SetRegister (FALSE);
+    //
+    // Check whether Smm Relocation is done or not.
+    // If not, will do the SmmBases Relocation here!!!
+    //
+    if (!mSmmRelocated) {
+      //
+      // Restore SMBASE for BSP and all APs
+      //
+      SmmRelocateBases ();
+    } else {
+      //
+      // Issue SMI IPI (All Excluding  Self SMM IPI + BSP SMM IPI) to execute first SMI init.
+      //
+      ExecuteFirstSmiInit ();
+    }
+  }
 
   //
-  // Place AP into the safe code, count down the number with lock mechanism in the safe code.
+  // Skip initialization if mAcpiCpuData is not valid
   //
-  TopOfStack  = (UINTN)Stack + sizeof (Stack);
-  TopOfStack &= ~(UINTN)(CPU_STACK_ALIGNMENT - 1);
-  CopyMem ((VOID *)(UINTN)mApHltLoopCode, mApHltLoopCodeTemplate, sizeof (mApHltLoopCodeTemplate));
-  TransferApToSafeState ((UINTN)mApHltLoopCode, TopOfStack, (UINTN)&mNumberToFinish);
+  if (mAcpiCpuData.NumberOfCpus > 0) {
+    //
+    // Restore MSRs for BSP and all APs
+    //
+    InitializeCpuAfterRebase (IsBsp);
+  }
 }
 
 /**
@@ -627,91 +738,7 @@ PrepareApStartupVector (
   mExchangeInfo->BufferStart                         = (UINT32)StartupVector;
   mExchangeInfo->Cr3                                 = (UINT32)(AsmReadCr3 ());
   mExchangeInfo->InitializeFloatingPointUnitsAddress = (UINTN)InitializeFloatingPointUnits;
-}
-
-/**
-  The function is invoked before SMBASE relocation in S3 path to restores CPU status.
-
-  The function is invoked before SMBASE relocation in S3 path. It does first time microcode load
-  and restores MTRRs for both BSP and APs.
-
-**/
-VOID
-InitializeCpuBeforeRebase (
-  VOID
-  )
-{
-  LoadMtrrData (mAcpiCpuData.MtrrTable);
-
-  SetRegister (TRUE);
-
-  ProgramVirtualWireMode ();
-
-  PrepareApStartupVector (mAcpiCpuData.StartupVector);
-
-  if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
-    ASSERT (mNumberOfCpus <= mAcpiCpuData.NumberOfCpus);
-  } else {
-    ASSERT (mNumberOfCpus == mAcpiCpuData.NumberOfCpus);
-  }
-
-  mNumberToFinish           = (UINT32)(mNumberOfCpus - 1);
-  mExchangeInfo->ApFunction = (VOID *)(UINTN)InitializeAp;
-
-  //
-  // Execute code for before SmmBaseReloc. Note: This flag is maintained across S3 boots.
-  //
-  mInitApsAfterSmmBaseReloc = FALSE;
-
-  //
-  // Send INIT IPI - SIPI to all APs
-  //
-  SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);
-
-  while (mNumberToFinish > 0) {
-    CpuPause ();
-  }
-}
-
-/**
-  The function is invoked after SMBASE relocation in S3 path to restores CPU status.
-
-  The function is invoked after SMBASE relocation in S3 path. It restores configuration according to
-  data saved by normal boot path for both BSP and APs.
-
-**/
-VOID
-InitializeCpuAfterRebase (
-  VOID
-  )
-{
-  if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
-    ASSERT (mNumberOfCpus <= mAcpiCpuData.NumberOfCpus);
-  } else {
-    ASSERT (mNumberOfCpus == mAcpiCpuData.NumberOfCpus);
-  }
-
-  mNumberToFinish = (UINT32)(mNumberOfCpus - 1);
-
-  //
-  // Signal that SMM base relocation is complete and to continue initialization for all APs.
-  //
-  mInitApsAfterSmmBaseReloc = TRUE;
-
-  //
-  // Must begin set register after all APs have continue their initialization.
-  // This is a requirement to support semaphore mechanism in register table.
-  // Because if semaphore's dependence type is package type, semaphore will wait
-  // for all Aps in one package finishing their tasks before set next register
-  // for all APs. If the Aps not begin its task during BSP doing its task, the
-  // BSP thread will hang because it is waiting for other Aps in the same
-  // package finishing their task.
-  //
-  SetRegister (FALSE);
-
-  while (mNumberToFinish > 0) {
-    CpuPause ();
-  }
+  mExchangeInfo->ApFunction                          = (VOID *)(UINTN)InitializeCpuProcedure;
 }
 
 /**
@@ -813,44 +840,33 @@ SmmRestoreCpu (
     InitializeDebugAgent (DEBUG_AGENT_INIT_THUNK_PEI_IA32TOX64, (VOID *)&Ia32Idtr, NULL);
   }
 
+  mBspApicId = GetApicId ();
   //
-  // Skip initialization if mAcpiCpuData is not valid
+  // Skip AP initialization if mAcpiCpuData is not valid
   //
   if (mAcpiCpuData.NumberOfCpus > 0) {
-    //
-    // First time microcode load and restore MTRRs
-    //
-    InitializeCpuBeforeRebase ();
-  }
+    if (FeaturePcdGet (PcdCpuHotPlugSupport)) {
+      ASSERT (mNumberOfCpus <= mAcpiCpuData.NumberOfCpus);
+    } else {
+      ASSERT (mNumberOfCpus == mAcpiCpuData.NumberOfCpus);
+    }
 
-  DEBUG ((DEBUG_INFO, "SmmRestoreCpu: mSmmRelocated is %d\n", mSmmRelocated));
+    mNumberToFinish = (UINT32)mNumberOfCpus;
 
-  //
-  // Check whether Smm Relocation is done or not.
-  // If not, will do the SmmBases Relocation here!!!
-  //
-  if (!mSmmRelocated) {
     //
-    // Restore SMBASE for BSP and all APs
+    // Execute code for before SmmBaseReloc. Note: This flag is maintained across S3 boots.
     //
-    SmmRelocateBases ();
-  } else {
-    //
-    // Issue SMI IPI (All Excluding  Self SMM IPI + BSP SMM IPI) to execute first SMI init.
-    //
-    ExecuteFirstSmiInit ();
-  }
+    mInitApsAfterSmmBaseReloc = FALSE;
 
-  //
-  // Skip initialization if mAcpiCpuData is not valid
-  //
-  if (mAcpiCpuData.NumberOfCpus > 0) {
+    PrepareApStartupVector (mAcpiCpuData.StartupVector);
     //
-    // Restore MSRs for BSP and all APs
+    // Send INIT IPI - SIPI to all APs
     //
-    InitializeCpuAfterRebase ();
+    SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);
   }
 
+  InitializeCpuProcedure (NULL);
+
   //
   // Set a flag to restore SMM configuration in S3 path.
   //
-- 
2.31.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107904): https://edk2.groups.io/g/devel/message/107904
Mute This Topic: https://groups.io/mt/100866133/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-



  parent reply	other threads:[~2023-08-21  2:10 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-08-21  2:09 [edk2-devel] [Patch V2 0/5] Use MpService2Ppi to wakeup CPU in Smm CpuS3 duntan
2023-08-21  2:09 ` [edk2-devel] [Patch V2 1/5] MdeModulePkg: add MpService2Ppi field in SMM_S3_RESUME_STATE duntan
2023-08-21  2:09 ` [edk2-devel] [Patch V2 2/5] UefiCpuPkg/S3Resume2Pei: prepare MpService2Ppi in S3Resume duntan
2023-09-06  3:11   ` Ni, Ray
2023-08-21  2:09 ` [edk2-devel] [Patch V2 3/5] UefiCpuPkg/S3Resume2Pei: assert for invalid excution mode combo duntan
2023-09-06  3:11   ` Ni, Ray
2023-08-21  2:09 ` duntan [this message]
2023-08-21  2:09 ` [edk2-devel] [Patch V2 5/5] UefiCpuPkg/PiSmmCpuDxe: use MpService2Ppi to wakeup AP in s3 duntan
     [not found] ` <177D440115CF68CB.15959@groups.io>
2023-09-06  3:22   ` [edk2-devel] [Patch V2 1/5] MdeModulePkg: add MpService2Ppi field in SMM_S3_RESUME_STATE duntan
2023-09-06  5:37     ` Ni, Ray
2023-09-07 15:02     ` Wang, Jian J

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20230821020947.346-5-dun.tan@intel.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox