]> git.proxmox.com Git - mirror_edk2.git/blame - UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
1. Separated DxeSmmCpuExceptionHandlerLib.inf into 2 instance DxeCpuExceptionHandlerL...
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / Ia32 / ExceptionHandlerAsm.asm
CommitLineData
8f07f895 1;------------------------------------------------------------------------------ ;\r
e41aad15 2; Copyright (c) 2012 - 2013, 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
56 db 0 ; 0 will be fixed \r
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
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
253 mov eax, cr4\r
254 or eax, 208h\r
255 mov cr4, eax\r
256 push eax\r
257 mov eax, cr3\r
258 push eax\r
259 mov eax, cr2\r
260 push eax\r
261 xor eax, eax\r
262 push eax\r
263 mov eax, cr0\r
264 push eax\r
265\r
266;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
267 mov eax, dr7\r
268 push eax\r
269 mov eax, dr6\r
270 push eax\r
271 mov eax, dr3\r
272 push eax\r
273 mov eax, dr2\r
274 push eax\r
275 mov eax, dr1\r
276 push eax\r
277 mov eax, dr0\r
278 push eax\r
279\r
280;; FX_SAVE_STATE_IA32 FxSaveState;\r
281 sub esp, 512\r
282 mov edi, esp\r
283 db 0fh, 0aeh, 07h ;fxsave [edi]\r
284\r
285;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
286 cld\r
287\r
288;; UINT32 ExceptionData;\r
289 push dword ptr [ebp + 2 * 4]\r
290\r
291;; Prepare parameter and call\r
292 mov edx, esp\r
293 push edx\r
294 mov edx, dword ptr [ebp + 1 * 4]\r
295 push edx\r
296\r
297 ;\r
298 ; Call External Exception Handler\r
299 ;\r
300 mov eax, CommonExceptionHandler\r
301 call eax\r
302 add esp, 8\r
303\r
304 cli\r
305;; UINT32 ExceptionData;\r
306 add esp, 4\r
307\r
308;; FX_SAVE_STATE_IA32 FxSaveState;\r
309 mov esi, esp\r
310 db 0fh, 0aeh, 0eh ; fxrstor [esi]\r
311 add esp, 512\r
312\r
313;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
314;; Skip restoration of DRx registers to support in-circuit emualators\r
315;; or debuggers set breakpoint in interrupt/exception context\r
316 add esp, 4 * 6\r
317\r
318;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
319 pop eax\r
320 mov cr0, eax\r
321 add esp, 4 ; not for Cr1\r
322 pop eax\r
323 mov cr2, eax\r
324 pop eax\r
325 mov cr3, eax\r
326 pop eax\r
327 mov cr4, eax\r
328\r
329;; UINT32 EFlags;\r
330 pop dword ptr [ebp + 5 * 4]\r
331\r
332;; UINT32 Ldtr, Tr;\r
333;; UINT32 Gdtr[2], Idtr[2];\r
334;; Best not let anyone mess with these particular registers...\r
335 add esp, 24\r
336\r
337;; UINT32 Eip;\r
338 pop dword ptr [ebp + 3 * 4]\r
339\r
340;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
341;; NOTE - modified segment registers could hang the debugger... We\r
342;; could attempt to insulate ourselves against this possibility,\r
343;; but that poses risks as well.\r
344;;\r
345 pop gs\r
346 pop fs\r
347 pop es\r
348 pop ds\r
349 pop dword ptr [ebp + 4 * 4]\r
350 pop ss\r
351\r
352;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
353 pop edi\r
354 pop esi\r
355 add esp, 4 ; not for ebp\r
356 add esp, 4 ; not for esp\r
357 pop ebx\r
358 pop edx\r
359 pop ecx\r
360 pop eax\r
361\r
e41aad15
JF
362 pop dword ptr [ebp - 8]\r
363 pop dword ptr [ebp - 4]\r
8f07f895 364 mov esp, ebp\r
365 pop ebp\r
366 add esp, 8\r
e41aad15
JF
367 cmp dword ptr [esp - 16], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler\r
368 jz DoReturn\r
369 cmp dword ptr [esp - 20], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag\r
370 jz ErrorCode\r
371 jmp dword ptr [esp - 16]\r
372ErrorCode:\r
373 sub esp, 4\r
374 jmp dword ptr [esp - 12]\r
375\r
376DoReturn: \r
377 cmp mDoFarReturnFlag, 0 ; Check if need to do far return instead of IRET\r
378 jz DoIret\r
379 push [esp + 8] ; save EFLAGS\r
380 add esp, 16\r
381 push [esp - 8] ; save CS in new location\r
382 push [esp - 8] ; save EIP in new location\r
383 push [esp - 8] ; save EFLAGS in new location\r
384 popfd ; restore EFLAGS\r
385 retf ; far return\r
386\r
387DoIret:\r
8f07f895 388 iretd\r
389\r
390CommonInterruptEntry ENDP\r
391\r
392;---------------------------------------;\r
e41aad15 393; _AsmGetTemplateAddressMap ;\r
8f07f895 394;----------------------------------------------------------------------------;\r
395; \r
396; Protocol prototype\r
e41aad15 397; AsmGetTemplateAddressMap (\r
8f07f895 398; EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap\r
399; );\r
400; \r
401; Routine Description:\r
402; \r
403; Return address map of interrupt handler template so that C code can generate\r
404; interrupt table.\r
405; \r
406; Arguments:\r
407; \r
408; \r
409; Returns: \r
410; \r
411; Nothing\r
412;\r
413; \r
414; Input: [ebp][0] = Original ebp\r
415; [ebp][4] = Return address\r
416; \r
417; Output: Nothing\r
418; \r
419; Destroys: Nothing\r
420;-----------------------------------------------------------------------------;\r
e41aad15 421AsmGetTemplateAddressMap proc near public\r
8f07f895 422 push ebp ; C prolog\r
423 mov ebp, esp\r
424 pushad\r
425\r
e41aad15
JF
426 mov ebx, dword ptr [ebp + 08h]\r
427 mov dword ptr [ebx], AsmIdtVectorBegin\r
428 mov dword ptr [ebx + 4h], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32\r
429 mov dword ptr [ebx + 8h], HookAfterStubBegin\r
8f07f895 430 \r
431 popad\r
432 pop ebp\r
433 ret\r
e41aad15
JF
434AsmGetTemplateAddressMap ENDP\r
435\r
436;-------------------------------------------------------------------------------------\r
437; AsmVectorNumFixup (*VectorBase, VectorNum);\r
438;-------------------------------------------------------------------------------------\r
439AsmVectorNumFixup proc near public\r
440 mov eax, dword ptr [esp + 8]\r
441 mov ecx, [esp + 4]\r
442 mov [ecx + (VectorNum - HookAfterStubBegin)], al\r
443 ret\r
444AsmVectorNumFixup ENDP\r
8f07f895 445END\r