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