]> git.proxmox.com Git - mirror_edk2.git/blob - SourceLevelDebugPkg/Library/DebugAgent/DebugAgentCommon/Ia32/AsmFuncs.S
Import SourceLevelDebugPkg.
[mirror_edk2.git] / SourceLevelDebugPkg / Library / DebugAgent / DebugAgentCommon / Ia32 / AsmFuncs.S
1 #------------------------------------------------------------------------------
2 #
3 # Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>
4 # This program and the accompanying materials
5 # are licensed and made available under the terms and conditions of the BSD License
6 # which accompanies this distribution. The full text of the license may be found at
7 # http://opensource.org/licenses/bsd-license.php.
8 #
9 # THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
11 #
12 # Module Name:
13 #
14 # AsmFuncs.S
15 #
16 # Abstract:
17 #
18 # Debug interrupt handle functions.
19 #
20 #------------------------------------------------------------------------------
21
22 #include "DebugException.h"
23
24 ASM_GLOBAL ASM_PFX(InterruptProcess)
25 ASM_GLOBAL ASM_PFX(Exception0Handle)
26 ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)
27 ASM_GLOBAL ASM_PFX(TimerInterruptHandle)
28 ASM_GLOBAL ASM_PFX(CommonEntry)
29
30 .data
31
32 ASM_PFX(ExceptionStubHeaderSize): .word ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
33
34 .text
35
36 ASM_PFX(Exception0Handle):
37 cli
38 pushl %eax
39 mov $0, %eax
40 jmp ASM_PFX(CommonEntry)
41 ASM_PFX(Exception1Handle):
42 cli
43 pushl %eax
44 mov $1, %eax
45 jmp ASM_PFX(CommonEntry)
46 ASM_PFX(Exception2Handle):
47 cli
48 pushl %eax
49 mov $2, %eax
50 jmp ASM_PFX(CommonEntry)
51 ASM_PFX(Exception3Handle):
52 cli
53 pushl %eax
54 mov $3, %eax
55 jmp ASM_PFX(CommonEntry)
56 ASM_PFX(Exception4Handle):
57 cli
58 pushl %eax
59 mov $4, %eax
60 jmp ASM_PFX(CommonEntry)
61 ASM_PFX(Exception5Handle):
62 cli
63 pushl %eax
64 mov $5, %eax
65 jmp ASM_PFX(CommonEntry)
66 ASM_PFX(Exception6Handle):
67 cli
68 pushl %eax
69 mov $6, %eax
70 jmp ASM_PFX(CommonEntry)
71 ASM_PFX(Exception7Handle):
72 cli
73 pushl %eax
74 mov $7, %eax
75 jmp ASM_PFX(CommonEntry)
76 ASM_PFX(Exception8Handle):
77 cli
78 pushl %eax
79 mov $8, %eax
80 jmp ASM_PFX(CommonEntry)
81 ASM_PFX(Exception9Handle):
82 cli
83 pushl %eax
84 mov $9, %eax
85 jmp ASM_PFX(CommonEntry)
86 ASM_PFX(Exception10Handle):
87 cli
88 pushl %eax
89 mov $10, %eax
90 jmp ASM_PFX(CommonEntry)
91 ASM_PFX(Exception11Handle):
92 cli
93 pushl %eax
94 mov $11, %eax
95 jmp ASM_PFX(CommonEntry)
96 ASM_PFX(Exception12Handle):
97 cli
98 pushl %eax
99 mov $12, %eax
100 jmp ASM_PFX(CommonEntry)
101 ASM_PFX(Exception13Handle):
102 cli
103 pushl %eax
104 mov $13, %eax
105 jmp ASM_PFX(CommonEntry)
106 ASM_PFX(Exception14Handle):
107 cli
108 pushl %eax
109 mov $14, %eax
110 jmp ASM_PFX(CommonEntry)
111 ASM_PFX(Exception15Handle):
112 cli
113 pushl %eax
114 mov $15, %eax
115 jmp ASM_PFX(CommonEntry)
116 ASM_PFX(Exception16Handle):
117 cli
118 pushl %eax
119 mov $16, %eax
120 jmp ASM_PFX(CommonEntry)
121 ASM_PFX(Exception17Handle):
122 cli
123 pushl %eax
124 mov $17, %eax
125 jmp ASM_PFX(CommonEntry)
126 ASM_PFX(Exception18Handle):
127 cli
128 pushl %eax
129 mov $18, %eax
130 jmp ASM_PFX(CommonEntry)
131 ASM_PFX(Exception19Handle):
132 cli
133 pushl %eax
134 mov $19, %eax
135 jmp ASM_PFX(CommonEntry)
136
137 ASM_PFX(TimerInterruptHandle):
138 cli
139 pushl %eax
140 mov $32, %eax
141 jmp ASM_PFX(CommonEntry)
142
143
144 ASM_PFX(CommonEntry):
145
146 #---------------------------------------;
147 # _CommonEntry ;
148 #----------------------------------------------------------------------------;
149 # The follow algorithm is used for the common interrupt routine.
150 # Entry from each interrupt with a push eax and eax=interrupt number
151 #
152 # +---------------------+
153 # + EFlags +
154 # +---------------------+
155 # + CS +
156 # +---------------------+
157 # + EIP +
158 # +---------------------+
159 # + Error Code +
160 # +---------------------+
161 # + EAX / Vector Number +
162 # +---------------------+
163 # + EBP +
164 # +---------------------+ <-- EBP
165 #
166
167 # We need to determine if any extra data was pushed by the exception
168 cmpl $DEBUG_EXCEPT_DOUBLE_FAULT, %eax
169 je NoExtrPush
170 cmpl $DEBUG_EXCEPT_INVALID_TSS, %eax
171 je NoExtrPush
172 cmpl $DEBUG_EXCEPT_SEG_NOT_PRESENT, %eax
173 je NoExtrPush
174 cmpl $DEBUG_EXCEPT_STACK_FAULT, %eax
175 je NoExtrPush
176 cmpl $DEBUG_EXCEPT_GP_FAULT, %eax
177 je NoExtrPush
178 cmpl $DEBUG_EXCEPT_PAGE_FAULT, %eax
179 je NoExtrPush
180 cmpl $DEBUG_EXCEPT_ALIGNMENT_CHECK, %eax
181 je NoExtrPush
182
183 pushl (%esp)
184 movl $0, 4(%esp)
185
186 NoExtrPush:
187
188 pushl %ebp
189 movl %esp,%ebp
190
191 #
192 # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
193 # is 16-byte aligned
194 #
195 andl $0xfffffff0,%esp
196 subl $12,%esp
197
198 ## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
199 pushl 0x4(%ebp)
200 pushl %ebx
201 pushl %ecx
202 pushl %edx
203 mov %eax, %ebx # save vector in ebx
204 leal 24(%ebp),%ecx
205 pushl %ecx # save original ESP
206 pushl (%ebp)
207 pushl %esi
208 pushl %edi
209
210 ## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
211 movl %cr4, %eax
212 orl $0x208,%eax
213 movl %eax, %cr4
214 pushl %eax
215 movl %cr3, %eax
216 pushl %eax
217 movl %cr2, %eax
218 pushl %eax
219 xorl %eax,%eax
220 pushl %eax
221 movl %cr0, %eax
222 pushl %eax
223
224 ## UINT32 Gs, Fs, Es, Ds, Cs, Ss;
225 movl %ss,%eax
226 pushl %eax
227 movzwl 16(%ebp), %eax
228 pushl %eax
229 movl %ds,%eax
230 pushl %eax
231 movl %es,%eax
232 pushl %eax
233 movl %fs,%eax
234 pushl %eax
235 movl %gs,%eax
236 pushl %eax
237
238 ## UINT32 Eip;
239 pushl 12(%ebp)
240
241 ## UINT32 Gdtr[2], Idtr[2];
242 subl $8,%esp
243 sidt (%esp)
244 subl $8,%esp
245 sgdt (%esp)
246
247 ## UINT32 Ldtr, Tr;
248 xorl %eax,%eax
249 strl %eax
250 pushl %eax
251 sldtl %eax
252 pushl %eax
253
254 ## UINT32 EFlags;
255 pushl 20(%ebp)
256
257 ## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
258 movl %dr7, %eax
259 pushl %eax
260 ## clear Dr7 while executing debugger itself
261 xorl %eax,%eax
262 # movl %eax, %dr7
263
264 movl %dr6, %eax
265 pushl %eax
266 ## insure all status bits in dr6 are clear...
267 xorl %eax,%eax
268 movl %eax, %dr6
269
270 movl %dr3, %eax
271 pushl %eax
272 movl %dr2, %eax
273 pushl %eax
274 movl %dr1, %eax
275 pushl %eax
276 movl %dr0, %eax
277 pushl %eax
278
279 ## FX_SAVE_STATE_IA32 FxSaveState;
280 subl $512,%esp
281 movl %esp,%edi
282 .byte 0x0f, 0xae, 0x07 # fxsave [edi]
283
284 ## Clear Direction Flag
285 cld
286
287 ## Prepare parameter and call C function
288 pushl %esp
289 pushl %ebx
290 call ASM_PFX(InterruptProcess)
291 addl $8,%esp
292
293 ## FX_SAVE_STATE_IA32 FxSaveState;
294 movl %esp,%esi
295 .byte 0x0f, 0xae, 0x0e # fxrstor [esi]
296 addl $512,%esp
297
298 ## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
299 popl %eax
300 movl %eax, %dr0
301 popl %eax
302 movl %eax, %dr1
303 popl %eax
304 movl %eax, %dr2
305 popl %eax
306 movl %eax, %dr3
307 ## skip restore of dr6. We cleared dr6 during the context save.
308 addl $4,%esp
309 popl %eax
310 movl %eax, %dr7
311
312 ## UINT32 EFlags;
313 popl 20(%ebp)
314
315 ## UINT32 Ldtr, Tr;
316 ## UINT32 Gdtr[2], Idtr[2];
317 ## Best not let anyone mess with these particular registers...
318 addl $24,%esp
319
320 ## UINT32 Eip;
321 pop 12(%ebp)
322
323 ## UINT32 Gs, Fs, Es, Ds, Cs, Ss;
324 ## NOTE - modified segment registers could hang the debugger... We
325 ## could attempt to insulate ourselves against this possibility,
326 ## but that poses risks as well.
327 ##
328 popl %gs
329 popl %fs
330 popl %es
331 popl %ds
332 popl 16(%ebp)
333 popl %ss
334
335 ## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
336 popl %eax
337 movl %eax, %cr0
338 addl $4,%esp # not for Cr1
339 popl %eax
340 movl %eax, %cr2
341 popl %eax
342 movl %eax, %cr3
343 popl %eax
344 movl %eax, %cr4
345
346 ## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
347 popl %edi
348 popl %esi
349 addl $4,%esp # not for ebp
350 addl $4,%esp # not for esp
351 popl %edx
352 popl %ecx
353 popl %ebx
354 popl %eax
355
356 movl %ebp,%esp
357 popl %ebp
358 addl $8,%esp # skip eax
359 iretl
360