]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/CpuMpPei/X64/MpFuncs.nasm
UefiCpuPkg/CpuMpPei: Update files format to DOS
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / X64 / MpFuncs.nasm
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"
22 extern ASM_PFX(InitializeFloatingPointUnits)
23
24 DEFAULT REL
25
26 SECTION .text
27
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 ;-------------------------------------------------------------------------------------
35 global ASM_PFX(RendezvousFunnelProc)
36 ASM_PFX(RendezvousFunnelProc):
37 RendezvousFunnelProcStart:
38 ; At this point CS = 0x(vv00) and ip= 0x0.
39 ; Save BIST information to ebp firstly
40 BITS 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
75 o32 lgdt [cs:si]
76
77 mov si, IdtrLocation
78 o32 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
89 BITS 32
90 Flat32Start: ; 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
115 BITS 64
116 LongModeStart:
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
127 TestLock:
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
137 ProgramStack:
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
147 Releaselock:
148 mov rax, VacantFlag
149 mov edi, esi
150 add edi, LockLocation
151 xchg qword [edi], rax
152
153 CProcedureInvoke:
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
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
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
176 RendezvousFunnelProcEnd:
177
178 global ASM_PFX(AsmCliHltLoop)
179 ASM_PFX(AsmCliHltLoop):
180 cli
181 hlt
182 jmp $-2
183
184 ;-------------------------------------------------------------------------------------
185 ; AsmGetAddressMap (&AddressMap);
186 ;-------------------------------------------------------------------------------------
187 global ASM_PFX(AsmGetAddressMap)
188 ASM_PFX(AsmGetAddressMap):
189 mov rax, ASM_PFX(RendezvousFunnelProc)
190 mov qword [rcx], rax
191 mov qword [rcx + 8h], Flat32Start - RendezvousFunnelProcStart
192 mov qword [rcx + 10h], LongModeStart - RendezvousFunnelProcStart
193 mov qword [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
194 ret
195
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 ;-------------------------------------------------------------------------------------
201 global ASM_PFX(AsmExchangeRole)
202 ASM_PFX(AsmExchangeRole):
203 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
204 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
205
206 push rax
207 push rbx
208 push rcx
209 push rdx
210 push rsi
211 push rdi
212 push rbp
213 push r8
214 push r9
215 push r10
216 push r11
217 push r12
218 push r13
219 push r14
220 push r15
221
222 mov rax, cr0
223 push rax
224
225 mov rax, cr4
226 push rax
227
228 ; rsi contains MyInfo pointer
229 mov rsi, rcx
230
231 ; rdi contains OthersInfo pointer
232 mov rdi, rdx
233
234 ;Store EFLAGS, GDTR and IDTR regiter to stack
235 pushfq
236 sgdt [rsi + 16]
237 sidt [rsi + 26]
238
239 ; Store the its StackPointer
240 mov [rsi + 8], rsp
241
242 ; update its switch state to STORED
243 mov byte [rsi], CPU_SWITCH_STATE_STORED
244
245 WaitForOtherStored:
246 ; wait until the other CPU finish storing its state
247 cmp byte [rdi], CPU_SWITCH_STATE_STORED
248 jz OtherStored
249 pause
250 jmp WaitForOtherStored
251
252 OtherStored:
253 ; Since another CPU already stored its state, load them
254 ; load GDTR value
255 lgdt [rdi + 16]
256
257 ; load IDTR value
258 lidt [rdi + 26]
259
260 ; load its future StackPointer
261 mov rsp, [rdi + 8]
262
263 ; update the other CPU's switch state to LOADED
264 mov byte [rdi], CPU_SWITCH_STATE_LOADED
265
266 WaitForOtherLoaded:
267 ; wait until the other CPU finish loading new state,
268 ; otherwise the data in stack may corrupt
269 cmp byte [rsi], CPU_SWITCH_STATE_LOADED
270 jz OtherLoaded
271 pause
272 jmp WaitForOtherLoaded
273
274 OtherLoaded:
275 ; since the other CPU already get the data it want, leave this procedure
276 popfq
277
278 pop rax
279 mov cr4, rax
280
281 pop rax
282 mov cr0, rax
283
284 pop r15
285 pop r14
286 pop r13
287 pop r12
288 pop r11
289 pop r10
290 pop r9
291 pop r8
292 pop rbp
293 pop rdi
294 pop rsi
295 pop rdx
296 pop rcx
297 pop rbx
298 pop rax
299
300 ret
301
302 global ASM_PFX(AsmInitializeGdt)
303 ASM_PFX(AsmInitializeGdt):
304 push rbp
305 mov rbp, rsp
306
307 lgdt [rcx] ; update the GDTR
308
309 sub rsp, 0x10
310 mov rax, ASM_PFX(SetCodeSelectorFarJump)
311 mov [rsp], rax
312 mov rdx, LONG_MODE_CS
313 mov [rsp + 4], dx ; get new CS
314 jmp far dword [rsp] ; far jump with new CS
315 ASM_PFX(SetCodeSelectorFarJump):
316 add rsp, 0x10
317
318 mov rax, LONG_MODE_DS ; get new DS
319 mov ds, ax
320 mov es, ax
321 mov fs, ax
322 mov gs, ax
323 mov ss, ax
324
325 pop rbp
326
327 ret