\r
EFI_CPU_INTERRUPT_HANDLER mExternalVectorTable[EXCEPTION_VECTOR_NUMBER];\r
\r
+BOOLEAN mSmmRelocated = FALSE;\r
+volatile BOOLEAN *mSmmInitialized = NULL;\r
UINT32 mBspApicId = 0;\r
\r
//\r
InitializeMpSyncData ();\r
}\r
\r
- //\r
- // Hook return after RSM to set SMM re-based flag\r
- //\r
- SemaphoreHook (Index, &mRebased[Index]);\r
+ if (!mSmmRelocated) {\r
+ //\r
+ // Hook return after RSM to set SMM re-based flag\r
+ //\r
+ SemaphoreHook (Index, &mRebased[Index]);\r
+ }\r
\r
return;\r
}\r
ASSERT (FALSE);\r
}\r
\r
+/**\r
+ Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init.\r
+\r
+**/\r
+VOID\r
+ExecuteFirstSmiInit (\r
+ VOID\r
+ )\r
+{\r
+ UINTN Index;\r
+\r
+ if (mSmmInitialized == NULL) {\r
+ mSmmInitialized = (BOOLEAN *)AllocatePool (sizeof (BOOLEAN) * mMaxNumberOfCpus);\r
+ }\r
+\r
+ ASSERT (mSmmInitialized != NULL);\r
+ if (mSmmInitialized == NULL) {\r
+ return;\r
+ }\r
+\r
+ //\r
+ // Reset the mSmmInitialized to false.\r
+ //\r
+ ZeroMem ((VOID *)mSmmInitialized, sizeof (BOOLEAN) * mMaxNumberOfCpus);\r
+\r
+ //\r
+ // Get the BSP ApicId.\r
+ //\r
+ mBspApicId = GetApicId ();\r
+\r
+ //\r
+ // Issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) for SMM init\r
+ //\r
+ SendSmiIpi (mBspApicId);\r
+ SendSmiIpiAllExcludingSelf ();\r
+\r
+ //\r
+ // Wait for all processors to finish its 1st SMI\r
+ //\r
+ for (Index = 0; Index < mNumberOfCpus; Index++) {\r
+ while (!(BOOLEAN)mSmmInitialized[Index]) {\r
+ }\r
+ }\r
+}\r
+\r
/**\r
Relocate SmmBases for each processor.\r
\r
UINTN FamilyId;\r
UINTN ModelId;\r
UINT32 Cr3;\r
+ EFI_HOB_GUID_TYPE *GuidHob;\r
+ SMM_BASE_HOB_DATA *SmmBaseHobData;\r
+\r
+ GuidHob = NULL;\r
+ SmmBaseHobData = NULL;\r
\r
//\r
// Initialize address fixup\r
ASSERT (TileSize <= (SMRAM_SAVE_STATE_MAP_OFFSET + sizeof (SMRAM_SAVE_STATE_MAP) - SMM_HANDLER_OFFSET));\r
\r
//\r
- // Allocate buffer for all of the tiles.\r
- //\r
- // Intel(R) 64 and IA-32 Architectures Software Developer's Manual\r
- // Volume 3C, Section 34.11 SMBASE Relocation\r
- // For Pentium and Intel486 processors, the SMBASE values must be\r
- // aligned on a 32-KByte boundary or the processor will enter shutdown\r
- // state during the execution of a RSM instruction.\r
- //\r
- // Intel486 processors: FamilyId is 4\r
- // Pentium processors : FamilyId is 5\r
+ // Retrive the allocated SmmBase from gSmmBaseHobGuid. If found,\r
+ // means the SmBase relocation has been done.\r
//\r
- BufferPages = EFI_SIZE_TO_PAGES (SIZE_32KB + TileSize * (mMaxNumberOfCpus - 1));\r
- if ((FamilyId == 4) || (FamilyId == 5)) {\r
- Buffer = AllocateAlignedCodePages (BufferPages, SIZE_32KB);\r
+ GuidHob = GetFirstGuidHob (&gSmmBaseHobGuid);\r
+ if (GuidHob != NULL) {\r
+ //\r
+ // Check whether the Required TileSize is enough.\r
+ //\r
+ if (TileSize > SIZE_8KB) {\r
+ DEBUG ((DEBUG_ERROR, "The Range of Smbase in SMRAM is not enough -- Required TileSize = 0x%08x, Actual TileSize = 0x%08x\n", TileSize, SIZE_8KB));\r
+ CpuDeadLoop ();\r
+ return RETURN_BUFFER_TOO_SMALL;\r
+ }\r
+\r
+ SmmBaseHobData = GET_GUID_HOB_DATA (GuidHob);\r
+\r
+ //\r
+ // Assume single instance of HOB produced, expect the HOB.NumberOfProcessors equals to the mMaxNumberOfCpus.\r
+ //\r
+ ASSERT (SmmBaseHobData->NumberOfProcessors == (UINT32)mMaxNumberOfCpus && SmmBaseHobData->ProcessorIndex == 0);\r
+ mSmmRelocated = TRUE;\r
} else {\r
- Buffer = AllocateAlignedCodePages (BufferPages, SIZE_4KB);\r
- }\r
+ //\r
+ // When the HOB doesn't exist, allocate new SMBASE itself.\r
+ //\r
+ DEBUG ((DEBUG_INFO, "PiCpuSmmEntry: gSmmBaseHobGuid not found!\n"));\r
+ //\r
+ // Allocate buffer for all of the tiles.\r
+ //\r
+ // Intel(R) 64 and IA-32 Architectures Software Developer's Manual\r
+ // Volume 3C, Section 34.11 SMBASE Relocation\r
+ // For Pentium and Intel486 processors, the SMBASE values must be\r
+ // aligned on a 32-KByte boundary or the processor will enter shutdown\r
+ // state during the execution of a RSM instruction.\r
+ //\r
+ // Intel486 processors: FamilyId is 4\r
+ // Pentium processors : FamilyId is 5\r
+ //\r
+ BufferPages = EFI_SIZE_TO_PAGES (SIZE_32KB + TileSize * (mMaxNumberOfCpus - 1));\r
+ if ((FamilyId == 4) || (FamilyId == 5)) {\r
+ Buffer = AllocateAlignedCodePages (BufferPages, SIZE_32KB);\r
+ } else {\r
+ Buffer = AllocateAlignedCodePages (BufferPages, SIZE_4KB);\r
+ }\r
\r
- ASSERT (Buffer != NULL);\r
- DEBUG ((DEBUG_INFO, "SMRAM SaveState Buffer (0x%08x, 0x%08x)\n", Buffer, EFI_PAGES_TO_SIZE (BufferPages)));\r
+ ASSERT (Buffer != NULL);\r
+ DEBUG ((DEBUG_INFO, "New Allcoated SMRAM SaveState Buffer (0x%08x, 0x%08x)\n", Buffer, EFI_PAGES_TO_SIZE (BufferPages)));\r
+ }\r
\r
//\r
// Allocate buffer for pointers to array in SMM_CPU_PRIVATE_DATA.\r
// size for each CPU in the platform\r
//\r
for (Index = 0; Index < mMaxNumberOfCpus; Index++) {\r
- mCpuHotPlugData.SmBase[Index] = (UINTN)Buffer + Index * TileSize - SMM_HANDLER_OFFSET;\r
+ mCpuHotPlugData.SmBase[Index] = mSmmRelocated ? (UINTN)SmmBaseHobData->SmBase[Index] : (UINTN)Buffer + Index * TileSize - SMM_HANDLER_OFFSET;\r
+\r
gSmmCpuPrivate->CpuSaveStateSize[Index] = sizeof (SMRAM_SAVE_STATE_MAP);\r
gSmmCpuPrivate->CpuSaveState[Index] = (VOID *)(mCpuHotPlugData.SmBase[Index] + SMRAM_SAVE_STATE_MAP_OFFSET);\r
gSmmCpuPrivate->Operation[Index] = SmmCpuNone;\r
InitializeSmmIdt ();\r
\r
//\r
- // Relocate SMM Base addresses to the ones allocated from SMRAM\r
+ // Check whether Smm Relocation is done or not.\r
+ // If not, will do the SmmBases Relocation here!!!\r
//\r
- mRebased = (BOOLEAN *)AllocateZeroPool (sizeof (BOOLEAN) * mMaxNumberOfCpus);\r
- ASSERT (mRebased != NULL);\r
- SmmRelocateBases ();\r
+ if (!mSmmRelocated) {\r
+ //\r
+ // Relocate SMM Base addresses to the ones allocated from SMRAM\r
+ //\r
+ mRebased = (BOOLEAN *)AllocateZeroPool (sizeof (BOOLEAN) * mMaxNumberOfCpus);\r
+ ASSERT (mRebased != NULL);\r
+ SmmRelocateBases ();\r
\r
- //\r
- // Call hook for BSP to perform extra actions in normal mode after all\r
- // SMM base addresses have been relocated on all CPUs\r
- //\r
- SmmCpuFeaturesSmmRelocationComplete ();\r
+ //\r
+ // Call hook for BSP to perform extra actions in normal mode after all\r
+ // SMM base addresses have been relocated on all CPUs\r
+ //\r
+ SmmCpuFeaturesSmmRelocationComplete ();\r
+ }\r
\r
DEBUG ((DEBUG_INFO, "mXdSupported - 0x%x\n", mXdSupported));\r
\r
}\r
}\r
\r
+ //\r
+ // For relocated SMBASE, some MSRs & CSRs are still required to be configured in SMM Mode for SMM Initialization.\r
+ // Those MSRs & CSRs must be configured before normal SMI sources happen.\r
+ // So, here is to issue SMI IPI (All Excluding Self SMM IPI + BSP SMM IPI) to execute first SMI init.\r
+ //\r
+ if (mSmmRelocated) {\r
+ ExecuteFirstSmiInit ();\r
+\r
+ //\r
+ // Call hook for BSP to perform extra actions in normal mode after all\r
+ // SMM base addresses have been relocated on all CPUs\r
+ //\r
+ SmmCpuFeaturesSmmRelocationComplete ();\r
+ }\r
+\r
//\r
// Fill in SMM Reserved Regions\r
//\r