1#------------------------------------------------------------------------------
2#
3# Copyright (c) 2006 - 2014, 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
24ASM_GLOBAL ASM_PFX(InterruptProcess)
25
26ASM_GLOBAL ASM_PFX(Exception0Handle)
27ASM_GLOBAL ASM_PFX(ExceptionStubHeaderSize)
28ASM_GLOBAL ASM_PFX(TimerInterruptHandle)
29ASM_GLOBAL ASM_PFX(CommonEntry)
30
31.macro  AGENT_HANDLER_SIGNATURE
32  .byte 0x41, 0x47, 0x54, 0x48   # AGENT_HANDLER_SIGNATURE     SIGNATURE_32('A','G','T','H')
33.endm
34
35.data
36
37ASM_PFX(ExceptionStubHeaderSize):  .long     ASM_PFX(Exception1Handle) - ASM_PFX(Exception0Handle)
38
39
40.text
41
42AGENT_HANDLER_SIGNATURE
43ASM_PFX(Exception0Handle):
44   cli
45   pushq %rcx
46   mov   $0, %rcx
47   jmp   ASM_PFX(CommonEntry)
48AGENT_HANDLER_SIGNATURE
49ASM_PFX(Exception1Handle):
50   cli
51   pushq %rcx
52   mov   $1, %rcx
53   jmp   ASM_PFX(CommonEntry)
54AGENT_HANDLER_SIGNATURE
55ASM_PFX(Exception2Handle):
56   cli
57   pushq %rcx
58   mov   $2, %rcx
59   jmp   ASM_PFX(CommonEntry)
60AGENT_HANDLER_SIGNATURE
61ASM_PFX(Exception3Handle):
62   cli
63   pushq %rcx
64   mov   $3, %rcx
65   jmp   ASM_PFX(CommonEntry)
66AGENT_HANDLER_SIGNATURE
67ASM_PFX(Exception4Handle):
68   cli
69   pushq %rcx
70   mov   $4, %rcx
71   jmp   ASM_PFX(CommonEntry)
72AGENT_HANDLER_SIGNATURE
73ASM_PFX(Exception5Handle):
74   cli
75   pushq %rcx
76   mov   $5, %rcx
77   jmp   ASM_PFX(CommonEntry)
78AGENT_HANDLER_SIGNATURE
79ASM_PFX(Exception6Handle):
80   cli
81   pushq %rcx
82   mov   $6, %rcx
83   jmp   ASM_PFX(CommonEntry)
84AGENT_HANDLER_SIGNATURE
85ASM_PFX(Exception7Handle):
86   cli
87   pushq %rcx
88   mov   $7, %rcx
89   jmp   ASM_PFX(CommonEntry)
90AGENT_HANDLER_SIGNATURE
91ASM_PFX(Exception8Handle):
92   cli
93   pushq %rcx
94   mov   $8, %rcx
95   jmp   ASM_PFX(CommonEntry)
96AGENT_HANDLER_SIGNATURE
97ASM_PFX(Exception9Handle):
98   cli
99   pushq %rcx
100   mov   $9, %rcx
101   jmp   ASM_PFX(CommonEntry)
102AGENT_HANDLER_SIGNATURE
103ASM_PFX(Exception10Handle):
104   cli
105   pushq %rcx
106   mov   $10, %rcx
107   jmp   ASM_PFX(CommonEntry)
108AGENT_HANDLER_SIGNATURE
109ASM_PFX(Exception11Handle):
110   cli
111   pushq %rcx
112   mov   $11, %rcx
113   jmp   ASM_PFX(CommonEntry)
114AGENT_HANDLER_SIGNATURE
115ASM_PFX(Exception12Handle):
116   cli
117   pushq %rcx
118   mov   $12, %rcx
119   jmp   ASM_PFX(CommonEntry)
120AGENT_HANDLER_SIGNATURE
121ASM_PFX(Exception13Handle):
122   cli
123   pushq %rcx
124   mov   $13, %rcx
125   jmp   ASM_PFX(CommonEntry)
126AGENT_HANDLER_SIGNATURE
127ASM_PFX(Exception14Handle):
128   cli
129   pushq %rcx
130   mov   $14, %rcx
131   jmp   ASM_PFX(CommonEntry)
132AGENT_HANDLER_SIGNATURE
133ASM_PFX(Exception15Handle):
134   cli
135   pushq %rcx
136   mov   $15, %rcx
137   jmp   ASM_PFX(CommonEntry)
138AGENT_HANDLER_SIGNATURE
139ASM_PFX(Exception16Handle):
140   cli
141   pushq %rcx
142   mov   $16, %rcx
143   jmp   ASM_PFX(CommonEntry)
144AGENT_HANDLER_SIGNATURE
145ASM_PFX(Exception17Handle):
146   cli
147   pushq %rcx
148   mov   $17, %rcx
149   jmp   ASM_PFX(CommonEntry)
150AGENT_HANDLER_SIGNATURE
151ASM_PFX(Exception18Handle):
152   cli
153   pushq %rcx
154   mov   $18, %rcx
155   jmp   ASM_PFX(CommonEntry)
156AGENT_HANDLER_SIGNATURE
157ASM_PFX(Exception19Handle):
158   cli
159   pushq %rcx
160   mov   $19, %rcx
161   jmp   ASM_PFX(CommonEntry)
162AGENT_HANDLER_SIGNATURE
163ASM_PFX(TimerInterruptHandle):
164   cli
165   pushq %rcx
166   mov   $32, %rcx
167   jmp   ASM_PFX(CommonEntry)
168
169
170ASM_PFX(CommonEntry):
171
172#---------------------------------------;
173# CommonInterruptEntry                  ;
174#---------------------------------------;
175# The follow algorithm is used for the common interrupt routine.
176
177#
178# +---------------------+ <-- 16-byte aligned ensured by processor
179# +    Old SS           +
180# +---------------------+
181# +    Old RSP          +
182# +---------------------+
183# +    RFlags           +
184# +---------------------+
185# +    CS               +
186# +---------------------+
187# +    RIP              +
188# +---------------------+
189# +    Error Code       +
190# +---------------------+
191# + RCX / Vector Number +
192# +---------------------+
193# +    RBP              +
194# +---------------------+ <-- RBP, 16-byte aligned
195#
196
197# We need to determine if any extra data was pushed by the exception
198  cmpq    $DEBUG_EXCEPT_DOUBLE_FAULT, %rcx
199  je      NoExtrPush
200  cmpq    $DEBUG_EXCEPT_INVALID_TSS, %rcx
201  je      NoExtrPush
202  cmpq    $DEBUG_EXCEPT_SEG_NOT_PRESENT, %rcx
203  je      NoExtrPush
204  cmpq    $DEBUG_EXCEPT_STACK_FAULT, %rcx
205  je      NoExtrPush
206  cmpq    $DEBUG_EXCEPT_GP_FAULT, %rcx
207  je      NoExtrPush
208  cmpq    $DEBUG_EXCEPT_PAGE_FAULT, %rcx
209  je      NoExtrPush
210  cmpq    $DEBUG_EXCEPT_ALIGNMENT_CHECK, %rcx
211  je      NoExtrPush
212
213  pushq   (%rsp)
214  movq    $0, 8(%rsp)
215
216NoExtrPush:
217  #
218  # All interrupt handlers are invoked through interrupt gates, so
219  # IF flag automatically cleared at the entry point
220  pushq   %rbp
221  movq    %rsp, %rbp
222
223  #
224  # Since here the stack pointer is 16-byte aligned, so
225  # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
226  # is 16-byte aligned
227  #
228
229## UINT64  R8, R9, R10, R11, R12, R13, R14, R15;
230  pushq %r15
231  pushq %r14
232  pushq %r13
233  pushq %r12
234  pushq %r11
235  pushq %r10
236  pushq %r9
237  pushq %r8
238
239  movq  %cr8, %r8
240  pushq %r8
241
242## UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
243  pushq %rax
244  pushq %rbx
245  pushq 8(%rbp)      # original rcx
246  pushq %rdx
247  pushq 48(%rbp)     # original rsp
248  pushq (%rbp)       # original rbp
249  pushq %rsi
250  pushq %rdi
251
252## UINT64  Cr0, Cr1, Cr2, Cr3, Cr4;
253  movq    %cr4, %rax
254  orq     $0x208, %rax
255  movq    %rax, %cr4
256  pushq   %rax
257  movq    %cr3, %rax
258  pushq   %rax
259  movq    %cr2, %rax
260  pushq   %rax
261  xorq    %rax, %rax
262  pushq   %rax
263  movq    %cr0, %rax
264  pushq   %rax
265
266## UINT64  Gs, Fs, Es, Ds, Cs, Ss;  insure high 16 bits of each is zero
267  xorq     %rax, %rax      # set rax to 0
268  movzwq   56(%rbp), %rax
269#  movq     %ss, %rax
270  pushq    %rax
271  movzwq   32(%rbp), %rax
272#  movq     %cs, %rax
273  pushq    %rax
274  mov      %ds, %rax
275  pushq    %rax
276  mov      %es, %rax
277  pushq    %rax
278  mov      %fs, %rax
279  pushq    %rax
280  mov      %gs, %rax
281  pushq    %rax
282
283## UINT64  Rip;
284  pushq    24(%rbp)
285
286## UINT64  Gdtr[2], Idtr[2];
287  subq     $16, %rsp
288  sidt    (%rsp)
289  subq     $16, %rsp
290  sgdt    (%rsp)
291
292## UINT64  Ldtr, Tr;
293  xorq    %rax, %rax
294  strw    %ax
295  pushq   %rax
296  sldtw   %ax
297  pushq   %rax
298
299## UINT64  RFlags;
300  pushq   40(%rbp)
301
302## UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
303   movq    %dr7, %rax
304  pushq   %rax
305## clear Dr7 while executing debugger itself
306   xorq    %rax, %rax
307   movq    %rax, %dr7
308
309   movq    %dr6, %rax
310  pushq    %rax
311## insure all status bits in dr6 are clear...
312   xorq    %rax, %rax
313   movq    %rax, %dr6
314
315   movq    %dr3, %rax
316  pushq    %rax
317   movq    %dr2, %rax
318  pushq    %rax
319   movq    %dr1, %rax
320  pushq    %rax
321   movq    %dr0, %rax
322  pushq    %rax
323
324## FX_SAVE_STATE_X64 FxSaveState;
325   subq    $512, %rsp
326   movq    %rsp, %rdi
327   .byte   0x0f, 0xae, 0b00000111
328
329## save the exception data;
330   pushq   16(%rbp)
331
332## Clear Direction Flag
333  cld
334
335## Prepare parameter and call
336#  movq    8(%rbp), %rcx
337   movq    %rsp, %rdx
338   movq    %rcx, %r15   # save vector in r15
339  #
340  # Per X64 calling convention, allocate maximum parameter stack space
341  # and make sure RSP is 16-byte aligned
342  #
343   subq    $(32 + 8), %rsp
344   call    ASM_PFX(InterruptProcess)
345   addq    $(32 + 8), %rsp
346
347## skip the exception data;
348   addq    $8, %rsp
349
350## FX_SAVE_STATE_X64 FxSaveState;
351
352   movq    %rsp, %rsi
353   .byte   0x0f, 0xae, 0b00001110
354   addq    $512, %rsp
355
356## UINT64  Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
357   popq     %rax
358   movq     %rax, %dr0
359   popq     %rax
360   movq     %rax, %dr1
361   popq     %rax
362   movq     %rax, %dr2
363   popq     %rax
364   movq     %rax, %dr3
365## skip restore of dr6.  We cleared dr6 during the context save.
366   addq     $8, %rsp
367   popq     %rax
368   movq     %rax, %dr7
369
370## UINT64  RFlags;
371   popq    40(%rbp)
372
373## UINT64  Ldtr, Tr;
374## UINT64  Gdtr[2], Idtr[2];
375## Best not let anyone mess with these particular registers...
376   addq    $48, %rsp
377
378## UINT64  Rip;
379   popq    24(%rbp)
380
381## UINT64  Gs, Fs, Es, Ds, Cs, Ss;
382   popq     %rax
383  # mov     gs, rax ; not for gs
384   popq     %rax
385  # mov     fs, rax ; not for fs
386  # (X64 will not use fs and gs, so we do not restore it)
387   popq     %rax
388   mov      %rax, %es
389   popq     %rax
390   mov      %rax, %ds
391   popq     32(%rbp)
392   popq     56(%rbp)
393
394## UINT64  Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
395   popq     %rax
396   movq     %rax, %cr0
397   addq     $8, %rsp
398   popq     %rax
399   movq     %rax, %cr2
400   popq     %rax
401   movq     %rax, %cr3
402   popq     %rax
403   movq     %rax, %cr4
404
405## UINT64  Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
406## UINT64  R8, R9, R10, R11, R12, R13, R14, R15;
407   popq     %rdi
408   popq     %rsi
409   addq     $8, %rsp
410   addq     $8, %rsp
411   popq     %rdx
412   popq     %rcx
413   popq     %rbx
414   popq     %rax
415
416   popq     %r8
417   movq     %r8, %cr8
418
419   popq     %r8
420   popq     %r9
421   popq     %r10
422   popq     %r11
423   popq     %r12
424   popq     %r13
425   popq     %r14
426   popq     %r15
427
428   movq     %rbp, %rsp
429   popq     %rbp
430   addq     $16,  %rsp
431   iretq
432