1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2015, 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 InitializeFloatingPointUnits:PROC
25 ;-------------------------------------------------------------------------------------
26 ;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
27 ;procedure serializes all the AP processors through an Init sequence. It must be
28 ;noted that APs arrive here very raw...ie: real mode, no stack.
29 ;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
31 ;-------------------------------------------------------------------------------------
32 RendezvousFunnelProc PROC PUBLIC
33 RendezvousFunnelProcStart::
34 ; At this point CS = 0x(vv00) and ip= 0x0.
35 ; Save BIST information to ebp firstly
36 db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information
38 db 8ch,0c8h ; mov ax,cs
39 db 8eh,0d8h ; mov ds,ax
40 db 8eh,0c0h ; mov es,ax
41 db 8eh,0d0h ; mov ss,ax
42 db 33h,0c0h ; xor ax,ax
43 db 8eh,0e0h ; mov fs,ax
44 db 8eh,0e8h ; mov gs,ax
46 db 0BEh ; opcode of mov si, mem16
47 dw BufferStartLocation ; mov si, BufferStartLocation
48 db 66h, 8Bh, 1Ch ; mov ebx,dword ptr [si]
50 db 0BFh ; opcode of mov di, mem16
51 dw PmodeOffsetLocation ; mov di, PmodeOffsetLocation
52 db 66h, 8Bh, 05h ; mov eax,dword ptr [di]
53 db 8Bh, 0F8h ; mov di, ax
54 db 83h, 0EFh,06h ; sub di, 06h
55 db 66h, 03h, 0C3h ; add eax, ebx
56 db 66h, 89h, 05h ; mov dword ptr [di],eax
58 db 0BFh ; opcode of mov di, mem16
59 dw LmodeOffsetLocation ; mov di, LmodeOffsetLocation
60 db 66h, 8Bh, 05h ; mov eax,dword ptr [di]
61 db 8Bh, 0F8h ; mov di, ax
62 db 83h, 0EFh,06h ; sub di, 06h
63 db 66h, 03h, 0C3h ; add eax, ebx
64 db 66h, 89h, 05h ; mov dword ptr [di],eax
67 dw Cr3Location ; mov si, Cr3Location
68 db 66h, 8Bh, 0Ch ; mov ecx,dword ptr [si] ; ECX is keeping the value of CR3
70 db 0BEh ; opcode of mov si, mem16
71 dw GdtrLocation ; mov si, GdtrLocation
73 db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
76 dw IdtrLocation ; mov si, IdtrLocation
78 db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
80 db 33h, 0C0h ; xor ax, ax
81 db 8Eh, 0D8h ; mov ds, ax
83 db 0Fh, 20h, 0C0h ; mov eax, cr0 ;Get control register 0
84 db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ;Set PE bit (bit #0) & MP
85 db 0Fh, 22h, 0C0h ; mov cr0, eax
87 db 66h, 67h, 0EAh ; far jump
89 dw PROTECT_MODE_CS ; 16-bit selector
91 Flat32Start:: ; protected mode entry point
92 mov ax, PROTECT_MODE_DS
99 db 0Fh, 20h, 0E0h ; mov eax, cr4
100 db 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5
101 db 0Fh, 22h, 0E0h ; mov cr4, eax
103 db 0Fh, 22h, 0D9h ; mov cr3, ecx
106 dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.
107 db 0Fh, 32h ; rdmsr ; Read EFER.
108 db 0Fh, 0BAh, 0E8h, 08h ; bts eax, 8 ; Set LME=1.
109 db 0Fh, 30h ; wrmsr ; Write EFER.
111 db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.
112 db 0Fh, 0BAh, 0E8h, 1Fh ; bts eax, 31 ; Set PG=1.
113 db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.
116 db 67h, 0EAh ; far jump
117 dd 0h ; 32-bit offset
118 dw LONG_MODE_CS ; 16-bit selector
128 add edi, LockLocation
129 mov rax, NotVacantFlag
132 xchg qword ptr [edi], rax
133 cmp rax, NotVacantFlag
137 add edi, NumApsExecutingLoction
139 mov ebx, dword ptr [edi]
143 add edi, StackSizeLocation
144 mov rax, qword ptr [edi]
146 add edi, StackStartAddressLocation
147 add rax, qword ptr [edi]
149 mov qword ptr [edi], rax
154 add edi, LockLocation
155 xchg qword ptr [edi], rax
158 push rbp ; push BIST data
159 xor rbp, rbp ; clear ebp for call stack trace
163 mov rax, InitializeFloatingPointUnits
165 call rax ; Call assembly function to initialize FPU per UEFI spec
168 mov edx, ebx ; edx is NumApsExecuting
170 add ecx, LockLocation ; rcx is address of exchange info data buffer
173 add edi, ApProcedureLocation
174 mov rax, qword ptr [edi]
177 call rax ; invoke C function
181 RendezvousFunnelProc ENDP
182 RendezvousFunnelProcEnd::
190 ;-------------------------------------------------------------------------------------
191 ; AsmGetAddressMap (&AddressMap);
192 ;-------------------------------------------------------------------------------------
193 AsmGetAddressMap PROC
194 mov rax, offset RendezvousFunnelProcStart
195 mov qword ptr [rcx], rax
196 mov qword ptr [rcx + 8h], Flat32Start - RendezvousFunnelProcStart
197 mov qword ptr [rcx + 10h], LongModeStart - RendezvousFunnelProcStart
198 mov qword ptr [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
200 AsmGetAddressMap ENDP
202 ;-------------------------------------------------------------------------------------
203 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
204 ;about to become an AP. It switches it'stack with the current AP.
205 ;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
206 ;-------------------------------------------------------------------------------------
208 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
209 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
233 ; rsi contains MyInfo pointer
236 ; rdi contains OthersInfo pointer
239 ;Store EFLAGS, GDTR and IDTR regiter to stack
241 sgdt fword ptr [rsi + 16]
242 sidt fword ptr [rsi + 26]
244 ; Store the its StackPointer
245 mov qword ptr [rsi + 8], rsp
247 ; update its switch state to STORED
248 mov byte ptr [rsi], CPU_SWITCH_STATE_STORED
251 ; wait until the other CPU finish storing its state
252 cmp byte ptr [rdi], CPU_SWITCH_STATE_STORED
255 jmp WaitForOtherStored
258 ; Since another CPU already stored its state, load them
260 lgdt fword ptr [rdi + 16]
263 lidt fword ptr [rdi + 26]
265 ; load its future StackPointer
266 mov rsp, qword ptr [rdi + 8]
268 ; update the other CPU's switch state to LOADED
269 mov byte ptr [rdi], CPU_SWITCH_STATE_LOADED
272 ; wait until the other CPU finish loading new state,
273 ; otherwise the data in stack may corrupt
274 cmp byte ptr [rsi], CPU_SWITCH_STATE_LOADED
277 jmp WaitForOtherLoaded
280 ; since the other CPU already get the data it want, leave this procedure
308 AsmInitializeGdt PROC
312 lgdt fword PTR [rcx] ; update the GDTR
315 lea rax, SetCodeSelectorFarJump
317 mov rdx, LONG_MODE_CS
318 mov [rsp + 4], dx ; get new CS
320 SetCodeSelectorFarJump:
323 mov rax, LONG_MODE_DS ; get new DS
332 AsmInitializeGdt ENDP