Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com> --- UefiCpuPkg/CpuDxe/ApStartup.c | 5 ++-- UefiCpuPkg/CpuDxe/CpuMp.c | 62 +++++++++++++++++++++++++++++++++++++++++-- UefiCpuPkg/CpuDxe/CpuMp.h | 47 ++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 5 deletions(-)
diff --git a/UefiCpuPkg/CpuDxe/ApStartup.c b/UefiCpuPkg/CpuDxe/ApStartup.c index d159280..e259803 100644 --- a/UefiCpuPkg/CpuDxe/ApStartup.c +++ b/UefiCpuPkg/CpuDxe/ApStartup.c @@ -184,9 +184,8 @@ StartApsStackless ( SendInitSipiSipiAllExcludingSelf ((UINT32)(UINTN)(VOID*) StartupCode); - DisableInterrupts (); - CpuSleep (); - CpuDeadLoop (); + // wait 100ms + gBS->Stall (STALL_100_MILLI_SECOND); gBS->FreePages (StartAddress, EFI_SIZE_TO_PAGES (sizeof (*StartupCode))); diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c index 7d72cc0..4870971 100644 --- a/UefiCpuPkg/CpuDxe/CpuMp.c +++ b/UefiCpuPkg/CpuDxe/CpuMp.c @@ -18,6 +18,37 @@ VOID *mCommonStack = 0; VOID *mTopOfApCommonStack = 0; IA32_DESCRIPTOR gIdtr; +CPU_MP_SERVICE_DATA *mMpServiceData; +UINTN mCpuIndex = 0; + + +EFI_STATUS +InitMpSystemData ( + VOID + ) +{ + UINTN CpuIndex; + PROCESSOR_DATA_BLOCK *ProcessorData; + + for (CpuIndex = 0; CpuIndex < mMpServiceData->NumberOfProcessors; CpuIndex++) { + ProcessorData = mMpServiceData->ProcessorData[CpuIndex]; + + ProcessorData->Info.StatusFlag = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT; + if (CpuIndex == 0) { + ProcessorData->Info.StatusFlag |= PROCESSOR_AS_BSP_BIT; + } + ProcessorData->Info.Location.Package = (UINT32) CpuIndex; + ProcessorData->Info.Location.Core = 0; + ProcessorData->Info.Location.Thread = 0; + ProcessorData->State = (CpuIndex == 0) ? CPU_STATE_BUSY : CPU_STATE_IDLE; + InitializeSpinLock (&ProcessorData->StateLock); + ProcessorData->MpData.Procedure = NULL; + ProcessorData->MpData.Parameter = NULL; + InitializeSpinLock (&ProcessorData->MpData.ProcedureLock); + } + + return EFI_SUCCESS; +} VOID* EFIAPI @@ -27,6 +58,14 @@ ApEntryPointInC ( { VOID *ThisCommonStack = 0; VOID *ThisTopOfApCommonStack = 0; + PROCESSOR_DATA_BLOCK *ProcessorData; + + ProcessorData = AllocateZeroPool ( sizeof (PROCESSOR_DATA_BLOCK)); + ASSERT(ProcessorData != NULL); + + ProcessorData->Info.ProcessorId = GetApicId (); + mMpServiceData->ProcessorData[mCpuIndex] = ProcessorData; + mCpuIndex++; // APs use the same Interrupt Descriptor Table with BSP AsmWriteIdtr (&gIdtr); @@ -40,8 +79,6 @@ ApEntryPointInC ( ThisTopOfApCommonStack = (VOID*) ((UINTN)ThisCommonStack + SIZE_64KB); - DEBUG((DEBUG_ERROR, "!!%d: %p\n", GetApicId(), ThisTopOfApCommonStack)); - return ThisTopOfApCommonStack; } @@ -51,6 +88,8 @@ InitializeMpSupport ( VOID ) { + PROCESSOR_DATA_BLOCK *ProcessorData; + mCommonStack = AllocatePages (EFI_SIZE_TO_PAGES (SIZE_64KB)); mTopOfApCommonStack = (VOID*) ((UINTN)mCommonStack + SIZE_64KB); if (mCommonStack == NULL) { @@ -59,8 +98,27 @@ InitializeMpSupport ( AsmReadIdtr (&gIdtr); + mMpServiceData = AllocateZeroPool (sizeof (CPU_MP_SERVICE_DATA)); + ASSERT(mMpServiceData != NULL); + + // BSP info + ProcessorData = AllocateZeroPool (sizeof (PROCESSOR_DATA_BLOCK)); + ASSERT(ProcessorData != NULL); + + ProcessorData->Info.ProcessorId = 0; + mMpServiceData->ProcessorData[mCpuIndex] = ProcessorData; + mCpuIndex++; + StartApsStackless (AsmApEntryPoint); + mMpServiceData->NumberOfProcessors = mCpuIndex; + mMpServiceData->NumberOfEnabledProcessors = mCpuIndex; + + DEBUG((DEBUG_INFO, "%a: Detect CPU count: %d.\n", + __FUNCTION__, mMpServiceData->NumberOfProcessors)); + + InitMpSystemData (); + mTopOfApCommonStack = NULL; FreePages (mCommonStack, EFI_SIZE_TO_PAGES (SIZE_64KB)); mCommonStack = NULL; diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h index 884d87b..229c76d 100644 --- a/UefiCpuPkg/CpuDxe/CpuMp.h +++ b/UefiCpuPkg/CpuDxe/CpuMp.h @@ -15,6 +15,11 @@ #ifndef _CPU_MP_H_ #define _CPU_MP_H_ +#include <Protocol/MpService.h> +#include <Library/SynchronizationLib.h> + +#define STALL_100_MILLI_SECOND (1000 * 100) + VOID InitializeMpSupport ( VOID ); @@ -36,5 +41,47 @@ AsmApEntryPoint ( VOID ); +typedef enum { + CPU_STATE_IDLE, + CPU_STATE_BLOCKED, + CPU_STATE_READY, + CPU_STATE_BUSY, + CPU_STATE_FINISHED +} PROCESSOR_STATE; + +typedef struct { + EFI_AP_PROCEDURE Procedure; + VOID *Parameter; + SPIN_LOCK ProcedureLock; + UINTN Timeout; + EFI_EVENT WaitEvent; + BOOLEAN TimeoutActive; +} PROCESSOR_MP_DATA_BLOCK; + +// +// Define Individual Processor Data block. +// +typedef struct { + EFI_PROCESSOR_INFORMATION Info; + PROCESSOR_MP_DATA_BLOCK MpData; + PROCESSOR_STATE State; + SPIN_LOCK StateLock; + BOOLEAN *Finished; + EFI_EVENT CheckThisAPEvent; +} PROCESSOR_DATA_BLOCK; + +// +// Define MP data block which consumes individual processor block. +// +typedef struct { + UINTN NumberOfProcessors; + UINTN NumberOfEnabledProcessors; + PROCESSOR_DATA_BLOCK *ProcessorData[255]; + PROCESSOR_MP_DATA_BLOCK MpData; + UINTN *FailedList; + UINTN FailedListIndex; + EFI_EVENT CheckAllAPsEvent; +} CPU_MP_SERVICE_DATA; + #endif // _CPU_MP_H_ -- 1.9.3 ------------------------------------------------------------------------------ Infragistics Professional Build stunning WinForms apps today! Reboot your WinForms applications with our WinForms controls. Build a bridge from your legacy apps to the future. http://pubads.g.doubleclick.net/gampad/clk?id=153845071&iu=/4140/ostg.clktrk _______________________________________________ edk2-devel mailing list edk2-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/edk2-devel