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