]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/DebugSupportDxe/X64/AsmFuncs.S
free allocated memory in error handler.
[mirror_edk2.git] / MdeModulePkg / Universal / DebugSupportDxe / X64 / AsmFuncs.S
CommitLineData
7b414b4e 1#/**@file\r
2# Low leve x64 specific debug support functions.\r
3#\r
9d37f82f 4# Copyright (c) 2006 - 2009, Intel Corporation\r
7b414b4e 5# All rights reserved. This program and the accompanying materials\r
6# are licensed and made available under the terms and conditions of the BSD License\r
7# which accompanies this distribution. The full text of the license may be found at\r
8# http://opensource.org/licenses/bsd-license.php\r
9#\r
10# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12#\r
43a99f08 13#**/ \r
c1f23d63 14\r
132f41f0 15ASM_GLOBAL ASM_PFX(OrigVector)\r
16ASM_GLOBAL ASM_PFX(InterruptEntryStub)\r
17ASM_GLOBAL ASM_PFX(StubSize)\r
18ASM_GLOBAL ASM_PFX(CommonIdtEntry)\r
19ASM_GLOBAL ASM_PFX(FxStorSupport)\r
43a99f08 20 \r
21.data \r
c1f23d63 22\r
43a99f08 23ASM_PFX(StubSize): .long ASM_PFX(InterruptEntryStubEnd) - ASM_PFX(InterruptEntryStub)\r
24ASM_PFX(AppRsp): .long 0x11111111 # ?\r
25 .long 0x11111111 # ?\r
26ASM_PFX(DebugRsp): .long 0x22222222 # ?\r
27 .long 0x22222222 # ?\r
28ASM_PFX(ExtraPush): .long 0x33333333 # ?\r
29 .long 0x33333333 # ?\r
30ASM_PFX(ExceptData): .long 0x44444444 # ?\r
31 .long 0x44444444 # ?\r
32ASM_PFX(Rflags): .long 0x55555555 # ?\r
33 .long 0x55555555 # ?\r
34ASM_PFX(OrigVector): .long 0x66666666 # ?\r
35 .long 0x66666666 # ?\r
c1f23d63 36\r
43a99f08 37## The declarations below define the memory region that will be used for the debug stack.\r
38## The context record will be built by pushing register values onto this stack.\r
39## It is imparitive that alignment be carefully managed, since the FXSTOR and\r
40## FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned.\r
41##\r
42## The stub will switch stacks from the application stack to the debuger stack\r
43## and pushes the exception number.\r
44##\r
45## Then we building the context record on the stack. Since the stack grows down,\r
46## we push the fields of the context record from the back to the front. There\r
47## are 336 bytes of stack used prior allocating the 512 bytes of stack to be\r
48## used as the memory buffer for the fxstor instruction. Therefore address of\r
49## the buffer used for the FXSTOR instruction is &Eax - 336 - 512, which\r
50## must be 16 byte aligned.\r
51##\r
52## We carefully locate the stack to make this happen.\r
53##\r
54## For reference, the context structure looks like this:\r
55## struct {\r
56## UINT64 ExceptionData;\r
57## FX_SAVE_STATE_X64 FxSaveState; // 512 bytes, must be 16 byte aligned\r
58## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
59## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
60## UINT64 RFlags;\r
61## UINT64 Ldtr, Tr;\r
62## UINT64 Gdtr[2], Idtr[2];\r
63## UINT64 Rip;\r
64## UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
65## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
66## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
67## } SYSTEM_CONTEXT_X64; // 64 bit system context record\r
68\r
9d37f82f 69.p2align 4\r
43a99f08 70DebugStackEnd : .ascii "DbgStkEnd >>>>>>" # 16 byte long string - must be 16 bytes to preserve alignment\r
20b8fc38 71 .fill 0x1ffc, 4, 0x00000000\r
43a99f08 72 # 32K should be enough stack\r
73 # This allocation is coocked to insure\r
74 # that the the buffer for the FXSTORE instruction\r
75 # will be 16 byte aligned also.\r
76 #\r
77ASM_PFX(ExceptionNumber): .long 0x77777777 # first entry will be the vector number pushed by the stub\r
78 .long 0x77777777 # ?\r
79\r
80DebugStackBegin : .ascii "<<<< DbgStkBegin" # initial debug ESP == DebugStackBegin, set in stub\r
81 \r
82\r
83.text\r
84\r
85#------------------------------------------------------------------------------\r
86# BOOLEAN\r
87# FxStorSupport (\r
88# void\r
89# )\r
90#\r
91# Abstract: Returns TRUE if FxStor instructions are supported\r
92#\r
132f41f0 93ASM_GLOBAL ASM_PFX(FxStorSupport)\r
43a99f08 94ASM_PFX(FxStorSupport): \r
95#\r
96# cpuid corrupts rbx which must be preserved per the C calling convention\r
97#\r
7b8c3785 98 pushq %rbx\r
99 movq $1, %rax\r
43a99f08 100 cpuid\r
7b8c3785 101 movl %edx, %eax\r
102 andq $0x01000000, %rax\r
103 shrq $24, %rax\r
104 popq %rbx\r
43a99f08 105 ret\r
106#------------------------------------------------------------------------------\r
107# void\r
108# Vect2Desc (\r
109# IA32_IDT_GATE_DESCRIPTOR * DestDesc, // rcx\r
110# void (*Vector) (void) // rdx\r
111# )\r
112#\r
113# Abstract: Encodes an IDT descriptor with the given physical address\r
114#\r
132f41f0 115ASM_GLOBAL ASM_PFX(Vect2Desc)\r
43a99f08 116ASM_PFX(Vect2Desc):\r
7b8c3785 117 movq %rdx, %rax\r
118 movw %ax, (%rcx) # write bits 15..0 of offset\r
119 movw %cs, %dx\r
120 movw %dx, 2(%rcx) # SYS_CODE_SEL from GDT\r
121 movw $(0x0e00 | 0x8000), 4(%rcx) # type = 386 interrupt gate, present\r
122 shrq $16, %rax\r
123 movw %ax, 6(%rcx) # write bits 31..16 of offset\r
124 shrq $16, %rax\r
125 movl %eax, 8(%rcx) # write bits 63..32 of offset\r
43a99f08 126\r
127 ret\r
128\r
129#------------------------------------------------------------------------------\r
130# InterruptEntryStub\r
131#\r
132# Abstract: This code is not a function, but is a small piece of code that is\r
133# copied and fixed up once for each IDT entry that is hooked.\r
134#\r
132f41f0 135ASM_GLOBAL ASM_PFX(InterruptEntryStub)\r
43a99f08 136ASM_PFX(InterruptEntryStub):\r
137\r
7b8c3785 138 pushq $0 # push vector number - will be modified before installed\r
43a99f08 139 jmp ASM_PFX(CommonIdtEntry)\r
140 \r
132f41f0 141ASM_GLOBAL ASM_PFX(InterruptEntryStubEnd)\r
43a99f08 142ASM_PFX(InterruptEntryStubEnd):\r
c1f23d63 143\r
43a99f08 144#------------------------------------------------------------------------------\r
145# CommonIdtEntry\r
146#\r
147# Abstract: This code is not a function, but is the common part for all IDT\r
148# vectors.\r
149#\r
132f41f0 150ASM_GLOBAL ASM_PFX(CommonIdtEntry)\r
43a99f08 151##\r
152## At this point, the stub has saved the current application stack esp into AppRsp\r
153## and switched stacks to the debug stack, where it pushed the vector number\r
154##\r
155## The application stack looks like this:\r
156##\r
157## ...\r
158## (last application stack entry)\r
159## [16 bytes alignment, do not care it]\r
160## SS from interrupted task\r
161## RSP from interrupted task\r
162## rflags from interrupted task\r
163## CS from interrupted task\r
164## RIP from interrupted task\r
165## Error code <-------------------- Only present for some exeption types\r
166##\r
167## Vector Number <----------------- pushed in our IDT Entry\r
168##\r
169\r
170\r
171## The stub switched us to the debug stack and pushed the interrupt number.\r
172##\r
173## Next, construct the context record. It will be build on the debug stack by\r
174## pushing the registers in the correct order so as to create the context structure\r
175## on the debug stack. The context record must be built from the end back to the\r
176## beginning because the stack grows down...\r
177#\r
178## For reference, the context record looks like this:\r
179##\r
180## typedef\r
181## struct {\r
182## UINT64 ExceptionData;\r
183## FX_SAVE_STATE_X64 FxSaveState;\r
184## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
185## UINT64 Cr0, Cr2, Cr3, Cr4, Cr8;\r
186## UINT64 RFlags;\r
187## UINT64 Ldtr, Tr;\r
188## UINT64 Gdtr[2], Idtr[2];\r
189## UINT64 Rip;\r
190## UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
191## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
192## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
193## } SYSTEM_CONTEXT_X64; // 64\r
194ASM_PFX(CommonIdtEntry):\r
43a99f08 195## NOTE: we save rsp here to prevent compiler put rip reference cause error AppRsp\r
7b8c3785 196 pushq %rax\r
197 movq (8)(%rsp), %rax # save vector number\r
198 movq %rax, ASM_PFX(ExceptionNumber) # save vector number\r
199 popq %rax\r
200 addq $8, %rsp # pop vector number\r
201 movq %rsp, ASM_PFX(AppRsp) # save stack top\r
202 movq DebugStackBegin, %rsp # switch to debugger stack\r
203 subq $8, %rsp # leave space for vector number\r
43a99f08 204## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
205## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
7b8c3785 206 pushq %r15\r
207 pushq %r14\r
208 pushq %r13\r
209 pushq %r12\r
210 pushq %r11\r
211 pushq %r10\r
212 pushq %r9\r
213 pushq %r8\r
214 pushq %rax\r
215 pushq %rcx\r
216 pushq %rdx\r
217 pushq %rbx\r
218 pushq %rsp\r
219 pushq %rbp\r
220 pushq %rsi\r
221 pushq %rdi\r
43a99f08 222## Save interrupt state rflags register...\r
223 pushfq\r
7b8c3785 224 popq %rax\r
225 movq %rax, ASM_PFX(Rflags)\r
43a99f08 226## We need to determine if any extra data was pushed by the exception, and if so, save it\r
227## To do this, we check the exception number pushed by the stub, and cache the\r
228## result in a variable since we'll need this again.\r
7b8c3785 229 cmpl $0, ASM_PFX(ExceptionNumber)\r
43a99f08 230 jz ExtraPushOne\r
7b8c3785 231 cmpl $10, ASM_PFX(ExceptionNumber)\r
43a99f08 232 jz ExtraPushOne\r
7b8c3785 233 cmpl $11, ASM_PFX(ExceptionNumber)\r
43a99f08 234 jz ExtraPushOne\r
7b8c3785 235 cmpl $12, ASM_PFX(ExceptionNumber)\r
43a99f08 236 jz ExtraPushOne\r
7b8c3785 237 cmpl $13, ASM_PFX(ExceptionNumber)\r
43a99f08 238 jz ExtraPushOne\r
7b8c3785 239 cmpl $14, ASM_PFX(ExceptionNumber)\r
43a99f08 240 jz ExtraPushOne\r
7b8c3785 241 cmpl $17, ASM_PFX(ExceptionNumber)\r
43a99f08 242 jz ExtraPushOne\r
7b8c3785 243 movl $0, ASM_PFX(ExtraPush)\r
244 movl $0, ASM_PFX(ExceptData)\r
43a99f08 245 jmp ExtraPushDone\r
246ExtraPushOne:\r
7b8c3785 247 movl $1, ASM_PFX(ExtraPush)\r
43a99f08 248\r
249## If there's some extra data, save it also, and modify the saved AppRsp to effectively\r
250## pop this value off the application's stack.\r
7b8c3785 251 movq ASM_PFX(AppRsp), %rax \r
252 movq (%rax), %rbx\r
253 movq %rbx, ASM_PFX(ExceptData)\r
254 addq $8, %rax\r
255 movq %rax, ASM_PFX(AppRsp)\r
43a99f08 256\r
257ExtraPushDone:\r
258\r
259## The "push" above pushed the debug stack rsp. Since what we're actually doing\r
260## is building the context record on the debug stack, we need to save the pushed\r
261## debug RSP, and replace it with the application's last stack entry...\r
7b8c3785 262 movq 24(%rsp), %rax\r
263 movq %rax, ASM_PFX(DebugRsp)\r
264 movq ASM_PFX(AppRsp), %rax \r
265 addq $40, %rax\r
43a99f08 266 # application stack has ss, rsp, rflags, cs, & rip, so\r
509bc208 267 # last actual application stack entry is 40 bytes\r
268 # into the application stack.\r
7b8c3785 269 movq %rax, 24(%rsp)\r
509bc208 270\r
43a99f08 271## continue building context record\r
272## UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
7b8c3785 273 movq %ss, %rax\r
274 pushq %rax\r
43a99f08 275 # CS from application is one entry back in application stack\r
7b8c3785 276 movq ASM_PFX(AppRsp), %rax\r
277 movzxw 8(%rax), %rax\r
278 pushq %rax\r
279\r
280 movq %ds, %rax\r
281 pushq %rax\r
282 movq %es, %rax\r
283 pushq %rax\r
284 movq %fs, %rax\r
285 pushq %rax\r
286 movq %gs, %rax\r
287 pushq %rax\r
43a99f08 288## UINT64 Rip;\r
289 # Rip from application is on top of application stack\r
7b8c3785 290 movq ASM_PFX(AppRsp), %rax \r
291 pushq (%rax)\r
43a99f08 292## UINT64 Gdtr[2], Idtr[2];\r
7b8c3785 293 push $0\r
294 push $0\r
295 sidtq (%rsp)\r
296 push $0\r
297 push $0\r
298 sgdtq (%rsp)\r
43a99f08 299\r
300## UINT64 Ldtr, Tr;\r
7b8c3785 301 xorq %rax, %rax\r
302 str %ax\r
303 pushq %rax\r
304 sldt %ax\r
305 pushq %rax\r
43a99f08 306\r
307## UINT64 RFlags;\r
308## Rflags from application is two entries back in application stack\r
7b8c3785 309 movq ASM_PFX(AppRsp), %rax \r
310 pushq 16(%rax)\r
43a99f08 311## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
312## insure FXSAVE/FXRSTOR is enabled in CR4...\r
313## ... while we're at it, make sure DE is also enabled...\r
7b8c3785 314 movq %cr8, %rax\r
315 pushq %rax\r
316 movq %cr4, %rax\r
317 orq $0x208, %rax\r
318 movq %rax, %cr4\r
319 pushq %rax\r
320 movq %cr3, %rax\r
321 pushq %rax\r
322 movq %cr2, %rax\r
323 pushq %rax\r
324 push $0\r
325 movq %cr0, %rax\r
326 pushq %rax\r
43a99f08 327## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
7b8c3785 328 movq %dr7, %rax\r
329 pushq %rax\r
43a99f08 330## clear Dr7 while executing debugger itself\r
7b8c3785 331 xorq %rax, %rax\r
332 movq %rax, %dr7\r
43a99f08 333\r
7b8c3785 334 movq %dr6, %rax\r
335 pushq %rax\r
43a99f08 336## insure all status bits in dr6 are clear...\r
7b8c3785 337 xorq %rax, %rax\r
338 movq %rax, %dr6\r
339\r
340 movq %dr3, %rax\r
341 pushq %rax\r
342 movq %dr2, %rax\r
343 pushq %rax\r
344 movq %dr1, %rax\r
345 pushq %rax\r
346 movq %dr0, %rax\r
347 pushq %rax\r
43a99f08 348\r
349## FX_SAVE_STATE_X64 FxSaveState;\r
7b8c3785 350 subq $512, %rsp\r
351 movq %rsp, %rdi\r
43a99f08 352 # IMPORTANT!! The debug stack has been carefully constructed to\r
353 # insure that rsp and rdi are 16 byte aligned when we get here.\r
354 # They MUST be. If they are not, a GP fault will occur.\r
509bc208 355 \r
356 # FXSTOR_RDI\r
7b8c3785 357 fxsave (%rdi)\r
43a99f08 358\r
359## UINT64 ExceptionData;\r
7b8c3785 360 movq ASM_PFX(ExceptData), %rax\r
361 pushq %rax\r
509bc208 362\r
43a99f08 363# call to C code which will in turn call registered handler\r
364# pass in the vector number\r
7b8c3785 365 movq %rsp, %rdx\r
366 movq ASM_PFX(ExceptionNumber), %rcx \r
367 subq $40, %rsp\r
43a99f08 368 call ASM_PFX(InterruptDistrubutionHub)\r
7b8c3785 369 addq $40, %rsp\r
43a99f08 370# restore context...\r
371## UINT64 ExceptionData;\r
7b8c3785 372 addq $8, %rsp\r
509bc208 373\r
43a99f08 374## FX_SAVE_STATE_X64 FxSaveState;\r
7b8c3785 375 movq %rsp, %rsi\r
509bc208 376 \r
377 # FXRSTOR_RSI\r
7b8c3785 378 fxrstor (%rsi)\r
509bc208 379\r
7b8c3785 380 addq $512, %rsp\r
509bc208 381\r
382## UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
7b8c3785 383 popq %rax\r
384 movq %rax, %dr0\r
385 popq %rax\r
386 movq %rax, %dr1\r
387 popq %rax\r
388 movq %rax, %dr2\r
389 popq %rax\r
390 movq %rax, %dr3\r
509bc208 391\r
43a99f08 392## skip restore of dr6. We cleared dr6 during the context save.\r
7b8c3785 393 addq $8, %rsp\r
394 popq %rax\r
395 movq %rax, %dr7\r
509bc208 396\r
43a99f08 397## UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
7b8c3785 398 popq %rax\r
399 movq %rax, %cr0\r
400 addq $8, %rsp\r
401 popq %rax\r
402 movq %rax, %cr2\r
403 popq %rax\r
404 movq %rax, %cr3\r
405 popq %rax\r
406 movq %rax, %cr4\r
407 popq %rax\r
408 movq %rax, %cr8\r
43a99f08 409## UINT64 RFlags;\r
7b8c3785 410 movq ASM_PFX(AppRsp), %rax \r
411 popq 16(%rax)\r
43a99f08 412## UINT64 Ldtr, Tr;\r
413## UINT64 Gdtr[2], Idtr[2];\r
414## Best not let anyone mess with these particular registers...\r
7b8c3785 415 addq $48, %rsp\r
43a99f08 416## UINT64 Rip;\r
7b8c3785 417 popq (%rax)\r
43a99f08 418\r
419## UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
420## NOTE - modified segment registers could hang the debugger... We\r
421## could attempt to insulate ourselves against this possibility,\r
422## but that poses risks as well.\r
423##\r
424\r
7b8c3785 425 popq %rax\r
426 # movq %rax, %gs\r
427 popq %rax\r
428 # movq %rax, %fs\r
429 popq %rax\r
430 movq %rax, %es\r
431 popq %rax\r
432 movq %rax, %ds\r
433 movq ASM_PFX(AppRsp), %rax \r
434 popq 8(%rax)\r
435 popq %rax\r
436 movq %rax, %ss\r
43a99f08 437## The next stuff to restore is the general purpose registers that were pushed\r
438## using the "push" instruction.\r
439##\r
440## The value of RSP as stored in the context record is the application RSP\r
441## including the 5 entries on the application stack caused by the exception\r
442## itself. It may have been modified by the debug agent, so we need to\r
443## determine if we need to relocate the application stack.\r
444\r
7b8c3785 445 movq 24(%rsp), %rbx # move the potentially modified AppRsp into rbx\r
446 movq ASM_PFX(AppRsp), %rax \r
447 addq $40, %rax\r
448 cmpq %rax, %rbx\r
43a99f08 449 je NoAppStackMove\r
450\r
7b8c3785 451 movq ASM_PFX(AppRsp), %rax \r
452 movq (%rax), %rcx # RIP\r
453 movq %rcx, (%rbx)\r
43a99f08 454\r
7b8c3785 455 movq 8(%rax), %rcx # CS\r
456 movq %rcx, 8(%rbx)\r
43a99f08 457\r
7b8c3785 458 movq 16(%rax), %rcx # RFLAGS\r
459 movq %rcx, 16(%rbx)\r
43a99f08 460\r
7b8c3785 461 movq 24(%rax), %rcx # RSP\r
462 movq %rcx, 24(%rbx)\r
43a99f08 463\r
7b8c3785 464 movq 32(%rax), %rcx # SS\r
465 movq %rcx, 32(%rbx)\r
43a99f08 466\r
7b8c3785 467 movq %rbx, %rax # modify the saved AppRsp to the new AppRsp\r
468 movq %rax, ASM_PFX(AppRsp)\r
43a99f08 469NoAppStackMove:\r
7b8c3785 470 movq ASM_PFX(DebugRsp), %rax # restore the DebugRsp on the debug stack\r
43a99f08 471 # so our "pop" will not cause a stack switch\r
7b8c3785 472 movq %rax, 24(%rsp)\r
43a99f08 473\r
7b8c3785 474 cmpl $0x068, ASM_PFX(ExceptionNumber)\r
43a99f08 475 jne NoChain\r
476\r
477Chain:\r
478\r
479## Restore rflags so when we chain, the flags will be exactly as if we were never here.\r
480## We gin up the stack to do an iretq so we can get ALL the flags.\r
7b8c3785 481 movq ASM_PFX(AppRsp), %rax \r
482 movq 40(%rax), %rbx\r
483 pushq %rbx\r
484 movq %ss, %rax\r
485 pushq %rax\r
486 movq %rsp, %rax\r
487 addq $16, %rax\r
488 pushq %rax\r
489 movq ASM_PFX(AppRsp), %rax \r
490 movq 16(%rax), %rbx\r
491 andq $0xfffffffffffffcff, %rbx # special handling for IF and TF\r
492 pushq %rbx\r
493 movq %cs, %rax\r
494 pushq %rax\r
495 movq PhonyIretq, %rax \r
496 pushq %rax\r
43a99f08 497 iretq\r
498PhonyIretq:\r
499\r
500## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
501## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
7b8c3785 502 popq %rdi\r
503 popq %rsi\r
504 popq %rbp\r
505 popq %rsp\r
506 popq %rbx\r
507 popq %rdx\r
508 popq %rcx\r
509 popq %rax\r
510 popq %r8\r
511 popq %r9\r
512 popq %r10\r
513 popq %r11\r
514 popq %r12\r
515 popq %r13\r
516 popq %r14\r
517 popq %r15\r
43a99f08 518\r
519## Switch back to application stack\r
7b8c3785 520 movq ASM_PFX(AppRsp), %rsp \r
43a99f08 521## Jump to original handler\r
522 jmp ASM_PFX(OrigVector)\r
523NoChain:\r
524## UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
525## UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
7b8c3785 526 popq %rdi\r
527 popq %rsi\r
528 popq %rbp\r
529 popq %rsp\r
530 popq %rbx\r
531 popq %rdx\r
532 popq %rcx\r
533 popq %rax\r
534 popq %r8\r
535 popq %r9\r
536 popq %r10\r
537 popq %r11\r
538 popq %r12\r
539 popq %r13\r
540 popq %r14\r
541 popq %r15\r
43a99f08 542\r
543## Switch back to application stack\r
7b8c3785 544 movq ASM_PFX(AppRsp), %rsp \r
43a99f08 545\r
546## We're outa here...\r
547 iret\r