#define LEGACY_REGION_BASE (0xA0000 - LEGACY_REGION_SIZE)\r
\r
ACPI_CPU_DATA mAcpiCpuData;\r
-UINT32 mNumberToFinish;\r
+volatile UINT32 mNumberToFinish;\r
MP_CPU_EXCHANGE_INFO *mExchangeInfo;\r
BOOLEAN mRestoreSmmConfigurationInS3 = FALSE;\r
VOID *mGdtForAp = NULL;\r
\r
BOOLEAN mAcpiS3Enable = TRUE;\r
\r
+UINT8 *mApHltLoopCode = NULL;\r
+UINT8 mApHltLoopCodeTemplate[] = {\r
+ 0x8B, 0x44, 0x24, 0x04, // mov eax, dword ptr [esp+4]\r
+ 0xF0, 0xFF, 0x08, // lock dec dword ptr [eax]\r
+ 0xFA, // cli\r
+ 0xF4, // hlt\r
+ 0xEB, 0xFC // jmp $-2\r
+ };\r
+\r
/**\r
Get MSR spin lock by MSR index.\r
\r
CPU_REGISTER_TABLE *RegisterTableList;\r
UINT32 InitApicId;\r
UINTN Index;\r
+ UINTN TopOfStack;\r
+ UINT8 Stack[128];\r
\r
ProgramVirtualWireMode ();\r
DisableLvtInterrupts ();\r
}\r
\r
//\r
- // Count down the number with lock mechanism.\r
+ // Place AP into the safe code, count down the number with lock mechanism in the safe code.\r
//\r
- InterlockedDecrement (&mNumberToFinish);\r
+ TopOfStack = (UINTN) Stack + sizeof (Stack);\r
+ TopOfStack &= ~(UINTN) (CPU_STACK_ALIGNMENT - 1);\r
+ CopyMem ((VOID *) (UINTN) mApHltLoopCode, mApHltLoopCodeTemplate, sizeof (mApHltLoopCodeTemplate));\r
+ TransferApToSafeState ((UINTN)mApHltLoopCode, TopOfStack, (UINTN)&mNumberToFinish);\r
}\r
\r
/**\r
VOID *GuidHob;\r
EFI_SMRAM_DESCRIPTOR *SmramDescriptor;\r
SMM_S3_RESUME_STATE *SmmS3ResumeState;\r
+ EFI_PHYSICAL_ADDRESS Address;\r
+ EFI_STATUS Status;\r
\r
if (!mAcpiS3Enable) {\r
return;\r
// Patch SmmS3ResumeState->SmmS3Cr3\r
//\r
InitSmmS3Cr3 ();\r
+\r
+ //\r
+ // Allocate safe memory in ACPI NVS for AP to execute hlt loop in\r
+ // protected mode on S3 path\r
+ //\r
+ Address = BASE_4GB - 1;\r
+ Status = gBS->AllocatePages (\r
+ AllocateMaxAddress,\r
+ EfiACPIMemoryNVS,\r
+ EFI_SIZE_TO_PAGES (sizeof (mApHltLoopCodeTemplate)),\r
+ &Address\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+ mApHltLoopCode = (UINT8 *) (UINTN) Address;\r
}\r
\r
/**\r