+/**\r
+ Copy the data used to initialize processor register into SMRAM.\r
+\r
+ @param[in,out] CpuFeatureInitDataDst Pointer to the destination CPU_FEATURE_INIT_DATA structure.\r
+ @param[in] CpuFeatureInitDataSrc Pointer to the source CPU_FEATURE_INIT_DATA structure.\r
+\r
+**/\r
+VOID\r
+CopyCpuFeatureInitDatatoSmram (\r
+ IN OUT CPU_FEATURE_INIT_DATA *CpuFeatureInitDataDst,\r
+ IN CPU_FEATURE_INIT_DATA *CpuFeatureInitDataSrc\r
+ )\r
+{\r
+ CPU_STATUS_INFORMATION *CpuStatus;\r
+\r
+ if (!IsRegisterTableEmpty ((CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->PreSmmInitRegisterTable, mAcpiCpuData.NumberOfCpus)) {\r
+ CpuFeatureInitDataDst->PreSmmInitRegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE));\r
+ ASSERT (CpuFeatureInitDataDst->PreSmmInitRegisterTable != 0);\r
+\r
+ CopyRegisterTable (\r
+ (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataDst->PreSmmInitRegisterTable,\r
+ (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->PreSmmInitRegisterTable,\r
+ mAcpiCpuData.NumberOfCpus\r
+ );\r
+ }\r
+\r
+ if (!IsRegisterTableEmpty ((CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->RegisterTable, mAcpiCpuData.NumberOfCpus)) {\r
+ CpuFeatureInitDataDst->RegisterTable = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocatePool (mAcpiCpuData.NumberOfCpus * sizeof (CPU_REGISTER_TABLE));\r
+ ASSERT (CpuFeatureInitDataDst->RegisterTable != 0);\r
+\r
+ CopyRegisterTable (\r
+ (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataDst->RegisterTable,\r
+ (CPU_REGISTER_TABLE *)(UINTN)CpuFeatureInitDataSrc->RegisterTable,\r
+ mAcpiCpuData.NumberOfCpus\r
+ );\r
+ }\r
+\r
+ CpuStatus = &CpuFeatureInitDataDst->CpuStatus;\r
+ CopyMem (CpuStatus, &CpuFeatureInitDataSrc->CpuStatus, sizeof (CPU_STATUS_INFORMATION));\r
+\r
+ if (CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerPackage != 0) {\r
+ CpuStatus->ThreadCountPerPackage = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool (\r
+ sizeof (UINT32) * CpuStatus->PackageCount,\r
+ (UINT32 *)(UINTN)CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerPackage\r
+ );\r
+ ASSERT (CpuStatus->ThreadCountPerPackage != 0);\r
+ }\r
+\r
+ if (CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerCore != 0) {\r
+ CpuStatus->ThreadCountPerCore = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool (\r
+ sizeof (UINT8) * (CpuStatus->PackageCount * CpuStatus->MaxCoreCount),\r
+ (UINT32 *)(UINTN)CpuFeatureInitDataSrc->CpuStatus.ThreadCountPerCore\r
+ );\r
+ ASSERT (CpuStatus->ThreadCountPerCore != 0);\r
+ }\r
+\r
+ if (CpuFeatureInitDataSrc->ApLocation != 0) {\r
+ CpuFeatureInitDataDst->ApLocation = (EFI_PHYSICAL_ADDRESS)(UINTN)AllocateCopyPool (\r
+ mAcpiCpuData.NumberOfCpus * sizeof (EFI_CPU_PHYSICAL_LOCATION),\r
+ (EFI_CPU_PHYSICAL_LOCATION *)(UINTN)CpuFeatureInitDataSrc->ApLocation\r
+ );\r
+ ASSERT (CpuFeatureInitDataDst->ApLocation != 0);\r
+ }\r
+}\r
+\r