//\r
SPIN_LOCK *mMemoryMappedLock = NULL;\r
\r
+//\r
+// Signal that SMM BASE relocation is complete.\r
+//\r
+volatile BOOLEAN mInitApsAfterSmmBaseReloc;\r
+\r
/**\r
Get starting address and size of the rendezvous entry for APs.\r
Information for fixing a jump instruction in the code is also returned.\r
\r
This function programs registers for the calling processor.\r
\r
- @param RegisterTable Pointer to register table of the running processor.\r
+ @param RegisterTables Pointer to register table of the running processor.\r
+ @param RegisterTableCount Register table count.\r
\r
**/\r
VOID\r
SetProcessorRegister (\r
- IN CPU_REGISTER_TABLE *RegisterTable\r
+ IN CPU_REGISTER_TABLE *RegisterTables,\r
+ IN UINTN RegisterTableCount\r
)\r
{\r
CPU_REGISTER_TABLE_ENTRY *RegisterTableEntry;\r
UINTN Index;\r
UINTN Value;\r
SPIN_LOCK *MsrSpinLock;\r
+ UINT32 InitApicId;\r
+ CPU_REGISTER_TABLE *RegisterTable;\r
+\r
+ InitApicId = GetInitialApicId ();\r
+ RegisterTable = NULL;\r
+ for (Index = 0; Index < RegisterTableCount; Index++) {\r
+ if (RegisterTables[Index].InitialApicId == InitApicId) {\r
+ RegisterTable = &RegisterTables[Index];\r
+ break;\r
+ }\r
+ }\r
+ ASSERT (RegisterTable != NULL);\r
\r
//\r
// Traverse Register Table of this logical processor\r
}\r
\r
/**\r
- AP initialization before SMBASE relocation in the S3 boot path.\r
+ AP initialization before then after SMBASE relocation in the S3 boot path.\r
**/\r
VOID\r
-EarlyMPRendezvousProcedure (\r
+InitializeAp (\r
VOID\r
)\r
{\r
- CPU_REGISTER_TABLE *RegisterTableList;\r
- UINT32 InitApicId;\r
- UINTN Index;\r
+ UINTN TopOfStack;\r
+ UINT8 Stack[128];\r
\r
LoadMtrrData (mAcpiCpuData.MtrrTable);\r
\r
- //\r
- // Find processor number for this CPU.\r
- //\r
- RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable;\r
- InitApicId = GetInitialApicId ();\r
- for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {\r
- if (RegisterTableList[Index].InitialApicId == InitApicId) {\r
- SetProcessorRegister (&RegisterTableList[Index]);\r
- break;\r
- }\r
- }\r
+ SetProcessorRegister ((CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable, mAcpiCpuData.NumberOfCpus);\r
\r
//\r
// Count down the number with lock mechanism.\r
//\r
InterlockedDecrement (&mNumberToFinish);\r
-}\r
\r
-/**\r
- AP initialization after SMBASE relocation in the S3 boot path.\r
-**/\r
-VOID\r
-MPRendezvousProcedure (\r
- VOID\r
- )\r
-{\r
- CPU_REGISTER_TABLE *RegisterTableList;\r
- UINT32 InitApicId;\r
- UINTN Index;\r
- UINTN TopOfStack;\r
- UINT8 Stack[128];\r
+ //\r
+ // Wait for BSP to signal SMM Base relocation done.\r
+ //\r
+ while (!mInitApsAfterSmmBaseReloc) {\r
+ CpuPause ();\r
+ }\r
\r
ProgramVirtualWireMode ();\r
DisableLvtInterrupts ();\r
\r
- RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable;\r
- InitApicId = GetInitialApicId ();\r
- for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {\r
- if (RegisterTableList[Index].InitialApicId == InitApicId) {\r
- SetProcessorRegister (&RegisterTableList[Index]);\r
- break;\r
- }\r
- }\r
+ SetProcessorRegister ((CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable, mAcpiCpuData.NumberOfCpus);\r
\r
//\r
// Place AP into the safe code, count down the number with lock mechanism in the safe code.\r
\r
**/\r
VOID\r
-EarlyInitializeCpu (\r
+InitializeCpuBeforeRebase (\r
VOID\r
)\r
{\r
- CPU_REGISTER_TABLE *RegisterTableList;\r
- UINT32 InitApicId;\r
- UINTN Index;\r
-\r
LoadMtrrData (mAcpiCpuData.MtrrTable);\r
\r
- //\r
- // Find processor number for this CPU.\r
- //\r
- RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable;\r
- InitApicId = GetInitialApicId ();\r
- for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {\r
- if (RegisterTableList[Index].InitialApicId == InitApicId) {\r
- SetProcessorRegister (&RegisterTableList[Index]);\r
- break;\r
- }\r
- }\r
+ SetProcessorRegister ((CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.PreSmmInitRegisterTable, mAcpiCpuData.NumberOfCpus);\r
\r
ProgramVirtualWireMode ();\r
\r
PrepareApStartupVector (mAcpiCpuData.StartupVector);\r
\r
mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1;\r
- mExchangeInfo->ApFunction = (VOID *) (UINTN) EarlyMPRendezvousProcedure;\r
+ mExchangeInfo->ApFunction = (VOID *) (UINTN) InitializeAp;\r
+\r
+ //\r
+ // Execute code for before SmmBaseReloc. Note: This flag is maintained across S3 boots.\r
+ //\r
+ mInitApsAfterSmmBaseReloc = FALSE;\r
\r
//\r
// Send INIT IPI - SIPI to all APs\r
\r
**/\r
VOID\r
-InitializeCpu (\r
+InitializeCpuAfterRebase (\r
VOID\r
)\r
{\r
- CPU_REGISTER_TABLE *RegisterTableList;\r
- UINT32 InitApicId;\r
- UINTN Index;\r
-\r
- RegisterTableList = (CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable;\r
- InitApicId = GetInitialApicId ();\r
- for (Index = 0; Index < mAcpiCpuData.NumberOfCpus; Index++) {\r
- if (RegisterTableList[Index].InitialApicId == InitApicId) {\r
- SetProcessorRegister (&RegisterTableList[Index]);\r
- break;\r
- }\r
- }\r
+ SetProcessorRegister ((CPU_REGISTER_TABLE *) (UINTN) mAcpiCpuData.RegisterTable, mAcpiCpuData.NumberOfCpus);\r
\r
mNumberToFinish = mAcpiCpuData.NumberOfCpus - 1;\r
- //\r
- // StackStart was updated when APs were waken up in EarlyInitializeCpu.\r
- // Re-initialize StackAddress to original beginning address.\r
- //\r
- mExchangeInfo->StackStart = (VOID *) (UINTN) mAcpiCpuData.StackAddress;\r
- mExchangeInfo->ApFunction = (VOID *) (UINTN) MPRendezvousProcedure;\r
\r
//\r
- // Send INIT IPI - SIPI to all APs\r
+ // Signal that SMM base relocation is complete and to continue initialization.\r
//\r
- SendInitSipiSipiAllExcludingSelf ((UINT32)mAcpiCpuData.StartupVector);\r
+ mInitApsAfterSmmBaseReloc = TRUE;\r
\r
while (mNumberToFinish > 0) {\r
CpuPause ();\r
//\r
// First time microcode load and restore MTRRs\r
//\r
- EarlyInitializeCpu ();\r
+ InitializeCpuBeforeRebase ();\r
}\r
\r
//\r
//\r
// Restore MSRs for BSP and all APs\r
//\r
- InitializeCpu ();\r
+ InitializeCpuAfterRebase ();\r
}\r
\r
//\r