CpuMp.c revision 9840b1299de78458a42d35b8d1d6cbadd1f6da72
16022e28cf744a885c278dad256d50670741ea123Jordan Justen/** @file 26022e28cf744a885c278dad256d50670741ea123Jordan Justen CPU DXE Module. 36022e28cf744a885c278dad256d50670741ea123Jordan Justen 46022e28cf744a885c278dad256d50670741ea123Jordan Justen Copyright (c) 2008 - 2014, Intel Corporation. All rights reserved.<BR> 56022e28cf744a885c278dad256d50670741ea123Jordan Justen This program and the accompanying materials 66022e28cf744a885c278dad256d50670741ea123Jordan Justen are licensed and made available under the terms and conditions of the BSD License 76022e28cf744a885c278dad256d50670741ea123Jordan Justen which accompanies this distribution. The full text of the license may be found at 86022e28cf744a885c278dad256d50670741ea123Jordan Justen http://opensource.org/licenses/bsd-license.php 96022e28cf744a885c278dad256d50670741ea123Jordan Justen 106022e28cf744a885c278dad256d50670741ea123Jordan Justen THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 116022e28cf744a885c278dad256d50670741ea123Jordan Justen WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 126022e28cf744a885c278dad256d50670741ea123Jordan Justen 136022e28cf744a885c278dad256d50670741ea123Jordan Justen**/ 146022e28cf744a885c278dad256d50670741ea123Jordan Justen 156022e28cf744a885c278dad256d50670741ea123Jordan Justen#include "CpuDxe.h" 166022e28cf744a885c278dad256d50670741ea123Jordan Justen#include "CpuMp.h" 176022e28cf744a885c278dad256d50670741ea123Jordan Justen 186a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen FanUINTN gMaxLogicalProcessorNumber; 196a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen FanUINTN gApStackSize; 203f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanUINTN gPollInterval = 100; // 100 microseconds 216a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan 2203673ae11e255b9467e8f317175495b1ff79f965Chen FanMP_SYSTEM_DATA mMpSystemData; 239840b1299de78458a42d35b8d1d6cbadd1f6da72Chen FanEFI_HANDLE mMpServiceHandle = NULL; 249840b1299de78458a42d35b8d1d6cbadd1f6da72Chen FanEFI_EVENT mExitBootServicesEvent = (EFI_EVENT)NULL; 2503673ae11e255b9467e8f317175495b1ff79f965Chen Fan 26fab82c1873b792bce33fb22c32db71324fc0ac3bJordan JustenVOID *mCommonStack = 0; 27fab82c1873b792bce33fb22c32db71324fc0ac3bJordan JustenVOID *mTopOfApCommonStack = 0; 286a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen FanVOID *mApStackStart = 0; 29fab82c1873b792bce33fb22c32db71324fc0ac3bJordan Justen 30232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fanvolatile BOOLEAN mAPsAlreadyInitFinished = FALSE; 31acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fanvolatile BOOLEAN mStopCheckAllAPsStatus = TRUE; 32acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan 33003973d98cf1ef84ab810cb4f3870acd3a7f40a6Chen FanEFI_MP_SERVICES_PROTOCOL mMpServicesTemplate = { 34d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan GetNumberOfProcessors, 35e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan GetProcessorInfo, 365fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan StartupAllAPs, 373f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan StartupThisAP, 38b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan SwitchBSP, 39fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan EnableDisableAP, 40cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan WhoAmI 41003973d98cf1ef84ab810cb4f3870acd3a7f40a6Chen Fan}; 42003973d98cf1ef84ab810cb4f3870acd3a7f40a6Chen Fan 436022e28cf744a885c278dad256d50670741ea123Jordan Justen/** 44d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan Get Mp Service Lock. 45d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan 46d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan @param CpuData the pointer to CPU_DATA_BLOCK of specified processor 47d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan 48d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan**/ 49d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen FanVOID 50d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen FanGetMpSpinLock ( 51d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan IN CPU_DATA_BLOCK *CpuData 52d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan ) 53d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan{ 54d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan while (!AcquireSpinLockOrFail (&CpuData->CpuDataLock)) { 55d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan CpuPause (); 56d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan } 570e724fc1981b3c47bb16432c4c414a50c9e3a519Chen Fan CpuData->LockSelf = GetApicId (); 58d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan} 59d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan 60d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan/** 61d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan Release Mp Service Lock. 62d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan 63d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan @param CpuData the pointer to CPU_DATA_BLOCK of specified processor 64d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan 65d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan**/ 66d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen FanVOID 67d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen FanReleaseMpSpinLock ( 68d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan IN CPU_DATA_BLOCK *CpuData 69d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan ) 70d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan{ 71d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan ReleaseSpinLock (&CpuData->CpuDataLock); 72d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan} 73d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan 74d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan/** 75d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan Check whether caller processor is BSP. 76d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 77d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan @retval TRUE the caller is BSP 78d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan @retval FALSE the caller is AP 79d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 80d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan**/ 81d894d8b704324da8ed902677703ed9d4f7c85076Chen FanBOOLEAN 82d894d8b704324da8ed902677703ed9d4f7c85076Chen FanIsBSP ( 83d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan VOID 84d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan ) 85d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan{ 86d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan UINTN CpuIndex; 87d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan CPU_DATA_BLOCK *CpuData; 88d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 89d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan CpuData = NULL; 90d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 91d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan WhoAmI (&mMpServicesTemplate, &CpuIndex); 92d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan CpuData = &mMpSystemData.CpuDatas[CpuIndex]; 93d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 94d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan return CpuData->Info.StatusFlag & PROCESSOR_AS_BSP_BIT ? TRUE : FALSE; 95d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan} 96d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 97d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan/** 98fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan Get the Application Processors state. 99fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 100fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @param CpuData the pointer to CPU_DATA_BLOCK of specified AP 101fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 102fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @retval CPU_STATE the AP status 103fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 104fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan**/ 105fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen FanCPU_STATE 106fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen FanGetApState ( 107fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan IN CPU_DATA_BLOCK *CpuData 108fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan ) 109fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan{ 110fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan CPU_STATE State; 111fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 112d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan GetMpSpinLock (CpuData); 113fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan State = CpuData->State; 114d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan ReleaseMpSpinLock (CpuData); 115fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 116fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan return State; 117fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan} 118fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 119fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan/** 1203f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan Set the Application Processors state. 1213f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 1223f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param CpuData The pointer to CPU_DATA_BLOCK of specified AP 1233f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param State The AP status 1243f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 1253f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan**/ 1263f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanVOID 1273f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanSetApState ( 1283f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN CPU_DATA_BLOCK *CpuData, 1293f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN CPU_STATE State 1303f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan ) 1313f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan{ 132d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan GetMpSpinLock (CpuData); 1333f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData->State = State; 134d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan ReleaseMpSpinLock (CpuData); 1353f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan} 1363f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 1373f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan/** 1383f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan Set the Application Processor prepare to run a function specified 1393f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan by Params. 1403f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 1413f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param CpuData the pointer to CPU_DATA_BLOCK of specified AP 1423f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param Procedure A pointer to the function to be run on enabled APs of the system 1433f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param ProcedureArgument Pointer to the optional parameter of the assigned function 1443f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 1453f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan**/ 1463f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanVOID 1473f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanSetApProcedure ( 1483f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN CPU_DATA_BLOCK *CpuData, 1493f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN EFI_AP_PROCEDURE Procedure, 1503f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN VOID *ProcedureArgument 1513f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan ) 1523f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan{ 153d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan GetMpSpinLock (CpuData); 1543f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData->Parameter = ProcedureArgument; 1553f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData->Procedure = Procedure; 156d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan ReleaseMpSpinLock (CpuData); 1573f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan} 1583f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 1593f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan/** 160fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan Check the Application Processors Status whether contains the Flags. 161fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 162fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @param CpuData the pointer to CPU_DATA_BLOCK of specified AP 163fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION 164fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 165fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @retval TRUE the AP status includes the StatusFlag 166fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @retval FALSE the AP status excludes the StatusFlag 167fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 168fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan**/ 169fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen FanBOOLEAN 170fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen FanTestCpuStatusFlag ( 171fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan IN CPU_DATA_BLOCK *CpuData, 172fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan IN UINT32 Flags 173fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan ) 174fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan{ 175fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan UINT32 Ret; 176fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 177d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan GetMpSpinLock (CpuData); 178fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan Ret = CpuData->Info.StatusFlag & Flags; 179d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan ReleaseMpSpinLock (CpuData); 180fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 181fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan return !!(Ret); 182fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan} 183fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 184fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan/** 185fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan Bitwise-Or of the Application Processors Status with the Flags. 186fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 187fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @param CpuData the pointer to CPU_DATA_BLOCK of specified AP 188fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION 189fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 190fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan**/ 191fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen FanVOID 192fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen FanCpuStatusFlagOr ( 193fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan IN CPU_DATA_BLOCK *CpuData, 194fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan IN UINT32 Flags 195fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan ) 196fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan{ 197d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan GetMpSpinLock (CpuData); 198fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan CpuData->Info.StatusFlag |= Flags; 199d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan ReleaseMpSpinLock (CpuData); 200fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan} 201fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 202fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan/** 203fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan Bitwise-AndNot of the Application Processors Status with the Flags. 204fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 205fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @param CpuData the pointer to CPU_DATA_BLOCK of specified AP 206fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @param Flags the StatusFlag describing in EFI_PROCESSOR_INFORMATION 207fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 208fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan**/ 209fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen FanVOID 210fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen FanCpuStatusFlagAndNot ( 211fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan IN CPU_DATA_BLOCK *CpuData, 212fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan IN UINT32 Flags 213fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan ) 214fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan{ 215d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan GetMpSpinLock (CpuData); 216fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan CpuData->Info.StatusFlag &= ~Flags; 217d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan ReleaseMpSpinLock (CpuData); 218fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan} 219fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 220fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan/** 2213f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan Searches for the next blocking AP. 2223f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 2233f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan Search for the next AP that is put in blocking state by single-threaded StartupAllAPs(). 2243f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 2253f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param NextNumber Pointer to the processor number of the next blocking AP. 2263f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 2273f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @retval EFI_SUCCESS The next blocking AP has been found. 2283f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @retval EFI_NOT_FOUND No blocking AP exists. 2293f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 2303f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan**/ 2313f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanEFI_STATUS 2323f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanGetNextBlockedNumber ( 2333f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan OUT UINTN *NextNumber 2343f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan ) 2353f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan{ 2363f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan UINTN Number; 2373f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CPU_STATE CpuState; 2383f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CPU_DATA_BLOCK *CpuData; 2393f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 2403f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) { 2413f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData = &mMpSystemData.CpuDatas[Number]; 2423f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) { 2433f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan // 2443f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan // Skip BSP 2453f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan // 2463f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan continue; 2473f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 2483f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 2493f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuState = GetApState (CpuData); 2503f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (CpuState == CpuStateBlocked) { 2513f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan *NextNumber = Number; 2523f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan return EFI_SUCCESS; 2533f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 2543f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 2553f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 2563f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan return EFI_NOT_FOUND; 2573f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan} 2583f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 2593f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan/** 2605fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan Check if the APs state are finished, and update them to idle state 2615fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan by StartupAllAPs(). 2625fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 2635fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan**/ 2645fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen FanVOID 2655fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen FanCheckAndUpdateAllAPsToIdleState ( 2665fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan VOID 2675fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan ) 2685fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan{ 2695fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan UINTN ProcessorNumber; 2705fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan UINTN NextNumber; 2715fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CPU_DATA_BLOCK *CpuData; 2725fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan EFI_STATUS Status; 2735fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CPU_STATE CpuState; 2745fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 2755fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan for (ProcessorNumber = 0; ProcessorNumber < mMpSystemData.NumberOfProcessors; ProcessorNumber++) { 2765fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CpuData = &mMpSystemData.CpuDatas[ProcessorNumber]; 2775fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) { 2785fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 2795fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // Skip BSP 2805fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 2815fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan continue; 2825fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 2835fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 2845fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) { 2855fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 2865fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // Skip Disabled processors 2875fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 2885fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan continue; 2895fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 2905fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 2915fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CpuState = GetApState (CpuData); 2925fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (CpuState == CpuStateFinished) { 2935fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.FinishCount++; 2945fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (mMpSystemData.SingleThread) { 2955fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan Status = GetNextBlockedNumber (&NextNumber); 2965fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (!EFI_ERROR (Status)) { 2975fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan SetApState (&mMpSystemData.CpuDatas[NextNumber], CpuStateReady); 2985fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan SetApProcedure (&mMpSystemData.CpuDatas[NextNumber], 2995fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.Procedure, 3005fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.ProcedureArgument); 3015fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 3025fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 3035fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 3045fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan SetApState (CpuData, CpuStateIdle); 3055fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 3065fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 3075fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan} 3085fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 3095fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan/** 3105fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan If the timeout expires before all APs returns from Procedure, 3115fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan we should forcibly terminate the executing AP and fill FailedList back 3125fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan by StartupAllAPs(). 3135fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 3145fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan**/ 3155fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen FanVOID 3165fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen FanResetAllFailedAPs ( 3175fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan VOID 3185fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan ) 3195fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan{ 3205fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CPU_DATA_BLOCK *CpuData; 3215fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan UINTN Number; 3225fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CPU_STATE CpuState; 3235fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 3245fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (mMpSystemData.FailedList != NULL) { 3255fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan *mMpSystemData.FailedList = AllocatePool ((mMpSystemData.StartCount - mMpSystemData.FinishCount + 1) * sizeof(UINTN)); 3265fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan ASSERT (*mMpSystemData.FailedList != NULL); 3275fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 3285fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 3295fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) { 3305fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CpuData = &mMpSystemData.CpuDatas[Number]; 3315fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) { 3325fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 3335fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // Skip BSP 3345fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 3355fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan continue; 3365fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 3375fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 3385fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) { 3395fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 3405fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // Skip Disabled processors 3415fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 3425fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan continue; 3435fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 3445fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 3455fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CpuState = GetApState (CpuData); 3465fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (CpuState != CpuStateIdle) { 3475fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (mMpSystemData.FailedList != NULL) { 3485fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan (*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex++] = Number; 3495fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 3505fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan ResetProcessorToIdleState (CpuData); 3515fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 3525fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 3535fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 3545fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (mMpSystemData.FailedList != NULL) { 3555fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan (*mMpSystemData.FailedList)[mMpSystemData.FailedListIndex] = END_OF_CPU_LIST; 3565fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 3575fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan} 3585fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 3595fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan/** 360d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan This service retrieves the number of logical processor in the platform 361d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan and the number of those logical processors that are enabled on this boot. 362d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan This service may only be called from the BSP. 363d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 364d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan This function is used to retrieve the following information: 365d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan - The number of logical processors that are present in the system. 366d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan - The number of enabled logical processors in the system at the instant 367d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan this call is made. 368d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 369d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan Because MP Service Protocol provides services to enable and disable processors 370d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan dynamically, the number of enabled logical processors may vary during the 371d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan course of a boot session. 372d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 373d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan If this service is called from an AP, then EFI_DEVICE_ERROR is returned. 374d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan If NumberOfProcessors or NumberOfEnabledProcessors is NULL, then 375d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan EFI_INVALID_PARAMETER is returned. Otherwise, the total number of processors 376d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan is returned in NumberOfProcessors, the number of currently enabled processor 377d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan is returned in NumberOfEnabledProcessors, and EFI_SUCCESS is returned. 378d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 379d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL 380d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan instance. 381d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan @param[out] NumberOfProcessors Pointer to the total number of logical 382d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan processors in the system, including the BSP 383d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan and disabled APs. 384d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan @param[out] NumberOfEnabledProcessors Pointer to the number of enabled logical 385d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan processors that exist in system, including 386d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan the BSP. 387d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 388d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan @retval EFI_SUCCESS The number of logical processors and enabled 389d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan logical processors was retrieved. 390d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan @retval EFI_DEVICE_ERROR The calling processor is an AP. 391d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan @retval EFI_INVALID_PARAMETER NumberOfProcessors is NULL. 392d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan @retval EFI_INVALID_PARAMETER NumberOfEnabledProcessors is NULL. 393d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 394d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan**/ 395d894d8b704324da8ed902677703ed9d4f7c85076Chen FanEFI_STATUS 396d894d8b704324da8ed902677703ed9d4f7c85076Chen FanEFIAPI 397d894d8b704324da8ed902677703ed9d4f7c85076Chen FanGetNumberOfProcessors ( 398d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan IN EFI_MP_SERVICES_PROTOCOL *This, 399d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan OUT UINTN *NumberOfProcessors, 400d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan OUT UINTN *NumberOfEnabledProcessors 401d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan ) 402d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan{ 403d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan if ((NumberOfProcessors == NULL) || (NumberOfEnabledProcessors == NULL)) { 404d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan return EFI_INVALID_PARAMETER; 405d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan } 406d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 407d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan if (!IsBSP ()) { 408d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan return EFI_DEVICE_ERROR; 409d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan } 410d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 411d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan *NumberOfProcessors = mMpSystemData.NumberOfProcessors; 412d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan *NumberOfEnabledProcessors = mMpSystemData.NumberOfEnabledProcessors; 413d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan return EFI_SUCCESS; 414d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan} 415d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan 416d894d8b704324da8ed902677703ed9d4f7c85076Chen Fan/** 417e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan Gets detailed MP-related information on the requested processor at the 418e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan instant this call is made. This service may only be called from the BSP. 419e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan 420e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan This service retrieves detailed MP-related information about any processor 421e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan on the platform. Note the following: 422e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan - The processor information may change during the course of a boot session. 423e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan - The information presented here is entirely MP related. 424e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan 425e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan Information regarding the number of caches and their sizes, frequency of operation, 426e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan slot numbers is all considered platform-related information and is not provided 427e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan by this service. 428e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan 429e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL 430e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan instance. 431e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan @param[in] ProcessorNumber The handle number of processor. 432e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan @param[out] ProcessorInfoBuffer A pointer to the buffer where information for 433e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan the requested processor is deposited. 434e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan 435e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan @retval EFI_SUCCESS Processor information was returned. 436e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan @retval EFI_DEVICE_ERROR The calling processor is an AP. 437e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan @retval EFI_INVALID_PARAMETER ProcessorInfoBuffer is NULL. 438e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan @retval EFI_NOT_FOUND The processor with the handle specified by 439e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan ProcessorNumber does not exist in the platform. 440e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan 441e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan**/ 442e7938b5a869fc42df7f026752f39ea85090eb3f9Chen FanEFI_STATUS 443e7938b5a869fc42df7f026752f39ea85090eb3f9Chen FanEFIAPI 444e7938b5a869fc42df7f026752f39ea85090eb3f9Chen FanGetProcessorInfo ( 445e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan IN EFI_MP_SERVICES_PROTOCOL *This, 446e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan IN UINTN ProcessorNumber, 447e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan OUT EFI_PROCESSOR_INFORMATION *ProcessorInfoBuffer 448e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan ) 449e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan{ 450e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan if (ProcessorInfoBuffer == NULL) { 451e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan return EFI_INVALID_PARAMETER; 452e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan } 453e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan 454e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan if (!IsBSP ()) { 455e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan return EFI_DEVICE_ERROR; 456e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan } 457e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan 458e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) { 459e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan return EFI_NOT_FOUND; 460e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan } 461e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan 462e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan CopyMem (ProcessorInfoBuffer, &mMpSystemData.CpuDatas[ProcessorNumber], sizeof (EFI_PROCESSOR_INFORMATION)); 463e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan return EFI_SUCCESS; 464e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan} 465e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan 466e7938b5a869fc42df7f026752f39ea85090eb3f9Chen Fan/** 4675fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan This service executes a caller provided function on all enabled APs. APs can 4685fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan run either simultaneously or one at a time in sequence. This service supports 4695fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan both blocking and non-blocking requests. The non-blocking requests use EFI 4705fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan events so the BSP can detect when the APs have finished. This service may only 4715fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan be called from the BSP. 4725fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 4735fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan This function is used to dispatch all the enabled APs to the function specified 4745fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan by Procedure. If any enabled AP is busy, then EFI_NOT_READY is returned 4755fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan immediately and Procedure is not started on any AP. 4765fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 4775fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan If SingleThread is TRUE, all the enabled APs execute the function specified by 4785fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan Procedure one by one, in ascending order of processor handle number. Otherwise, 4795fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan all the enabled APs execute the function specified by Procedure simultaneously. 4805fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 4815fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan If WaitEvent is NULL, execution is in blocking mode. The BSP waits until all 4825fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan APs finish or TimeoutInMicroseconds expires. Otherwise, execution is in non-blocking 4835fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mode, and the BSP returns from this service without waiting for APs. If a 4845fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan non-blocking mode is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT 4855fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan is signaled, then EFI_UNSUPPORTED must be returned. 4865fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 4875fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan If the timeout specified by TimeoutInMicroseconds expires before all APs return 4885fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan from Procedure, then Procedure on the failed APs is terminated. All enabled APs 4895fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan are always available for further calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() 4905fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan and EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). If FailedCpuList is not NULL, its 4915fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan content points to the list of processor handle numbers in which Procedure was 4925fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan terminated. 4935fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 4945fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan Note: It is the responsibility of the consumer of the EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() 4955fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan to make sure that the nature of the code that is executed on the BSP and the 4965fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan dispatched APs is well controlled. The MP Services Protocol does not guarantee 4975fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan that the Procedure function is MP-safe. Hence, the tasks that can be run in 4985fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan parallel are limited to certain independent tasks and well-controlled exclusive 4995fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan code. EFI services and protocols may not be called by APs unless otherwise 5005fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan specified. 5015fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 5025fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan In blocking execution mode, BSP waits until all APs finish or 5035fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan TimeoutInMicroseconds expires. 5045fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 5055fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan In non-blocking execution mode, BSP is freed to return to the caller and then 5065fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan proceed to the next task without having to wait for APs. The following 5075fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan sequence needs to occur in a non-blocking execution mode: 5085fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 5095fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan -# The caller that intends to use this MP Services Protocol in non-blocking 5105fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mode creates WaitEvent by calling the EFI CreateEvent() service. The caller 5115fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan invokes EFI_MP_SERVICES_PROTOCOL.StartupAllAPs(). If the parameter WaitEvent 5125fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan is not NULL, then StartupAllAPs() executes in non-blocking mode. It requests 5135fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan the function specified by Procedure to be started on all the enabled APs, 5145fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan and releases the BSP to continue with other tasks. 5155fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan -# The caller can use the CheckEvent() and WaitForEvent() services to check 5165fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan the state of the WaitEvent created in step 1. 5175fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan -# When the APs complete their task or TimeoutInMicroSecondss expires, the MP 5185fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan Service signals WaitEvent by calling the EFI SignalEvent() function. If 5195fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan FailedCpuList is not NULL, its content is available when WaitEvent is 5205fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan signaled. If all APs returned from Procedure prior to the timeout, then 5215fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan FailedCpuList is set to NULL. If not all APs return from Procedure before 5225fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan the timeout, then FailedCpuList is filled in with the list of the failed 5235fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan APs. The buffer is allocated by MP Service Protocol using AllocatePool(). 5245fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan It is the caller's responsibility to free the buffer with FreePool() service. 5255fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan -# This invocation of SignalEvent() function informs the caller that invoked 5265fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() that either all the APs completed 5275fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan the specified task or a timeout occurred. The contents of FailedCpuList 5285fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan can be examined to determine which APs did not complete the specified task 5295fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan prior to the timeout. 5305fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 5315fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL 5325fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan instance. 5335fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @param[in] Procedure A pointer to the function to be run on 5345fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan enabled APs of the system. See type 5355fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan EFI_AP_PROCEDURE. 5365fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @param[in] SingleThread If TRUE, then all the enabled APs execute 5375fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan the function specified by Procedure one by 5385fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan one, in ascending order of processor handle 5395fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan number. If FALSE, then all the enabled APs 5405fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan execute the function specified by Procedure 5415fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan simultaneously. 5425fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @param[in] WaitEvent The event created by the caller with CreateEvent() 5435fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan service. If it is NULL, then execute in 5445fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan blocking mode. BSP waits until all APs finish 5455fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan or TimeoutInMicroseconds expires. If it's 5465fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan not NULL, then execute in non-blocking mode. 5475fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan BSP requests the function specified by 5485fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan Procedure to be started on all the enabled 5495fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan APs, and go on executing immediately. If 5505fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan all return from Procedure, or TimeoutInMicroseconds 5515fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan expires, this event is signaled. The BSP 5525fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan can use the CheckEvent() or WaitForEvent() 5535fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan services to check the state of event. Type 5545fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan EFI_EVENT is defined in CreateEvent() in 5555fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan the Unified Extensible Firmware Interface 5565fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan Specification. 5575fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for 5585fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan APs to return from Procedure, either for 5595fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan blocking or non-blocking mode. Zero means 5605fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan infinity. If the timeout expires before 5615fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan all APs return from Procedure, then Procedure 5625fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan on the failed APs is terminated. All enabled 5635fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan APs are available for next function assigned 5645fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() 5655fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan or EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). 5665fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan If the timeout expires in blocking mode, 5675fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan BSP returns EFI_TIMEOUT. If the timeout 5685fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan expires in non-blocking mode, WaitEvent 5695fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan is signaled with SignalEvent(). 5705fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @param[in] ProcedureArgument The parameter passed into Procedure for 5715fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan all APs. 5725fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @param[out] FailedCpuList If NULL, this parameter is ignored. Otherwise, 5735fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if all APs finish successfully, then its 5745fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan content is set to NULL. If not all APs 5755fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan finish before timeout expires, then its 5765fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan content is set to address of the buffer 5775fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan holding handle numbers of the failed APs. 5785fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan The buffer is allocated by MP Service Protocol, 5795fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan and it's the caller's responsibility to 5805fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan free the buffer with FreePool() service. 5815fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan In blocking mode, it is ready for consumption 5825fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan when the call returns. In non-blocking mode, 5835fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan it is ready when WaitEvent is signaled. The 5845fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan list of failed CPU is terminated by 5855fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan END_OF_CPU_LIST. 5865fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 5875fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @retval EFI_SUCCESS In blocking mode, all APs have finished before 5885fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan the timeout expired. 5895fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @retval EFI_SUCCESS In non-blocking mode, function has been dispatched 5905fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan to all enabled APs. 5915fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @retval EFI_UNSUPPORTED A non-blocking mode request was made after the 5925fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was 5935fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan signaled. 5945fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @retval EFI_DEVICE_ERROR Caller processor is AP. 5955fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @retval EFI_NOT_STARTED No enabled APs exist in the system. 5965fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @retval EFI_NOT_READY Any enabled APs are busy. 5975fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @retval EFI_TIMEOUT In blocking mode, the timeout expired before 5985fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan all enabled APs have finished. 5995fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @retval EFI_INVALID_PARAMETER Procedure is NULL. 6005fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6015fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan**/ 6025fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen FanEFI_STATUS 6035fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen FanEFIAPI 6045fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen FanStartupAllAPs ( 6055fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan IN EFI_MP_SERVICES_PROTOCOL *This, 6065fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan IN EFI_AP_PROCEDURE Procedure, 6075fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan IN BOOLEAN SingleThread, 6085fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan IN EFI_EVENT WaitEvent OPTIONAL, 6095fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan IN UINTN TimeoutInMicroseconds, 6105fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan IN VOID *ProcedureArgument OPTIONAL, 6115fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan OUT UINTN **FailedCpuList OPTIONAL 6125fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan ) 6135fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan{ 6145fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan EFI_STATUS Status; 6155fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CPU_DATA_BLOCK *CpuData; 6165fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan UINTN Number; 6175fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CPU_STATE APInitialState; 6185fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6195fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CpuData = NULL; 6205fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6215fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (FailedCpuList != NULL) { 6225fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan *FailedCpuList = NULL; 6235fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 6245fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6255fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (!IsBSP ()) { 6265fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan return EFI_DEVICE_ERROR; 6275fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 6285fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6295fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (mMpSystemData.NumberOfProcessors == 1) { 6305fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan return EFI_NOT_STARTED; 6315fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 6325fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6335fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (Procedure == NULL) { 6345fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan return EFI_INVALID_PARAMETER; 6355fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 6365fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 637cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // 638cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // temporarily stop checkAllAPsStatus for avoid resource dead-lock. 639cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // 640cd8c700b03e38e9389a8f13e193a431072802593Chen Fan mStopCheckAllAPsStatus = TRUE; 641cd8c700b03e38e9389a8f13e193a431072802593Chen Fan 6425fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) { 6435fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CpuData = &mMpSystemData.CpuDatas[Number]; 6445fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) { 6455fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 6465fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // Skip BSP 6475fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 6485fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan continue; 6495fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 6505fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6515fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) { 6525fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 6535fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // Skip Disabled processors 6545fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 6555fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan continue; 6565fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 6575fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6585fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (GetApState (CpuData) != CpuStateIdle) { 6595fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan return EFI_NOT_READY; 6605fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 6615fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 6625fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6635fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.Procedure = Procedure; 6645fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.ProcedureArgument = ProcedureArgument; 6655fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.WaitEvent = WaitEvent; 6665fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.Timeout = TimeoutInMicroseconds; 6675fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.TimeoutActive = !!(TimeoutInMicroseconds); 6685fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.FinishCount = 0; 6695fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.StartCount = 0; 6705fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.SingleThread = SingleThread; 6715fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.FailedList = FailedCpuList; 6725fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.FailedListIndex = 0; 6735fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan APInitialState = CpuStateReady; 6745fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6755fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) { 6765fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CpuData = &mMpSystemData.CpuDatas[Number]; 6775fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) { 6785fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 6795fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // Skip BSP 6805fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 6815fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan continue; 6825fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 6835fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6845fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (!TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) { 6855fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 6865fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // Skip Disabled processors 6875fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 6885fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan continue; 6895fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 6905fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 6915fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 6925fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // Get APs prepared, and put failing APs into FailedCpuList 6935fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // if "SingleThread", only 1 AP will put to ready state, other AP will be put to ready 6945fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // state 1 by 1, until the previous 1 finished its task 6955fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // if not "SingleThread", all APs are put to ready state from the beginning 6965fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 6975fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (GetApState (CpuData) == CpuStateIdle) { 6985fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.StartCount++; 6995fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 7005fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan SetApState (CpuData, APInitialState); 7015fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 7025fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (APInitialState == CpuStateReady) { 7035fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan SetApProcedure (CpuData, Procedure, ProcedureArgument); 7045fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 7055fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 7065fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (SingleThread) { 7075fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan APInitialState = CpuStateBlocked; 7085fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 7095fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 7105fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 7115fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 712acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan mStopCheckAllAPsStatus = FALSE; 713acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan 7145fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (WaitEvent != NULL) { 715acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // 716acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // non blocking 717acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // 718acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan return EFI_SUCCESS; 7195fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 7205fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 721cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // 722cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // Blocking temporarily stop CheckAllAPsStatus() 723cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // 724cd8c700b03e38e9389a8f13e193a431072802593Chen Fan mStopCheckAllAPsStatus = TRUE; 725cd8c700b03e38e9389a8f13e193a431072802593Chen Fan 7265fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan while (TRUE) { 7275fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CheckAndUpdateAllAPsToIdleState (); 7285fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (mMpSystemData.FinishCount == mMpSystemData.StartCount) { 7295fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan Status = EFI_SUCCESS; 7305fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan goto Done; 7315fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 7325fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 7335fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 7345fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // task timeout 7355fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 7365fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) { 7375fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan ResetAllFailedAPs(); 7385fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan Status = EFI_TIMEOUT; 7395fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan goto Done; 7405fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 7415fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 7425fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan gBS->Stall (gPollInterval); 7435fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.Timeout -= gPollInterval; 7445fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 7455fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 7465fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen FanDone: 7475fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 7485fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan return Status; 7495fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan} 7505fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 7515fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan/** 7523f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan This service lets the caller get one enabled AP to execute a caller-provided 7533f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan function. The caller can request the BSP to either wait for the completion 7543f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan of the AP or just proceed with the next task by using the EFI event mechanism. 7553f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan See EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() for more details on non-blocking 7563f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan execution support. This service may only be called from the BSP. 7573f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 7583f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan This function is used to dispatch one enabled AP to the function specified by 7593f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan Procedure passing in the argument specified by ProcedureArgument. If WaitEvent 7603f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan is NULL, execution is in blocking mode. The BSP waits until the AP finishes or 7613f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan TimeoutInMicroSecondss expires. Otherwise, execution is in non-blocking mode. 7623f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan BSP proceeds to the next task without waiting for the AP. If a non-blocking mode 7633f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan is requested after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled, 7643f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan then EFI_UNSUPPORTED must be returned. 7653f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 7663f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan If the timeout specified by TimeoutInMicroseconds expires before the AP returns 7673f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan from Procedure, then execution of Procedure by the AP is terminated. The AP is 7683f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan available for subsequent calls to EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() and 7693f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). 7703f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 7713f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL 7723f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan instance. 7733f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param[in] Procedure A pointer to the function to be run on 7743f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan enabled APs of the system. See type 7753f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan EFI_AP_PROCEDURE. 7763f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param[in] ProcessorNumber The handle number of the AP. The range is 7773f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan from 0 to the total number of logical 7783f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan processors minus 1. The total number of 7793f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan logical processors can be retrieved by 7803f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). 7813f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param[in] WaitEvent The event created by the caller with CreateEvent() 7823f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan service. If it is NULL, then execute in 7833f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan blocking mode. BSP waits until all APs finish 7843f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan or TimeoutInMicroseconds expires. If it's 7853f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan not NULL, then execute in non-blocking mode. 7863f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan BSP requests the function specified by 7873f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan Procedure to be started on all the enabled 7883f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan APs, and go on executing immediately. If 7893f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan all return from Procedure or TimeoutInMicroseconds 7903f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan expires, this event is signaled. The BSP 7913f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan can use the CheckEvent() or WaitForEvent() 7923f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan services to check the state of event. Type 7933f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan EFI_EVENT is defined in CreateEvent() in 7943f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan the Unified Extensible Firmware Interface 7953f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan Specification. 7963f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param[in] TimeoutInMicroseconds Indicates the time limit in microseconds for 7973f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan APs to return from Procedure, either for 7983f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan blocking or non-blocking mode. Zero means 7993f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan infinity. If the timeout expires before 8003f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan all APs return from Procedure, then Procedure 8013f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan on the failed APs is terminated. All enabled 8023f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan APs are available for next function assigned 8033f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan by EFI_MP_SERVICES_PROTOCOL.StartupAllAPs() 8043f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan or EFI_MP_SERVICES_PROTOCOL.StartupThisAP(). 8053f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan If the timeout expires in blocking mode, 8063f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan BSP returns EFI_TIMEOUT. If the timeout 8073f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan expires in non-blocking mode, WaitEvent 8083f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan is signaled with SignalEvent(). 8093f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param[in] ProcedureArgument The parameter passed into Procedure for 8103f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan all APs. 8113f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param[out] Finished If NULL, this parameter is ignored. In 8123f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan blocking mode, this parameter is ignored. 8133f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan In non-blocking mode, if AP returns from 8143f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan Procedure before the timeout expires, its 8153f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan content is set to TRUE. Otherwise, the 8163f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan value is set to FALSE. The caller can 8173f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan determine if the AP returned from Procedure 8183f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan by evaluating this value. 8193f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 8203f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @retval EFI_SUCCESS In blocking mode, specified AP finished before 8213f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan the timeout expires. 8223f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @retval EFI_SUCCESS In non-blocking mode, the function has been 8233f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan dispatched to specified AP. 8243f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @retval EFI_UNSUPPORTED A non-blocking mode request was made after the 8253f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan UEFI event EFI_EVENT_GROUP_READY_TO_BOOT was 8263f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan signaled. 8273f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @retval EFI_DEVICE_ERROR The calling processor is an AP. 8283f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @retval EFI_TIMEOUT In blocking mode, the timeout expired before 8293f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan the specified AP has finished. 8303f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @retval EFI_NOT_READY The specified AP is busy. 8313f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @retval EFI_NOT_FOUND The processor with the handle specified by 8323f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan ProcessorNumber does not exist. 8333f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP or disabled AP. 8343f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @retval EFI_INVALID_PARAMETER Procedure is NULL. 8353f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 8363f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan**/ 8373f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanEFI_STATUS 8383f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanEFIAPI 8393f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanStartupThisAP ( 8403f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN EFI_MP_SERVICES_PROTOCOL *This, 8413f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN EFI_AP_PROCEDURE Procedure, 8423f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN UINTN ProcessorNumber, 8433f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN EFI_EVENT WaitEvent OPTIONAL, 8443f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN UINTN TimeoutInMicroseconds, 8453f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN VOID *ProcedureArgument OPTIONAL, 8463f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan OUT BOOLEAN *Finished OPTIONAL 8473f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan ) 8483f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan{ 8493f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CPU_DATA_BLOCK *CpuData; 8503f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 8513f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData = NULL; 8523f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 8533f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (Finished != NULL) { 8543f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan *Finished = FALSE; 8553f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 8563f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 8573f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (!IsBSP ()) { 8583f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan return EFI_DEVICE_ERROR; 8593f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 8603f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 8613f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (Procedure == NULL) { 8623f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan return EFI_INVALID_PARAMETER; 8633f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 8643f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 8653f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) { 8663f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan return EFI_NOT_FOUND; 8673f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 8683f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 869cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // 870cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // temporarily stop checkAllAPsStatus for avoid resource dead-lock. 871cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // 872cd8c700b03e38e9389a8f13e193a431072802593Chen Fan mStopCheckAllAPsStatus = TRUE; 873cd8c700b03e38e9389a8f13e193a431072802593Chen Fan 8743f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData = &mMpSystemData.CpuDatas[ProcessorNumber]; 8753f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT) || 8763f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan !TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) { 8773f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan return EFI_INVALID_PARAMETER; 8783f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 8793f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 8803f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (GetApState (CpuData) != CpuStateIdle) { 8813f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan return EFI_NOT_READY; 8823f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 8833f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 8843f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan SetApState (CpuData, CpuStateReady); 8853f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 8863f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan SetApProcedure (CpuData, Procedure, ProcedureArgument); 8873f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 8883f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData->Timeout = TimeoutInMicroseconds; 8893f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData->WaitEvent = WaitEvent; 8903f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData->TimeoutActive = !!(TimeoutInMicroseconds); 8913f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData->Finished = Finished; 8923f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 893acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan mStopCheckAllAPsStatus = FALSE; 894acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan 8953f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (WaitEvent != NULL) { 8963f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan // 8973f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan // Non Blocking 8983f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan // 899acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan return EFI_SUCCESS; 9003f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 9013f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 9023f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan // 9033f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan // Blocking 9043f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan // 9053f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan while (TRUE) { 9063f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (GetApState (CpuData) == CpuStateFinished) { 9073f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan SetApState (CpuData, CpuStateIdle); 9083f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan break; 9093f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 9103f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 9113f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (CpuData->TimeoutActive && CpuData->Timeout < 0) { 9123f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan ResetProcessorToIdleState (CpuData); 9133f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan return EFI_TIMEOUT; 9143f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 9153f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 9163f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan gBS->Stall (gPollInterval); 9173f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData->Timeout -= gPollInterval; 9183f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 9193f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 9203f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan return EFI_SUCCESS; 9213f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan} 9223f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 9233f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan/** 924b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan This service switches the requested AP to be the BSP from that point onward. 925b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan This service changes the BSP for all purposes. This call can only be performed 926b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan by the current BSP. 927b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan 928b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan This service switches the requested AP to be the BSP from that point onward. 929b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan This service changes the BSP for all purposes. The new BSP can take over the 930b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan execution of the old BSP and continue seamlessly from where the old one left 931b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan off. This service may not be supported after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT 932b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan is signaled. 933b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan 934b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan If the BSP cannot be switched prior to the return from this service, then 935b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan EFI_UNSUPPORTED must be returned. 936b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan 937b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. 938b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan @param[in] ProcessorNumber The handle number of AP that is to become the new 939b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan BSP. The range is from 0 to the total number of 940b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan logical processors minus 1. The total number of 941b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan logical processors can be retrieved by 942b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). 943b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan @param[in] EnableOldBSP If TRUE, then the old BSP will be listed as an 944b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan enabled AP. Otherwise, it will be disabled. 945b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan 946b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan @retval EFI_SUCCESS BSP successfully switched. 947b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan @retval EFI_UNSUPPORTED Switching the BSP cannot be completed prior to 948b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan this service returning. 949b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan @retval EFI_UNSUPPORTED Switching the BSP is not supported. 950b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan @retval EFI_SUCCESS The calling processor is an AP. 951b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan @retval EFI_NOT_FOUND The processor with the handle specified by 952b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan ProcessorNumber does not exist. 953b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the current BSP or 954b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan a disabled AP. 955b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan @retval EFI_NOT_READY The specified AP is busy. 956b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan 957b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan**/ 958b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen FanEFI_STATUS 959b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen FanEFIAPI 960b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen FanSwitchBSP ( 961b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan IN EFI_MP_SERVICES_PROTOCOL *This, 962b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan IN UINTN ProcessorNumber, 963b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan IN BOOLEAN EnableOldBSP 964b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan ) 965b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan{ 966b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan // 967b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan // Current always return unsupported. 968b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan // 969b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan return EFI_UNSUPPORTED; 970b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan} 971b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan 972b7c05ba5173f4ae8ccfc901755aa79dcc97ebde2Chen Fan/** 973fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan This service lets the caller enable or disable an AP from this point onward. 974fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan This service may only be called from the BSP. 975fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 976fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan This service allows the caller enable or disable an AP from this point onward. 977fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan The caller can optionally specify the health status of the AP by Health. If 978fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan an AP is being disabled, then the state of the disabled AP is implementation 979fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan dependent. If an AP is enabled, then the implementation must guarantee that a 980fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan complete initialization sequence is performed on the AP, so the AP is in a state 981fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan that is compatible with an MP operating system. This service may not be supported 982fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan after the UEFI Event EFI_EVENT_GROUP_READY_TO_BOOT is signaled. 983fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 984fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan If the enable or disable AP operation cannot be completed prior to the return 985fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan from this service, then EFI_UNSUPPORTED must be returned. 986fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 987fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. 988fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @param[in] ProcessorNumber The handle number of AP that is to become the new 989fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan BSP. The range is from 0 to the total number of 990fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan logical processors minus 1. The total number of 991fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan logical processors can be retrieved by 992fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). 993fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @param[in] EnableAP Specifies the new state for the processor for 994fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan enabled, FALSE for disabled. 995fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @param[in] HealthFlag If not NULL, a pointer to a value that specifies 996fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan the new health status of the AP. This flag 997fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan corresponds to StatusFlag defined in 998fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan EFI_MP_SERVICES_PROTOCOL.GetProcessorInfo(). Only 999fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan the PROCESSOR_HEALTH_STATUS_BIT is used. All other 1000fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan bits are ignored. If it is NULL, this parameter 1001fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan is ignored. 1002fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 1003fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @retval EFI_SUCCESS The specified AP was enabled or disabled successfully. 1004fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @retval EFI_UNSUPPORTED Enabling or disabling an AP cannot be completed 1005fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan prior to this service returning. 1006fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @retval EFI_UNSUPPORTED Enabling or disabling an AP is not supported. 1007fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @retval EFI_DEVICE_ERROR The calling processor is an AP. 1008fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @retval EFI_NOT_FOUND Processor with the handle specified by ProcessorNumber 1009fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan does not exist. 1010fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan @retval EFI_INVALID_PARAMETER ProcessorNumber specifies the BSP. 1011fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 1012fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan**/ 1013fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen FanEFI_STATUS 1014fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen FanEFIAPI 1015fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen FanEnableDisableAP ( 1016fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan IN EFI_MP_SERVICES_PROTOCOL *This, 1017fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan IN UINTN ProcessorNumber, 1018fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan IN BOOLEAN EnableAP, 1019fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan IN UINT32 *HealthFlag OPTIONAL 1020fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan ) 1021fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan{ 1022fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan CPU_DATA_BLOCK *CpuData; 1023cd8c700b03e38e9389a8f13e193a431072802593Chen Fan BOOLEAN TempStopCheckState; 1024cd8c700b03e38e9389a8f13e193a431072802593Chen Fan 1025cd8c700b03e38e9389a8f13e193a431072802593Chen Fan CpuData = NULL; 1026cd8c700b03e38e9389a8f13e193a431072802593Chen Fan TempStopCheckState = FALSE; 1027fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 1028fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan if (!IsBSP ()) { 1029fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan return EFI_DEVICE_ERROR; 1030fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan } 1031fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 1032fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan if (ProcessorNumber >= mMpSystemData.NumberOfProcessors) { 1033fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan return EFI_NOT_FOUND; 1034fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan } 1035fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 1036cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // 1037cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // temporarily stop checkAllAPsStatus for initialize parameters. 1038cd8c700b03e38e9389a8f13e193a431072802593Chen Fan // 1039cd8c700b03e38e9389a8f13e193a431072802593Chen Fan if (!mStopCheckAllAPsStatus) { 1040cd8c700b03e38e9389a8f13e193a431072802593Chen Fan mStopCheckAllAPsStatus = TRUE; 1041cd8c700b03e38e9389a8f13e193a431072802593Chen Fan TempStopCheckState = TRUE; 1042cd8c700b03e38e9389a8f13e193a431072802593Chen Fan } 1043cd8c700b03e38e9389a8f13e193a431072802593Chen Fan 1044fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan CpuData = &mMpSystemData.CpuDatas[ProcessorNumber]; 1045fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan if (TestCpuStatusFlag (CpuData, PROCESSOR_AS_BSP_BIT)) { 1046fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan return EFI_INVALID_PARAMETER; 1047fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan } 1048fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 1049fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan if (GetApState (CpuData) != CpuStateIdle) { 1050fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan return EFI_UNSUPPORTED; 1051fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan } 1052fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 1053fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan if (EnableAP) { 1054fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan if (!(TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT))) { 1055fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan mMpSystemData.NumberOfEnabledProcessors++; 1056fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan } 1057fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan CpuStatusFlagOr (CpuData, PROCESSOR_ENABLED_BIT); 1058fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan } else { 1059fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan if (TestCpuStatusFlag (CpuData, PROCESSOR_ENABLED_BIT)) { 1060fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan mMpSystemData.NumberOfEnabledProcessors--; 1061fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan } 1062fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan CpuStatusFlagAndNot (CpuData, PROCESSOR_ENABLED_BIT); 1063fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan } 1064fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 1065fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan if (HealthFlag != NULL) { 1066fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan CpuStatusFlagAndNot (CpuData, (UINT32)~PROCESSOR_HEALTH_STATUS_BIT); 1067fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan CpuStatusFlagOr (CpuData, (*HealthFlag & PROCESSOR_HEALTH_STATUS_BIT)); 1068fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan } 1069fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 1070cd8c700b03e38e9389a8f13e193a431072802593Chen Fan if (TempStopCheckState) { 1071cd8c700b03e38e9389a8f13e193a431072802593Chen Fan mStopCheckAllAPsStatus = FALSE; 1072cd8c700b03e38e9389a8f13e193a431072802593Chen Fan } 1073cd8c700b03e38e9389a8f13e193a431072802593Chen Fan 1074fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan return EFI_SUCCESS; 1075fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan} 1076fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan 1077fa7ce675b991bca6e18fcda8446737717ae3c1f6Chen Fan/** 1078cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan This return the handle number for the calling processor. This service may be 1079cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan called from the BSP and APs. 1080cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan 1081cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan This service returns the processor handle number for the calling processor. 1082cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan The returned value is in the range from 0 to the total number of logical 1083cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan processors minus 1. The total number of logical processors can be retrieved 1084cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan with EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). This service may be 1085cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan called from the BSP and APs. If ProcessorNumber is NULL, then EFI_INVALID_PARAMETER 1086cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan is returned. Otherwise, the current processors handle number is returned in 1087cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan ProcessorNumber, and EFI_SUCCESS is returned. 1088cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan 1089cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan @param[in] This A pointer to the EFI_MP_SERVICES_PROTOCOL instance. 1090cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan @param[out] ProcessorNumber The handle number of AP that is to become the new 1091cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan BSP. The range is from 0 to the total number of 1092cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan logical processors minus 1. The total number of 1093cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan logical processors can be retrieved by 1094cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan EFI_MP_SERVICES_PROTOCOL.GetNumberOfProcessors(). 1095cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan 1096cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan @retval EFI_SUCCESS The current processor handle number was returned 1097cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan in ProcessorNumber. 1098cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan @retval EFI_INVALID_PARAMETER ProcessorNumber is NULL. 1099cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan 1100cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan**/ 1101cfa2fac1f667b227a29a2219321b651c7a143071Chen FanEFI_STATUS 1102cfa2fac1f667b227a29a2219321b651c7a143071Chen FanEFIAPI 1103cfa2fac1f667b227a29a2219321b651c7a143071Chen FanWhoAmI ( 1104cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan IN EFI_MP_SERVICES_PROTOCOL *This, 1105cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan OUT UINTN *ProcessorNumber 1106cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan ) 1107cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan{ 1108cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan UINTN Index; 1109cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan UINT32 ProcessorId; 1110cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan 1111cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan if (ProcessorNumber == NULL) { 1112cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan return EFI_INVALID_PARAMETER; 1113cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan } 1114cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan 1115cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan ProcessorId = GetApicId (); 1116cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan for (Index = 0; Index < mMpSystemData.NumberOfProcessors; Index++) { 1117cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan if (mMpSystemData.CpuDatas[Index].Info.ProcessorId == ProcessorId) { 1118cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan break; 1119cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan } 1120cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan } 1121cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan 1122cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan *ProcessorNumber = Index; 1123cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan return EFI_SUCCESS; 1124cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan} 1125cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan 1126cfa2fac1f667b227a29a2219321b651c7a143071Chen Fan/** 11273f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan Terminate AP's task and set it to idle state. 11283f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 11293f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan This function terminates AP's task due to timeout by sending INIT-SIPI, 11303f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan and sends it to idle state. 11313f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 11323f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param CpuData the pointer to CPU_DATA_BLOCK of specified AP 11333f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 11343f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan**/ 11353f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanVOID 11363f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanResetProcessorToIdleState ( 11373f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN CPU_DATA_BLOCK *CpuData 11383f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan ) 11393f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan{ 1140ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan ResetApStackless ((UINT32)CpuData->Info.ProcessorId); 11413f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan} 11423f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 11433f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan/** 1144e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan Application Processors do loop routine 1145e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan after switch to its own stack. 1146e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan 1147e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan @param Context1 A pointer to the context to pass into the function. 1148e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan @param Context2 A pointer to the context to pass into the function. 1149e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan 1150e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan**/ 1151e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen FanVOID 1152e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen FanProcessorToIdleState ( 1153e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan IN VOID *Context1, OPTIONAL 1154e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan IN VOID *Context2 OPTIONAL 1155e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan ) 1156e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan{ 11579908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan UINTN ProcessorNumber; 11589908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan CPU_DATA_BLOCK *CpuData; 11599908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan EFI_AP_PROCEDURE Procedure; 11609908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan VOID *ProcedureArgument; 11619908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan 1162232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fan AsmApDoneWithCommonStack (); 1163232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fan 1164232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fan while (!mAPsAlreadyInitFinished) { 1165232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fan CpuPause (); 1166232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fan } 1167232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fan 11689908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan WhoAmI (&mMpServicesTemplate, &ProcessorNumber); 11699908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan CpuData = &mMpSystemData.CpuDatas[ProcessorNumber]; 1170e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan 1171ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan // 11720e724fc1981b3c47bb16432c4c414a50c9e3a519Chen Fan // Avoid forcibly reset AP caused the AP got lock not release. 11730e724fc1981b3c47bb16432c4c414a50c9e3a519Chen Fan // 11740e724fc1981b3c47bb16432c4c414a50c9e3a519Chen Fan if (CpuData->LockSelf == (INTN) GetApicId ()) { 11750e724fc1981b3c47bb16432c4c414a50c9e3a519Chen Fan ReleaseSpinLock (&CpuData->CpuDataLock); 11760e724fc1981b3c47bb16432c4c414a50c9e3a519Chen Fan } 11770e724fc1981b3c47bb16432c4c414a50c9e3a519Chen Fan 11780e724fc1981b3c47bb16432c4c414a50c9e3a519Chen Fan // 1179ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan // Avoid forcibly reset AP caused the AP State is not updated. 1180ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan // 1181ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan GetMpSpinLock (CpuData); 1182ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan CpuData->State = CpuStateIdle; 1183ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan CpuData->Procedure = NULL; 1184ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan ReleaseMpSpinLock (CpuData); 1185ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan 11869908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan while (TRUE) { 1187d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan GetMpSpinLock (CpuData); 11889908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan ProcedureArgument = CpuData->Parameter; 11899908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan Procedure = CpuData->Procedure; 1190d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan ReleaseMpSpinLock (CpuData); 11919908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan 11929908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan if (Procedure != NULL) { 11939908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan Procedure (ProcedureArgument); 11949908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan 1195d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan GetMpSpinLock (CpuData); 11969908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan CpuData->Procedure = NULL; 1197d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan CpuData->State = CpuStateFinished; 1198d16cf36d2a226cf6a527099407b6b0b70a0f9faaChen Fan ReleaseMpSpinLock (CpuData); 11999908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan } 12009908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan 12019908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan CpuPause (); 12029908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan } 12039908a829d0c1c92ca9bf462c0d9210f63784c131Chen Fan 1204e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan CpuSleep (); 1205e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan CpuDeadLoop (); 1206e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan} 1207e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan 1208e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan/** 12093f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan Checks AP' status periodically. 12103f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 12113f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan This function is triggerred by timer perodically to check the 12123f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan state of AP forStartupThisAP() executed in non-blocking mode. 12133f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 12143f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param Event Event triggered. 12153f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan @param Context Parameter passed with the event. 12163f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 12173f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan**/ 12183f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanVOID 12193f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanEFIAPI 12203f4f0af8724c56ed6fac052b5086e33511aa9a80Chen FanCheckThisAPStatus ( 12213f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN EFI_EVENT Event, 12223f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan IN VOID *Context 12233f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan ) 12243f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan{ 12253f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CPU_DATA_BLOCK *CpuData; 12263f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CPU_STATE CpuState; 12273f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 12283f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData = (CPU_DATA_BLOCK *) Context; 12293f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (CpuData->TimeoutActive) { 12303f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData->Timeout -= gPollInterval; 12313f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 12323f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 12333f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuState = GetApState (CpuData); 12343f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 12353f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (CpuState == CpuStateFinished) { 12363f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (CpuData->Finished) { 12373f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan *CpuData->Finished = TRUE; 12383f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 12393f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan SetApState (CpuData, CpuStateIdle); 12403f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan goto out; 12413f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 12423f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 12433f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (CpuData->TimeoutActive && CpuData->Timeout < 0) { 12443f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan if (CpuState != CpuStateIdle && 12453f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan CpuData->Finished) { 12463f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan *CpuData->Finished = FALSE; 12473f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 12483f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan ResetProcessorToIdleState (CpuData); 12493f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan goto out; 12503f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan } 12513f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 12523f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan return; 12533f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 12543f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fanout: 1255acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan CpuData->TimeoutActive = FALSE; 1256acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan gBS->SignalEvent (CpuData->WaitEvent); 1257acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan CpuData->WaitEvent = NULL; 12583f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan} 12593f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 12603f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan/** 12615fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan Checks APs' status periodically. 12625fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 12635fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan This function is triggerred by timer perodically to check the 12645fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan state of APs for StartupAllAPs() executed in non-blocking mode. 12655fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 12665fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @param Event Event triggered. 12675fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan @param Context Parameter passed with the event. 12685fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 12695fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan**/ 12705fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen FanVOID 12715fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen FanEFIAPI 12725fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen FanCheckAllAPsStatus ( 12735fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan IN EFI_EVENT Event, 12745fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan IN VOID *Context 12755fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan ) 12765fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan{ 1277acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan CPU_DATA_BLOCK *CpuData; 1278acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan UINTN Number; 1279e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan EFI_STATUS Status; 1280acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan 12815fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan if (mMpSystemData.TimeoutActive) { 12825fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.Timeout -= gPollInterval; 12835fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 12845fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 1285acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan if (mStopCheckAllAPsStatus) { 1286acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan return; 1287acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan } 12885fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 1289e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan // 1290e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan // avoid next timer enter. 1291e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan // 1292e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan Status = gBS->SetTimer ( 1293e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan mMpSystemData.CheckAllAPsEvent, 1294e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan TimerCancel, 1295e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan 0 1296e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan ); 1297e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan ASSERT_EFI_ERROR (Status); 1298e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan 1299acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan if (mMpSystemData.WaitEvent != NULL) { 1300acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan CheckAndUpdateAllAPsToIdleState (); 13015fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 1302acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // task timeout 13035fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan // 1304acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan if (mMpSystemData.TimeoutActive && mMpSystemData.Timeout < 0) { 1305acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan ResetAllFailedAPs(); 1306acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // 1307acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // force exit 1308acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // 1309acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan mMpSystemData.FinishCount = mMpSystemData.StartCount; 1310acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan } 13115fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 1312acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan if (mMpSystemData.FinishCount != mMpSystemData.StartCount) { 1313e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan goto EXIT; 1314acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan } 13155fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 1316acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan mMpSystemData.TimeoutActive = FALSE; 13175fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan gBS->SignalEvent (mMpSystemData.WaitEvent); 13185fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan mMpSystemData.WaitEvent = NULL; 1319acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan mStopCheckAllAPsStatus = TRUE; 1320e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan 1321e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan goto EXIT; 1322acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan } 1323acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan 1324acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // 1325acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // check each AP status for StartupThisAP 1326acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // 1327acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan for (Number = 0; Number < mMpSystemData.NumberOfProcessors; Number++) { 1328acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan CpuData = &mMpSystemData.CpuDatas[Number]; 1329acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan if (CpuData->WaitEvent) { 1330acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan CheckThisAPStatus (NULL, (VOID *)CpuData); 1331acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan } 13325fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan } 1333e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan 1334e4aaf764281d12cb8bfe605393a5520e00715838Chen FanEXIT: 1335e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan Status = gBS->SetTimer ( 1336e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan mMpSystemData.CheckAllAPsEvent, 1337e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan TimerPeriodic, 1338e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan EFI_TIMER_PERIOD_MICROSECONDS (100) 1339e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan ); 1340e4aaf764281d12cb8bfe605393a5520e00715838Chen Fan ASSERT_EFI_ERROR (Status); 13415fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan} 13425fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 13435fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan/** 13441535c888c6f06bb35881e83cd7ee49fb8554942bJordan Justen Application Processor C code entry point. 13451535c888c6f06bb35881e83cd7ee49fb8554942bJordan Justen 13461535c888c6f06bb35881e83cd7ee49fb8554942bJordan Justen**/ 13471535c888c6f06bb35881e83cd7ee49fb8554942bJordan JustenVOID 13481535c888c6f06bb35881e83cd7ee49fb8554942bJordan JustenEFIAPI 13491535c888c6f06bb35881e83cd7ee49fb8554942bJordan JustenApEntryPointInC ( 13501535c888c6f06bb35881e83cd7ee49fb8554942bJordan Justen VOID 13511535c888c6f06bb35881e83cd7ee49fb8554942bJordan Justen ) 13521535c888c6f06bb35881e83cd7ee49fb8554942bJordan Justen{ 1353ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan VOID* TopOfApStack; 1354ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan UINTN ProcessorNumber; 135503673ae11e255b9467e8f317175495b1ff79f965Chen Fan 1356ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan if (!mAPsAlreadyInitFinished) { 1357ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan FillInProcessorInformation (FALSE, mMpSystemData.NumberOfProcessors); 1358ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan TopOfApStack = (UINT8*)mApStackStart + gApStackSize; 1359ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan mApStackStart = TopOfApStack; 136003673ae11e255b9467e8f317175495b1ff79f965Chen Fan 1361ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan // 1362ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan // Store the Stack address, when reset the AP, We can found the original address. 1363ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan // 1364ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan mMpSystemData.CpuDatas[mMpSystemData.NumberOfProcessors].TopOfStack = TopOfApStack; 1365ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan mMpSystemData.NumberOfProcessors++; 1366ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan mMpSystemData.NumberOfEnabledProcessors++; 1367ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan } else { 1368ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan WhoAmI (&mMpServicesTemplate, &ProcessorNumber); 1369ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan // 1370ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan // Get the original stack address. 1371ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan // 1372ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan TopOfApStack = mMpSystemData.CpuDatas[ProcessorNumber].TopOfStack; 1373ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan } 1374e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan 1375e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan SwitchStack ( 1376e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan (SWITCH_STACK_ENTRY_POINT)(UINTN)ProcessorToIdleState, 1377e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan NULL, 1378e343f8f7b35a400bb1d6e0edd7dddc53dd9e436dChen Fan NULL, 137903673ae11e255b9467e8f317175495b1ff79f965Chen Fan TopOfApStack); 138003673ae11e255b9467e8f317175495b1ff79f965Chen Fan} 138103673ae11e255b9467e8f317175495b1ff79f965Chen Fan 138203673ae11e255b9467e8f317175495b1ff79f965Chen Fan/** 138303673ae11e255b9467e8f317175495b1ff79f965Chen Fan This function is called by all processors (both BSP and AP) once and collects MP related data. 138403673ae11e255b9467e8f317175495b1ff79f965Chen Fan 138503673ae11e255b9467e8f317175495b1ff79f965Chen Fan @param Bsp TRUE if the CPU is BSP 138603673ae11e255b9467e8f317175495b1ff79f965Chen Fan @param ProcessorNumber The specific processor number 138703673ae11e255b9467e8f317175495b1ff79f965Chen Fan 138803673ae11e255b9467e8f317175495b1ff79f965Chen Fan @retval EFI_SUCCESS Data for the processor collected and filled in 138903673ae11e255b9467e8f317175495b1ff79f965Chen Fan 139003673ae11e255b9467e8f317175495b1ff79f965Chen Fan**/ 139103673ae11e255b9467e8f317175495b1ff79f965Chen FanEFI_STATUS 139203673ae11e255b9467e8f317175495b1ff79f965Chen FanFillInProcessorInformation ( 139303673ae11e255b9467e8f317175495b1ff79f965Chen Fan IN BOOLEAN Bsp, 139403673ae11e255b9467e8f317175495b1ff79f965Chen Fan IN UINTN ProcessorNumber 139503673ae11e255b9467e8f317175495b1ff79f965Chen Fan ) 139603673ae11e255b9467e8f317175495b1ff79f965Chen Fan{ 139703673ae11e255b9467e8f317175495b1ff79f965Chen Fan CPU_DATA_BLOCK *CpuData; 139803673ae11e255b9467e8f317175495b1ff79f965Chen Fan UINT32 ProcessorId; 139903673ae11e255b9467e8f317175495b1ff79f965Chen Fan 140003673ae11e255b9467e8f317175495b1ff79f965Chen Fan CpuData = &mMpSystemData.CpuDatas[ProcessorNumber]; 140103673ae11e255b9467e8f317175495b1ff79f965Chen Fan ProcessorId = GetApicId (); 140203673ae11e255b9467e8f317175495b1ff79f965Chen Fan CpuData->Info.ProcessorId = ProcessorId; 140303673ae11e255b9467e8f317175495b1ff79f965Chen Fan CpuData->Info.StatusFlag = PROCESSOR_ENABLED_BIT | PROCESSOR_HEALTH_STATUS_BIT; 140403673ae11e255b9467e8f317175495b1ff79f965Chen Fan if (Bsp) { 140503673ae11e255b9467e8f317175495b1ff79f965Chen Fan CpuData->Info.StatusFlag |= PROCESSOR_AS_BSP_BIT; 140603673ae11e255b9467e8f317175495b1ff79f965Chen Fan } 140703673ae11e255b9467e8f317175495b1ff79f965Chen Fan CpuData->Info.Location.Package = ProcessorId; 140803673ae11e255b9467e8f317175495b1ff79f965Chen Fan CpuData->Info.Location.Core = 0; 140903673ae11e255b9467e8f317175495b1ff79f965Chen Fan CpuData->Info.Location.Thread = 0; 141003673ae11e255b9467e8f317175495b1ff79f965Chen Fan CpuData->State = Bsp ? CpuStateBuzy : CpuStateIdle; 141103673ae11e255b9467e8f317175495b1ff79f965Chen Fan 141203673ae11e255b9467e8f317175495b1ff79f965Chen Fan CpuData->Procedure = NULL; 141303673ae11e255b9467e8f317175495b1ff79f965Chen Fan CpuData->Parameter = NULL; 141403673ae11e255b9467e8f317175495b1ff79f965Chen Fan InitializeSpinLock (&CpuData->CpuDataLock); 14150e724fc1981b3c47bb16432c4c414a50c9e3a519Chen Fan CpuData->LockSelf = -1; 141603673ae11e255b9467e8f317175495b1ff79f965Chen Fan 141703673ae11e255b9467e8f317175495b1ff79f965Chen Fan return EFI_SUCCESS; 14181535c888c6f06bb35881e83cd7ee49fb8554942bJordan Justen} 14191535c888c6f06bb35881e83cd7ee49fb8554942bJordan Justen 142003673ae11e255b9467e8f317175495b1ff79f965Chen Fan/** 142103673ae11e255b9467e8f317175495b1ff79f965Chen Fan Prepare the System Data. 142203673ae11e255b9467e8f317175495b1ff79f965Chen Fan 142303673ae11e255b9467e8f317175495b1ff79f965Chen Fan @retval EFI_SUCCESS the System Data finished initilization. 142403673ae11e255b9467e8f317175495b1ff79f965Chen Fan 142503673ae11e255b9467e8f317175495b1ff79f965Chen Fan**/ 142603673ae11e255b9467e8f317175495b1ff79f965Chen FanEFI_STATUS 142703673ae11e255b9467e8f317175495b1ff79f965Chen FanInitMpSystemData ( 142803673ae11e255b9467e8f317175495b1ff79f965Chen Fan VOID 142903673ae11e255b9467e8f317175495b1ff79f965Chen Fan ) 143003673ae11e255b9467e8f317175495b1ff79f965Chen Fan{ 14313f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan EFI_STATUS Status; 14323f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 143303673ae11e255b9467e8f317175495b1ff79f965Chen Fan ZeroMem (&mMpSystemData, sizeof (MP_SYSTEM_DATA)); 143403673ae11e255b9467e8f317175495b1ff79f965Chen Fan 143503673ae11e255b9467e8f317175495b1ff79f965Chen Fan mMpSystemData.NumberOfProcessors = 1; 143603673ae11e255b9467e8f317175495b1ff79f965Chen Fan mMpSystemData.NumberOfEnabledProcessors = 1; 143703673ae11e255b9467e8f317175495b1ff79f965Chen Fan 143803673ae11e255b9467e8f317175495b1ff79f965Chen Fan mMpSystemData.CpuDatas = AllocateZeroPool (sizeof (CPU_DATA_BLOCK) * gMaxLogicalProcessorNumber); 143903673ae11e255b9467e8f317175495b1ff79f965Chen Fan ASSERT(mMpSystemData.CpuDatas != NULL); 144003673ae11e255b9467e8f317175495b1ff79f965Chen Fan 14415fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan Status = gBS->CreateEvent ( 14425fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan EVT_TIMER | EVT_NOTIFY_SIGNAL, 14435fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan TPL_CALLBACK, 14445fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan CheckAllAPsStatus, 14455fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan NULL, 14465fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan &mMpSystemData.CheckAllAPsEvent 14475fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan ); 14485fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan ASSERT_EFI_ERROR (Status); 14495fee172fb75ba07df4638abfd0cfc0ce83fc1073Chen Fan 1450acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // 1451acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // Set timer to check all APs status. 1452acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan // 1453acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan Status = gBS->SetTimer ( 1454acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan mMpSystemData.CheckAllAPsEvent, 1455acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan TimerPeriodic, 1456acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan EFI_TIMER_PERIOD_MICROSECONDS (100) 1457acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan ); 1458acb2172d15ed793c8ae0484700d42dcc105f2ea1Chen Fan ASSERT_EFI_ERROR (Status); 14593f4f0af8724c56ed6fac052b5086e33511aa9a80Chen Fan 146003673ae11e255b9467e8f317175495b1ff79f965Chen Fan // 146103673ae11e255b9467e8f317175495b1ff79f965Chen Fan // BSP 146203673ae11e255b9467e8f317175495b1ff79f965Chen Fan // 146303673ae11e255b9467e8f317175495b1ff79f965Chen Fan FillInProcessorInformation (TRUE, 0); 146403673ae11e255b9467e8f317175495b1ff79f965Chen Fan 146503673ae11e255b9467e8f317175495b1ff79f965Chen Fan return EFI_SUCCESS; 146603673ae11e255b9467e8f317175495b1ff79f965Chen Fan} 14671535c888c6f06bb35881e83cd7ee49fb8554942bJordan Justen 14681535c888c6f06bb35881e83cd7ee49fb8554942bJordan Justen/** 14699840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan Callback function for ExitBootServices. 14709840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan 14719840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan @param Event Event whose notification function is being invoked. 14729840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan @param Context The pointer to the notification function's context, 14739840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan which is implementation-dependent. 14749840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan 14759840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan**/ 14769840b1299de78458a42d35b8d1d6cbadd1f6da72Chen FanVOID 14779840b1299de78458a42d35b8d1d6cbadd1f6da72Chen FanEFIAPI 14789840b1299de78458a42d35b8d1d6cbadd1f6da72Chen FanExitBootServicesCallback ( 14799840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan IN EFI_EVENT Event, 14809840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan IN VOID *Context 14819840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan ) 14829840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan{ 14839840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan // 14849840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan // Avoid APs access invalid buff datas which allocated by BootServices, 14859840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan // so we send INIT IPI to APs to let them wait for SIPI state. 14869840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan // 14879840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan SendInitIpiAllExcludingSelf (); 14889840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan} 14899840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan 14909840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan/** 14916022e28cf744a885c278dad256d50670741ea123Jordan Justen Initialize Multi-processor support. 14926022e28cf744a885c278dad256d50670741ea123Jordan Justen 14936022e28cf744a885c278dad256d50670741ea123Jordan Justen**/ 14946022e28cf744a885c278dad256d50670741ea123Jordan JustenVOID 14956022e28cf744a885c278dad256d50670741ea123Jordan JustenInitializeMpSupport ( 14966022e28cf744a885c278dad256d50670741ea123Jordan Justen VOID 14976022e28cf744a885c278dad256d50670741ea123Jordan Justen ) 14986022e28cf744a885c278dad256d50670741ea123Jordan Justen{ 14994a50c2728540b9c487c9eccf19548f5322851212Chen Fan EFI_STATUS Status; 15004a50c2728540b9c487c9eccf19548f5322851212Chen Fan 15016a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan gMaxLogicalProcessorNumber = (UINTN) PcdGet32 (PcdCpuMaxLogicalProcessorNumber); 15026a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan if (gMaxLogicalProcessorNumber < 1) { 15036a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan DEBUG ((DEBUG_ERROR, "Setting PcdCpuMaxLogicalProcessorNumber should be more than zero.\n")); 15046a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan return; 15056a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan } 15066a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan 15076a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan if (gMaxLogicalProcessorNumber == 1) { 15086a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan return; 15096a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan } 15106a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan 15116a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan gApStackSize = (UINTN) PcdGet32 (PcdCpuApStackSize); 15126a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan ASSERT ((gApStackSize & (SIZE_4KB - 1)) == 0); 15136a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan 15146a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan mApStackStart = AllocatePages (EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize)); 15156a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan ASSERT (mApStackStart != NULL); 15166022e28cf744a885c278dad256d50670741ea123Jordan Justen 15176a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan // 15186a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan // the first buffer of stack size used for common stack, when the amount of AP 15196a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan // more than 1, we should never free the common stack which maybe used for AP reset. 15206a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan // 15216a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan mCommonStack = mApStackStart; 15226a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan mTopOfApCommonStack = (UINT8*) mApStackStart + gApStackSize; 15236a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan mApStackStart = mTopOfApCommonStack; 15246a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan 152503673ae11e255b9467e8f317175495b1ff79f965Chen Fan InitMpSystemData (); 15266a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan 1527fe078dd57f5e935c28eac7348b758ca6fb5e696fChen Fan PrepareAPStartupCode (); 1528fe078dd57f5e935c28eac7348b758ca6fb5e696fChen Fan 1529dee9376ffc6e5522bb5e50512b521952a5421fa5Jordan Justen StartApsStackless (); 1530dee9376ffc6e5522bb5e50512b521952a5421fa5Jordan Justen 1531dee9376ffc6e5522bb5e50512b521952a5421fa5Jordan Justen DEBUG ((DEBUG_INFO, "Detect CPU count: %d\n", mMpSystemData.NumberOfProcessors)); 153203673ae11e255b9467e8f317175495b1ff79f965Chen Fan if (mMpSystemData.NumberOfProcessors == 1) { 1533fe078dd57f5e935c28eac7348b758ca6fb5e696fChen Fan FreeApStartupCode (); 15346a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan FreePages (mCommonStack, EFI_SIZE_TO_PAGES (gMaxLogicalProcessorNumber * gApStackSize)); 15356a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan return; 15366a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan } 15376a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan 1538232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fan mMpSystemData.CpuDatas = ReallocatePool ( 1539232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fan sizeof (CPU_DATA_BLOCK) * gMaxLogicalProcessorNumber, 1540232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fan sizeof (CPU_DATA_BLOCK) * mMpSystemData.NumberOfProcessors, 1541232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fan mMpSystemData.CpuDatas); 1542232eb4c82637e92b65ebbfc89a45e9daa8535171Chen Fan 1543ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan mAPsAlreadyInitFinished = TRUE; 1544ac9dbb3b03313c7426c5bb15663b20b57ca771ceChen Fan 15454a50c2728540b9c487c9eccf19548f5322851212Chen Fan Status = gBS->InstallMultipleProtocolInterfaces ( 15464a50c2728540b9c487c9eccf19548f5322851212Chen Fan &mMpServiceHandle, 15474a50c2728540b9c487c9eccf19548f5322851212Chen Fan &gEfiMpServiceProtocolGuid, &mMpServicesTemplate, 15484a50c2728540b9c487c9eccf19548f5322851212Chen Fan NULL 15494a50c2728540b9c487c9eccf19548f5322851212Chen Fan ); 15504a50c2728540b9c487c9eccf19548f5322851212Chen Fan ASSERT_EFI_ERROR (Status); 15514a50c2728540b9c487c9eccf19548f5322851212Chen Fan 155203673ae11e255b9467e8f317175495b1ff79f965Chen Fan if (mMpSystemData.NumberOfProcessors < gMaxLogicalProcessorNumber) { 155303673ae11e255b9467e8f317175495b1ff79f965Chen Fan FreePages (mApStackStart, EFI_SIZE_TO_PAGES ( 155403673ae11e255b9467e8f317175495b1ff79f965Chen Fan (gMaxLogicalProcessorNumber - mMpSystemData.NumberOfProcessors) * 155503673ae11e255b9467e8f317175495b1ff79f965Chen Fan gApStackSize)); 15566a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan } 15579840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan 15589840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan Status = gBS->CreateEvent ( 15599840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan EVT_SIGNAL_EXIT_BOOT_SERVICES, 15609840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan TPL_CALLBACK, 15619840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan ExitBootServicesCallback, 15629840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan NULL, 15639840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan &mExitBootServicesEvent 15649840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan ); 15659840b1299de78458a42d35b8d1d6cbadd1f6da72Chen Fan ASSERT_EFI_ERROR (Status); 15666a26a597a38d36c670a5c1ce0bf54c8a413a1868Chen Fan} 1567