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
25externdef InterruptProcess:near
26
27data SEGMENT
28
29public          Exception0Handle, TimerInterruptHandle, ExceptionStubHeaderSize
30
31AGENT_HANDLER_SIGNATURE  MACRO
32  db   41h, 47h, 54h, 48h       ; SIGNATURE_32('A','G','T','H')
33ENDM
34
35ExceptionStubHeaderSize        dd      Exception1Handle - Exception0Handle ;
36CommonEntryAddr                dq      CommonEntry ;
37
38.code
39
40AGENT_HANDLER_SIGNATURE
41Exception0Handle:
42    cli
43    push    rcx
44    mov     rcx, 0
45    jmp     qword ptr [CommonEntryAddr]
46AGENT_HANDLER_SIGNATURE
47Exception1Handle:
48    cli
49    push    rcx
50    mov     rcx, 1
51    jmp     qword ptr [CommonEntryAddr]
52AGENT_HANDLER_SIGNATURE
53Exception2Handle:
54    cli
55    push    rcx
56    mov     rcx, 2
57    jmp     qword ptr [CommonEntryAddr]
58AGENT_HANDLER_SIGNATURE
59Exception3Handle:
60    cli
61    push    rcx
62    mov     rcx, 3
63    jmp     qword ptr [CommonEntryAddr]
64AGENT_HANDLER_SIGNATURE
65Exception4Handle:
66    cli
67    push    rcx
68    mov     rcx, 4
69    jmp     qword ptr [CommonEntryAddr]
70AGENT_HANDLER_SIGNATURE
71Exception5Handle:
72    cli
73    push    rcx
74    mov     rcx, 5
75    jmp     qword ptr [CommonEntryAddr]
76AGENT_HANDLER_SIGNATURE
77Exception6Handle:
78    cli
79    push    rcx
80    mov     rcx, 6
81    jmp     qword ptr [CommonEntryAddr]
82AGENT_HANDLER_SIGNATURE
83Exception7Handle:
84    cli
85    push    rcx
86    mov     rcx, 7
87    jmp     qword ptr [CommonEntryAddr]
88AGENT_HANDLER_SIGNATURE
89Exception8Handle:
90    cli
91    push    rcx
92    mov     rcx, 8
93    jmp     qword ptr [CommonEntryAddr]
94AGENT_HANDLER_SIGNATURE
95Exception9Handle:
96    cli
97    push    rcx
98    mov     rcx, 9
99    jmp     qword ptr [CommonEntryAddr]
100AGENT_HANDLER_SIGNATURE
101Exception10Handle:
102    cli
103    push    rcx
104    mov     rcx, 10
105    jmp     qword ptr [CommonEntryAddr]
106AGENT_HANDLER_SIGNATURE
107Exception11Handle:
108    cli
109    push    rcx
110    mov     rcx, 11
111    jmp     qword ptr [CommonEntryAddr]
112AGENT_HANDLER_SIGNATURE
113Exception12Handle:
114    cli
115    push    rcx
116    mov     rcx, 12
117    jmp     qword ptr [CommonEntryAddr]
118AGENT_HANDLER_SIGNATURE
119Exception13Handle:
120    cli
121    push    rcx
122    mov     rcx, 13
123    jmp     qword ptr [CommonEntryAddr]
124AGENT_HANDLER_SIGNATURE
125Exception14Handle:
126    cli
127    push    rcx
128    mov     rcx, 14
129    jmp     qword ptr [CommonEntryAddr]
130AGENT_HANDLER_SIGNATURE
131Exception15Handle:
132    cli
133    push    rcx
134    mov     rcx, 15
135    jmp     qword ptr [CommonEntryAddr]
136AGENT_HANDLER_SIGNATURE
137Exception16Handle:
138    cli
139    push    rcx
140    mov     rcx, 16
141    jmp     qword ptr [CommonEntryAddr]
142AGENT_HANDLER_SIGNATURE
143Exception17Handle:
144    cli
145    push    rcx
146    mov     rcx, 17
147    jmp     qword ptr [CommonEntryAddr]
148AGENT_HANDLER_SIGNATURE
149Exception18Handle:
150    cli
151    push    rcx
152    mov     rcx, 18
153    jmp     qword ptr [CommonEntryAddr]
154AGENT_HANDLER_SIGNATURE
155Exception19Handle:
156    cli
157    push    rcx
158    mov     rcx, 19
159    jmp     qword ptr [CommonEntryAddr]
160AGENT_HANDLER_SIGNATURE
161TimerInterruptHandle:
162    cli
163    push    rcx
164    mov     rcx, 32
165    jmp     qword ptr [CommonEntryAddr]
166
167CommonEntry:
168    ; We need to determine if any extra data was pushed by the exception
169    cmp     rcx, DEBUG_EXCEPT_DOUBLE_FAULT
170    je      NoExtrPush
171    cmp     rcx, DEBUG_EXCEPT_INVALID_TSS
172    je      NoExtrPush
173    cmp     rcx, DEBUG_EXCEPT_SEG_NOT_PRESENT
174    je      NoExtrPush
175    cmp     rcx, DEBUG_EXCEPT_STACK_FAULT
176    je      NoExtrPush
177    cmp     rcx, DEBUG_EXCEPT_GP_FAULT
178    je      NoExtrPush
179    cmp     rcx, DEBUG_EXCEPT_PAGE_FAULT
180    je      NoExtrPush
181    cmp     rcx, DEBUG_EXCEPT_ALIGNMENT_CHECK
182    je      NoExtrPush
183
184    push    [rsp]
185    mov     qword ptr [rsp + 8], 0
186
187NoExtrPush:
188    push    rbp
189    mov     rbp, rsp
190
191    ; store UINT64  r8, r9, r10, r11, r12, r13, r14, r15;
192    push    r15
193    push    r14
194    push    r13
195    push    r12
196    push    r11
197    push    r10
198    push    r9
199    push    r8
200
201    mov     r8, cr8
202    push    r8
203
204    ; store UINT64  Rdi, Rsi, Rbp, Rsp, Rdx, Rcx, Rbx, Rax;
205    push    rax
206    push    rbx
207    push    qword ptr [rbp + 8]       ; original rcx
208    push    rdx
209    push    qword ptr [rbp + 6 * 8]   ; original rsp
210    push    qword ptr [rbp]           ; original rbp
211    push    rsi
212    push    rdi
213
214    ;; UINT32  Cr0, Cr1, Cr2, Cr3, Cr4;
215    ;; insure FXSAVE/FXRSTOR is enabled in CR4...
216    ;; ... while we're at it, make sure DE is also enabled...
217    mov     rax, cr4
218    or      rax, 208h
219    mov     cr4, rax
220    push    rax
221    mov     rax, cr3
222    push    rax
223    mov     rax, cr2
224    push    rax
225    push    0
226    mov     rax, cr0
227    push    rax
228
229    xor     rax, rax
230    mov     rax, Ss
231    push    rax
232    mov     rax, Cs
233    push    rax
234    mov     rax, Ds
235    push    rax
236    mov     rax, Es
237    push    rax
238    mov     rax, Fs
239    push    rax
240    mov     rax, Gs
241    push    rax
242
243    ;; EIP
244    mov     rax, [rbp + 8 * 3] ; EIP
245    push    rax
246
247    ;; UINT64  Gdtr[2], Idtr[2];
248    sub  rsp, 16
249    sidt fword ptr [rsp]
250    sub  rsp, 16
251    sgdt fword ptr [rsp]
252
253    ;; UINT64  Ldtr, Tr;
254    xor  rax, rax
255    str  ax
256    push rax
257    sldt ax
258    push rax
259
260    ;; EFlags
261    mov     rax, [rbp + 8 * 5]
262    push    rax
263
264    ;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
265    mov     rax, dr7
266    push    rax
267
268    ;; clear Dr7 while executing debugger itself
269    xor     rax, rax
270    mov     dr7, rax
271
272    ;; Dr6
273    mov     rax, dr6
274    push    rax
275
276    ;; insure all status bits in dr6 are clear...
277    xor     rax, rax
278    mov     dr6, rax
279
280    mov     rax, dr3
281    push    rax
282    mov     rax, dr2
283    push    rax
284    mov     rax, dr1
285    push    rax
286    mov     rax, dr0
287    push    rax
288
289    ;; Clear Direction Flag
290    cld
291
292    sub     rsp, 512
293    mov     rdi, rsp
294    ;; Clear the buffer
295    xor     rax, rax
296    push    rcx
297    mov     rcx, 64 ;= 512 / 8
298    rep     stosq
299    pop     rcx
300    mov     rdi, rsp
301    db 0fh, 0aeh, 00000111y ;fxsave [rdi]
302
303    ;; save the exception data
304    push    qword ptr [rbp + 16]
305
306    ; call the C interrupt process function
307    mov     rdx, rsp      ; Structure
308    mov     r15, rcx      ; save vector in r15
309
310    ;
311    ; Per X64 calling convention, allocate maximum parameter stack space
312    ; and make sure RSP is 16-byte aligned
313    ;
314    sub     rsp, 32 + 8
315    call    InterruptProcess
316    add     rsp, 32 + 8
317
318    ;; skip the exception data
319    add     rsp, 8
320
321    mov     rsi, rsp
322    db 0fh, 0aeh, 00001110y ; fxrstor [rsi]
323    add     rsp, 512
324
325    ;; UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
326    pop     rax
327    mov     dr0, rax
328    pop     rax
329    mov     dr1, rax
330    pop     rax
331    mov     dr2, rax
332    pop     rax
333    mov     dr3, rax
334    ;; skip restore of dr6.  We cleared dr6 during the context save.
335    add     rsp, 8
336    pop     rax
337    mov     dr7, rax
338
339    ;; set EFlags
340    pop     qword ptr [rbp + 8 * 5]
341
342    ;; UINT64  Ldtr, Tr;
343    ;; UINT64  Gdtr[2], Idtr[2];
344    ;; Best not let anyone mess with these particular registers...
345    add     rsp, 24 * 2
346
347    ;; UINT64  Eip;
348    pop     qword ptr [rbp + 8 * 3]   ; set EIP in stack
349
350    ;; UINT64  Gs, Fs, Es, Ds, Cs, Ss;
351    ;; NOTE - modified segment registers could hang the debugger...  We
352    ;;        could attempt to insulate ourselves against this possibility,
353    ;;        but that poses risks as well.
354    ;;
355    pop     rax
356    pop     rax
357    pop     rax
358    mov     es, rax
359    pop     rax
360    mov     ds, rax
361    pop     qword ptr [rbp + 8 * 4]    ; Set CS in stack
362    pop     rax
363    mov     ss, rax
364
365    ;; UINT64  Cr0, Cr1, Cr2, Cr3, Cr4;
366    pop     rax
367    mov     cr0, rax
368    add     rsp, 8    ; skip for Cr1
369    pop     rax
370    mov     cr2, rax
371    pop     rax
372    mov     cr3, rax
373    pop     rax
374    mov     cr4, rax
375
376    ;; restore general register
377    pop    rdi
378    pop    rsi
379    add    rsp, 8  ; skip rbp
380    add    rsp, 8  ; skip rsp
381    pop    rdx
382    pop    rcx
383    pop    rbx
384    pop    rax
385
386    pop    r8
387    mov    cr8, r8
388
389    ; store UINT64  r8, r9, r10, r11, r12, r13, r14, r15;
390    pop     r8
391    pop     r9
392    pop     r10
393    pop     r11
394    pop     r12
395    pop     r13
396    pop     r14
397    pop     r15
398
399    mov     rsp, rbp
400    pop     rbp
401    add     rsp, 16      ; skip rcx and error code
402
403    iretq
404
405END
406