]> git.proxmox.com Git - mirror_edk2.git/blame - SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
SourceLevelDebugPkg/DebugAgent: Support IA32 processors without DE or FXSAVE/FXRESTOR
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / DebugAgentCommon / Ia32 / AsmFuncs.S
CommitLineData
18b144ea 1#------------------------------------------------------------------------------\r
2#\r
5f72e68c 3# Copyright (c) 2010 - 2015, Intel Corporation. All rights reserved.<BR>\r
18b144ea 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# Module Name:\r
13#\r
14# AsmFuncs.S\r
15#\r
16# Abstract:\r
17#\r
18# Debug interrupt handle functions.\r
19#\r
20#------------------------------------------------------------------------------\r
21\r
22#include "DebugException.h"\r
23\r
24ASM_GLOBAL ASM_PFX(InterruptProcess)\r
25ASM_GLOBAL ASM_PFX(Exception0Handle)\r
26ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)\r
27ASM_GLOBAL ASM_PFX(TimerInterruptHandle)\r
28ASM_GLOBAL ASM_PFX(CommonEntry)\r
29\r
8cc26df4
JF
30.macro AGENT_HANDLER_SIGNATURE\r
31 .byte 0x41, 0x47, 0x54, 0x48 # AGENT_HANDLER_SIGNATURE SIGNATURE_32('A','G','T','H')\r
32.endm\r
33\r
18b144ea 34.data\r
35\r
19ee4a90 36ASM_PFX(ExceptionStubHeaderSize): .long ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)\r
18b144ea 37\r
38.text\r
39\r
8cc26df4 40AGENT_HANDLER_SIGNATURE\r
18b144ea 41ASM_PFX(Exception0Handle):\r
42 cli\r
43 pushl %eax\r
44 mov $0, %eax\r
45 jmp ASM_PFX(CommonEntry)\r
8cc26df4 46AGENT_HANDLER_SIGNATURE\r
18b144ea 47ASM_PFX(Exception1Handle):\r
48 cli\r
49 pushl %eax\r
50 mov $1, %eax\r
51 jmp ASM_PFX(CommonEntry)\r
8cc26df4 52AGENT_HANDLER_SIGNATURE\r
18b144ea 53ASM_PFX(Exception2Handle):\r
54 cli\r
55 pushl %eax\r
56 mov $2, %eax\r
57 jmp ASM_PFX(CommonEntry)\r
8cc26df4 58AGENT_HANDLER_SIGNATURE\r
18b144ea 59ASM_PFX(Exception3Handle):\r
60 cli\r
61 pushl %eax\r
62 mov $3, %eax\r
63 jmp ASM_PFX(CommonEntry)\r
8cc26df4 64AGENT_HANDLER_SIGNATURE\r
18b144ea 65ASM_PFX(Exception4Handle):\r
66 cli\r
67 pushl %eax\r
68 mov $4, %eax\r
69 jmp ASM_PFX(CommonEntry)\r
8cc26df4 70AGENT_HANDLER_SIGNATURE\r
18b144ea 71ASM_PFX(Exception5Handle):\r
72 cli\r
73 pushl %eax\r
74 mov $5, %eax\r
75 jmp ASM_PFX(CommonEntry)\r
8cc26df4 76AGENT_HANDLER_SIGNATURE\r
18b144ea 77ASM_PFX(Exception6Handle):\r
78 cli\r
79 pushl %eax\r
80 mov $6, %eax\r
81 jmp ASM_PFX(CommonEntry)\r
8cc26df4 82AGENT_HANDLER_SIGNATURE\r
18b144ea 83ASM_PFX(Exception7Handle):\r
84 cli\r
85 pushl %eax\r
86 mov $7, %eax\r
87 jmp ASM_PFX(CommonEntry)\r
8cc26df4 88AGENT_HANDLER_SIGNATURE\r
18b144ea 89ASM_PFX(Exception8Handle):\r
90 cli\r
91 pushl %eax\r
92 mov $8, %eax\r
93 jmp ASM_PFX(CommonEntry)\r
8cc26df4 94AGENT_HANDLER_SIGNATURE\r
18b144ea 95ASM_PFX(Exception9Handle):\r
96 cli\r
97 pushl %eax\r
98 mov $9, %eax\r
99 jmp ASM_PFX(CommonEntry)\r
8cc26df4 100AGENT_HANDLER_SIGNATURE\r
18b144ea 101ASM_PFX(Exception10Handle):\r
102 cli\r
103 pushl %eax\r
104 mov $10, %eax\r
105 jmp ASM_PFX(CommonEntry)\r
8cc26df4 106AGENT_HANDLER_SIGNATURE\r
18b144ea 107ASM_PFX(Exception11Handle):\r
108 cli\r
109 pushl %eax\r
110 mov $11, %eax\r
111 jmp ASM_PFX(CommonEntry)\r
8cc26df4 112AGENT_HANDLER_SIGNATURE\r
18b144ea 113ASM_PFX(Exception12Handle):\r
114 cli\r
115 pushl %eax\r
116 mov $12, %eax\r
117 jmp ASM_PFX(CommonEntry)\r
8cc26df4 118AGENT_HANDLER_SIGNATURE\r
18b144ea 119ASM_PFX(Exception13Handle):\r
120 cli\r
121 pushl %eax\r
122 mov $13, %eax\r
123 jmp ASM_PFX(CommonEntry)\r
8cc26df4 124AGENT_HANDLER_SIGNATURE\r
18b144ea 125ASM_PFX(Exception14Handle):\r
126 cli\r
127 pushl %eax\r
128 mov $14, %eax\r
129 jmp ASM_PFX(CommonEntry)\r
8cc26df4 130AGENT_HANDLER_SIGNATURE\r
18b144ea 131ASM_PFX(Exception15Handle):\r
132 cli\r
133 pushl %eax\r
134 mov $15, %eax\r
135 jmp ASM_PFX(CommonEntry)\r
8cc26df4 136AGENT_HANDLER_SIGNATURE\r
18b144ea 137ASM_PFX(Exception16Handle):\r
138 cli\r
139 pushl %eax\r
140 mov $16, %eax\r
141 jmp ASM_PFX(CommonEntry)\r
8cc26df4 142AGENT_HANDLER_SIGNATURE\r
18b144ea 143ASM_PFX(Exception17Handle):\r
144 cli\r
145 pushl %eax\r
146 mov $17, %eax\r
147 jmp ASM_PFX(CommonEntry)\r
8cc26df4 148AGENT_HANDLER_SIGNATURE\r
18b144ea 149ASM_PFX(Exception18Handle):\r
150 cli\r
151 pushl %eax\r
152 mov $18, %eax\r
153 jmp ASM_PFX(CommonEntry)\r
8cc26df4 154AGENT_HANDLER_SIGNATURE\r
18b144ea 155ASM_PFX(Exception19Handle):\r
156 cli\r
157 pushl %eax\r
158 mov $19, %eax\r
159 jmp ASM_PFX(CommonEntry)\r
8cc26df4 160AGENT_HANDLER_SIGNATURE\r
18b144ea 161ASM_PFX(TimerInterruptHandle):\r
162 cli\r
163 pushl %eax\r
164 mov $32, %eax\r
165 jmp ASM_PFX(CommonEntry)\r
166\r
167\r
168ASM_PFX(CommonEntry):\r
169\r
170#---------------------------------------;\r
171# _CommonEntry ;\r
172#----------------------------------------------------------------------------;\r
173# The follow algorithm is used for the common interrupt routine.\r
174# Entry from each interrupt with a push eax and eax=interrupt number\r
175#\r
176# +---------------------+\r
177# + EFlags +\r
178# +---------------------+\r
179# + CS +\r
180# +---------------------+\r
181# + EIP +\r
182# +---------------------+\r
183# + Error Code +\r
184# +---------------------+\r
185# + EAX / Vector Number +\r
186# +---------------------+\r
187# + EBP +\r
188# +---------------------+ <-- EBP\r
189#\r
190\r
191# We need to determine if any extra data was pushed by the exception\r
192 cmpl $DEBUG_EXCEPT_DOUBLE_FAULT, %eax\r
193 je NoExtrPush\r
194 cmpl $DEBUG_EXCEPT_INVALID_TSS, %eax\r
195 je NoExtrPush\r
196 cmpl $DEBUG_EXCEPT_SEG_NOT_PRESENT, %eax\r
197 je NoExtrPush\r
198 cmpl $DEBUG_EXCEPT_STACK_FAULT, %eax\r
199 je NoExtrPush\r
200 cmpl $DEBUG_EXCEPT_GP_FAULT, %eax\r
201 je NoExtrPush\r
202 cmpl $DEBUG_EXCEPT_PAGE_FAULT, %eax\r
203 je NoExtrPush\r
204 cmpl $DEBUG_EXCEPT_ALIGNMENT_CHECK, %eax\r
205 je NoExtrPush\r
206\r
207 pushl (%esp)\r
208 movl $0, 4(%esp)\r
209\r
210NoExtrPush:\r
211\r
212 pushl %ebp\r
213 movl %esp,%ebp\r
214\r
215 #\r
216 # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
217 # is 16-byte aligned\r
218 #\r
219 andl $0xfffffff0,%esp\r
220 subl $12,%esp\r
221\r
222## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
223 pushl 0x4(%ebp)\r
224 pushl %ebx\r
225 pushl %ecx\r
226 pushl %edx\r
227 mov %eax, %ebx # save vector in ebx\r
228 leal 24(%ebp),%ecx\r
229 pushl %ecx # save original ESP\r
230 pushl (%ebp)\r
231 pushl %esi\r
232 pushl %edi\r
233\r
234## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
5f72e68c
MK
235## insure FXSAVE/FXRSTOR is enabled in CR4...\r
236## ... while we're at it, make sure DE is also enabled...\r
237 mov $1, %eax\r
238 pushl %ebx # temporarily save value of ebx on stack \r
239 cpuid # use CPUID to determine if FXSAVE/FXRESTOR \r
240 # and DE are supported\r
241 popl %ebx # retore value of ebx that was overwritten\r
242 # by CPUID \r
18b144ea 243 movl %cr4, %eax\r
5f72e68c
MK
244 pushl %eax # push cr4 firstly\r
245 testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support\r
246 jz L1\r
247 orl $BIT9, %eax # Set CR4.OSFXSR\r
248L1: \r
249 testl $BIT2, %edx # Test for Debugging Extensions support\r
250 jz L2\r
251 orl $BIT3, %eax # Set CR4.DE\r
252L2: \r
18b144ea 253 movl %eax, %cr4\r
18b144ea 254 movl %cr3, %eax\r
255 pushl %eax\r
256 movl %cr2, %eax\r
257 pushl %eax\r
258 xorl %eax,%eax\r
259 pushl %eax\r
260 movl %cr0, %eax\r
261 pushl %eax\r
262\r
263## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
264 movl %ss,%eax\r
265 pushl %eax\r
266 movzwl 16(%ebp), %eax\r
267 pushl %eax\r
268 movl %ds,%eax\r
269 pushl %eax\r
270 movl %es,%eax\r
271 pushl %eax\r
272 movl %fs,%eax\r
273 pushl %eax\r
274 movl %gs,%eax\r
275 pushl %eax\r
276\r
277## UINT32 Eip;\r
278 pushl 12(%ebp)\r
279\r
280## UINT32 Gdtr[2], Idtr[2];\r
281 subl $8,%esp\r
282 sidt (%esp)\r
283 subl $8,%esp\r
284 sgdt (%esp)\r
285\r
286## UINT32 Ldtr, Tr;\r
287 xorl %eax,%eax\r
288 strl %eax\r
289 pushl %eax\r
290 sldtl %eax\r
291 pushl %eax\r
292\r
293## UINT32 EFlags;\r
294 pushl 20(%ebp)\r
295\r
296## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
297 movl %dr7, %eax\r
298 pushl %eax\r
299## clear Dr7 while executing debugger itself\r
300 xorl %eax,%eax\r
b422b62c 301 movl %eax, %dr7\r
18b144ea 302\r
303 movl %dr6, %eax\r
304 pushl %eax\r
305## insure all status bits in dr6 are clear...\r
306 xorl %eax,%eax\r
307 movl %eax, %dr6\r
308\r
309 movl %dr3, %eax\r
310 pushl %eax\r
311 movl %dr2, %eax\r
312 pushl %eax\r
313 movl %dr1, %eax\r
314 pushl %eax\r
315 movl %dr0, %eax\r
316 pushl %eax\r
317\r
318## FX_SAVE_STATE_IA32 FxSaveState;\r
319 subl $512,%esp\r
320 movl %esp,%edi\r
5f72e68c
MK
321 testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support.\r
322 # edx still contains result from CPUID above\r
323 jz L3\r
18b144ea 324 .byte 0x0f, 0xae, 0x07 # fxsave [edi]\r
5f72e68c 325L3: \r
18b144ea 326\r
93c0bdec 327## save the exception data\r
328 pushl 8(%esp)\r
329\r
18b144ea 330## Clear Direction Flag\r
331 cld\r
332 \r
333## Prepare parameter and call C function\r
334 pushl %esp\r
335 pushl %ebx\r
336 call ASM_PFX(InterruptProcess)\r
337 addl $8,%esp\r
338\r
93c0bdec 339## skip the exception data\r
340 addl $4,%esp\r
341\r
18b144ea 342## FX_SAVE_STATE_IA32 FxSaveState;\r
343 movl %esp,%esi\r
5f72e68c
MK
344 movl $1, %eax\r
345 cpuid # use CPUID to determine if FXSAVE/FXRESTOR\r
346 # are supported\r
347 testl $BIT24, %edx # Test for FXSAVE/FXRESTOR support\r
348 jz L4\r
18b144ea 349 .byte 0x0f, 0xae, 0x0e # fxrstor [esi]\r
5f72e68c 350L4: \r
18b144ea 351 addl $512,%esp\r
352\r
353## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
354 popl %eax\r
355 movl %eax, %dr0\r
356 popl %eax\r
357 movl %eax, %dr1\r
358 popl %eax\r
359 movl %eax, %dr2\r
360 popl %eax\r
361 movl %eax, %dr3\r
362## skip restore of dr6. We cleared dr6 during the context save.\r
363 addl $4,%esp\r
364 popl %eax\r
365 movl %eax, %dr7\r
366\r
367## UINT32 EFlags;\r
368 popl 20(%ebp)\r
369\r
370## UINT32 Ldtr, Tr;\r
371## UINT32 Gdtr[2], Idtr[2];\r
372## Best not let anyone mess with these particular registers...\r
373 addl $24,%esp\r
374\r
375## UINT32 Eip;\r
376 pop 12(%ebp)\r
377\r
378## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
379## NOTE - modified segment registers could hang the debugger... We\r
380## could attempt to insulate ourselves against this possibility,\r
381## but that poses risks as well.\r
382##\r
383 popl %gs\r
384 popl %fs\r
385 popl %es\r
386 popl %ds\r
387 popl 16(%ebp)\r
388 popl %ss\r
389\r
390## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
391 popl %eax\r
392 movl %eax, %cr0\r
393 addl $4,%esp # not for Cr1\r
394 popl %eax\r
395 movl %eax, %cr2\r
396 popl %eax\r
397 movl %eax, %cr3\r
398 popl %eax\r
399 movl %eax, %cr4\r
400\r
401## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
402 popl %edi\r
403 popl %esi\r
404 addl $4,%esp # not for ebp\r
405 addl $4,%esp # not for esp\r
406 popl %edx\r
407 popl %ecx\r
408 popl %ebx\r
409 popl %eax\r
410\r
411 movl %ebp,%esp\r
412 popl %ebp\r
413 addl $8,%esp # skip eax\r
414 iretl\r
415 \r