]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
03e00924fb0cd0b22c0b73fcb8baf5dcc2807980
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / X64 / MpFuncs.asm
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 ; MpFuncs32.asm
14 ;
15 ; Abstract:
16 ;
17 ; This is the assembly code for MP support
18 ;
19 ;-------------------------------------------------------------------------------
20
21 include MpEqu.inc
22 extern InitializeFloatingPointUnits:PROC
23
24 .code
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 ;-------------------------------------------------------------------------------------
32 RendezvousFunnelProc PROC PUBLIC
33 RendezvousFunnelProcStart::
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 LmodeOffsetLocation ; mov di, LmodeOffsetLocation
52 db 66h, 8Bh, 05h ; mov eax, [di]
53 db 0BFh ; opcode of mov di, mem16
54 dw CodeSegmentLocation ; mov di, CodeSegmentLocation
55 db 66h, 8Bh, 15h ; mov edx, [di]
56 db 89h, 0C7h ; mov di, ax
57 db 83h, 0EFh, 02h ; sub di, 02h
58 db 89h, 15h ; mov [di], dx ; Patch long mode CS
59 db 83h, 0EFh, 04h ; sub di, 04h
60 db 66h, 01h, 0D8h ; add eax, ebx
61 db 66h, 89h, 05h ; mov [di], eax ; Patch address
62
63 db 0BEh ; opcode of mov si, mem16
64 dw GdtrLocation ; mov si, GdtrLocation
65 db 66h ; db 66h
66 db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]
67
68 db 0BEh
69 dw IdtrLocation ; mov si, IdtrLocation
70 db 66h ; db 66h
71 db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]
72
73 db 0BFh ; opcode of mov di, mem16
74 dw DataSegmentLocation ; mov di, DataSegmentLocation
75 db 66h, 8Bh, 3Dh ; mov edi, [di] ; Save long mode DS in edi
76
77 db 0BEh
78 dw Cr3Location ; mov si, Cr3Location
79 db 66h, 8Bh, 0Ch ; mov ecx, dword ptr [si] ; ECX is keeping the value of CR3
80
81 db 31h, 0C0h ; xor ax, ax
82 db 8Eh, 0D8h ; mov ds, ax ; Clear data segment
83
84 db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0
85 db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ; Set PE bit (bit #0) & MP
86 db 0Fh, 22h, 0C0h ; mov cr0, eax
87
88 db 0Fh, 20h, 0E0h ; mov eax, cr4
89 db 66h, 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5
90 db 0Fh, 22h, 0E0h ; mov cr4, eax
91
92 db 0Fh, 22h, 0D9h ; mov cr3, ecx
93
94 db 66h, 0B9h
95 dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.
96 db 0Fh, 32h ; rdmsr ; Read EFER.
97 db 66h, 0Fh, 0BAh, 0E8h, 08h; bts eax, 8 ; Set LME=1.
98 db 0Fh, 30h ; wrmsr ; Write EFER.
99
100 db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.
101 db 66h, 0Fh, 0BAh, 0E8h, 1Fh; bts eax, 31 ; Set PG=1.
102 db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.
103
104 LONG_JUMP:
105 db 66h, 0EAh ; far jump
106 dd 0h ; 32-bit offset
107 dw 0h ; 16-bit selector
108
109 LongModeStart::
110 mov eax, edi
111 mov ds, ax
112 mov es, ax
113 mov ss, ax
114
115 mov esi, ebx
116 mov edi, esi
117 add edi, LockLocation
118 mov rax, NotVacantFlag
119
120 TestLock:
121 xchg qword ptr [edi], rax
122 cmp rax, NotVacantFlag
123 jz TestLock
124
125 mov edi, esi
126 add edi, NumApsExecutingLoction
127 inc dword ptr [edi]
128 mov ebx, dword ptr [edi]
129
130 ProgramStack:
131 mov edi, esi
132 add edi, StackSizeLocation
133 mov rax, qword ptr [edi]
134 mov edi, esi
135 add edi, StackStartAddressLocation
136 add rax, qword ptr [edi]
137 mov rsp, rax
138 mov qword ptr [edi], rax
139
140 Releaselock:
141 mov rax, VacantFlag
142 mov edi, esi
143 add edi, LockLocation
144 xchg qword ptr [edi], rax
145
146 CProcedureInvoke:
147 push rbp ; push BIST data
148 xor rbp, rbp ; clear ebp for call stack trace
149 push rbp
150 mov rbp, rsp
151
152 mov rax, InitializeFloatingPointUnits
153 sub rsp, 20h
154 call rax ; Call assembly function to initialize FPU per UEFI spec
155 add rsp, 20h
156
157 mov edx, ebx ; edx is NumApsExecuting
158 mov ecx, esi
159 add ecx, LockLocation ; rcx is address of exchange info data buffer
160
161 mov edi, esi
162 add edi, ApProcedureLocation
163 mov rax, qword ptr [edi]
164
165 sub rsp, 20h
166 call rax ; invoke C function
167 add rsp, 20h
168 jmp $
169
170 RendezvousFunnelProc ENDP
171 RendezvousFunnelProcEnd::
172
173 ;-------------------------------------------------------------------------------------
174 ; AsmGetAddressMap (&AddressMap);
175 ;-------------------------------------------------------------------------------------
176 AsmGetAddressMap PROC
177 mov rax, offset RendezvousFunnelProcStart
178 mov qword ptr [rcx], rax
179 mov qword ptr [rcx + 8h], 0
180 mov qword ptr [rcx + 10h], LongModeStart - RendezvousFunnelProcStart
181 mov qword ptr [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
182 ret
183 AsmGetAddressMap ENDP
184
185 ;-------------------------------------------------------------------------------------
186 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
187 ;about to become an AP. It switches it'stack with the current AP.
188 ;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
189 ;-------------------------------------------------------------------------------------
190 AsmExchangeRole PROC
191 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
192 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
193
194 push rax
195 push rbx
196 push rcx
197 push rdx
198 push rsi
199 push rdi
200 push rbp
201 push r8
202 push r9
203 push r10
204 push r11
205 push r12
206 push r13
207 push r14
208 push r15
209
210 mov rax, cr0
211 push rax
212
213 mov rax, cr4
214 push rax
215
216 ; rsi contains MyInfo pointer
217 mov rsi, rcx
218
219 ; rdi contains OthersInfo pointer
220 mov rdi, rdx
221
222 ;Store EFLAGS, GDTR and IDTR regiter to stack
223 pushfq
224 sgdt fword ptr [rsi + 16]
225 sidt fword ptr [rsi + 26]
226
227 ; Store the its StackPointer
228 mov qword ptr [rsi + 8], rsp
229
230 ; update its switch state to STORED
231 mov byte ptr [rsi], CPU_SWITCH_STATE_STORED
232
233 WaitForOtherStored:
234 ; wait until the other CPU finish storing its state
235 cmp byte ptr [rdi], CPU_SWITCH_STATE_STORED
236 jz OtherStored
237 pause
238 jmp WaitForOtherStored
239
240 OtherStored:
241 ; Since another CPU already stored its state, load them
242 ; load GDTR value
243 lgdt fword ptr [rdi + 16]
244
245 ; load IDTR value
246 lidt fword ptr [rdi + 26]
247
248 ; load its future StackPointer
249 mov rsp, qword ptr [rdi + 8]
250
251 ; update the other CPU's switch state to LOADED
252 mov byte ptr [rdi], CPU_SWITCH_STATE_LOADED
253
254 WaitForOtherLoaded:
255 ; wait until the other CPU finish loading new state,
256 ; otherwise the data in stack may corrupt
257 cmp byte ptr [rsi], CPU_SWITCH_STATE_LOADED
258 jz OtherLoaded
259 pause
260 jmp WaitForOtherLoaded
261
262 OtherLoaded:
263 ; since the other CPU already get the data it want, leave this procedure
264 popfq
265
266 pop rax
267 mov cr4, rax
268
269 pop rax
270 mov cr0, rax
271
272 pop r15
273 pop r14
274 pop r13
275 pop r12
276 pop r11
277 pop r10
278 pop r9
279 pop r8
280 pop rbp
281 pop rdi
282 pop rsi
283 pop rdx
284 pop rcx
285 pop rbx
286 pop rax
287
288 ret
289 AsmExchangeRole ENDP
290
291 END