Revision: 17997
http://sourceforge.net/p/edk2/code/17997
Author: vanjeff
Date: 2015-07-15 03:38:35 +0000 (Wed, 15 Jul 2015)
Log Message:
-----------
UefiCpuPkg/CpuMpPei: Wakeup APs and collect AP count
BSP will send broadcast INIT Startup IPI to all APs and collect APs count and
BIST information.
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jeff Fan <[email protected]>
Reviewed-by: Feng Tian <[email protected]>
Reviewed-by: Jiewen Yao <[email protected]>
Modified Paths:
--------------
trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.c
trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.h
trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
Modified: trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.c
===================================================================
--- trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.c 2015-07-15 03:38:10 UTC (rev
17996)
+++ trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.c 2015-07-15 03:38:35 UTC (rev
17997)
@@ -39,6 +39,91 @@
};
/**
+ This function will be called from AP reset code if BSP uses WakeUpAP.
+
+ @param ExchangeInfo Pointer to the MP exchange info buffer
+ @param NumApsExecuting Number of curret executing AP
+**/
+VOID
+EFIAPI
+ApCFunction (
+ IN MP_CPU_EXCHANGE_INFO *ExchangeInfo,
+ IN UINTN NumApsExecuting
+ )
+{
+ PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINTN BistData;
+
+ PeiCpuMpData = ExchangeInfo->PeiCpuMpData;
+ if (PeiCpuMpData->InitFlag) {
+ //
+ // This is first time AP wakeup, get BIST inforamtion from AP stack
+ //
+ BistData = *(UINTN *) (PeiCpuMpData->Buffer + NumApsExecuting *
PeiCpuMpData->CpuApStackSize - sizeof (UINTN));
+ PeiCpuMpData->CpuData[NumApsExecuting].ApicId = GetInitialApicId ();
+ PeiCpuMpData->CpuData[NumApsExecuting].Health.Uint32 = (UINT32) BistData;
+ }
+
+ //
+ // AP finished executing C code
+ //
+ InterlockedIncrement ((UINT32 *)&PeiCpuMpData->FinishedCount);
+
+}
+
+/**
+ This function will be called by BSP to wakeup AP.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+ @param Broadcast TRUE: Send broadcast IPI to all APs
+ FALSE: Send IPI to AP by ApicId
+ @param ApicId Apic ID for the processor to be waked
+ @param Procedure The function to be invoked by AP
+ @param ProcedureArgument The argument to be passed into AP function
+**/
+VOID
+WakeUpAP (
+ IN PEI_CPU_MP_DATA *PeiCpuMpData,
+ IN BOOLEAN Broadcast,
+ IN UINT32 ApicId,
+ IN EFI_AP_PROCEDURE Procedure, OPTIONAL
+ IN VOID *ProcedureArgument OPTIONAL
+ )
+{
+ volatile MP_CPU_EXCHANGE_INFO *ExchangeInfo;
+
+ PeiCpuMpData->ApFunction = (UINTN) Procedure;
+ PeiCpuMpData->ApFunctionArgument = (UINTN) ProcedureArgument;
+ PeiCpuMpData->FinishedCount = 0;
+
+ ExchangeInfo = PeiCpuMpData->MpCpuExchangeInfo;
+ ExchangeInfo->Lock = 0;
+ ExchangeInfo->StackStart = PeiCpuMpData->Buffer;
+ ExchangeInfo->StackSize = PeiCpuMpData->CpuApStackSize;
+ ExchangeInfo->BufferStart = PeiCpuMpData->WakeupBuffer;
+ ExchangeInfo->PmodeOffset = PeiCpuMpData->AddressMap.PModeEntryOffset;
+ ExchangeInfo->LmodeOffset = PeiCpuMpData->AddressMap.LModeEntryOffset;
+ ExchangeInfo->Cr3 = AsmReadCr3 ();
+ ExchangeInfo->CFunction = (UINTN) ApCFunction;
+ ExchangeInfo->NumApsExecuting = 0;
+ ExchangeInfo->PeiCpuMpData = PeiCpuMpData;
+
+ //
+ // Get the BSP's data of GDT and IDT
+ //
+ CopyMem ((VOID *)&ExchangeInfo->GdtrProfile, &mGdt, sizeof(mGdt));
+ AsmReadIdtr ((IA32_DESCRIPTOR *) &ExchangeInfo->IdtrProfile);
+
+ if (Broadcast) {
+ SendInitSipiSipiAllExcludingSelf ((UINT32) ExchangeInfo->BufferStart);
+ } else {
+ SendInitSipiSipi (ApicId, (UINT32) ExchangeInfo->BufferStart);
+ }
+
+ return ;
+}
+
+/**
Get available system memory below 1MB by specified size.
@param WakeupBufferSize Wakeup buffer size required
@@ -132,6 +217,35 @@
);
}
/**
+ This function will get CPU count in the system.
+
+ @param PeiCpuMpData Pointer to PEI CPU MP Data
+
+ @return AP processor count
+**/
+UINT32
+CountProcessorNumber (
+ IN PEI_CPU_MP_DATA *PeiCpuMpData
+ )
+{
+
+ //
+ // Send broadcast IPI to APs to wakeup APs
+ //
+ PeiCpuMpData->InitFlag = 1;
+ WakeUpAP (PeiCpuMpData, TRUE, 0, NULL, NULL);
+ //
+ // Wait for AP task to complete and then exit.
+ //
+ MicroSecondDelay (PcdGet32 (PcdCpuApInitTimeOutInMicroSeconds));
+ PeiCpuMpData->InitFlag = 0;
+ PeiCpuMpData->CpuCount += (UINT32)
PeiCpuMpData->MpCpuExchangeInfo->NumApsExecuting;
+
+ DEBUG ((EFI_D_INFO, "CpuMpPei: Find %d processors in system.\n",
PeiCpuMpData->CpuCount));
+ return PeiCpuMpData->CpuCount;
+}
+
+/**
Prepare for AP wakeup buffer and copy AP reset code into it.
Get wakeup buffer below 1MB. Allocate memory for CPU MP Data and APs Stack.
@@ -213,6 +327,7 @@
{
PEI_CPU_MP_DATA *PeiCpuMpData;
+ UINT32 ProcessorCount;
//
// Load new GDT table on BSP
@@ -222,6 +337,10 @@
// Get wakeup buffer and copy AP reset code in it
//
PeiCpuMpData = PrepareAPStartupVector ();
+ //
+ // Count processor number and collect processor information
+ //
+ ProcessorCount = CountProcessorNumber (PeiCpuMpData);
return EFI_SUCCESS;
}
Modified: trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.h
===================================================================
--- trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.h 2015-07-15 03:38:10 UTC (rev
17996)
+++ trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.h 2015-07-15 03:38:35 UTC (rev
17997)
@@ -27,6 +27,8 @@
#include <Library/PcdLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
+#include <Library/SynchronizationLib.h>
+#include <Library/TimerLib.h>
#include <Library/UefiCpuLib.h>
//
// AP state
@@ -85,6 +87,7 @@
UINTN NumApsExecuting;
UINTN LmodeOffset;
UINTN Cr3;
+ PEI_CPU_MP_DATA *PeiCpuMpData;
} MP_CPU_EXCHANGE_INFO;
#pragma pack()
@@ -108,6 +111,10 @@
UINTN WakeupBuffer;
UINTN BackupBuffer;
UINTN BackupBufferSize;
+ UINTN ApFunction;
+ UINTN ApFunctionArgument;
+ volatile UINT32 FinishedCount;
+ BOOLEAN InitFlag;
PEI_CPU_DATA *CpuData;
volatile MP_CPU_EXCHANGE_INFO *MpCpuExchangeInfo;
};
Modified: trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.inf
===================================================================
--- trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.inf 2015-07-15 03:38:10 UTC (rev
17996)
+++ trunk/edk2/UefiCpuPkg/CpuMpPei/CpuMpPei.inf 2015-07-15 03:38:35 UTC (rev
17997)
@@ -56,11 +56,14 @@
PcdLib
PeimEntryPoint
PeiServicesLib
+ SynchronizationLib
+ TimerLib
UefiCpuLib
[Pcd]
gUefiCpuPkgTokenSpaceGuid.PcdCpuMaxLogicalProcessorNumber
+ gUefiCpuPkgTokenSpaceGuid.PcdCpuApInitTimeOutInMicroSeconds
gUefiCpuPkgTokenSpaceGuid.PcdCpuApStackSize
[Depex]
------------------------------------------------------------------------------
Don't Limit Your Business. Reach for the Cloud.
GigeNET's Cloud Solutions provide you with the tools and support that
you need to offload your IT needs and focus on growing your business.
Configured For All Businesses. Start Your Cloud Today.
https://www.gigenetcloud.com/
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits