]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm
Remove CPU dead loop code from IA32 assembly codes.
[mirror_edk2.git] / UefiCpuPkg / CpuDxe / Ia32 / CpuAsm.asm
CommitLineData
a47463f2 1 TITLE CpuAsm.asm:\r
2;------------------------------------------------------------------------------\r
3;*\r
139259bc 4;* Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
01a1c0fc 5;* This program and the accompanying materials\r
a47463f2 6;* are licensed and made available under the terms and conditions of the BSD License\r
7;* which accompanies this distribution. The full text of the license may be found at\r
8;* http://opensource.org/licenses/bsd-license.php\r
9;*\r
10;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12;*\r
13;* CpuAsm.asm\r
14;*\r
15;* Abstract:\r
16;*\r
17;------------------------------------------------------------------------------\r
18\r
19 .686\r
20 .model flat,C\r
21 .code\r
22\r
23EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions\r
24\r
25;\r
26; point to the external interrupt vector table\r
27;\r
28ExternalVectorTablePtr DWORD 0\r
29\r
30InitializeExternalVectorTablePtr PROC PUBLIC\r
31 mov eax, [esp+4]\r
32 mov ExternalVectorTablePtr, eax\r
33 ret\r
34InitializeExternalVectorTablePtr ENDP\r
35\r
36;------------------------------------------------------------------------------\r
37; VOID\r
38; SetCodeSelector (\r
39; UINT16 Selector\r
40; );\r
41;------------------------------------------------------------------------------\r
42SetCodeSelector PROC PUBLIC\r
43 mov ecx, [esp+4]\r
44 sub esp, 0x10\r
45 lea eax, setCodeSelectorLongJump\r
46 mov [esp], eax\r
47 mov [esp+4], cx\r
48 jmp fword ptr [esp]\r
49setCodeSelectorLongJump:\r
50 add esp, 0x10\r
51 ret\r
52SetCodeSelector ENDP\r
53\r
54;------------------------------------------------------------------------------\r
55; VOID\r
56; SetDataSelectors (\r
57; UINT16 Selector\r
58; );\r
59;------------------------------------------------------------------------------\r
60SetDataSelectors PROC PUBLIC\r
61 mov ecx, [esp+4]\r
62 mov ss, cx\r
63 mov ds, cx\r
64 mov es, cx\r
65 mov fs, cx\r
66 mov gs, cx\r
67 ret\r
68SetDataSelectors ENDP\r
69\r
70;---------------------------------------;\r
71; CommonInterruptEntry ;\r
72;---------------------------------------;\r
73; The follow algorithm is used for the common interrupt routine.\r
74\r
75CommonInterruptEntry PROC PUBLIC\r
76 cli\r
77 ;\r
78 ; All interrupt handlers are invoked through interrupt gates, so\r
79 ; IF flag automatically cleared at the entry point\r
80 ;\r
81\r
82 ;\r
83 ; Calculate vector number\r
84 ;\r
85 ; Get the return address of call, actually, it is the\r
86 ; address of vector number.\r
87 ;\r
88 xchg ecx, [esp]\r
89 mov cx, [ecx]\r
90 and ecx, 0FFFFh\r
91 cmp ecx, 32 ; Intel reserved vector for exceptions?\r
92 jae NoErrorCode\r
93 bt mErrorCodeFlag, ecx\r
94 jc HasErrorCode\r
95\r
96NoErrorCode:\r
97\r
98 ;\r
99 ; Stack:\r
100 ; +---------------------+\r
101 ; + EFlags +\r
102 ; +---------------------+\r
103 ; + CS +\r
104 ; +---------------------+\r
105 ; + EIP +\r
106 ; +---------------------+\r
107 ; + ECX +\r
108 ; +---------------------+ <-- ESP\r
109 ;\r
110 ; Registers:\r
111 ; ECX - Vector Number\r
112 ;\r
113\r
114 ;\r
115 ; Put Vector Number on stack\r
116 ;\r
117 push ecx\r
118\r
119 ;\r
120 ; Put 0 (dummy) error code on stack, and restore ECX\r
121 ;\r
122 xor ecx, ecx ; ECX = 0\r
123 xchg ecx, [esp+4]\r
124\r
125 jmp ErrorCodeAndVectorOnStack\r
126\r
127HasErrorCode:\r
128\r
129 ;\r
130 ; Stack:\r
131 ; +---------------------+\r
132 ; + EFlags +\r
133 ; +---------------------+\r
134 ; + CS +\r
135 ; +---------------------+\r
136 ; + EIP +\r
137 ; +---------------------+\r
138 ; + Error Code +\r
139 ; +---------------------+\r
140 ; + ECX +\r
141 ; +---------------------+ <-- ESP\r
142 ;\r
143 ; Registers:\r
144 ; ECX - Vector Number\r
145 ;\r
146\r
147 ;\r
148 ; Put Vector Number on stack and restore ECX\r
149 ;\r
150 xchg ecx, [esp]\r
151\r
a47463f2 152ErrorCodeAndVectorOnStack:\r
153 push ebp\r
154 mov ebp, esp\r
155\r
156 ;\r
157 ; Stack:\r
158 ; +---------------------+\r
159 ; + EFlags +\r
160 ; +---------------------+\r
161 ; + CS +\r
162 ; +---------------------+\r
163 ; + EIP +\r
164 ; +---------------------+\r
165 ; + Error Code +\r
166 ; +---------------------+\r
167 ; + Vector Number +\r
168 ; +---------------------+\r
169 ; + EBP +\r
170 ; +---------------------+ <-- EBP\r
171 ;\r
172\r
173 ;\r
174 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
175 ; is 16-byte aligned\r
176 ;\r
177 and esp, 0fffffff0h\r
178 sub esp, 12\r
179\r
180;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
181 push eax\r
182 push ecx\r
183 push edx\r
184 push ebx\r
185 lea ecx, [ebp + 6 * 4]\r
186 push ecx ; ESP\r
187 push dword ptr [ebp] ; EBP\r
188 push esi\r
189 push edi\r
190\r
191;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
192 mov eax, ss\r
193 push eax\r
194 movzx eax, word ptr [ebp + 4 * 4]\r
195 push eax\r
196 mov eax, ds\r
197 push eax\r
198 mov eax, es\r
199 push eax\r
200 mov eax, fs\r
201 push eax\r
202 mov eax, gs\r
203 push eax\r
204\r
205;; UINT32 Eip;\r
206 mov eax, [ebp + 3 * 4]\r
207 push eax\r
208\r
209;; UINT32 Gdtr[2], Idtr[2];\r
210 sub esp, 8\r
211 sidt [esp]\r
212 mov eax, [esp + 2]\r
213 xchg eax, [esp]\r
214 and eax, 0FFFFh\r
215 mov [esp+4], eax\r
216\r
217 sub esp, 8\r
218 sgdt [esp]\r
219 mov eax, [esp + 2]\r
220 xchg eax, [esp]\r
221 and eax, 0FFFFh\r
222 mov [esp+4], eax\r
223\r
224;; UINT32 Ldtr, Tr;\r
225 xor eax, eax\r
226 str ax\r
227 push eax\r
228 sldt ax\r
229 push eax\r
230\r
231;; UINT32 EFlags;\r
232 mov eax, [ebp + 5 * 4]\r
233 push eax\r
234\r
235;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
236 mov eax, cr4\r
237 or eax, 208h\r
238 mov cr4, eax\r
239 push eax\r
240 mov eax, cr3\r
241 push eax\r
242 mov eax, cr2\r
243 push eax\r
244 xor eax, eax\r
245 push eax\r
246 mov eax, cr0\r
247 push eax\r
248\r
249;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
250 mov eax, dr7\r
251 push eax\r
a47463f2 252 mov eax, dr6\r
253 push eax\r
a47463f2 254 mov eax, dr3\r
255 push eax\r
256 mov eax, dr2\r
257 push eax\r
258 mov eax, dr1\r
259 push eax\r
260 mov eax, dr0\r
261 push eax\r
262\r
263;; FX_SAVE_STATE_IA32 FxSaveState;\r
264 sub esp, 512\r
265 mov edi, esp\r
266 db 0fh, 0aeh, 07h ;fxsave [edi]\r
267\r
ad8cbf71 268;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
269 cld\r
270\r
a47463f2 271;; UINT32 ExceptionData;\r
272 push dword ptr [ebp + 2 * 4]\r
273\r
274;; call into exception handler\r
275 mov eax, ExternalVectorTablePtr ; get the interrupt vectors base\r
276 or eax, eax ; NULL?\r
277 jz nullExternalExceptionHandler\r
278\r
279 mov ecx, [ebp + 4]\r
280 mov eax, [eax + ecx * 4]\r
281 or eax, eax ; NULL?\r
282 jz nullExternalExceptionHandler\r
283\r
284;; Prepare parameter and call\r
285 mov edx, esp\r
286 push edx\r
287 mov edx, dword ptr [ebp + 1 * 4]\r
288 push edx\r
289\r
290 ;\r
291 ; Call External Exception Handler\r
292 ;\r
293 call eax\r
294 add esp, 8\r
295\r
296nullExternalExceptionHandler:\r
297\r
298 cli\r
299;; UINT32 ExceptionData;\r
300 add esp, 4\r
301\r
302;; FX_SAVE_STATE_IA32 FxSaveState;\r
303 mov esi, esp\r
304 db 0fh, 0aeh, 0eh ; fxrstor [esi]\r
305 add esp, 512\r
306\r
307;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
61ece967 308;; Skip restoration of DRx registers to support in-circuit emualators\r
309;; or debuggers set breakpoint in interrupt/exception context\r
310 add esp, 4 * 6\r
a47463f2 311\r
312;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
313 pop eax\r
314 mov cr0, eax\r
315 add esp, 4 ; not for Cr1\r
316 pop eax\r
317 mov cr2, eax\r
318 pop eax\r
319 mov cr3, eax\r
320 pop eax\r
321 mov cr4, eax\r
322\r
323;; UINT32 EFlags;\r
324 pop dword ptr [ebp + 5 * 4]\r
325\r
326;; UINT32 Ldtr, Tr;\r
327;; UINT32 Gdtr[2], Idtr[2];\r
328;; Best not let anyone mess with these particular registers...\r
329 add esp, 24\r
330\r
331;; UINT32 Eip;\r
332 pop dword ptr [ebp + 3 * 4]\r
333\r
334;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
335;; NOTE - modified segment registers could hang the debugger... We\r
336;; could attempt to insulate ourselves against this possibility,\r
337;; but that poses risks as well.\r
338;;\r
339 pop gs\r
340 pop fs\r
341 pop es\r
342 pop ds\r
343 pop dword ptr [ebp + 4 * 4]\r
344 pop ss\r
345\r
346;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
347 pop edi\r
348 pop esi\r
349 add esp, 4 ; not for ebp\r
350 add esp, 4 ; not for esp\r
351 pop ebx\r
352 pop edx\r
353 pop ecx\r
354 pop eax\r
355\r
356 mov esp, ebp\r
357 pop ebp\r
358 add esp, 8\r
359 iretd\r
360\r
361CommonInterruptEntry ENDP\r
362\r
363END\r