UefiCpuPkg/MpInitLib: add struct MP_HAND_OFF_CONFIG

Move the WaitLoopExecutionMode and StartupSignalValue fields to a
separate HOB with the new struct.

WaitLoopExecutionMode and StartupSignalValue are independent of
processor index ranges; they are global to MpInitLib (i.e., the entire
system). Therefore they shouldn't be repeated in every MpHandOff GUID
HOB.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-Id: <20240228114855.1615788-1-kraxel@redhat.com>
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Ray Ni <ray.ni@intel.com>
Cc: Laszlo Ersek <lersek@redhat.com>
Cc: Oliver Steffen <osteffen@redhat.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
[lersek@redhat.com: turn the "Cc:" message headers from Gerd's on-list
 posting into "Cc:" tags in the commit message, in order to pacify
 "PatchCheck.py"]
This commit is contained in:
Gerd Hoffmann 2024-02-28 12:48:55 +01:00 committed by mergify[bot]
parent bac9c74080
commit dc7cfa9bab
4 changed files with 75 additions and 22 deletions

View File

@ -15,7 +15,13 @@
0x11e2bd88, 0xed38, 0x4abd, {0xa3, 0x99, 0x21, 0xf2, 0x5f, 0xd0, 0x7a, 0x60 } \ 0x11e2bd88, 0xed38, 0x4abd, {0xa3, 0x99, 0x21, 0xf2, 0x5f, 0xd0, 0x7a, 0x60 } \
} }
#define MP_HANDOFF_CONFIG_GUID \
{ \
0xdabbd793, 0x7b46, 0x4144, {0x8a, 0xd4, 0x10, 0x1c, 0x7c, 0x08, 0xeb, 0xfa } \
}
extern EFI_GUID mMpHandOffGuid; extern EFI_GUID mMpHandOffGuid;
extern EFI_GUID mMpHandOffConfigGuid;
// //
// The information required to transfer from the PEI phase to the // The information required to transfer from the PEI phase to the
@ -43,8 +49,11 @@ typedef struct {
// //
UINT32 ProcessorIndex; UINT32 ProcessorIndex;
UINT32 CpuCount; UINT32 CpuCount;
UINT32 WaitLoopExecutionMode;
UINT32 StartupSignalValue;
PROCESSOR_HAND_OFF Info[]; PROCESSOR_HAND_OFF Info[];
} MP_HAND_OFF; } MP_HAND_OFF;
typedef struct {
UINT32 WaitLoopExecutionMode;
UINT32 StartupSignalValue;
} MP_HAND_OFF_CONFIG;
#endif #endif

View File

