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