;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2015 - 2022, Intel Corporation. All rights reserved.<BR>\r
+; Copyright (c) 2015 - 2023, Intel Corporation. All rights reserved.<BR>\r
; SPDX-License-Identifier: BSD-2-Clause-Patent\r
;\r
; Module Name:\r
mov esp, dword [edi + CPU_INFO_IN_HOB.ApTopOfStack]\r
\r
CProcedureInvoke:\r
+ ;\r
+ ; Reserve 4 bytes for CpuMpData.\r
+ ; When the AP wakes up again via INIT-SIPI-SIPI, push 0 will cause the existing CpuMpData to be overwritten with 0.\r
+ ; CpuMpData is filled in via InitializeApData() during the first time INIT-SIPI-SIPI,\r
+ ; while overwirrten may occurs when under ApInHltLoop but InitFlag is not set to ApInitConfig.\r
+ ; Therefore reservation is implemented by sub esp instead of push 0.\r
+ ;\r
+ sub esp, 4\r
push ebp ; push BIST data at top of AP stack\r
xor ebp, ebp ; clear ebp for call stack trace\r
push ebp\r
RendezvousFunnelProcEnd:\r
\r
;-------------------------------------------------------------------------------------\r
-; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);\r
+; AsmRelocateApLoopGeneric (MwaitSupport, ApTargetCState, PmCodeSegment, TopOfApStack, CountTofinish, Pm16CodeSegment, SevEsAPJumpTable, WakeupBuffer);\r
;\r
; The last three parameters (Pm16CodeSegment, SevEsAPJumpTable and WakeupBuffer) are\r
; specific to SEV-ES support and are not applicable on IA32.\r
;-------------------------------------------------------------------------------------\r
-AsmRelocateApLoopStart:\r
+AsmRelocateApLoopGenericStart:\r
mov eax, esp\r
- mov esp, [eax + 16] ; TopOfApStack\r
+ mov esp, [eax + 12] ; TopOfApStack\r
push dword [eax] ; push return address for stack trace\r
push ebp\r
mov ebp, esp\r
mov ebx, [eax + 8] ; ApTargetCState\r
mov ecx, [eax + 4] ; MwaitSupport\r
- mov eax, [eax + 20] ; CountTofinish\r
+ mov eax, [eax + 16] ; CountTofinish\r
lock dec dword [eax] ; (*CountTofinish)--\r
cmp cl, 1 ; Check mwait-monitor support\r
- jnz HltLoop\r
-MwaitLoop:\r
+ jnz HltLoopGeneric\r
+MwaitLoopGeneric:\r
cli\r
mov eax, esp\r
xor ecx, ecx\r
mov eax, ebx ; Mwait Cx, Target C-State per eax[7:4]\r
shl eax, 4\r
mwait\r
- jmp MwaitLoop\r
-HltLoop:\r
+ jmp MwaitLoopGeneric\r
+HltLoopGeneric:\r
cli\r
hlt\r
- jmp HltLoop\r
-AsmRelocateApLoopEnd:\r
+ jmp HltLoopGeneric\r
+AsmRelocateApLoopGenericEnd:\r
\r
;-------------------------------------------------------------------------------------\r
; AsmGetAddressMap (&AddressMap);\r
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelAddress], RendezvousFunnelProcStart\r
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.ModeEntryOffset], Flat32Start - RendezvousFunnelProcStart\r
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RendezvousFunnelSize], RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
- mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddress], AsmRelocateApLoopStart\r
- mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSize], AsmRelocateApLoopEnd - AsmRelocateApLoopStart\r
+ mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncAddressGeneric], AsmRelocateApLoopGenericStart\r
+ mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.RelocateApLoopFuncSizeGeneric], AsmRelocateApLoopGenericEnd - AsmRelocateApLoopGenericStart\r
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.ModeTransitionOffset], Flat32Start - RendezvousFunnelProcStart\r
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset], SwitchToRealProcStart - Flat32Start\r
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOffset], 0\r
; edi contains OthersInfo pointer\r
mov edi, [ebp + 28h]\r
\r
- ;Store EFLAGS, GDTR and IDTR register to stack\r
+ ;Store EFLAGS to stack\r
pushfd\r
- mov eax, cr4\r
- push eax ; push cr4 firstly\r
- mov eax, cr0\r
- push eax\r
-\r
- sgdt [esi + CPU_EXCHANGE_ROLE_INFO.Gdtr]\r
- sidt [esi + CPU_EXCHANGE_ROLE_INFO.Idtr]\r
\r
; Store the its StackPointer\r
mov [esi + CPU_EXCHANGE_ROLE_INFO.StackPointer],esp\r
jmp WaitForOtherStored\r
\r
OtherStored:\r
- ; Since another CPU already stored its state, load them\r
- ; load GDTR value\r
- lgdt [edi + CPU_EXCHANGE_ROLE_INFO.Gdtr]\r
-\r
- ; load IDTR value\r
- lidt [edi + CPU_EXCHANGE_ROLE_INFO.Idtr]\r
-\r
; load its future StackPointer\r
mov esp, [edi + CPU_EXCHANGE_ROLE_INFO.StackPointer]\r
\r
\r
OtherLoaded:\r
; since the other CPU already get the data it want, leave this procedure\r
- pop eax\r
- mov cr0, eax\r
- pop eax\r
- mov cr4, eax\r
popfd\r
\r
popad\r