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 ; AsmGetAddressMap (&AddressMap);
173 ;-------------------------------------------------------------------------------------
174 global ASM_PFX(AsmGetAddressMap)
175 ASM_PFX(AsmGetAddressMap):
180 mov dword [ebx], RendezvousFunnelProcStart
181 mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
182 mov dword [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
187 ;-------------------------------------------------------------------------------------
188 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
189 ;about to become an AP. It switches it'stack with the current AP.
190 ;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
191 ;-------------------------------------------------------------------------------------
192 global ASM_PFX(AsmExchangeRole)
193 ASM_PFX(AsmExchangeRole):
194 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
195 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
199 ; esi contains MyInfo pointer
202 ; edi contains OthersInfo pointer
205 ;Store EFLAGS, GDTR and IDTR register to stack
208 push eax ; push cr4 firstly
215 ; Store the its StackPointer
218 ; update its switch state to STORED
219 mov byte [esi], CPU_SWITCH_STATE_STORED
222 ; wait until the other CPU finish storing its state
223 cmp byte [edi], CPU_SWITCH_STATE_STORED
226 jmp WaitForOtherStored
229 ; Since another CPU already stored its state, load them
236 ; load its future StackPointer
239 ; update the other CPU's switch state to LOADED
240 mov byte [edi], CPU_SWITCH_STATE_LOADED
243 ; wait until the other CPU finish loading new state,
244 ; otherwise the data in stack may corrupt
245 cmp byte [esi], CPU_SWITCH_STATE_LOADED
248 jmp WaitForOtherLoaded
251 ; since the other CPU already get the data it want, leave this procedure