]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/MpInitLib/Ia32/MpFuncs.nasm
UefiCpuPkg/MpInitLib: Add InitFlag and CpuInfo in MP_CPU_EXCHANGE_INFO
[mirror_edk2.git] / UefiCpuPkg / Library / MpInitLib / Ia32 / MpFuncs.nasm
CommitLineData
d94e5f67
JF
1;------------------------------------------------------------------------------ ;\r
2; Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>\r
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; MpFuncs.nasm\r
14;\r
15; Abstract:\r
16;\r
17; This is the assembly code for MP support\r
18;\r
19;-------------------------------------------------------------------------------\r
20\r
21%include "MpEqu.inc"\r
22extern ASM_PFX(InitializeFloatingPointUnits)\r
23\r
24SECTION .text\r
25\r
26;-------------------------------------------------------------------------------------\r
27;RendezvousFunnelProc procedure follows. All APs execute their procedure. This\r
28;procedure serializes all the AP processors through an Init sequence. It must be\r
29;noted that APs arrive here very raw...ie: real mode, no stack.\r
30;ALSO THIS PROCEDURE IS EXECUTED BY APs ONLY ON 16 BIT MODE. HENCE THIS PROC\r
31;IS IN MACHINE CODE.\r
32;-------------------------------------------------------------------------------------\r
33global ASM_PFX(RendezvousFunnelProc)\r
34ASM_PFX(RendezvousFunnelProc):\r
35RendezvousFunnelProcStart:\r
36; At this point CS = 0x(vv00) and ip= 0x0.\r
37BITS 16\r
38 mov ebp, eax ; save BIST information\r
39\r
40 mov ax, cs\r
41 mov ds, ax\r
42 mov es, ax\r
43 mov ss, ax\r
44 xor ax, ax\r
45 mov fs, ax\r
46 mov gs, ax\r
47\r
48 mov si, BufferStartLocation\r
49 mov ebx, [si]\r
50\r
51 mov si, ModeOffsetLocation\r
52 mov eax, [si]\r
53 mov si, CodeSegmentLocation\r
54 mov edx, [si]\r
55 mov di, ax\r
56 sub di, 02h\r
57 mov [di], dx\r
58 sub di, 04h\r
59 add eax, ebx\r
60 mov [di],eax\r
61\r
62 mov si, DataSegmentLocation\r
63 mov edx, [si]\r
64\r
65 mov si, GdtrLocation\r
66o32 lgdt [cs:si]\r
67\r
68 mov si, IdtrLocation\r
69o32 lidt [cs:si]\r
70\r
71 xor ax, ax\r
72 mov ds, ax\r
73\r
8396e2dd
JF
74 mov eax, cr0 ; Get control register 0\r
75 or eax, 000000003h ; Set PE bit (bit #0) & MP\r
d94e5f67
JF
76 mov cr0, eax\r
77\r
78 jmp 0:strict dword 0 ; far jump to protected mode\r
79BITS 32\r
80Flat32Start: ; protected mode entry point\r
81 mov ds, dx\r
82 mov es, dx\r
83 mov fs, dx\r
84 mov gs, dx\r
85 mov ss, dx\r
86\r
87 mov esi, ebx\r
5c66d125
JF
88\r
89 mov edi, esi\r
90 add edi, EnableExecuteDisableLocation\r
91 cmp byte [edi], 0\r
92 jz SkipEnableExecuteDisable\r
93\r
94 ;\r
95 ; Enable IA32 PAE execute disable\r
96 ;\r
97\r
98 mov ecx, 0xc0000080\r
99 rdmsr\r
100 bts eax, 11\r
101 wrmsr\r
102\r
103 mov edi, esi\r
104 add edi, Cr3Location\r
105 mov eax, dword [edi]\r
106 mov cr3, eax\r
107\r
108 mov eax, cr4\r
109 bts eax, 5\r
110 mov cr4, eax\r
111\r
112 mov eax, cr0\r
113 bts eax, 31\r
114 mov cr0, eax\r
115\r
116SkipEnableExecuteDisable:\r
117\r
d94e5f67
JF
118 mov edi, esi\r
119 add edi, LockLocation\r
120 mov eax, NotVacantFlag\r
121\r
122TestLock:\r
123 xchg [edi], eax\r
124 cmp eax, NotVacantFlag\r
125 jz TestLock\r
126\r
127 mov edi, esi\r
8396e2dd 128 add edi, NumApsExecutingLocation\r
d94e5f67
JF
129 inc dword [edi]\r
130 mov ebx, [edi]\r
131\r
132ProgramStack:\r
133 mov edi, esi\r
134 add edi, StackSizeLocation\r
135 mov eax, [edi]\r
136 mov edi, esi\r
137 add edi, StackStartAddressLocation\r
138 add eax, [edi]\r
139 mov esp, eax\r
140 mov [edi], eax\r
141\r
142Releaselock:\r
143 mov eax, VacantFlag\r
144 mov edi, esi\r
145 add edi, LockLocation\r
146 xchg [edi], eax\r
147\r
148CProcedureInvoke:\r
149 push ebp ; push BIST data at top of AP stack\r
150 xor ebp, ebp ; clear ebp for call stack trace\r
151 push ebp\r
152 mov ebp, esp\r
153\r
154 mov eax, ASM_PFX(InitializeFloatingPointUnits)\r
155 call eax ; Call assembly function to initialize FPU per UEFI spec\r
156\r
157 push ebx ; Push NumApsExecuting\r
158 mov eax, esi\r
159 add eax, LockLocation\r
160 push eax ; push address of exchange info data buffer\r
161\r
162 mov edi, esi\r
163 add edi, ApProcedureLocation\r
164 mov eax, [edi]\r
165\r
8396e2dd 166 call eax ; Invoke C function\r
d94e5f67 167\r
8396e2dd 168 jmp $ ; Never reach here\r
d94e5f67
JF
169RendezvousFunnelProcEnd:\r
170\r
76157021
JF
171;-------------------------------------------------------------------------------------\r
172; AsmRelocateApLoop (MwaitSupport, ApTargetCState, PmCodeSegment);\r
173;-------------------------------------------------------------------------------------\r
174global ASM_PFX(AsmRelocateApLoop)\r
175ASM_PFX(AsmRelocateApLoop):\r
176AsmRelocateApLoopStart:\r
177 cmp byte [esp + 4], 1\r
178 jnz HltLoop\r
179MwaitLoop:\r
180 mov eax, esp\r
181 xor ecx, ecx\r
182 xor edx, edx\r
183 monitor\r
184 mov eax, [esp + 8] ; Mwait Cx, Target C-State per eax[7:4]\r
185 shl eax, 4\r
186 mwait\r
187 jmp MwaitLoop\r
188HltLoop:\r
189 cli\r
190 hlt\r
191 jmp HltLoop\r
192 ret\r
193AsmRelocateApLoopEnd:\r
194\r
d94e5f67
JF
195;-------------------------------------------------------------------------------------\r
196; AsmGetAddressMap (&AddressMap);\r
197;-------------------------------------------------------------------------------------\r
198global ASM_PFX(AsmGetAddressMap)\r
199ASM_PFX(AsmGetAddressMap):\r
200 pushad\r
201 mov ebp,esp\r
202\r
203 mov ebx, [ebp + 24h]\r
204 mov dword [ebx], RendezvousFunnelProcStart\r
205 mov dword [ebx + 4h], Flat32Start - RendezvousFunnelProcStart\r
206 mov dword [ebx + 8h], RendezvousFunnelProcEnd - RendezvousFunnelProcStart\r
f7f85d83
JF
207 mov dword [ebx + 0Ch], AsmRelocateApLoopStart\r
208 mov dword [ebx + 10h], AsmRelocateApLoopEnd - AsmRelocateApLoopStart\r
d94e5f67
JF
209\r
210 popad\r
211 ret\r
212\r
213;-------------------------------------------------------------------------------------\r
214;AsmExchangeRole procedure follows. This procedure executed by current BSP, that is\r
215;about to become an AP. It switches it'stack with the current AP.\r
216;AsmExchangeRole (IN CPU_EXCHANGE_INFO *MyInfo, IN CPU_EXCHANGE_INFO *OthersInfo);\r
217;-------------------------------------------------------------------------------------\r
218global ASM_PFX(AsmExchangeRole)\r
219ASM_PFX(AsmExchangeRole):\r
220 ; DO NOT call other functions in this function, since 2 CPU may use 1 stack\r
221 ; at the same time. If 1 CPU try to call a function, stack will be corrupted.\r
222 pushad\r
223 mov ebp,esp\r
224\r
225 ; esi contains MyInfo pointer\r
226 mov esi, [ebp + 24h]\r
227\r
228 ; edi contains OthersInfo pointer\r
229 mov edi, [ebp + 28h]\r
230\r
231 ;Store EFLAGS, GDTR and IDTR register to stack\r
232 pushfd\r
233 mov eax, cr4\r
234 push eax ; push cr4 firstly\r
235 mov eax, cr0\r
236 push eax\r
237\r
238 sgdt [esi + 8]\r
239 sidt [esi + 14]\r
240\r
241 ; Store the its StackPointer\r
242 mov [esi + 4],esp\r
243\r
244 ; update its switch state to STORED\r
245 mov byte [esi], CPU_SWITCH_STATE_STORED\r
246\r
247WaitForOtherStored:\r
248 ; wait until the other CPU finish storing its state\r
249 cmp byte [edi], CPU_SWITCH_STATE_STORED\r
250 jz OtherStored\r
251 pause\r
252 jmp WaitForOtherStored\r
253\r
254OtherStored:\r
255 ; Since another CPU already stored its state, load them\r
256 ; load GDTR value\r
257 lgdt [edi + 8]\r
258\r
259 ; load IDTR value\r
260 lidt [edi + 14]\r
261\r
262 ; load its future StackPointer\r
263 mov esp, [edi + 4]\r
264\r
265 ; update the other CPU's switch state to LOADED\r
266 mov byte [edi], CPU_SWITCH_STATE_LOADED\r
267\r
268WaitForOtherLoaded:\r
269 ; wait until the other CPU finish loading new state,\r
270 ; otherwise the data in stack may corrupt\r
271 cmp byte [esi], CPU_SWITCH_STATE_LOADED\r
272 jz OtherLoaded\r
273 pause\r
274 jmp WaitForOtherLoaded\r
275\r
276OtherLoaded:\r
277 ; since the other CPU already get the data it want, leave this procedure\r
278 pop eax\r
279 mov cr0, eax\r
280 pop eax\r
281 mov cr4, eax\r
282 popfd\r
283\r
284 popad\r
285 ret\r