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;
31InterruptProcess                 PROTO   C
32
33public    Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize
34
35AGENT_HANDLER_SIGNATURE  MACRO
36  db   41h, 47h, 54h, 48h       ; SIGNATURE_32('A','G','T','H')
37ENDM
38
39.data
40
41ExceptionStubHeaderSize   DD    Exception1Handle - Exception0Handle
42CommonEntryAddr           DD    CommonEntry
43
44.code
45
46AGENT_HANDLER_SIGNATURE
47Exception0Handle:
48    cli
49    push    eax
50    mov     eax, 0
51    jmp     dword ptr [CommonEntryAddr]
52AGENT_HANDLER_SIGNATURE
53Exception1Handle:
54    cli
55    push    eax
56    mov     eax, 1
57    jmp     dword ptr [CommonEntryAddr]
58AGENT_HANDLER_SIGNATURE
59Exception2Handle:
60    cli
61    push    eax
62    mov     eax, 2
63    jmp     dword ptr [CommonEntryAddr]
64AGENT_HANDLER_SIGNATURE
65Exception3Handle:
66    cli
67    push    eax
68    mov     eax, 3
69    jmp     dword ptr [CommonEntryAddr]
70AGENT_HANDLER_SIGNATURE
71Exception4Handle:
72    cli
73    push    eax
74    mov     eax, 4
75    jmp     dword ptr [CommonEntryAddr]
76AGENT_HANDLER_SIGNATURE
77Exception5Handle:
78    cli
79    push    eax
80    mov     eax, 5
81    jmp     dword ptr [CommonEntryAddr]
82AGENT_HANDLER_SIGNATURE
83Exception6Handle:
84    cli
85    push    eax
86    mov     eax, 6
87    jmp     dword ptr [CommonEntryAddr]
88AGENT_HANDLER_SIGNATURE
89Exception7Handle:
90    cli
91    push    eax
92    mov     eax, 7
93    jmp     dword ptr [CommonEntryAddr]
94AGENT_HANDLER_SIGNATURE
95Exception8Handle:
96    cli
97    push    eax
98    mov     eax, 8
99    jmp     dword ptr [CommonEntryAddr]
100AGENT_HANDLER_SIGNATURE
101Exception9Handle:
102    cli
103    push    eax
104    mov     eax, 9
105    jmp     dword ptr [CommonEntryAddr]
106AGENT_HANDLER_SIGNATURE
107Exception10Handle:
108    cli
109    push    eax
110    mov     eax, 10
111    jmp     dword ptr [CommonEntryAddr]
112AGENT_HANDLER_SIGNATURE
113Exception11Handle:
114    cli
115    push    eax
116    mov     eax, 11
117    jmp     dword ptr [CommonEntryAddr]
118AGENT_HANDLER_SIGNATURE
119Exception12Handle:
120    cli
121    push    eax
122    mov     eax, 12
123    jmp     dword ptr [CommonEntryAddr]
124AGENT_HANDLER_SIGNATURE
125Exception13Handle:
126    cli
127    push    eax
128    mov     eax, 13
129    jmp     dword ptr [CommonEntryAddr]
130AGENT_HANDLER_SIGNATURE
131Exception14Handle:
132    cli
133    push    eax
134    mov     eax, 14
135    jmp     dword ptr [CommonEntryAddr]
136AGENT_HANDLER_SIGNATURE
137Exception15Handle:
138    cli
139    push    eax
140    mov     eax, 15
141    jmp     dword ptr [CommonEntryAddr]
142AGENT_HANDLER_SIGNATURE
143Exception16Handle:
144    cli
145    push    eax
146    mov     eax, 16
147    jmp     dword ptr [CommonEntryAddr]
148AGENT_HANDLER_SIGNATURE
149Exception17Handle:
150    cli
151    push    eax
152    mov     eax, 17
153    jmp     dword ptr [CommonEntryAddr]
154AGENT_HANDLER_SIGNATURE
155Exception18Handle:
156    cli
157    push    eax
158    mov     eax, 18
159    jmp     dword ptr [CommonEntryAddr]
160AGENT_HANDLER_SIGNATURE
161Exception19Handle:
162    cli
163    push    eax
164    mov     eax, 19
165    jmp     dword ptr [CommonEntryAddr]
166AGENT_HANDLER_SIGNATURE
167TimerInterruptHandle:
168    cli
169    push    eax
170    mov     eax, 32
171    jmp     dword ptr [CommonEntryAddr]
172
173CommonEntry:
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
207NoExtrPush:
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
422END
423