/** AP initialization after SMBASE relocation in the S3 boot path. **/ VOID MPRendezvousProcedure ( VOID ) { CPU_REGISTER_TABLE *RegisterTableList; UINT32 InitApicId; UINTN Index; ProgramVirtualWireMode (); DisableLvtInterrupts (); RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable; InitApicId = GetInitialApicId (); for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) { if (RegisterTableList[Index].InitialApicId == InitApicId) { SetProcessorRegister (&RegisterTableList[Index]); break; } } // // Count down the number with lock mechanism. // InterlockedDecrement (&mNumberToFinish); }
/** The function is invoked before SMBASE relocation in S3 path to restores CPU status. The function is invoked before SMBASE relocation in S3 path. It does first time microcode load and restores MTRRs for both BSP and APs. **/ VOID InitializeCpuBeforeRebase ( VOID ) { LoadMtrrData (mAcpiCpuData.MtrrTable); SetProcessorRegister ((CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable, mAcpiCpuData.NumberOfCpus); ProgramVirtualWireMode (); PrepareApStartupVector (mAcpiCpuData.StartupVector); mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1; mExchangeInfo->ApFunction = (VOID *) (UINTN) InitializeAp; // // Execute code for before SmmBaseReloc. Note: This flag is maintained across S3 boots. // mInitApsAfterSmmBaseReloc = FALSE; // // Send INIT IPI - SIPI to all APs // SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector); while (mNumberToFinish > 0) { CpuPause (); } }
/** Triggers CPU-only reset and restores processor environment. This function triggers CPU-only reset and restores processor environment. **/ VOID CpuOnlyResetAndRestore ( VOID ) { MTRR_SETTINGS MtrrSetting; MtrrGetAllMtrrs (&MtrrSetting); InitiateCpuOnlyReset (); DispatchAPAndWait ( TRUE, 0, EarlyMpInit ); EarlyMpInit (mCpuConfigConextBuffer.BspNumber); ProgramVirtualWireMode (); }
/** The function is invoked before SMBASE relocation in S3 path to restors CPU status. The function is invoked before SMBASE relocation in S3 path. It does first time microcode load and restores MTRRs for both BSP and APs. **/ VOID EarlyInitializeCpu ( VOID ) { CPU_REGISTER_TABLE *RegisterTableList; UINT32 InitApicId; UINTN Index; LoadMtrrData (mAcpiCpuData.MtrrTable); // // Find processor number for this CPU. // RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable; InitApicId = GetInitialApicId (); for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) { if (RegisterTableList[Index].InitialApicId == InitApicId) { SetProcessorRegister (&RegisterTableList[Index]); break; } } ProgramVirtualWireMode (); PrepareAPStartupVector (mAcpiCpuData.StartupVector); mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1; mExchangeInfo->ApFunction = (VOID *) (UINTN) EarlyMPRendezvousProcedure; // // Send INIT IPI - SIPI to all APs // SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector); while (mNumberToFinish > 0) { CpuPause (); } }
/** AP initialization before then after SMBASE relocation in the S3 boot path. **/ VOID InitializeAp ( VOID ) { UINTN TopOfStack; UINT8 Stack[128]; LoadMtrrData (mAcpiCpuData.MtrrTable); SetProcessorRegister ((CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable, mAcpiCpuData.NumberOfCpus); // // Count down the number with lock mechanism. // InterlockedDecrement (&mNumberToFinish); // // Wait for BSP to signal SMM Base relocation done. // while (!mInitApsAfterSmmBaseReloc) { CpuPause (); } ProgramVirtualWireMode (); DisableLvtInterrupts (); SetProcessorRegister ((CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable, mAcpiCpuData.NumberOfCpus); // // Place AP into the safe code, count down the number with lock mechanism in the safe code. // TopOfStack = (UINTN) Stack + sizeof (Stack); TopOfStack &= ~(UINTN) (CPU_STACK_ALIGNMENT - 1); CopyMem ((VOID *) (UINTN) mApHltLoopCode, mApHltLoopCodeTemplate, sizeof (mApHltLoopCodeTemplate)); TransferApToSafeState ((UINTN)mApHltLoopCode, TopOfStack, (UINTN)&mNumberToFinish); }