we register a new interrupt handler for AP to invoke the specified produce. which vector is CALL_FUNCTION_VECTOR 0x30.
Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Chen Fan <chen.fan.f...@cn.fujitsu.com> --- UefiCpuPkg/CpuDxe/CpuMp.c | 64 ++++++++++++++++++++++++++++++++++++++++++++++- UefiCpuPkg/CpuDxe/CpuMp.h | 2 ++ 2 files changed, 65 insertions(+), 1 deletion(-) diff --git a/UefiCpuPkg/CpuDxe/CpuMp.c b/UefiCpuPkg/CpuDxe/CpuMp.c index 4870971..5720afe 100644 --- a/UefiCpuPkg/CpuDxe/CpuMp.c +++ b/UefiCpuPkg/CpuDxe/CpuMp.c @@ -21,6 +21,29 @@ IA32_DESCRIPTOR gIdtr; CPU_MP_SERVICE_DATA *mMpServiceData; UINTN mCpuIndex = 0; +VOID +SetApState ( + IN PROCESSOR_DATA_BLOCK *Processor, + IN PROCESSOR_STATE State + ) +{ + AcquireSpinLock (&Processor->StateLock); + Processor->State = State; + ReleaseSpinLock (&Processor->StateLock); +} + +VOID +SetApProcedure ( + IN PROCESSOR_DATA_BLOCK *Processor, + IN EFI_AP_PROCEDURE Procedure, + IN VOID *ProcedureArgument + ) +{ + AcquireSpinLock (&Processor->MpData.ProcedureLock); + Processor->MpData.Parameter = ProcedureArgument; + Processor->MpData.Procedure = Procedure; + ReleaseSpinLock (&Processor->MpData.ProcedureLock); +} EFI_STATUS InitMpSystemData ( @@ -82,12 +105,42 @@ ApEntryPointInC ( return ThisTopOfApCommonStack; } +VOID +EFIAPI +CallFunctionInterrupt ( + IN EFI_EXCEPTION_TYPE InterruptType, + IN EFI_SYSTEM_CONTEXT SystemContext + ) +{ + UINTN ProcessorId; + PROCESSOR_DATA_BLOCK *ProcessorData = NULL; + UINTN CpuIndex; + + ProcessorId = GetApicId(); + + for (CpuIndex = 0; CpuIndex < mMpServiceData->NumberOfProcessors; CpuIndex++) { + if (mMpServiceData->ProcessorData[CpuIndex]->Info.ProcessorId == ProcessorId) { + ProcessorData = mMpServiceData->ProcessorData[CpuIndex]; + break; + } + } + + if (ProcessorData) { + if (ProcessorData->MpData.Procedure) { + ProcessorData->MpData.Procedure (ProcessorData->MpData.Parameter); + } + SetApProcedure (ProcessorData, NULL, NULL); + SetApState (ProcessorData, CPU_STATE_FINISHED); + } + SendApicEoi (); +} VOID InitializeMpSupport ( VOID ) { + EFI_STATUS Status; PROCESSOR_DATA_BLOCK *ProcessorData; mCommonStack = AllocatePages (EFI_SIZE_TO_PAGES (SIZE_64KB)); @@ -117,7 +170,16 @@ InitializeMpSupport ( DEBUG((DEBUG_INFO, "%a: Detect CPU count: %d.\n", __FUNCTION__, mMpServiceData->NumberOfProcessors)); - InitMpSystemData (); + if (mMpServiceData->NumberOfProcessors > 1) { + EFI_CPU_ARCH_PROTOCOL *Cpu; + + Status = gBS->LocateProtocol (&gEfiCpuArchProtocolGuid, NULL, (VOID **)&Cpu); + ASSERT_EFI_ERROR (Status); + Status = Cpu->RegisterInterruptHandler (Cpu, CALL_FUNCTION_VECTOR, CallFunctionInterrupt); + ASSERT_EFI_ERROR (Status); + + InitMpSystemData (); + } mTopOfApCommonStack = NULL; FreePages (mCommonStack, EFI_SIZE_TO_PAGES (SIZE_64KB)); diff --git a/UefiCpuPkg/CpuDxe/CpuMp.h b/UefiCpuPkg/CpuDxe/CpuMp.h index 229c76d..b80954c 100644 --- a/UefiCpuPkg/CpuDxe/CpuMp.h +++ b/UefiCpuPkg/CpuDxe/CpuMp.h @@ -20,6 +20,8 @@ #define STALL_100_MILLI_SECOND (1000 * 100) +#define CALL_FUNCTION_VECTOR 0x30 + VOID InitializeMpSupport ( VOID ); -- 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