]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
UefiCpuPkg/CpuMpPei: Implementation of PeiSwitchBSP ()
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / X64 / MpFuncs.asm
CommitLineData
f9d30595
JF
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.
7;
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.
10;
11; Module Name:
12;
13; MpFuncs32.asm
14;
15; Abstract:
16;
17; This is the assembly code for MP support
18;
19;-------------------------------------------------------------------------------
20
21include MpEqu.inc
46ba0f63
JF
22extern InitializeFloatingPointUnits:PROC
23
f9d30595 24.code
34ff8715
JF
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
30;IS IN MACHINE CODE.
31;-------------------------------------------------------------------------------------
32RendezvousFunnelProc PROC PUBLIC
33RendezvousFunnelProcStart::
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
37
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
45
46 db 0BEh ; opcode of mov si, mem16
47 dw BufferStartLocation ; mov si, BufferStartLocation
48 db 66h, 8Bh, 1Ch ; mov ebx,dword ptr [si]
49
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
57
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
65
66 db 0BEh
67 dw Cr3Location ; mov si, Cr3Location
68 db 66h, 8Bh, 0Ch ; mov ecx,dword ptr [si] ; ECX is keeping the value of CR3
69
70 db 0BEh ; opcode of mov si, mem16
71 dw GdtrLocation ; mov si, GdtrLocation
72 db 66h ; db 66h
73 db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
74
75 db 0BEh
76 dw IdtrLocation ; mov si, IdtrLocation
77 db 66h ; db 66h
78 db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
79
80 db 33h, 0C0h ; xor ax, ax
81 db 8Eh, 0D8h ; mov ds, ax
82
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
86
87 db 66h, 67h, 0EAh ; far jump
88 dd 0h ; 32-bit offset
89 dw PROTECT_MODE_CS ; 16-bit selector
90
91Flat32Start:: ; protected mode entry point
92 mov ax, PROTECT_MODE_DS
93 mov ds, ax
94 mov es, ax
95 mov fs, ax
96 mov gs, ax
97 mov ss, ax
98
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
102
103 db 0Fh, 22h, 0D9h ; mov cr3, ecx
104
105 db 0B9h
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.
110
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.
114
115LONG_JUMP:
116 db 67h, 0EAh ; far jump
117 dd 0h ; 32-bit offset
118 dw LONG_MODE_CS ; 16-bit selector
119
120LongModeStart::
121 mov ax, LONG_MODE_DS
122 mov ds, ax
123 mov es, ax
124 mov ss, ax
125
126 mov esi, ebx
127 mov edi, esi
128 add edi, LockLocation
129 mov rax, NotVacantFlag
130
131TestLock:
132 xchg qword ptr [edi], rax
133 cmp rax, NotVacantFlag
134 jz TestLock
135
136 mov edi, esi
137 add edi, NumApsExecutingLoction
138 inc dword ptr [edi]
139 mov ebx, dword ptr [edi]
140
141ProgramStack:
142 mov edi, esi
143 add edi, StackSizeLocation
144 mov rax, qword ptr [edi]
145 mov edi, esi
146 add edi, StackStartAddressLocation
147 add rax, qword ptr [edi]
148 mov rsp, rax
149 mov qword ptr [edi], rax
150
151Releaselock:
152 mov rax, VacantFlag
153 mov edi, esi
154 add edi, LockLocation
155 xchg qword ptr [edi], rax
156
157CProcedureInvoke:
158 push rbp ; push BIST data
159 xor rbp, rbp ; clear ebp for call stack trace
160 push rbp
161 mov rbp, rsp
162
46ba0f63
JF
163 mov rax, InitializeFloatingPointUnits
164 sub rsp, 20h
165 call rax ; Call assembly function to initialize FPU per UEFI spec
166 add rsp, 20h
34ff8715
JF
167
168 mov edx, ebx ; edx is NumApsExecuting
169 mov ecx, esi
170 add ecx, LockLocation ; rcx is address of exchange info data buffer
171
172 mov edi, esi
173 add edi, ApProcedureLocation
174 mov rax, qword ptr [edi]
175
176 sub rsp, 20h
177 call rax ; invoke C function
178 add rsp, 20h
179 jmp $
180
181RendezvousFunnelProc ENDP
182RendezvousFunnelProcEnd::
f9d30595 183
8018cb15
JF
184;-------------------------------------------------------------------------------------
185; AsmGetAddressMap (&AddressMap);
186;-------------------------------------------------------------------------------------
187AsmGetAddressMap PROC
188 mov rax, offset RendezvousFunnelProcStart
189 mov qword ptr [rcx], rax
190 mov qword ptr [rcx + 8h], Flat32Start - RendezvousFunnelProcStart
191 mov qword ptr [rcx + 10h], LongModeStart - RendezvousFunnelProcStart
192 mov qword ptr [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
193 ret
194AsmGetAddressMap ENDP
f9d30595 195
3798f351
JF
196;-------------------------------------------------------------------------------------
197;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
198;about to become an AP. It switches it'stack with the current AP.
199;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
200;-------------------------------------------------------------------------------------
201AsmExchangeRole PROC
202 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
203 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
204
205 push rax
206 push rbx
207 push rcx
208 push rdx
209 push rsi
210 push rdi
211 push rbp
212 push r8
213 push r9
214 push r10
215 push r11
216 push r12
217 push r13
218 push r14
219 push r15
220
221 mov rax, cr0
222 push rax
223
224 mov rax, cr4
225 push rax
226
227 ; rsi contains MyInfo pointer
228 mov rsi, rcx
229
230 ; rdi contains OthersInfo pointer
231 mov rdi, rdx
232
233 ;Store EFLAGS, GDTR and IDTR regiter to stack
234 pushfq
235 sgdt fword ptr [rsi + 16]
236 sidt fword ptr [rsi + 26]
237
238 ; Store the its StackPointer
239 mov qword ptr [rsi + 8], rsp
240
241 ; update its switch state to STORED
242 mov byte ptr [rsi], CPU_SWITCH_STATE_STORED
243
244WaitForOtherStored:
245 ; wait until the other CPU finish storing its state
246 cmp byte ptr [rdi], CPU_SWITCH_STATE_STORED
247 jz OtherStored
248 pause
249 jmp WaitForOtherStored
250
251OtherStored:
252 ; Since another CPU already stored its state, load them
253 ; load GDTR value
254 lgdt fword ptr [rdi + 16]
255
256 ; load IDTR value
257 lidt fword ptr [rdi + 26]
258
259 ; load its future StackPointer
260 mov rsp, qword ptr [rdi + 8]
261
262 ; update the other CPU's switch state to LOADED
263 mov byte ptr [rdi], CPU_SWITCH_STATE_LOADED
264
265WaitForOtherLoaded:
266 ; wait until the other CPU finish loading new state,
267 ; otherwise the data in stack may corrupt
268 cmp byte ptr [rsi], CPU_SWITCH_STATE_LOADED
269 jz OtherLoaded
270 pause
271 jmp WaitForOtherLoaded
272
273OtherLoaded:
274 ; since the other CPU already get the data it want, leave this procedure
275 popfq
276
277 pop rax
278 mov cr4, rax
279
280 pop rax
281 mov cr0, rax
282
283 pop r15
284 pop r14
285 pop r13
286 pop r12
287 pop r11
288 pop r10
289 pop r9
290 pop r8
291 pop rbp
292 pop rdi
293 pop rsi
294 pop rdx
295 pop rcx
296 pop rbx
297 pop rax
298
299 ret
300AsmExchangeRole ENDP
301
f9d30595
JF
302AsmInitializeGdt PROC
303 push rbp
304 mov rbp, rsp
305
306 lgdt fword PTR [rcx] ; update the GDTR
307
308 sub rsp, 0x10
309 lea rax, SetCodeSelectorFarJump
310 mov [rsp], rax
311 mov rdx, LONG_MODE_CS
312 mov [rsp + 4], dx ; get new CS
313 jmp fword ptr [rsp]
314SetCodeSelectorFarJump:
315 add rsp, 0x10
316
317 mov rax, LONG_MODE_DS ; get new DS
318 mov ds, ax
319 mov es, ax
320 mov fs, ax
321 mov gs, ax
322 mov ss, ax
323
324 pop rbp
325 ret
326AsmInitializeGdt ENDP
327
328END