@ -15,6 +15,7 @@
EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID; EFI_GUID mCpuInitMpLibHobGuid = CPU_INIT_MP_LIB_HOB_GUID;
EFI_GUID mMpHandOffGuid = MP_HANDOFF_GUID; EFI_GUID mMpHandOffGuid = MP_HANDOFF_GUID;
EFI_GUID mMpHandOffConfigGuid = MP_HANDOFF_CONFIG_GUID;
/** /**
Save the volatile registers required to be restored following INIT IPI. Save the volatile registers required to be restored following INIT IPI.
@ -1935,10 +1936,12 @@ GetBspNumber (
This procedure allows the AP to switch to another section of This procedure allows the AP to switch to another section of
memory and continue its loop there. memory and continue its loop there.
@param[in] MpHandOffConfig Pointer to MP hand-off config HOB body.
@param[in] FirstMpHandOff Pointer to first MP hand-off HOB body. @param[in] FirstMpHandOff Pointer to first MP hand-off HOB body.
**/ **/
VOID VOID
SwitchApContext ( SwitchApContext (
IN CONST MP_HAND_OFF_CONFIG *MpHandOffConfig,
IN CONST MP_HAND_OFF *FirstMpHandOff IN CONST MP_HAND_OFF *FirstMpHandOff
) )
{ {
@ -1955,7 +1958,7 @@ SwitchApContext (
for (Index = 0; Index < MpHandOff->CpuCount; Index++) { for (Index = 0; Index < MpHandOff->CpuCount; Index++) {
if (MpHandOff->ProcessorIndex + Index != BspNumber) { if (MpHandOff->ProcessorIndex + Index != BspNumber) {
*(UINTN *)(UINTN)MpHandOff->Info[Index].StartupProcedureAddress = (UINTN)SwitchContextPerAp; *(UINTN *)(UINTN)MpHandOff->Info[Index].StartupProcedureAddress = (UINTN)SwitchContextPerAp;
*(UINT32 *)(UINTN)MpHandOff->Info[Index].StartupSignalAddress = MpHandOff->StartupSignalValue; *(UINT32 *)(UINTN)MpHandOff->Info[Index].StartupSignalAddress = MpHandOffConfig->StartupSignalValue;
} }
} }
} }
@ -1975,6 +1978,26 @@ SwitchApContext (
} }
} }
/**
Get pointer to MP_HAND_OFF_CONFIG GUIDed HOB body.
@return The pointer to MP_HAND_OFF_CONFIG structure.
**/
MP_HAND_OFF_CONFIG *
GetMpHandOffConfigHob (
VOID
)
{
EFI_HOB_GUID_TYPE *GuidHob;
GuidHob = GetFirstGuidHob (&mMpHandOffConfigGuid);
if (GuidHob == NULL) {
return NULL;
}
return (MP_HAND_OFF_CONFIG *)GET_GUID_HOB_DATA (GuidHob);
}
/** /**
Get pointer to next MP_HAND_OFF GUIDed HOB body. Get pointer to next MP_HAND_OFF GUIDed HOB body.
@ -2022,6 +2045,7 @@ MpInitLibInitialize (
VOID VOID
) )
{ {
MP_HAND_OFF_CONFIG *MpHandOffConfig;
MP_HAND_OFF *FirstMpHandOff; MP_HAND_OFF *FirstMpHandOff;
MP_HAND_OFF *MpHandOff; MP_HAND_OFF *MpHandOff;
CPU_INFO_IN_HOB *CpuInfoInHob; CPU_INFO_IN_HOB *CpuInfoInHob;
@ -2239,13 +2263,24 @@ MpInitLibInitialize (
} }
} }
MpHandOffConfig = GetMpHandOffConfigHob ();
if (MpHandOffConfig == NULL) {
DEBUG ((
DEBUG_ERROR,
"%a: at least one MpHandOff HOB, but no MpHandOffConfig HOB\n",
__func__
));
ASSERT (MpHandOffConfig != NULL);
CpuDeadLoop ();
}
DEBUG (( DEBUG ((
DEBUG_INFO, DEBUG_INFO,
"FirstMpHandOff->WaitLoopExecutionMode: %04d, sizeof (VOID *): %04d\n", "FirstMpHandOff->WaitLoopExecutionMode: %04d, sizeof (VOID *): %04d\n",
FirstMpHandOff->WaitLoopExecutionMode, MpHandOffConfig->WaitLoopExecutionMode,
sizeof (VOID *) sizeof (VOID *)
)); ));
if (FirstMpHandOff->WaitLoopExecutionMode == sizeof (VOID *)) { if (MpHandOffConfig->WaitLoopExecutionMode == sizeof (VOID *)) {
ASSERT (CpuMpData->ApLoopMode != ApInHltLoop); ASSERT (CpuMpData->ApLoopMode != ApInHltLoop);
CpuMpData->FinishedCount = 0; CpuMpData->FinishedCount = 0;
@ -2261,7 +2296,7 @@ MpInitLibInitialize (
// enables the APs to switch to a different memory section and continue their // enables the APs to switch to a different memory section and continue their
// looping process there. // looping process there.
// //
SwitchApContext (FirstMpHandOff); SwitchApContext (MpHandOffConfig, FirstMpHandOff);
// //
// Wait for all APs finished initialization // Wait for all APs finished initialization
// //

View File

@ -482,6 +482,7 @@ GetWakeupBuffer (
**/ **/
VOID VOID
SwitchApContext ( SwitchApContext (
IN CONST MP_HAND_OFF_CONFIG *MpHandOffConfig,
IN CONST MP_HAND_OFF *FirstMpHandOff IN CONST MP_HAND_OFF *FirstMpHandOff
); );

View File

@ -133,6 +133,7 @@ SaveCpuMpData (
UINT32 HobBase; UINT32 HobBase;
CPU_INFO_IN_HOB *CpuInfoInHob; CPU_INFO_IN_HOB *CpuInfoInHob;
MP_HAND_OFF *MpHandOff; MP_HAND_OFF *MpHandOff;
MP_HAND_OFF_CONFIG MpHandOffConfig;
UINTN MpHandOffSize; UINTN MpHandOffSize;
MaxCpusPerHob = (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE) - sizeof (MP_HAND_OFF)) / sizeof (PROCESSOR_HAND_OFF); MaxCpusPerHob = (0xFFF8 - sizeof (EFI_HOB_GUID_TYPE) - sizeof (MP_HAND_OFF)) / sizeof (PROCESSOR_HAND_OFF);
@ -155,11 +156,6 @@ SaveCpuMpData (
MpHandOff->ProcessorIndex = HobBase; MpHandOff->ProcessorIndex = HobBase;
MpHandOff->CpuCount = CpusInHob; MpHandOff->CpuCount = CpusInHob;
if (CpuMpData->ApLoopMode != ApInHltLoop) {
MpHandOff->StartupSignalValue = MP_HAND_OFF_SIGNAL;
MpHandOff->WaitLoopExecutionMode = sizeof (VOID *);
}
} }
MpHandOff->Info[Index-HobBase].ApicId = CpuInfoInHob[Index].ApicId; MpHandOff->Info[Index-HobBase].ApicId = CpuInfoInHob[Index].ApicId;
@ -170,6 +166,18 @@ SaveCpuMpData (
} }
} }
ZeroMem (&MpHandOffConfig, sizeof (MpHandOffConfig));
if (CpuMpData->ApLoopMode != ApInHltLoop) {
MpHandOffConfig.StartupSignalValue = MP_HAND_OFF_SIGNAL;
MpHandOffConfig.WaitLoopExecutionMode = sizeof (VOID *);
}
BuildGuidDataHob (
&mMpHandOffConfigGuid,
(VOID *)&MpHandOffConfig,
sizeof (MpHandOffConfig)
);
// //
// Build location of CPU MP DATA buffer in HOB // Build location of CPU MP DATA buffer in HOB
// //