]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
UefiCpuPkg/CpuMpPei: Remove PmodeOffset and LmodeOffset
[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 ModeOffsetLocation ; mov di, ModeOffsetLocation
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], LongModeStart - RendezvousFunnelProcStart
180 mov qword ptr [rcx + 10h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart
181 ret
182 AsmGetAddressMap ENDP
183
184 ;-------------------------------------------------------------------------------------
185 ;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is
186 ;about to become an AP. It switches it'stack with the current AP.
187 ;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);
188 ;-------------------------------------------------------------------------------------
189 AsmExchangeRole PROC
190 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack
191 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.
192
193 push rax
194 push rbx
195 push rcx
196 push rdx
197 push rsi
198 push rdi
199 push rbp
200 push r8
201 push r9
202 push r10
203 push r11
204 push r12
205 push r13
206 push r14
207 push r15
208
209 mov rax, cr0
210 push rax
211
212 mov rax, cr4
213 push rax
214
215 ; rsi contains MyInfo pointer
216 mov rsi, rcx
217
218 ; rdi contains OthersInfo pointer
219 mov rdi, rdx
220
221 ;Store EFLAGS, GDTR and IDTR regiter to stack
222 pushfq
223 sgdt fword ptr [rsi + 16]
224 sidt fword ptr [rsi + 26]
225
226 ; Store the its StackPointer
227 mov qword ptr [rsi + 8], rsp
228
229 ; update its switch state to STORED
230 mov byte ptr [rsi], CPU_SWITCH_STATE_STORED
231
232 WaitForOtherStored:
233 ; wait until the other CPU finish storing its state
234 cmp byte ptr [rdi], CPU_SWITCH_STATE_STORED
235 jz OtherStored
236 pause
237 jmp WaitForOtherStored
238
239 OtherStored:
240 ; Since another CPU already stored its state, load them
241 ; load GDTR value
242 lgdt fword ptr [rdi + 16]
243
244 ; load IDTR value
245 lidt fword ptr [rdi + 26]
246
247 ; load its future StackPointer
248 mov rsp, qword ptr [rdi + 8]
249
250 ; update the other CPU's switch state to LOADED
251 mov byte ptr [rdi], CPU_SWITCH_STATE_LOADED
252
253 WaitForOtherLoaded:
254 ; wait until the other CPU finish loading new state,
255 ; otherwise the data in stack may corrupt
256 cmp byte ptr [rsi], CPU_SWITCH_STATE_LOADED
257 jz OtherLoaded
258 pause
259 jmp WaitForOtherLoaded
260
261 OtherLoaded:
262 ; since the other CPU already get the data it want, leave this procedure
263 popfq
264
265 pop rax
266 mov cr4, rax
267
268 pop rax
269 mov cr0, rax
270
271 pop r15
272 pop r14
273 pop r13
274 pop r12
275 pop r11
276 pop r10
277 pop r9
278 pop r8
279 pop rbp
280 pop rdi
281 pop rsi
282 pop rdx
283 pop rcx
284 pop rbx
285 pop rax
286
287 ret
288 AsmExchangeRole ENDP
289
290 END