]> git.proxmox.com Git - mirror_edk2.git/blob - UefiCpuPkg/Library/CpuExceptionHandlerLib/Ia32/ExceptionHandlerAsm.asm
Import two CPU Exception Handler Library instances: SecPeiCpuExceptionHandler.inf...
[mirror_edk2.git] / UefiCpuPkg / Library / CpuExceptionHandlerLib / Ia32 / ExceptionHandlerAsm.asm
1 ;------------------------------------------------------------------------------ ;
2 ; Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
3 ; This program and the accompanying materials
4 ; are licensed and made available under the terms and conditions of the BSD License
5 ; which accompanies this distribution. The full text of the license may be found at
6 ; http://opensource.org/licenses/bsd-license.php.
7 ;
8 ; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
9 ; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
10 ;
11 ; Module Name:
12 ;
13 ; ExceptionHandlerAsm.Asm
14 ;
15 ; Abstract:
16 ;
17 ; IA32 CPU Exception Handler
18 ;
19 ; Notes:
20 ;
21 ;------------------------------------------------------------------------------
22
23 .686
24 .model flat,C
25
26 ;
27 ; CommonExceptionHandler()
28 ;
29 CommonExceptionHandler PROTO C
30
31 .data
32
33 CommonEntryAddr DD CommonInterruptEntry
34
35 EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
36
37 .code
38
39 ;
40 ; exception handler stub table
41 ;
42 Exception0Handle:
43 push 0
44 jmp dword ptr [CommonEntryAddr]
45 Exception1Handle:
46 push 1
47 jmp dword ptr [CommonEntryAddr]
48 Exception2Handle:
49 push 2
50 jmp dword ptr [CommonEntryAddr]
51 Exception3Handle:
52 push 3
53 jmp dword ptr [CommonEntryAddr]
54 Exception4Handle:
55 push 4
56 jmp dword ptr [CommonEntryAddr]
57 Exception5Handle:
58 push 5
59 jmp dword ptr [CommonEntryAddr]
60 Exception6Handle:
61 push 6
62 jmp dword ptr [CommonEntryAddr]
63 Exception7Handle:
64 push 7
65 jmp dword ptr [CommonEntryAddr]
66 Exception8Handle:
67 push 8
68 jmp dword ptr [CommonEntryAddr]
69 Exception9Handle:
70 push 9
71 jmp dword ptr [CommonEntryAddr]
72 Exception10Handle:
73 push 10
74 jmp dword ptr [CommonEntryAddr]
75 Exception11Handle:
76 push 11
77 jmp dword ptr [CommonEntryAddr]
78 Exception12Handle:
79 push 12
80 jmp dword ptr [CommonEntryAddr]
81 Exception13Handle:
82 push 13
83 jmp dword ptr [CommonEntryAddr]
84 Exception14Handle:
85 push 14
86 jmp dword ptr [CommonEntryAddr]
87 Exception15Handle:
88 push 15
89 jmp dword ptr [CommonEntryAddr]
90 Exception16Handle:
91 push 16
92 jmp dword ptr [CommonEntryAddr]
93 Exception17Handle:
94 push 17
95 jmp dword ptr [CommonEntryAddr]
96 Exception18Handle:
97 push 18
98 jmp dword ptr [CommonEntryAddr]
99 Exception19Handle:
100 push 19
101 jmp dword ptr [CommonEntryAddr]
102 Exception20Handle:
103 push 20
104 jmp dword ptr [CommonEntryAddr]
105 Exception21Handle:
106 push 21
107 jmp dword ptr [CommonEntryAddr]
108 Exception22Handle:
109 push 22
110 jmp dword ptr [CommonEntryAddr]
111 Exception23Handle:
112 push 23
113 jmp dword ptr [CommonEntryAddr]
114 Exception24Handle:
115 push 24
116 jmp dword ptr [CommonEntryAddr]
117 Exception25Handle:
118 push 25
119 jmp dword ptr [CommonEntryAddr]
120 Exception26Handle:
121 push 26
122 jmp dword ptr [CommonEntryAddr]
123 Exception27Handle:
124 push 27
125 jmp dword ptr [CommonEntryAddr]
126 Exception28Handle:
127 push 28
128 jmp dword ptr [CommonEntryAddr]
129 Exception29Handle:
130 push 29
131 jmp dword ptr [CommonEntryAddr]
132 Exception30Handle:
133 push 30
134 jmp dword ptr [CommonEntryAddr]
135 Exception31Handle:
136 push 31
137 jmp dword ptr [CommonEntryAddr]
138
139 ;----------------------------------------------------------------------------;
140 ; CommonInterruptEntry ;
141 ;----------------------------------------------------------------------------;
142 ; The follow algorithm is used for the common interrupt routine.
143 ; Entry from each interrupt with a push eax and eax=interrupt number
144
145 CommonInterruptEntry PROC PUBLIC
146 cli
147 ;
148 ; All interrupt handlers are invoked through interrupt gates, so
149 ; IF flag automatically cleared at the entry point
150 ;
151
152 ;
153 ; Calculate vector number
154 ;
155 ; Get the return address of call, actually, it is the
156 ; address of vector number.
157 ;
158 xchg ecx, [esp]
159 and ecx, 0FFFFh
160 cmp ecx, 32 ; Intel reserved vector for exceptions?
161 jae NoErrorCode
162 bt mErrorCodeFlag, ecx
163 jc HasErrorCode
164
165 NoErrorCode:
166
167 ;
168 ; Stack:
169 ; +---------------------+
170 ; + EFlags +
171 ; +---------------------+
172 ; + CS +
173 ; +---------------------+
174 ; + EIP +
175 ; +---------------------+
176 ; + ECX +
177 ; +---------------------+ <-- ESP
178 ;
179 ; Registers:
180 ; ECX - Vector Number
181 ;
182
183 ;
184 ; Put Vector Number on stack
185 ;
186 push ecx
187
188 ;
189 ; Put 0 (dummy) error code on stack, and restore ECX
190 ;
191 xor ecx, ecx ; ECX = 0
192 xchg ecx, [esp+4]
193
194 jmp ErrorCodeAndVectorOnStack
195
196 HasErrorCode:
197
198 ;
199 ; Stack:
200 ; +---------------------+
201 ; + EFlags +
202 ; +---------------------+
203 ; + CS +
204 ; +---------------------+
205 ; + EIP +
206 ; +---------------------+
207 ; + Error Code +
208 ; +---------------------+
209 ; + ECX +
210 ; +---------------------+ <-- ESP
211 ;
212 ; Registers:
213 ; ECX - Vector Number
214 ;
215
216 ;
217 ; Put Vector Number on stack and restore ECX
218 ;
219 xchg ecx, [esp]
220
221 ;
222 ; Fall through to join main routine code
223 ; at ErrorCodeAndVectorOnStack
224 ;
225 @@:
226 jmp @B
227
228 ErrorCodeAndVectorOnStack:
229 push ebp
230 mov ebp, esp
231
232 ;
233 ; Stack:
234 ; +---------------------+
235 ; + EFlags +
236 ; +---------------------+
237 ; + CS +
238 ; +---------------------+
239 ; + EIP +
240 ; +---------------------+
241 ; + Error Code +
242 ; +---------------------+
243 ; + Vector Number +
244 ; +---------------------+
245 ; + EBP +
246 ; +---------------------+ <-- EBP
247 ;
248
249 ;
250 ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
251 ; is 16-byte aligned
252 ;
253 and esp, 0fffffff0h
254 sub esp, 12
255
256 ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
257 push eax
258 push ecx
259 push edx
260 push ebx
261 lea ecx, [ebp + 6 * 4]
262 push ecx ; ESP
263 push dword ptr [ebp] ; EBP
264 push esi
265 push edi
266
267 ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
268 mov eax, ss
269 push eax
270 movzx eax, word ptr [ebp + 4 * 4]
271 push eax
272 mov eax, ds
273 push eax
274 mov eax, es
275 push eax
276 mov eax, fs
277 push eax
278 mov eax, gs
279 push eax
280
281 ;; UINT32 Eip;
282 mov eax, [ebp + 3 * 4]
283 push eax
284
285 ;; UINT32 Gdtr[2], Idtr[2];
286 sub esp, 8
287 sidt [esp]
288 mov eax, [esp + 2]
289 xchg eax, [esp]
290 and eax, 0FFFFh
291 mov [esp+4], eax
292
293 sub esp, 8
294 sgdt [esp]
295 mov eax, [esp + 2]
296 xchg eax, [esp]
297 and eax, 0FFFFh
298 mov [esp+4], eax
299
300 ;; UINT32 Ldtr, Tr;
301 xor eax, eax
302 str ax
303 push eax
304 sldt ax
305 push eax
306
307 ;; UINT32 EFlags;
308 mov eax, [ebp + 5 * 4]
309 push eax
310
311 ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
312 mov eax, cr4
313 or eax, 208h
314 mov cr4, eax
315 push eax
316 mov eax, cr3
317 push eax
318 mov eax, cr2
319 push eax
320 xor eax, eax
321 push eax
322 mov eax, cr0
323 push eax
324
325 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
326 mov eax, dr7
327 push eax
328 mov eax, dr6
329 push eax
330 mov eax, dr3
331 push eax
332 mov eax, dr2
333 push eax
334 mov eax, dr1
335 push eax
336 mov eax, dr0
337 push eax
338
339 ;; FX_SAVE_STATE_IA32 FxSaveState;
340 sub esp, 512
341 mov edi, esp
342 db 0fh, 0aeh, 07h ;fxsave [edi]
343
344 ;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
345 cld
346
347 ;; UINT32 ExceptionData;
348 push dword ptr [ebp + 2 * 4]
349
350 ;; Prepare parameter and call
351 mov edx, esp
352 push edx
353 mov edx, dword ptr [ebp + 1 * 4]
354 push edx
355
356 ;
357 ; Call External Exception Handler
358 ;
359 mov eax, CommonExceptionHandler
360 call eax
361 add esp, 8
362
363 cli
364 ;; UINT32 ExceptionData;
365 add esp, 4
366
367 ;; FX_SAVE_STATE_IA32 FxSaveState;
368 mov esi, esp
369 db 0fh, 0aeh, 0eh ; fxrstor [esi]
370 add esp, 512
371
372 ;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
373 ;; Skip restoration of DRx registers to support in-circuit emualators
374 ;; or debuggers set breakpoint in interrupt/exception context
375 add esp, 4 * 6
376
377 ;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
378 pop eax
379 mov cr0, eax
380 add esp, 4 ; not for Cr1
381 pop eax
382 mov cr2, eax
383 pop eax
384 mov cr3, eax
385 pop eax
386 mov cr4, eax
387
388 ;; UINT32 EFlags;
389 pop dword ptr [ebp + 5 * 4]
390
391 ;; UINT32 Ldtr, Tr;
392 ;; UINT32 Gdtr[2], Idtr[2];
393 ;; Best not let anyone mess with these particular registers...
394 add esp, 24
395
396 ;; UINT32 Eip;
397 pop dword ptr [ebp + 3 * 4]
398
399 ;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
400 ;; NOTE - modified segment registers could hang the debugger... We
401 ;; could attempt to insulate ourselves against this possibility,
402 ;; but that poses risks as well.
403 ;;
404 pop gs
405 pop fs
406 pop es
407 pop ds
408 pop dword ptr [ebp + 4 * 4]
409 pop ss
410
411 ;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
412 pop edi
413 pop esi
414 add esp, 4 ; not for ebp
415 add esp, 4 ; not for esp
416 pop ebx
417 pop edx
418 pop ecx
419 pop eax
420
421 mov esp, ebp
422 pop ebp
423 add esp, 8
424 iretd
425
426 CommonInterruptEntry ENDP
427
428 ;---------------------------------------;
429 ; _GetTemplateAddressMap ;
430 ;----------------------------------------------------------------------------;
431 ;
432 ; Protocol prototype
433 ; GetTemplateAddressMap (
434 ; EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
435 ; );
436 ;
437 ; Routine Description:
438 ;
439 ; Return address map of interrupt handler template so that C code can generate
440 ; interrupt table.
441 ;
442 ; Arguments:
443 ;
444 ;
445 ; Returns:
446 ;
447 ; Nothing
448 ;
449 ;
450 ; Input: [ebp][0] = Original ebp
451 ; [ebp][4] = Return address
452 ;
453 ; Output: Nothing
454 ;
455 ; Destroys: Nothing
456 ;-----------------------------------------------------------------------------;
457 GetTemplateAddressMap proc near public
458 push ebp ; C prolog
459 mov ebp, esp
460 pushad
461
462 mov ebx, dword ptr [ebp+08h]
463 mov dword ptr [ebx], Exception0Handle
464 mov dword ptr [ebx+4h], Exception1Handle - Exception0Handle
465
466 popad
467 pop ebp
468 ret
469 GetTemplateAddressMap ENDP
470
471 END