]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/CpuMpPei/X64/MpFuncs.asm
UefiCpuPkg/CpuMpPei: Remove un-used variables and functions
[mirror_edk2.git] / UefiCpuPkg / CpuMpPei / X64 / MpFuncs.asm
CommitLineData
ea0f431c 1;------------------------------------------------------------------------------ ;\r
d1471c01 2; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
ea0f431c
JF
3; This program and the accompanying materials\r
4; are licensed and made available under the terms and conditions of the BSD License\r
5; which accompanies this distribution. The full text of the license may be found at\r
6; http://opensource.org/licenses/bsd-license.php.\r
7;\r
8; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
9; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
10;\r
11; Module Name:\r
12;\r
13; MpFuncs32.asm\r
14;\r
15; Abstract:\r
16;\r
17; This is the assembly code for MP support\r
18;\r
19;-------------------------------------------------------------------------------\r
20\r
21include MpEqu.inc\r
22extern InitializeFloatingPointUnits:PROC\r
23\r
24.code\r
25;-------------------------------------------------------------------------------------\r
26;RendezvousFunnelProc procedure follows. All APs execute their procedure. This\r
27;procedure serializes all the AP processors through an Init sequence. It must be\r
28;noted that APs arrive here very raw...ie: real mode, no stack.\r
29;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r
30;IS IN MACHINE CODE.\r
31;-------------------------------------------------------------------------------------\r
32RendezvousFunnelProc PROC PUBLIC\r
33RendezvousFunnelProcStart::\r
34; At this point CS = 0x(vv00) and ip= 0x0.\r
35; Save BIST information to ebp firstly\r
36 db 66h, 08bh, 0e8h ; mov ebp, eax ; save BIST information\r
37\r
d1471c01
JF
38 db 8ch,0c8h ; mov ax, cs\r
39 db 8eh,0d8h ; mov ds, ax\r
40 db 8eh,0c0h ; mov es, ax\r
41 db 8eh,0d0h ; mov ss, ax\r
42 db 33h,0c0h ; xor ax, ax\r
43 db 8eh,0e0h ; mov fs, ax\r
44 db 8eh,0e8h ; mov gs, ax\r
ea0f431c
JF
45\r
46 db 0BEh ; opcode of mov si, mem16\r
47 dw BufferStartLocation ; mov si, BufferStartLocation\r
d1471c01
JF
48 db 66h, 8Bh, 1Ch ; mov ebx, dword ptr [si]\r
49\r
50 db 0BFh ; opcode of mov di, mem16 \r
51 dw LmodeOffsetLocation ; mov di, LmodeOffsetLocation\r
52 db 66h, 8Bh, 05h ; mov eax, [di]\r
53 db 0BFh ; opcode of mov di, mem16 \r
54 dw CodeSegmentLocation ; mov di, CodeSegmentLocation\r
55 db 66h, 8Bh, 15h ; mov edx, [di]\r
56 db 89h, 0C7h ; mov di, ax\r
57 db 83h, 0EFh, 02h ; sub di, 02h \r
58 db 89h, 15h ; mov [di], dx ; Patch long mode CS\r
59 db 83h, 0EFh, 04h ; sub di, 04h\r
60 db 66h, 01h, 0D8h ; add eax, ebx\r
61 db 66h, 89h, 05h ; mov [di], eax ; Patch address\r
ea0f431c
JF
62\r
63 db 0BEh ; opcode of mov si, mem16\r
64 dw GdtrLocation ; mov si, GdtrLocation\r
65 db 66h ; db 66h\r
66 db 2Eh, 0Fh, 01h, 14h ; lgdt fword ptr cs:[si]\r
67\r
68 db 0BEh\r
69 dw IdtrLocation ; mov si, IdtrLocation\r
70 db 66h ; db 66h\r
71 db 2Eh,0Fh, 01h, 1Ch ; lidt fword ptr cs:[si]\r
72\r
d1471c01
JF
73 db 0BFh ; opcode of mov di, mem16 \r
74 dw DataSegmentLocation ; mov di, DataSegmentLocation\r
75 db 66h, 8Bh, 3Dh ; mov edi, [di] ; Save long mode DS in edi\r
ea0f431c 76\r
d1471c01
JF
77 db 0BEh\r
78 dw Cr3Location ; mov si, Cr3Location\r
79 db 66h, 8Bh, 0Ch ; mov ecx, dword ptr [si] ; ECX is keeping the value of CR3\r
ea0f431c 80\r
d1471c01
JF
81 db 31h, 0C0h ; xor ax, ax\r
82 db 8Eh, 0D8h ; mov ds, ax ; Clear data segment\r
ea0f431c 83\r
d1471c01
JF
84 db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Get control register 0\r
85 db 66h, 83h, 0C8h, 03h ; or eax, 000000003h ; Set PE bit (bit #0) & MP\r
86 db 0Fh, 22h, 0C0h ; mov cr0, eax\r
ea0f431c 87\r
d1471c01
JF
88 db 0Fh, 20h, 0E0h ; mov eax, cr4\r
89 db 66h, 0Fh, 0BAh, 0E8h, 05h ; bts eax, 5\r
90 db 0Fh, 22h, 0E0h ; mov cr4, eax\r
ea0f431c
JF
91\r
92 db 0Fh, 22h, 0D9h ; mov cr3, ecx\r
93\r
d1471c01 94 db 66h, 0B9h\r
ea0f431c
JF
95 dd 0C0000080h ; mov ecx, 0c0000080h ; EFER MSR number.\r
96 db 0Fh, 32h ; rdmsr ; Read EFER.\r
d1471c01 97 db 66h, 0Fh, 0BAh, 0E8h, 08h; bts eax, 8 ; Set LME=1.\r
ea0f431c
JF
98 db 0Fh, 30h ; wrmsr ; Write EFER.\r
99\r
100 db 0Fh, 20h, 0C0h ; mov eax, cr0 ; Read CR0.\r
d1471c01 101 db 66h, 0Fh, 0BAh, 0E8h, 1Fh; bts eax, 31 ; Set PG=1.\r
ea0f431c
JF
102 db 0Fh, 22h, 0C0h ; mov cr0, eax ; Write CR0.\r
103\r
104LONG_JUMP:\r
d1471c01 105 db 66h, 0EAh ; far jump\r
ea0f431c 106 dd 0h ; 32-bit offset\r
d1471c01 107 dw 0h ; 16-bit selector\r
ea0f431c
JF
108\r
109LongModeStart::\r
d1471c01 110 mov eax, edi\r
ea0f431c
JF
111 mov ds, ax\r
112 mov es, ax\r
113 mov ss, ax\r
114\r
115 mov esi, ebx\r
116 mov edi, esi\r
117 add edi, LockLocation\r
118 mov rax, NotVacantFlag\r
119\r
120TestLock:\r
121 xchg qword ptr [edi], rax\r
122 cmp rax, NotVacantFlag\r
123 jz TestLock\r
124\r
125 mov edi, esi\r
126 add edi, NumApsExecutingLoction\r
127 inc dword ptr [edi]\r
128 mov ebx, dword ptr [edi]\r
129\r
130ProgramStack:\r
131 mov edi, esi\r
132 add edi, StackSizeLocation\r
133 mov rax, qword ptr [edi]\r
134 mov edi, esi\r
135 add edi, StackStartAddressLocation\r
136 add rax, qword ptr [edi]\r
137 mov rsp, rax\r
138 mov qword ptr [edi], rax\r
139\r
140Releaselock:\r
141 mov rax, VacantFlag\r
142 mov edi, esi\r
143 add edi, LockLocation\r
144 xchg qword ptr [edi], rax\r
145\r
146CProcedureInvoke:\r
147 push rbp ; push BIST data\r
148 xor rbp, rbp ; clear ebp for call stack trace\r
149 push rbp\r
150 mov rbp, rsp\r
151\r
152 mov rax, InitializeFloatingPointUnits\r
153 sub rsp, 20h\r
154 call rax ; Call assembly function to initialize FPU per UEFI spec\r
155 add rsp, 20h\r
156\r
157 mov edx, ebx ; edx is NumApsExecuting\r
158 mov ecx, esi\r
159 add ecx, LockLocation ; rcx is address of exchange info data buffer\r
160\r
161 mov edi, esi\r
162 add edi, ApProcedureLocation\r
163 mov rax, qword ptr [edi]\r
164\r
165 sub rsp, 20h\r
166 call rax ; invoke C function\r
167 add rsp, 20h\r
168 jmp $\r
169\r
170RendezvousFunnelProc ENDP\r
171RendezvousFunnelProcEnd::\r
172\r
ea0f431c
JF
173;-------------------------------------------------------------------------------------\r
174; AsmGetAddressMap (&AddressMap);\r
175;-------------------------------------------------------------------------------------\r
176AsmGetAddressMap PROC\r
177 mov rax, offset RendezvousFunnelProcStart\r
178 mov qword ptr [rcx], rax\r
d1471c01 179 mov qword ptr [rcx + 8h], 0\r
ea0f431c
JF
180 mov qword ptr [rcx + 10h], LongModeStart - RendezvousFunnelProcStart\r
181 mov qword ptr [rcx + 18h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
182 ret\r
183AsmGetAddressMap ENDP\r
184\r
185;-------------------------------------------------------------------------------------\r
186;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is\r
187;about to become an AP. It switches it'stack with the current AP.\r
188;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);\r
189;-------------------------------------------------------------------------------------\r
190AsmExchangeRole PROC\r
191 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack\r
192 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.\r
193\r
194 push rax\r
195 push rbx\r
196 push rcx\r
197 push rdx\r
198 push rsi\r
199 push rdi\r
200 push rbp\r
201 push r8\r
202 push r9\r
203 push r10\r
204 push r11\r
205 push r12\r
206 push r13\r
207 push r14\r
208 push r15\r
209\r
210 mov rax, cr0\r
211 push rax\r
212\r
213 mov rax, cr4\r
214 push rax\r
215\r
216 ; rsi contains MyInfo pointer\r
217 mov rsi, rcx\r
218\r
219 ; rdi contains OthersInfo pointer\r
220 mov rdi, rdx\r
221\r
222 ;Store EFLAGS, GDTR and IDTR regiter to stack\r
223 pushfq\r
224 sgdt fword ptr [rsi + 16]\r
225 sidt fword ptr [rsi + 26]\r
226\r
227 ; Store the its StackPointer\r
228 mov qword ptr [rsi + 8], rsp\r
229\r
230 ; update its switch state to STORED\r
231 mov byte ptr [rsi], CPU_SWITCH_STATE_STORED\r
232\r
233WaitForOtherStored:\r
234 ; wait until the other CPU finish storing its state\r
235 cmp byte ptr [rdi], CPU_SWITCH_STATE_STORED\r
236 jz OtherStored\r
237 pause\r
238 jmp WaitForOtherStored\r
239\r
240OtherStored:\r
241 ; Since another CPU already stored its state, load them\r
242 ; load GDTR value\r
243 lgdt fword ptr [rdi + 16]\r
244\r
245 ; load IDTR value\r
246 lidt fword ptr [rdi + 26]\r
247\r
248 ; load its future StackPointer\r
249 mov rsp, qword ptr [rdi + 8]\r
250\r
251 ; update the other CPU's switch state to LOADED\r
252 mov byte ptr [rdi], CPU_SWITCH_STATE_LOADED\r
253\r
254WaitForOtherLoaded:\r
255 ; wait until the other CPU finish loading new state,\r
256 ; otherwise the data in stack may corrupt\r
257 cmp byte ptr [rsi], CPU_SWITCH_STATE_LOADED\r
258 jz OtherLoaded\r
259 pause\r
260 jmp WaitForOtherLoaded\r
261\r
262OtherLoaded:\r
263 ; since the other CPU already get the data it want, leave this procedure\r
264 popfq\r
265\r
266 pop rax\r
267 mov cr4, rax\r
268\r
269 pop rax\r
270 mov cr0, rax\r
271\r
272 pop r15\r
273 pop r14\r
274 pop r13\r
275 pop r12\r
276 pop r11\r
277 pop r10\r
278 pop r9\r
279 pop r8\r
280 pop rbp\r
281 pop rdi\r
282 pop rsi\r
283 pop rdx\r
284 pop rcx\r
285 pop rbx\r
286 pop rax\r
287\r
288 ret\r
289AsmExchangeRole ENDP\r
290\r
ea0f431c 291END\r