summaryrefslogtreecommitdiffstats
path: root/UefiCpuPkg/Library/MpInitLib/MpLib.c
diff options
context:
space:
mode:
authorXie, Yuanhao <yuanhao.xie@intel.com>2023-06-28 16:47:22 +0800
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>2023-07-11 02:47:27 +0000
commit8bb018afaf2a4af16e410bba01b42d245250c82c (patch)
treeef8e5183abb8e618a1a0f8bb9b9796e6894ecc71 /UefiCpuPkg/Library/MpInitLib/MpLib.c
parent243212b0d0bb33d0a64db8cd974d243e5aefdf3d (diff)
downloadedk2-8bb018afaf2a4af16e410bba01b42d245250c82c.tar.gz
edk2-8bb018afaf2a4af16e410bba01b42d245250c82c.tar.bz2
edk2-8bb018afaf2a4af16e410bba01b42d245250c82c.zip
UefiCpuPkg: Create MpHandOff.
Initially, the purpose of the Hob was twofold: it served as a way to transfer information from PEI to DXE. However, during the DXE phase, only a few fields from the CPU_MP_DATA which collected in PEI phase were needed. A new Hob was specifically created to transfer information to the DXE phase. This new Hob contained only the essential fields required for reuse in DXE. For instance, instead of directly including the BspNumber in MpHandOff, the DXE phase introduced the use of GetBspNumber() to collect the BspNumber from ApicID and CpuCount. The SaveCpuMpData() function was updated to construct the MP_HAND_OFF Hob. Additionally, the function introduced the MP_HAND_OFF_SIGNAL, which solely served the purpose of awakening the APs and transitioning their context from PEI to DXE. The WaitLoopExecutionMode field indicated whether the bit mode of PEI matched that of DXE. Both of them were filled only if the ApLoopMode was not ApInHltLoop. In the case of ApInHltLoop, it remained necessary to wake up the APs using the init-sipi-sipi sequence. This improvement still allow INIT-SIPI-SIPI even APs are wait in Run/Mwait loop mode. The function GetMpHandOffHob() was added to facilitate access to the collected MpHandOff in the DXE phase. The CpuMpData in the DXE phase was updated by gathering information from MpHandOff. Since MpHandOff replaced the usage of OldCpuMpData and contained essential information from the PEI phase to the DXE phase. AmdSevUpdateCpuMpData was included to maintain the original implementation of AmdSev, ensuring that OldCpuMpData->NewCpuMpData pointed to CpuMpData. Tested-by: Gerd Hoffmann <kraxel@redhat.com> Acked-by: Gerd Hoffmann <kraxel@redhat.com> Reviewed-by: Ray Ni <ray.ni@intel.com> Cc: Eric Dong <eric.dong@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Cc: Tom Lendacky <thomas.lendacky@amd.com> Signed-off-by: Yuanhao Xie <yuanhao.xie@intel.com>
Diffstat (limited to 'UefiCpuPkg/Library/MpInitLib/MpLib.c')
-rw-r--r--UefiCpuPkg/Library/MpInitLib/MpLib.c83
1 files changed, 70 insertions, 13 deletions
diff --git a/UefiCpuPkg/Library/MpInitLib/MpLib.c b/UefiCpuPkg/Library/MpInitLib/MpLib.c
index e8dd640f9b..ccc01859f0 100644
--- a/UefiCpuPkg/Library/MpInitLib/MpLib.c
+++ b/UefiCpuPkg/Library/MpInitLib/MpLib.c
@@ -14,6 +14,7 @@
#include <Register/Amd/Ghcb.h>
EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID;
+EFI_GUID mMpHandOffGuid = MP_HANDOFF_GUID;
/**
Save the volatile registers required to be restored following INIT IPI.
@@ -1815,6 +1816,59 @@ CheckAllAPs (
}
/**
+ This function Get BspNumber.
+
+ @param[in] MpHandOff Pointer to MpHandOff
+ @return BspNumber
+**/
+UINT32
+GetBspNumber (
+ IN CONST MP_HAND_OFF *MpHandOff
+ )
+{
+ UINT32 ApicId;
+ UINT32 BspNumber;
+ UINT32 Index;
+
+ //
+ // Get the processor number for the BSP
+ //
+ BspNumber = MAX_UINT32;
+ ApicId = GetInitialApicId ();
+ for (Index = 0; Index < MpHandOff->CpuCount; Index++) {
+ if (MpHandOff->Info[Index].ApicId == ApicId) {
+ BspNumber = Index;
+ }
+ }
+
+ ASSERT (BspNumber != MAX_UINT32);
+
+ return BspNumber;
+}
+
+/**
+ Get pointer to MP_HAND_OFF GUIDed HOB.
+
+ @return The pointer to MP_HAND_OFF structure.
+**/
+MP_HAND_OFF *
+GetMpHandOffHob (
+ VOID
+ )
+{
+ EFI_HOB_GUID_TYPE *GuidHob;
+ MP_HAND_OFF *MpHandOff;
+
+ MpHandOff = NULL;
+ GuidHob = GetFirstGuidHob (&mMpHandOffGuid);
+ if (GuidHob != NULL) {
+ MpHandOff = (MP_HAND_OFF *)GET_GUID_HOB_DATA (GuidHob);
+ }
+
+ return MpHandOff;
+}
+
+/**
MP Initialize Library initialization.
This service will allocate AP reset vector and wakeup all APs to do APs
@@ -1833,7 +1887,7 @@ MpInitLibInitialize (
VOID
)
{
- CPU_MP_DATA *OldCpuMpData;
+ MP_HAND_OFF *MpHandOff;
CPU_INFO_IN_HOB *CpuInfoInHob;
UINT32 MaxLogicalProcessorNumber;
UINT32 ApStackSize;
@@ -1852,11 +1906,11 @@ MpInitLibInitialize (
UINTN BackupBufferAddr;
UINTN ApIdtBase;
- OldCpuMpData = GetCpuMpDataFromGuidedHob ();
- if (OldCpuMpData == NULL) {
+ MpHandOff = GetMpHandOffHob ();
+ if (MpHandOff == NULL) {
MaxLogicalProcessorNumber = PcdGet32 (PcdCpuMaxLogicalProcessorNumber);
} else {
- MaxLogicalProcessorNumber = OldCpuMpData->CpuCount;
+ MaxLogicalProcessorNumber = MpHandOff->CpuCount;
}
ASSERT (MaxLogicalProcessorNumber != 0);
@@ -2000,7 +2054,7 @@ MpInitLibInitialize (
//
ProgramVirtualWireMode ();
- if (OldCpuMpData == NULL) {
+ if (MpHandOff == NULL) {
if (MaxLogicalProcessorNumber > 1) {
//
// Wakeup all APs and calculate the processor count in system
@@ -2012,15 +2066,18 @@ MpInitLibInitialize (
// APs have been wakeup before, just get the CPU Information
// from HOB
//
- OldCpuMpData->NewCpuMpData = CpuMpData;
- CpuMpData->CpuCount = OldCpuMpData->CpuCount;
- CpuMpData->BspNumber = OldCpuMpData->BspNumber;
- CpuMpData->CpuInfoInHob = OldCpuMpData->CpuInfoInHob;
- CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
+ AmdSevUpdateCpuMpData (CpuMpData);
+ CpuMpData->CpuCount = MpHandOff->CpuCount;
+ CpuMpData->BspNumber = GetBspNumber (MpHandOff);
+ CpuInfoInHob = (CPU_INFO_IN_HOB *)(UINTN)CpuMpData->CpuInfoInHob;
for (Index = 0; Index < CpuMpData->CpuCount; Index++) {
InitializeSpinLock (&CpuMpData->CpuData[Index].ApLock);
- CpuMpData->CpuData[Index].CpuHealthy = (CpuInfoInHob[Index].Health == 0) ? TRUE : FALSE;
+ CpuMpData->CpuData[Index].CpuHealthy = (MpHandOff->Info[Index].Health == 0) ? TRUE : FALSE;
CpuMpData->CpuData[Index].ApFunction = 0;
+ CpuInfoInHob[Index].InitialApicId = MpHandOff->Info[Index].ApicId;
+ CpuInfoInHob[Index].ApTopOfStack = CpuMpData->Buffer + (Index + 1) * CpuMpData->CpuApStackSize;
+ CpuInfoInHob[Index].ApicId = MpHandOff->Info[Index].ApicId;
+ CpuInfoInHob[Index].Health = MpHandOff->Info[Index].Health;
}
}
@@ -2049,7 +2106,7 @@ MpInitLibInitialize (
// Wakeup APs to do some AP initialize sync (Microcode & MTRR)
//
if (CpuMpData->CpuCount > 1) {
- if (OldCpuMpData != NULL) {
+ if (MpHandOff != NULL) {
//
// Only needs to use this flag for DXE phase to update the wake up
// buffer. Wakeup buffer allocated in PEI phase is no longer valid
@@ -2066,7 +2123,7 @@ MpInitLibInitialize (
CpuPause ();
}
- if (OldCpuMpData != NULL) {
+ if (MpHandOff != NULL) {
CpuMpData->InitFlag = ApInitDone;
}