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