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 mov eax, NotVacantFlag
94 cmp eax, NotVacantFlag
98 add edi, NumApsExecutingLoction
104 add edi, StackSizeLocation
107 add edi, StackStartAddressLocation
115 add edi, LockLocation
119 push ebp ; push BIST data at top of AP stack
120 xor ebp, ebp ; clear ebp for call stack trace
124 mov eax, ASM_PFX(InitializeFloatingPointUnits)
125 call eax ; Call assembly function to initialize FPU per UEFI spec
127 push ebx ; Push NumApsExecuting
129 add eax, LockLocation
130 push eax ; push address of exchange info data buffer
133 add edi, ApProcedureLocation
136 call eax ; invoke C function
138 jmp $ ; never reach here
139 RendezvousFunnelProcEnd:
141 ;-------------------------------------------------------------------------------------
142 ; AsmGetAddressMap (&AddressMap);
143 ;-------------------------------------------------------------------------------------
144 global ASM_PFX(AsmGetAddressMap)
145 ASM_PFX(AsmGetAddressMap):
150 mov dword [ebx], RendezvousFunnelProcStart
151 mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart
152 mov dword [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
157 ;-------------------------------------------------------------------------------------
158 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
159 ;about to become an AP. It switches it'stack with the current AP.
160 ;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
161 ;-------------------------------------------------------------------------------------
162 global ASM_PFX(AsmExchangeRole)
163 ASM_PFX(AsmExchangeRole):
164 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
165 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
169 ; esi contains MyInfo pointer
172 ; edi contains OthersInfo pointer
175 ;Store EFLAGS, GDTR and IDTR register to stack
178 push eax ; push cr4 firstly
185 ; Store the its StackPointer
188 ; update its switch state to STORED
189 mov byte [esi], CPU_SWITCH_STATE_STORED
192 ; wait until the other CPU finish storing its state
193 cmp byte [edi], CPU_SWITCH_STATE_STORED
196 jmp WaitForOtherStored
199 ; Since another CPU already stored its state, load them
206 ; load its future StackPointer
209 ; update the other CPU's switch state to LOADED
210 mov byte [edi], CPU_SWITCH_STATE_LOADED
213 ; wait until the other CPU finish loading new state,
214 ; otherwise the data in stack may corrupt
215 cmp byte [esi], CPU_SWITCH_STATE_LOADED
218 jmp WaitForOtherLoaded
221 ; since the other CPU already get the data it want, leave this procedure