]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm
UefiCpuPkg/CpuMpPei: Implementation of PeiSwitchBSP ()
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / X64 / MpFuncs.nasm
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; MpFuncs.nasm
14;
15; Abstract:
16;
17; This is the assembly code for MP support
18;
19;-------------------------------------------------------------------------------
20
21%include "MpEqu.inc"
46ba0f63 22extern ASM_PFX(InitializeFloatingPointUnits)
34ff8715 23
f9d30595 24DEFAULT REL
34ff8715 25
f9d30595
JF
26SECTION .text
27
34ff8715
JF
28;-------------------------------------------------------------------------------------
29;RendezvousFunnelProc procedure follows. All APs execute their procedure. This
30;procedure serializes all the AP processors through an Init sequence. It must be
31;noted that APs arrive here very raw...ie: real mode, no stack.
32;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC
33;IS IN MACHINE CODE.
34;-------------------------------------------------------------------------------------
35global ASM_PFX(RendezvousFunnelProc)
36ASM_PFX(RendezvousFunnelProc):
37RendezvousFunnelProcStart:
38; At this point CS = 0x(vv00) and ip= 0x0.
39; Save BIST information to ebp firstly
40BITS 16
41
42 mov eax, 1234h
43 mov ebp, eax ; save BIST information
44
45 mov ax, cs
46 mov ds, ax
47 mov es, ax
48 mov ss, ax
49 xor ax, ax
50 mov fs, ax
51 mov gs, ax
52
53 mov si, BufferStartLocation
54 mov ebx, [si]
55
56 mov di, PmodeOffsetLocation
57 mov eax, [di]
58 mov di, ax
59 sub di, 06h
60 add eax, ebx
61 mov [di],eax
62
63 mov di, LmodeOffsetLocation
64 mov eax, [di]
65 mov di, ax
66 sub di, 06h
67 add eax, ebx
68 mov [di],eax
69
70
71 mov si, Cr3Location
72 mov ecx,[si] ; ECX is keeping the value of CR3
73
74 mov si, GdtrLocation
75o32 lgdt [cs:si]
76
77 mov si, IdtrLocation
78o32 lidt [cs:si]
79
80
81 xor ax, ax
82 mov ds, ax
83
84 mov eax, cr0 ;Get control register 0
85 or eax, 000000003h ;Set PE bit (bit #0) & MP
86 mov cr0, eax
87
88 jmp PROTECT_MODE_CS:strict dword 0 ; far jump to protected mode
89BITS 32
90Flat32Start: ; protected mode entry point
91 mov ax, PROTECT_MODE_DS
92 mov ds, ax
93 mov es, ax
94 mov fs, ax
95 mov gs, ax
96 mov ss, ax
97
98 mov eax, cr4
99 bts eax, 5
100 mov cr4, eax
101
102 mov cr3, ecx
103
104
105 mov ecx, 0c0000080h ; EFER MSR number.
106 rdmsr ; Read EFER.
107 bts eax, 8 ; Set LME=1.
108 wrmsr ; Write EFER.
109
110 mov eax, cr0 ; Read CR0.
111 bts eax, 31 ; Set PG=1.
112 mov cr0, eax ; Write CR0.
113
114 jmp LONG_MODE_CS:strict dword 0 ; far jump to long mode
115BITS 64
116LongModeStart:
117 mov ax, LONG_MODE_DS
118 mov ds, ax
119 mov es, ax
120 mov ss, ax
121
122 mov esi, ebx
123 mov edi, esi
124 add edi, LockLocation
125 mov rax, NotVacantFlag
126
127TestLock:
128 xchg qword [edi], rax
129 cmp rax, NotVacantFlag
130 jz TestLock
131
132 mov edi, esi
133 add edi, NumApsExecutingLoction
134 inc dword [edi]
135 mov ebx, [edi]
136
137ProgramStack:
138 mov edi, esi
139 add edi, StackSizeLocation
140 mov rax, qword [edi]
141 mov edi, esi
142 add edi, StackStartAddressLocation
143 add rax, qword [edi]
144 mov rsp, rax
145 mov qword [edi], rax
146
147Releaselock:
148 mov rax, VacantFlag
149 mov edi, esi
150 add edi, LockLocation
151 xchg qword [edi], rax
152
153CProcedureInvoke:
154 push rbp ; push BIST data at top of AP stack
155 xor rbp, rbp ; clear ebp for call stack trace
156 push rbp
157 mov rbp, rsp
158
46ba0f63
JF
159 mov rax, ASM_PFX(InitializeFloatingPointUnits)
160 sub rsp, 20h
161 call rax ; Call assembly function to initialize FPU per UEFI spec
162 add rsp, 20h
34ff8715
JF
163
164 mov edx, ebx ; edx is NumApsExecuting
165 mov ecx, esi
166 add ecx, LockLocation ; rcx is address of exchange info data buffer
167
168 mov edi, esi
169 add edi, ApProcedureLocation
170 mov rax, qword [edi]
171
172 sub rsp, 20h
173 call rax ; invoke C function
174 add rsp, 20h
175
176RendezvousFunnelProcEnd:
177
8018cb15
JF
178;-------------------------------------------------------------------------------------
179; AsmGetAddressMap (&AddressMap);
180;-------------------------------------------------------------------------------------
181global ASM_PFX(AsmGetAddressMap)
182ASM_PFX(AsmGetAddressMap):
183 mov rax, ASM_PFX(RendezvousFunnelProc)
184 mov qword [rcx], rax
185 mov qword [rcx + 8h], Flat32Start - RendezvousFunnelProcStart
186 mov qword [rcx + 10h], LongModeStart - RendezvousFunnelProcStart
187 mov qword [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
188 ret
34ff8715 189
3798f351
JF
190;-------------------------------------------------------------------------------------
191;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
192;about to become an AP. It switches it'stack with the current AP.
193;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
194;-------------------------------------------------------------------------------------
195global ASM_PFX(AsmExchangeRole)
196ASM_PFX(AsmExchangeRole):
197 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
198 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
199
200 push rax
201 push rbx
202 push rcx
203 push rdx
204 push rsi
205 push rdi
206 push rbp
207 push r8
208 push r9
209 push r10
210 push r11
211 push r12
212 push r13
213 push r14
214 push r15
215
216 mov rax, cr0
217 push rax
218
219 mov rax, cr4
220 push rax
221
222 ; rsi contains MyInfo pointer
223 mov rsi, rcx
224
225 ; rdi contains OthersInfo pointer
226 mov rdi, rdx
227
228 ;Store EFLAGS, GDTR and IDTR regiter to stack
229 pushfq
230 sgdt [rsi + 16]
231 sidt [rsi + 26]
232
233 ; Store the its StackPointer
234 mov [rsi + 8], rsp
235
236 ; update its switch state to STORED
237 mov byte [rsi], CPU_SWITCH_STATE_STORED
238
239WaitForOtherStored:
240 ; wait until the other CPU finish storing its state
241 cmp byte [rdi], CPU_SWITCH_STATE_STORED
242 jz OtherStored
243 pause
244 jmp WaitForOtherStored
245
246OtherStored:
247 ; Since another CPU already stored its state, load them
248 ; load GDTR value
249 lgdt [rdi + 16]
250
251 ; load IDTR value
252 lidt [rdi + 26]
253
254 ; load its future StackPointer
255 mov rsp, [rdi + 8]
256
257 ; update the other CPU's switch state to LOADED
258 mov byte [rdi], CPU_SWITCH_STATE_LOADED
259
260WaitForOtherLoaded:
261 ; wait until the other CPU finish loading new state,
262 ; otherwise the data in stack may corrupt
263 cmp byte [rsi], CPU_SWITCH_STATE_LOADED
264 jz OtherLoaded
265 pause
266 jmp WaitForOtherLoaded
267
268OtherLoaded:
269 ; since the other CPU already get the data it want, leave this procedure
270 popfq
271
272 pop rax
273 mov cr4, rax
274
275 pop rax
276 mov cr0, rax
277
278 pop r15
279 pop r14
280 pop r13
281 pop r12
282 pop r11
283 pop r10
284 pop r9
285 pop r8
286 pop rbp
287 pop rdi
288 pop rsi
289 pop rdx
290 pop rcx
291 pop rbx
292 pop rax
293
294 ret
295
f9d30595
JF
296global ASM_PFX(AsmInitializeGdt)
297ASM_PFX(AsmInitializeGdt):
298 push rbp
299 mov rbp, rsp
300
301 lgdt [rcx] ; update the GDTR
302
303 sub rsp, 0x10
304 mov rax, ASM_PFX(SetCodeSelectorFarJump)
305 mov [rsp], rax
306 mov rdx, LONG_MODE_CS
307 mov [rsp + 4], dx ; get new CS
308 jmp far dword [rsp] ; far jump with new CS
309ASM_PFX(SetCodeSelectorFarJump):
310 add rsp, 0x10
311
312 mov rax, LONG_MODE_DS ; get new DS
313 mov ds, ax
314 mov es, ax
315 mov fs, ax
316 mov gs, ax
317 mov ss, ax
318
319 pop rbp
320
321 ret