]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
SourceLevelDebugPkg: Remove X86 ASM and S files
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / Ia32 / ExceptionHandlerAsm.asm
CommitLineData
8f07f895 1;------------------------------------------------------------------------------ ;\r
087c67d0 2; Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.<BR>\r
8f07f895 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; ExceptionHandlerAsm.Asm\r
14;\r
15; Abstract:\r
16;\r
17; IA32 CPU Exception Handler\r
18;\r
19; Notes:\r
20;\r
21;------------------------------------------------------------------------------\r
22\r
23 .686\r
24 .model flat,C\r
25\r
26;\r
27; CommonExceptionHandler()\r
28;\r
29CommonExceptionHandler PROTO C\r
30\r
31.data\r
32\r
e41aad15
JF
33EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions\r
34EXTRN mDoFarReturnFlag:DWORD ; Do far return flag\r
8f07f895 35\r
36.code\r
37\r
e41aad15
JF
38ALIGN 8\r
39\r
8f07f895 40;\r
41; exception handler stub table\r
42;\r
e41aad15
JF
43AsmIdtVectorBegin:\r
44REPEAT 32\r
45 db 6ah ; push #VectorNum\r
46 db ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum\r
47 push eax\r
48 mov eax, CommonInterruptEntry\r
49 jmp eax\r
50ENDM\r
51AsmIdtVectorEnd:\r
52\r
53HookAfterStubBegin:\r
54 db 6ah ; push\r
55VectorNum:\r
dd563742 56 db 0 ; 0 will be fixed\r
e41aad15
JF
57 push eax\r
58 mov eax, HookAfterStubHeaderEnd\r
59 jmp eax\r
60HookAfterStubHeaderEnd:\r
61 pop eax\r
62 sub esp, 8 ; reserve room for filling exception data later\r
63 push [esp + 8]\r
64 xchg ecx, [esp] ; get vector number\r
65 bt mErrorCodeFlag, ecx\r
66 jnc @F\r
67 push [esp] ; addition push if exception data needed\r
68@@:\r
69 xchg ecx, [esp] ; restore ecx\r
70 push eax\r
8f07f895 71\r
72;----------------------------------------------------------------------------;\r
73; CommonInterruptEntry ;\r
74;----------------------------------------------------------------------------;\r
75; The follow algorithm is used for the common interrupt routine.\r
76; Entry from each interrupt with a push eax and eax=interrupt number\r
e41aad15
JF
77; Stack:\r
78; +---------------------+\r
79; + EFlags +\r
80; +---------------------+\r
81; + CS +\r
82; +---------------------+\r
83; + EIP +\r
84; +---------------------+\r
85; + Error Code +\r
86; +---------------------+\r
87; + Vector Number +\r
88; +---------------------+\r
89; + EBP +\r
90; +---------------------+ <-- EBP\r
8f07f895 91CommonInterruptEntry PROC PUBLIC\r
92 cli\r
e41aad15 93 pop eax\r
8f07f895 94 ;\r
95 ; All interrupt handlers are invoked through interrupt gates, so\r
96 ; IF flag automatically cleared at the entry point\r
97 ;\r
98\r
99 ;\r
e41aad15 100 ; Get vector number from top of stack\r
8f07f895 101 ;\r
102 xchg ecx, [esp]\r
e41aad15 103 and ecx, 0FFh ; Vector number should be less than 256\r
8f07f895 104 cmp ecx, 32 ; Intel reserved vector for exceptions?\r
105 jae NoErrorCode\r
106 bt mErrorCodeFlag, ecx\r
107 jc HasErrorCode\r
108\r
109NoErrorCode:\r
110\r
111 ;\r
112 ; Stack:\r
113 ; +---------------------+\r
114 ; + EFlags +\r
115 ; +---------------------+\r
116 ; + CS +\r
117 ; +---------------------+\r
118 ; + EIP +\r
119 ; +---------------------+\r
120 ; + ECX +\r
121 ; +---------------------+ <-- ESP\r
122 ;\r
123 ; Registers:\r
124 ; ECX - Vector Number\r
125 ;\r
126\r
127 ;\r
128 ; Put Vector Number on stack\r
129 ;\r
130 push ecx\r
131\r
132 ;\r
133 ; Put 0 (dummy) error code on stack, and restore ECX\r
134 ;\r
135 xor ecx, ecx ; ECX = 0\r
136 xchg ecx, [esp+4]\r
137\r
138 jmp ErrorCodeAndVectorOnStack\r
139\r
140HasErrorCode:\r
141\r
142 ;\r
143 ; Stack:\r
144 ; +---------------------+\r
145 ; + EFlags +\r
146 ; +---------------------+\r
147 ; + CS +\r
148 ; +---------------------+\r
149 ; + EIP +\r
150 ; +---------------------+\r
151 ; + Error Code +\r
152 ; +---------------------+\r
153 ; + ECX +\r
154 ; +---------------------+ <-- ESP\r
155 ;\r
156 ; Registers:\r
157 ; ECX - Vector Number\r
158 ;\r
159\r
160 ;\r
161 ; Put Vector Number on stack and restore ECX\r
162 ;\r
163 xchg ecx, [esp]\r
164\r
8f07f895 165ErrorCodeAndVectorOnStack:\r
166 push ebp\r
167 mov ebp, esp\r
168\r
169 ;\r
170 ; Stack:\r
171 ; +---------------------+\r
172 ; + EFlags +\r
173 ; +---------------------+\r
174 ; + CS +\r
175 ; +---------------------+\r
176 ; + EIP +\r
177 ; +---------------------+\r
178 ; + Error Code +\r
179 ; +---------------------+\r
180 ; + Vector Number +\r
181 ; +---------------------+\r
182 ; + EBP +\r
183 ; +---------------------+ <-- EBP\r
184 ;\r
185\r
186 ;\r
187 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
188 ; is 16-byte aligned\r
189 ;\r
190 and esp, 0fffffff0h\r
191 sub esp, 12\r
192\r
e41aad15
JF
193 sub esp, 8\r
194 push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
195 push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
dd563742 196\r
8f07f895 197;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
198 push eax\r
199 push ecx\r
200 push edx\r
201 push ebx\r
202 lea ecx, [ebp + 6 * 4]\r
203 push ecx ; ESP\r
204 push dword ptr [ebp] ; EBP\r
205 push esi\r
206 push edi\r
207\r
208;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
209 mov eax, ss\r
210 push eax\r
211 movzx eax, word ptr [ebp + 4 * 4]\r
212 push eax\r
213 mov eax, ds\r
214 push eax\r
215 mov eax, es\r
216 push eax\r
217 mov eax, fs\r
218 push eax\r
219 mov eax, gs\r
220 push eax\r
221\r
222;; UINT32 Eip;\r
223 mov eax, [ebp + 3 * 4]\r
224 push eax\r
225\r
226;; UINT32 Gdtr[2], Idtr[2];\r
227 sub esp, 8\r
228 sidt [esp]\r
229 mov eax, [esp + 2]\r
230 xchg eax, [esp]\r
231 and eax, 0FFFFh\r
232 mov [esp+4], eax\r
233\r
234 sub esp, 8\r
235 sgdt [esp]\r
236 mov eax, [esp + 2]\r
237 xchg eax, [esp]\r
238 and eax, 0FFFFh\r
239 mov [esp+4], eax\r
240\r
241;; UINT32 Ldtr, Tr;\r
242 xor eax, eax\r
243 str ax\r
244 push eax\r
245 sldt ax\r
246 push eax\r
247\r
248;; UINT32 EFlags;\r
249 mov eax, [ebp + 5 * 4]\r
250 push eax\r
251\r
252;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
087c67d0 253 mov eax, 1\r
dd563742
JF
254 push ebx ; temporarily save value of ebx on stack\r
255 cpuid ; use CPUID to determine if FXSAVE/FXRESTOR and DE\r
087c67d0 256 ; are supported\r
dd563742 257 pop ebx ; retore value of ebx that was overwritten by CPUID\r
8f07f895 258 mov eax, cr4\r
087c67d0
MK
259 push eax ; push cr4 firstly\r
260 test edx, BIT24 ; Test for FXSAVE/FXRESTOR support\r
261 jz @F\r
262 or eax, BIT9 ; Set CR4.OSFXSR\r
dd563742 263@@:\r
087c67d0
MK
264 test edx, BIT2 ; Test for Debugging Extensions support\r
265 jz @F\r
266 or eax, BIT3 ; Set CR4.DE\r
dd563742 267@@:\r
8f07f895 268 mov cr4, eax\r
8f07f895 269 mov eax, cr3\r
270 push eax\r
271 mov eax, cr2\r
272 push eax\r
273 xor eax, eax\r
274 push eax\r
275 mov eax, cr0\r
276 push eax\r
277\r
278;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
279 mov eax, dr7\r
280 push eax\r
281 mov eax, dr6\r
282 push eax\r
283 mov eax, dr3\r
284 push eax\r
285 mov eax, dr2\r
286 push eax\r
287 mov eax, dr1\r
288 push eax\r
289 mov eax, dr0\r
290 push eax\r
291\r
292;; FX_SAVE_STATE_IA32 FxSaveState;\r
293 sub esp, 512\r
294 mov edi, esp\r
087c67d0
MK
295 test edx, BIT24 ; Test for FXSAVE/FXRESTOR support.\r
296 ; edx still contains result from CPUID above\r
297 jz @F\r
8f07f895 298 db 0fh, 0aeh, 07h ;fxsave [edi]\r
dd563742 299@@:\r
8f07f895 300\r
301;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
302 cld\r
303\r
304;; UINT32 ExceptionData;\r
305 push dword ptr [ebp + 2 * 4]\r
306\r
307;; Prepare parameter and call\r
308 mov edx, esp\r
309 push edx\r
310 mov edx, dword ptr [ebp + 1 * 4]\r
311 push edx\r
312\r
313 ;\r
314 ; Call External Exception Handler\r
315 ;\r
316 mov eax, CommonExceptionHandler\r
317 call eax\r
318 add esp, 8\r
319\r
320 cli\r
321;; UINT32 ExceptionData;\r
322 add esp, 4\r
323\r
324;; FX_SAVE_STATE_IA32 FxSaveState;\r
325 mov esi, esp\r
087c67d0
MK
326 mov eax, 1\r
327 cpuid ; use CPUID to determine if FXSAVE/FXRESTOR\r
328 ; are supported\r
329 test edx, BIT24 ; Test for FXSAVE/FXRESTOR support\r
330 jz @F\r
8f07f895 331 db 0fh, 0aeh, 0eh ; fxrstor [esi]\r
dd563742 332@@:\r
8f07f895 333 add esp, 512\r
334\r
335;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
336;; Skip restoration of DRx registers to support in-circuit emualators\r
337;; or debuggers set breakpoint in interrupt/exception context\r
338 add esp, 4 * 6\r
339\r
340;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
341 pop eax\r
342 mov cr0, eax\r
343 add esp, 4 ; not for Cr1\r
344 pop eax\r
345 mov cr2, eax\r
346 pop eax\r
347 mov cr3, eax\r
348 pop eax\r
349 mov cr4, eax\r
350\r
351;; UINT32 EFlags;\r
352 pop dword ptr [ebp + 5 * 4]\r
353\r
354;; UINT32 Ldtr, Tr;\r
355;; UINT32 Gdtr[2], Idtr[2];\r
356;; Best not let anyone mess with these particular registers...\r
357 add esp, 24\r
358\r
359;; UINT32 Eip;\r
360 pop dword ptr [ebp + 3 * 4]\r
361\r
362;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
363;; NOTE - modified segment registers could hang the debugger... We\r
364;; could attempt to insulate ourselves against this possibility,\r
365;; but that poses risks as well.\r
366;;\r
367 pop gs\r
368 pop fs\r
369 pop es\r
370 pop ds\r
371 pop dword ptr [ebp + 4 * 4]\r
372 pop ss\r
373\r
374;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
375 pop edi\r
376 pop esi\r
377 add esp, 4 ; not for ebp\r
378 add esp, 4 ; not for esp\r
379 pop ebx\r
380 pop edx\r
381 pop ecx\r
382 pop eax\r
383\r
e41aad15
JF
384 pop dword ptr [ebp - 8]\r
385 pop dword ptr [ebp - 4]\r
8f07f895 386 mov esp, ebp\r
387 pop ebp\r
388 add esp, 8\r
e41aad15
JF
389 cmp dword ptr [esp - 16], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
390 jz DoReturn\r
391 cmp dword ptr [esp - 20], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
392 jz ErrorCode\r
393 jmp dword ptr [esp - 16]\r
394ErrorCode:\r
395 sub esp, 4\r
396 jmp dword ptr [esp - 12]\r
397\r
dd563742 398DoReturn:\r
e41aad15
JF
399 cmp mDoFarReturnFlag, 0 ; Check if need to do far return instead of IRET\r
400 jz DoIret\r
401 push [esp + 8] ; save EFLAGS\r
402 add esp, 16\r
403 push [esp - 8] ; save CS in new location\r
404 push [esp - 8] ; save EIP in new location\r
405 push [esp - 8] ; save EFLAGS in new location\r
406 popfd ; restore EFLAGS\r
407 retf ; far return\r
408\r
409DoIret:\r
8f07f895 410 iretd\r
411\r
412CommonInterruptEntry ENDP\r
413\r
414;---------------------------------------;\r
e41aad15 415; _AsmGetTemplateAddressMap ;\r
8f07f895 416;----------------------------------------------------------------------------;\r
dd563742 417;\r
8f07f895 418; Protocol prototype\r
e41aad15 419; AsmGetTemplateAddressMap (\r
8f07f895 420; EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
421; );\r
dd563742 422;\r
8f07f895 423; Routine Description:\r
dd563742 424;\r
8f07f895 425; Return address map of interrupt handler template so that C code can generate\r
426; interrupt table.\r
dd563742 427;\r
8f07f895 428; Arguments:\r
dd563742
JF
429;\r
430;\r
431; Returns:\r
432;\r
8f07f895 433; Nothing\r
434;\r
dd563742 435;\r
8f07f895 436; Input: [ebp][0] = Original ebp\r
437; [ebp][4] = Return address\r
dd563742 438;\r
8f07f895 439; Output: Nothing\r
dd563742 440;\r
8f07f895 441; Destroys: Nothing\r
442;-----------------------------------------------------------------------------;\r
e41aad15 443AsmGetTemplateAddressMap proc near public\r
8f07f895 444 push ebp ; C prolog\r
445 mov ebp, esp\r
446 pushad\r
447\r
e41aad15
JF
448 mov ebx, dword ptr [ebp + 08h]\r
449 mov dword ptr [ebx], AsmIdtVectorBegin\r
450 mov dword ptr [ebx + 4h], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32\r
451 mov dword ptr [ebx + 8h], HookAfterStubBegin\r
dd563742 452\r
8f07f895 453 popad\r
454 pop ebp\r
455 ret\r
e41aad15
JF
456AsmGetTemplateAddressMap ENDP\r
457\r
458;-------------------------------------------------------------------------------------\r
07da1ac8 459; AsmVectorNumFixup (*NewVectorAddr, VectorNum, *OldVectorAddr);\r
e41aad15
JF
460;-------------------------------------------------------------------------------------\r
461AsmVectorNumFixup proc near public\r
462 mov eax, dword ptr [esp + 8]\r
463 mov ecx, [esp + 4]\r
464 mov [ecx + (VectorNum - HookAfterStubBegin)], al\r
465 ret\r
466AsmVectorNumFixup ENDP\r
8f07f895 467END\r