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, PmodeOffsetLocation
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], 0
153 mov dword [ebx + 0ch], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
158 ;-------------------------------------------------------------------------------------
159 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
160 ;about to become an AP. It switches it'stack with the current AP.
161 ;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
162 ;-------------------------------------------------------------------------------------
163 global ASM_PFX(AsmExchangeRole)
164 ASM_PFX(AsmExchangeRole):
165 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
166 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
170 ; esi contains MyInfo pointer
173 ; edi contains OthersInfo pointer
176 ;Store EFLAGS, GDTR and IDTR register to stack
179 push eax ; push cr4 firstly
186 ; Store the its StackPointer
189 ; update its switch state to STORED
190 mov byte [esi], CPU_SWITCH_STATE_STORED
193 ; wait until the other CPU finish storing its state
194 cmp byte [edi], CPU_SWITCH_STATE_STORED
197 jmp WaitForOtherStored
200 ; Since another CPU already stored its state, load them
207 ; load its future StackPointer
210 ; update the other CPU's switch state to LOADED
211 mov byte [edi], CPU_SWITCH_STATE_LOADED
214 ; wait until the other CPU finish loading new state,
215 ; otherwise the data in stack may corrupt
216 cmp byte [esi], CPU_SWITCH_STATE_LOADED
219 jmp WaitForOtherLoaded
222 ; since the other CPU already get the data it want, leave this procedure
232 global ASM_PFX(AsmInitializeGdt)
233 ASM_PFX(AsmInitializeGdt):
237 mov edi, [ebp + 8] ; Load GDT register
239 lgdt [edi] ; and update the GDTR
242 mov eax, ASM_PFX(SetCodeSelectorFarJump)
245 ASM_PFX(SetCodeSelectorFarJump):
246 mov ax, PROTECT_MODE_DS ; Update the Base for the new selectors, too