1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
3 ; This program and the accompanying materials
4 ; are licensed and made available under the terms and conditions of the BSD License
5 ; which accompanies this distribution. The full text of the license may be found at
6 ; http://opensource.org/licenses/bsd-license.php.
8 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
17 ; This is the assembly code for MP support
19 ;-------------------------------------------------------------------------------
22 extern ASM_PFX(InitializeFloatingPointUnits)
26 ;-------------------------------------------------------------------------------------
27 ;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
28 ;procedure serializes all the AP processors through an Init sequence. It must be
29 ;noted that APs arrive here very raw...ie: real mode, no stack.
30 ;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
32 ;-------------------------------------------------------------------------------------
33 global ASM_PFX(RendezvousFunnelProc)
34 ASM_PFX(RendezvousFunnelProc):
35 RendezvousFunnelProcStart:
36 ; At this point CS = 0x(vv00) and ip= 0x0.
38 mov ebp, eax ; save BIST information
48 mov si, BufferStartLocation
51 mov si, ModeOffsetLocation
53 mov si, CodeSegmentLocation
62 mov si, DataSegmentLocation
74 mov eax, cr0 ; Get control register 0
75 or eax, 000000003h ; Set PE bit (bit #0) & MP
78 jmp 0:strict dword 0 ; far jump to protected mode
80 Flat32Start: ; protected mode entry point
90 add edi, EnableExecuteDisableLocation
92 jz SkipEnableExecuteDisable
95 ; Enable IA32 PAE execute disable
116 SkipEnableExecuteDisable:
119 add edi, LockLocation
120 mov eax, NotVacantFlag
124 cmp eax, NotVacantFlag
128 add edi, NumApsExecutingLocation
134 add edi, StackSizeLocation
137 add edi, StackStartAddressLocation
145 add edi, LockLocation
149 push ebp ; push BIST data at top of AP stack
150 xor ebp, ebp ; clear ebp for call stack trace
154 mov eax, ASM_PFX(InitializeFloatingPointUnits)
155 call eax ; Call assembly function to initialize FPU per UEFI spec
157 push ebx ; Push NumApsExecuting
159 add eax, LockLocation
160 push eax ; push address of exchange info data buffer
163 add edi, ApProcedureLocation
166 call eax ; Invoke C function
168 jmp $ ; Never reach here
169 RendezvousFunnelProcEnd:
171 ;-------------------------------------------------------------------------------------
172 ; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment);
173 ;-------------------------------------------------------------------------------------
174 global ASM_PFX(AsmRelocateApLoop)
175 ASM_PFX(AsmRelocateApLoop):
176 AsmRelocateApLoopStart:
177 cmp byte [esp + 4], 1
184 mov eax, [esp + 8] ; Mwait Cx, Target C-State per eax[7:4]
193 AsmRelocateApLoopEnd:
195 ;-------------------------------------------------------------------------------------
196 ; AsmGetAddressMap (&AddressMap);
197 ;-------------------------------------------------------------------------------------
198 global ASM_PFX(AsmGetAddressMap)
199 ASM_PFX(AsmGetAddressMap):
204 mov dword [ebx], RendezvousFunnelProcStart
205 mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
206 mov dword [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
207 mov dword [ebx + 0Ch], AsmRelocateApLoopStart
208 mov dword [ebx + 10h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart
213 ;-------------------------------------------------------------------------------------
214 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
215 ;about to become an AP. It switches it'stack with the current AP.
216 ;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
217 ;-------------------------------------------------------------------------------------
218 global ASM_PFX(AsmExchangeRole)
219 ASM_PFX(AsmExchangeRole):
220 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
221 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
225 ; esi contains MyInfo pointer
228 ; edi contains OthersInfo pointer
231 ;Store EFLAGS, GDTR and IDTR register to stack
234 push eax ; push cr4 firstly
241 ; Store the its StackPointer
244 ; update its switch state to STORED
245 mov byte [esi], CPU_SWITCH_STATE_STORED
248 ; wait until the other CPU finish storing its state
249 cmp byte [edi], CPU_SWITCH_STATE_STORED
252 jmp WaitForOtherStored
255 ; Since another CPU already stored its state, load them
262 ; load its future StackPointer
265 ; update the other CPU's switch state to LOADED
266 mov byte [edi], CPU_SWITCH_STATE_LOADED
269 ; wait until the other CPU finish loading new state,
270 ; otherwise the data in stack may corrupt
271 cmp byte [esi], CPU_SWITCH_STATE_LOADED
274 jmp WaitForOtherLoaded
277 ; since the other CPU already get the data it want, leave this procedure