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

Reply via email to