]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
UefiCpuPkg/CpuMpPei: Add AsmHltLoop ()
[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
fcc82734
JF
184AsmCliHltLoop PROC
185 cli
186 hlt
187 jmp $-2
188AsmCliHltLoop ENDP
189
8018cb15
JF
190;-------------------------------------------------------------------------------------
191; AsmGetAddressMap (&AddressMap);
192;-------------------------------------------------------------------------------------
193AsmGetAddressMap 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
199 ret
200AsmGetAddressMap ENDP
f9d30595 201
3798f351
JF
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;-------------------------------------------------------------------------------------
207AsmExchangeRole PROC
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.
210
211 push rax
212 push rbx
213 push rcx
214 push rdx
215 push rsi
216 push rdi
217 push rbp
218 push r8
219 push r9
220 push r10
221 push r11
222 push r12
223 push r13
224 push r14
225 push r15
226
227 mov rax, cr0
228 push rax
229
230 mov rax, cr4
231 push rax
232
233 ; rsi contains MyInfo pointer
234 mov rsi, rcx
235
236 ; rdi contains OthersInfo pointer
237 mov rdi, rdx
238
239 ;Store EFLAGS, GDTR and IDTR regiter to stack
240 pushfq
241 sgdt fword ptr [rsi + 16]
242 sidt fword ptr [rsi + 26]
243
244 ; Store the its StackPointer
245 mov qword ptr [rsi + 8], rsp
246
247 ; update its switch state to STORED
248 mov byte ptr [rsi], CPU_SWITCH_STATE_STORED
249
250WaitForOtherStored:
251 ; wait until the other CPU finish storing its state
252 cmp byte ptr [rdi], CPU_SWITCH_STATE_STORED
253 jz OtherStored
254 pause
255 jmp WaitForOtherStored
256
257OtherStored:
258 ; Since another CPU already stored its state, load them
259 ; load GDTR value
260 lgdt fword ptr [rdi + 16]
261
262 ; load IDTR value
263 lidt fword ptr [rdi + 26]
264
265 ; load its future StackPointer
266 mov rsp, qword ptr [rdi + 8]
267
268 ; update the other CPU's switch state to LOADED
269 mov byte ptr [rdi], CPU_SWITCH_STATE_LOADED
270
271WaitForOtherLoaded:
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
275 jz OtherLoaded
276 pause
277 jmp WaitForOtherLoaded
278
279OtherLoaded:
280 ; since the other CPU already get the data it want, leave this procedure
281 popfq
282
283 pop rax
284 mov cr4, rax
285
286 pop rax
287 mov cr0, rax
288
289 pop r15
290 pop r14
291 pop r13
292 pop r12
293 pop r11
294 pop r10
295 pop r9
296 pop r8
297 pop rbp
298 pop rdi
299 pop rsi
300 pop rdx
301 pop rcx
302 pop rbx
303 pop rax
304
305 ret
306AsmExchangeRole ENDP
307
f9d30595
JF
308AsmInitializeGdt PROC
309 push rbp
310 mov rbp, rsp
311
312 lgdt fword PTR [rcx] ; update the GDTR
313
314 sub rsp, 0x10
315 lea rax, SetCodeSelectorFarJump
316 mov [rsp], rax
317 mov rdx, LONG_MODE_CS
318 mov [rsp + 4], dx ; get new CS
319 jmp fword ptr [rsp]
320SetCodeSelectorFarJump:
321 add rsp, 0x10
322
323 mov rax, LONG_MODE_DS ; get new DS
324 mov ds, ax
325 mov es, ax
326 mov fs, ax
327 mov gs, ax
328 mov ss, ax
329
330 pop rbp
331 ret
332AsmInitializeGdt ENDP
333
334END