;------------------------------------------------------------------------------ ;\r
-; Copyright (c) 2015 - 2021, 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
;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r
;IS IN MACHINE CODE.\r
;-------------------------------------------------------------------------------------\r
-global ASM_PFX(RendezvousFunnelProc)\r
-ASM_PFX(RendezvousFunnelProc):\r
RendezvousFunnelProcStart:\r
; At this point CS = 0x(vv00) and ip= 0x0.\r
BITS 16\r
lock inc dword [edi]\r
\r
; AP init\r
- mov edi, esi\r
- add edi, MP_CPU_EXCHANGE_INFO_FIELD (Lock)\r
- mov eax, NotVacantFlag\r
-\r
mov edi, esi\r
add edi, MP_CPU_EXCHANGE_INFO_FIELD (ApIndex)\r
mov ebx, 1\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
call eax ; Invoke C function\r
\r
jmp $ ; Never reach here\r
-RendezvousFunnelProcEnd:\r
\r
;-------------------------------------------------------------------------------------\r
;SwitchToRealProc procedure follows.\r
;NOT USED IN 32 BIT MODE.\r
;-------------------------------------------------------------------------------------\r
-global ASM_PFX(SwitchToRealProc)\r
-ASM_PFX(SwitchToRealProc):\r
SwitchToRealProcStart:\r
jmp $ ; Never reach here\r
SwitchToRealProcEnd:\r
\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
-global ASM_PFX(AsmRelocateApLoop)\r
-ASM_PFX(AsmRelocateApLoop):\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.SwitchToRealSize], SwitchToRealProcEnd - SwitchToRealProcStart\r
- mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealOffset], SwitchToRealProcStart - RendezvousFunnelProcStart\r
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealNoNxOffset], SwitchToRealProcStart - Flat32Start\r
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeOffset], 0\r
mov dword [ebx + MP_ASSEMBLY_ADDRESS_MAP.SwitchToRealPM16ModeSize], 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