-#------------------------------------------------------------------------------
-#*
-#* Copyright 2006 - 2009, Intel Corporation
-#* All rights reserved. This program and the accompanying materials
-#* are licensed and made available under the terms and conditions of the BSD License
-#* which accompanies this distribution. The full text of the license may be found at
-#* http://opensource.org/licenses/bsd-license.php
-#*
-#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#*
-#* CpuAsm.S
-#*
-#* Abstract:
-#*
-#------------------------------------------------------------------------------
-
-
-#.MMX
-#.XMM
-
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
-
-
-#
-# point to the external interrupt vector table
-#
-ExternalVectorTablePtr:
- .byte 0, 0, 0, 0
-
-ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)
-ASM_PFX(InitializeExternalVectorTablePtr):
- movl 4(%esp), %eax
- movl %eax, ExternalVectorTablePtr
- ret
-
-#------------------------------------------------------------------------------
-# VOID
-# SetCodeSelector (
-# UINT16 Selector
-# );
-#------------------------------------------------------------------------------
-ASM_GLOBAL ASM_PFX(SetCodeSelector)
-ASM_PFX(SetCodeSelector):
- movl 4(%esp), %ecx
- subl $0x10, %esp
- leal setCodeSelectorLongJump, %eax
- movl %eax, (%esp)
- movw %cx, 4(%esp)
- .byte 0xFF, 0x2C, 0x24 # jmp *(%esp) note:(FWORD jmp)
-setCodeSelectorLongJump:
- addl $0x10, %esp
- ret
-
-#------------------------------------------------------------------------------
-# VOID
-# SetDataSelectors (
-# UINT16 Selector
-# );
-#------------------------------------------------------------------------------
-ASM_GLOBAL ASM_PFX(SetDataSelectors)
-ASM_PFX(SetDataSelectors):
- movl 4(%esp), %ecx
- movw %cx, %ss
- movw %cx, %ds
- movw %cx, %es
- movw %cx, %fs
- movw %cx, %gs
- ret
-
-#---------------------------------------;
-# CommonInterruptEntry ;
-#---------------------------------------;
-# The follow algorithm is used for the common interrupt routine.
-
-ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
-ASM_PFX(CommonInterruptEntry):
- cli
- #
- # All interrupt handlers are invoked through interrupt gates, so
- # IF flag automatically cleared at the entry point
- #
-
- #
- # Calculate vector number
- #
- # Get the return address of call, actually, it is the
- # address of vector number.
- #
- xchgl (%esp), %ecx
- movw (%ecx), %cx
- andl $0x0FFFF, %ecx
- cmpl $32, %ecx # Intel reserved vector for exceptions?
- jae NoErrorCode
- bt %ecx, ASM_PFX(mErrorCodeFlag)
- jc HasErrorCode
-
-NoErrorCode:
-
- #
- # Stack:
- # +---------------------+
- # + EFlags +
- # +---------------------+
- # + CS +
- # +---------------------+
- # + EIP +
- # +---------------------+
- # + ECX +
- # +---------------------+ <-- ESP
- #
- # Registers:
- # ECX - Vector Number
- #
-
- #
- # Put Vector Number on stack
- #
- pushl %ecx
-
- #
- # Put 0 (dummy) error code on stack, and restore ECX
- #
- xorl %ecx, %ecx # ECX = 0
- xchgl 4(%esp), %ecx
-
- jmp ErrorCodeAndVectorOnStack
-
-HasErrorCode:
-
- #
- # Stack:
- # +---------------------+
- # + EFlags +
- # +---------------------+
- # + CS +
- # +---------------------+
- # + EIP +
- # +---------------------+
- # + Error Code +
- # +---------------------+
- # + ECX +
- # +---------------------+ <-- ESP
- #
- # Registers:
- # ECX - Vector Number
- #
-
- #
- # Put Vector Number on stack and restore ECX
- #
- xchgl (%esp), %ecx
-
- #
- # Fall through to join main routine code
- # at ErrorCodeAndVectorOnStack
- #
-CommonInterruptEntry_al_0000:
- jmp CommonInterruptEntry_al_0000
-
-ErrorCodeAndVectorOnStack:
- pushl %ebp
- movl %esp, %ebp
-
- #
- # Stack:
- # +---------------------+
- # + EFlags +
- # +---------------------+
- # + CS +
- # +---------------------+
- # + EIP +
- # +---------------------+
- # + Error Code +
- # +---------------------+
- # + Vector Number +
- # +---------------------+
- # + EBP +
- # +---------------------+ <-- EBP
- #
-
- #
- # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
- # is 16-byte aligned
- #
- andl $0x0fffffff0, %esp
- subl $12, %esp
-
-#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- pushl %eax
- pushl %ecx
- pushl %edx
- pushl %ebx
- leal 24(%ebp), %ecx
- pushl %ecx # ESP
- pushl (%ebp) # EBP
- pushl %esi
- pushl %edi
-
-#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
- movl %ss, %eax
- pushl %eax
- movzwl 16(%ebp), %eax
- pushl %eax
- movl %ds, %eax
- pushl %eax
- movl %es, %eax
- pushl %eax
- movl %fs, %eax
- pushl %eax
- movl %gs, %eax
- pushl %eax
-
-#; UINT32 Eip;
- movl 12(%ebp), %eax
- pushl %eax
-
-#; UINT32 Gdtr[2], Idtr[2];
- subl $8, %esp
- sidt (%esp)
- movl 2(%esp), %eax
- xchgl (%esp), %eax
- andl $0x0FFFF, %eax
- movl %eax, 4(%esp)
-
- subl $8, %esp
- sgdt (%esp)
- movl 2(%esp), %eax
- xchgl (%esp), %eax
- andl $0x0FFFF, %eax
- movl %eax, 4(%esp)
-
-#; UINT32 Ldtr, Tr;
- xorl %eax, %eax
- str %ax
- pushl %eax
- sldt %ax
- pushl %eax
-
-#; UINT32 EFlags;
- movl 20(%ebp), %eax
- pushl %eax
-
-#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- movl %cr4, %eax
- orl $0x208, %eax
- movl %eax, %cr4
- pushl %eax
- movl %cr3, %eax
- pushl %eax
- movl %cr2, %eax
- pushl %eax
- xorl %eax, %eax
- pushl %eax
- movl %cr0, %eax
- pushl %eax
-
-#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- movl %dr7, %eax
- pushl %eax
-#; clear Dr7 while executing debugger itself
- xorl %eax, %eax
- movl %eax, %dr7
-
- movl %dr6, %eax
- pushl %eax
-#; insure all status bits in dr6 are clear...
- xorl %eax, %eax
- movl %eax, %dr6
-
- movl %dr3, %eax
- pushl %eax
- movl %dr2, %eax
- pushl %eax
- movl %dr1, %eax
- pushl %eax
- movl %dr0, %eax
- pushl %eax
-
-#; FX_SAVE_STATE_IA32 FxSaveState;
- subl $512, %esp
- movl %esp, %edi
- .byte 0x0f, 0x0ae, 0x07 #fxsave [edi]
-
-#; UINT32 ExceptionData;
- pushl 8(%ebp)
-
-#; call into exception handler
- movl ExternalVectorTablePtr, %eax # get the interrupt vectors base
- orl %eax, %eax # NULL?
- jz nullExternalExceptionHandler
-
- mov 4(%ebp), %ecx
- movl (%eax,%ecx,4), %eax
- orl %eax, %eax # NULL?
- jz nullExternalExceptionHandler
-
-#; Prepare parameter and call
- movl %esp, %edx
- pushl %edx
- movl 4(%ebp), %edx
- pushl %edx
-
- #
- # Call External Exception Handler
- #
- call *%eax
- addl $8, %esp
-
-nullExternalExceptionHandler:
-
- cli
-#; UINT32 ExceptionData;
- addl $4, %esp
-
-#; FX_SAVE_STATE_IA32 FxSaveState;
- movl %esp, %esi
- .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]
- addl $512, %esp
-
-#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- popl %eax
- movl %eax, %dr0
- popl %eax
- movl %eax, %dr1
- popl %eax
- movl %eax, %dr2
- popl %eax
- movl %eax, %dr3
-#; skip restore of dr6. We cleared dr6 during the context save.
- addl $4, %esp
- popl %eax
- movl %eax, %dr7
-
-#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
- popl %eax
- movl %eax, %cr0
- addl $4, %esp # not for Cr1
- popl %eax
- movl %eax, %cr2
- popl %eax
- movl %eax, %cr3
- popl %eax
- movl %eax, %cr4
-
-#; UINT32 EFlags;
- popl 20(%ebp)
-
-#; UINT32 Ldtr, Tr;
-#; UINT32 Gdtr[2], Idtr[2];
-#; Best not let anyone mess with these particular registers...
- addl $24, %esp
-
-#; UINT32 Eip;
- popl 12(%ebp)
-
-#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
-#; NOTE - modified segment registers could hang the debugger... We
-#; could attempt to insulate ourselves against this possibility,
-#; but that poses risks as well.
-#;
- popl %gs
- popl %fs
- popl %es
- popl %ds
- popl 16(%ebp)
- popl %ss
-
-#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
- popl %edi
- popl %esi
- addl $4, %esp # not for ebp
- addl $4, %esp # not for esp
- popl %ebx
- popl %edx
- popl %ecx
- popl %eax
-
- movl %ebp, %esp
- popl %ebp
- addl $8, %esp
- iretl
-
-
-#END
-
+#------------------------------------------------------------------------------\r
+#*\r
+#* Copyright 2006 - 2009, Intel Corporation\r
+#* All rights reserved. This program and the accompanying materials\r
+#* are licensed and made available under the terms and conditions of the BSD License\r
+#* which accompanies this distribution. The full text of the license may be found at\r
+#* http://opensource.org/licenses/bsd-license.php\r
+#*\r
+#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#*\r
+#* CpuAsm.S\r
+#*\r
+#* Abstract:\r
+#*\r
+#------------------------------------------------------------------------------\r
+\r
+\r
+#.MMX\r
+#.XMM\r
+\r
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
+\r
+\r
+#\r
+# point to the external interrupt vector table\r
+#\r
+ExternalVectorTablePtr:\r
+ .byte 0, 0, 0, 0\r
+\r
+ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)\r
+ASM_PFX(InitializeExternalVectorTablePtr):\r
+ movl 4(%esp), %eax\r
+ movl %eax, ExternalVectorTablePtr\r
+ ret\r
+\r
+#------------------------------------------------------------------------------\r
+# VOID\r
+# SetCodeSelector (\r
+# UINT16 Selector\r
+# );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(SetCodeSelector)\r
+ASM_PFX(SetCodeSelector):\r
+ movl 4(%esp), %ecx\r
+ subl $0x10, %esp \r
+ leal setCodeSelectorLongJump, %eax \r
+ movl %eax, (%esp)\r
+ movw %cx, 4(%esp)\r
+ .byte 0xFF, 0x2C, 0x24 # jmp *(%esp) note:(FWORD jmp) \r
+setCodeSelectorLongJump:\r
+ addl $0x10, %esp \r
+ ret\r
+\r
+#------------------------------------------------------------------------------\r
+# VOID\r
+# SetDataSelectors (\r
+# UINT16 Selector\r
+# );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(SetDataSelectors)\r
+ASM_PFX(SetDataSelectors):\r
+ movl 4(%esp), %ecx\r
+ movw %cx, %ss\r
+ movw %cx, %ds\r
+ movw %cx, %es\r
+ movw %cx, %fs\r
+ movw %cx, %gs\r
+ ret\r
+\r
+#---------------------------------------;\r
+# CommonInterruptEntry ;\r
+#---------------------------------------;\r
+# The follow algorithm is used for the common interrupt routine.\r
+\r
+ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
+ASM_PFX(CommonInterruptEntry):\r
+ cli\r
+ #\r
+ # All interrupt handlers are invoked through interrupt gates, so\r
+ # IF flag automatically cleared at the entry point\r
+ #\r
+\r
+ #\r
+ # Calculate vector number\r
+ #\r
+ # Get the return address of call, actually, it is the\r
+ # address of vector number.\r
+ #\r
+ xchgl (%esp), %ecx\r
+ movw (%ecx), %cx\r
+ andl $0x0FFFF, %ecx\r
+ cmpl $32, %ecx # Intel reserved vector for exceptions?\r
+ jae NoErrorCode\r
+ bt %ecx, ASM_PFX(mErrorCodeFlag)\r
+ jc HasErrorCode\r
+\r
+NoErrorCode:\r
+\r
+ #\r
+ # Stack:\r
+ # +---------------------+\r
+ # + EFlags +\r
+ # +---------------------+\r
+ # + CS +\r
+ # +---------------------+\r
+ # + EIP +\r
+ # +---------------------+\r
+ # + ECX +\r
+ # +---------------------+ <-- ESP\r
+ #\r
+ # Registers:\r
+ # ECX - Vector Number\r
+ #\r
+\r
+ #\r
+ # Put Vector Number on stack\r
+ #\r
+ pushl %ecx\r
+\r
+ #\r
+ # Put 0 (dummy) error code on stack, and restore ECX\r
+ #\r
+ xorl %ecx, %ecx # ECX = 0\r
+ xchgl 4(%esp), %ecx\r
+\r
+ jmp ErrorCodeAndVectorOnStack\r
+\r
+HasErrorCode:\r
+\r
+ #\r
+ # Stack:\r
+ # +---------------------+\r
+ # + EFlags +\r
+ # +---------------------+\r
+ # + CS +\r
+ # +---------------------+\r
+ # + EIP +\r
+ # +---------------------+\r
+ # + Error Code +\r
+ # +---------------------+\r
+ # + ECX +\r
+ # +---------------------+ <-- ESP\r
+ #\r
+ # Registers:\r
+ # ECX - Vector Number\r
+ #\r
+\r
+ #\r
+ # Put Vector Number on stack and restore ECX\r
+ #\r
+ xchgl (%esp), %ecx \r
+\r
+ #\r
+ # Fall through to join main routine code\r
+ # at ErrorCodeAndVectorOnStack\r
+ #\r
+CommonInterruptEntry_al_0000:\r
+ jmp CommonInterruptEntry_al_0000\r
+\r
+ErrorCodeAndVectorOnStack:\r
+ pushl %ebp\r
+ movl %esp, %ebp\r
+\r
+ #\r
+ # Stack:\r
+ # +---------------------+\r
+ # + EFlags +\r
+ # +---------------------+\r
+ # + CS +\r
+ # +---------------------+\r
+ # + EIP +\r
+ # +---------------------+\r
+ # + Error Code +\r
+ # +---------------------+\r
+ # + Vector Number +\r
+ # +---------------------+\r
+ # + EBP +\r
+ # +---------------------+ <-- EBP\r
+ #\r
+\r
+ #\r
+ # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32\r
+ # is 16-byte aligned\r
+ #\r
+ andl $0x0fffffff0, %esp \r
+ subl $12, %esp\r
+\r
+#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
+ pushl %eax\r
+ pushl %ecx\r
+ pushl %edx\r
+ pushl %ebx\r
+ leal 24(%ebp), %ecx\r
+ pushl %ecx # ESP\r
+ pushl (%ebp) # EBP\r
+ pushl %esi\r
+ pushl %edi\r
+\r
+#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
+ movl %ss, %eax\r
+ pushl %eax\r
+ movzwl 16(%ebp), %eax \r
+ pushl %eax\r
+ movl %ds, %eax\r
+ pushl %eax\r
+ movl %es, %eax\r
+ pushl %eax\r
+ movl %fs, %eax\r
+ pushl %eax\r
+ movl %gs, %eax\r
+ pushl %eax\r
+\r
+#; UINT32 Eip;\r
+ movl 12(%ebp), %eax\r
+ pushl %eax\r
+\r
+#; UINT32 Gdtr[2], Idtr[2];\r
+ subl $8, %esp\r
+ sidt (%esp)\r
+ movl 2(%esp), %eax\r
+ xchgl (%esp), %eax\r
+ andl $0x0FFFF, %eax \r
+ movl %eax, 4(%esp)\r
+\r
+ subl $8, %esp\r
+ sgdt (%esp)\r
+ movl 2(%esp), %eax\r
+ xchgl (%esp), %eax\r
+ andl $0x0FFFF, %eax \r
+ movl %eax, 4(%esp)\r
+\r
+#; UINT32 Ldtr, Tr;\r
+ xorl %eax, %eax\r
+ str %ax\r
+ pushl %eax\r
+ sldt %ax\r
+ pushl %eax\r
+\r
+#; UINT32 EFlags;\r
+ movl 20(%ebp), %eax\r
+ pushl %eax\r
+\r
+#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
+ movl %cr4, %eax\r
+ orl $0x208, %eax\r
+ movl %eax, %cr4\r
+ pushl %eax\r
+ movl %cr3, %eax\r
+ pushl %eax\r
+ movl %cr2, %eax\r
+ pushl %eax\r
+ xorl %eax, %eax\r
+ pushl %eax\r
+ movl %cr0, %eax\r
+ pushl %eax\r
+\r
+#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+ movl %dr7, %eax\r
+ pushl %eax\r
+#; clear Dr7 while executing debugger itself\r
+ xorl %eax, %eax\r
+ movl %eax, %dr7\r
+\r
+ movl %dr6, %eax\r
+ pushl %eax\r
+#; insure all status bits in dr6 are clear...\r
+ xorl %eax, %eax\r
+ movl %eax, %dr6\r
+\r
+ movl %dr3, %eax\r
+ pushl %eax\r
+ movl %dr2, %eax\r
+ pushl %eax\r
+ movl %dr1, %eax\r
+ pushl %eax\r
+ movl %dr0, %eax\r
+ pushl %eax\r
+\r
+#; FX_SAVE_STATE_IA32 FxSaveState;\r
+ subl $512, %esp\r
+ movl %esp, %edi\r
+ .byte 0x0f, 0x0ae, 0x07 #fxsave [edi]\r
+\r
+#; UINT32 ExceptionData;\r
+ pushl 8(%ebp)\r
+\r
+#; call into exception handler\r
+ movl ExternalVectorTablePtr, %eax # get the interrupt vectors base\r
+ orl %eax, %eax # NULL?\r
+ jz nullExternalExceptionHandler\r
+\r
+ mov 4(%ebp), %ecx\r
+ movl (%eax,%ecx,4), %eax\r
+ orl %eax, %eax # NULL?\r
+ jz nullExternalExceptionHandler\r
+\r
+#; Prepare parameter and call\r
+ movl %esp, %edx\r
+ pushl %edx\r
+ movl 4(%ebp), %edx\r
+ pushl %edx\r
+\r
+ #\r
+ # Call External Exception Handler\r
+ #\r
+ call *%eax\r
+ addl $8, %esp\r
+\r
+nullExternalExceptionHandler:\r
+\r
+ cli\r
+#; UINT32 ExceptionData;\r
+ addl $4, %esp\r
+\r
+#; FX_SAVE_STATE_IA32 FxSaveState;\r
+ movl %esp, %esi\r
+ .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]\r
+ addl $512, %esp\r
+\r
+#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+ popl %eax\r
+ movl %eax, %dr0\r
+ popl %eax\r
+ movl %eax, %dr1\r
+ popl %eax\r
+ movl %eax, %dr2\r
+ popl %eax\r
+ movl %eax, %dr3\r
+#; skip restore of dr6. We cleared dr6 during the context save.\r
+ addl $4, %esp\r
+ popl %eax\r
+ movl %eax, %dr7\r
+\r
+#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
+ popl %eax\r
+ movl %eax, %cr0\r
+ addl $4, %esp # not for Cr1\r
+ popl %eax\r
+ movl %eax, %cr2\r
+ popl %eax\r
+ movl %eax, %cr3\r
+ popl %eax\r
+ movl %eax, %cr4\r
+\r
+#; UINT32 EFlags;\r
+ popl 20(%ebp)\r
+\r
+#; UINT32 Ldtr, Tr;\r
+#; UINT32 Gdtr[2], Idtr[2];\r
+#; Best not let anyone mess with these particular registers...\r
+ addl $24, %esp\r
+\r
+#; UINT32 Eip;\r
+ popl 12(%ebp)\r
+\r
+#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
+#; NOTE - modified segment registers could hang the debugger... We\r
+#; could attempt to insulate ourselves against this possibility,\r
+#; but that poses risks as well.\r
+#;\r
+ popl %gs\r
+ popl %fs\r
+ popl %es\r
+ popl %ds\r
+ popl 16(%ebp)\r
+ popl %ss\r
+\r
+#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
+ popl %edi\r
+ popl %esi\r
+ addl $4, %esp # not for ebp\r
+ addl $4, %esp # not for esp\r
+ popl %ebx\r
+ popl %edx\r
+ popl %ecx\r
+ popl %eax\r
+\r
+ movl %ebp, %esp\r
+ popl %ebp\r
+ addl $8, %esp\r
+ iretl\r
+\r
+\r
+#END\r
+\r
-#------------------------------------------------------------------------------
-#
-# Copyright (c) 2006 - 2009, Intel Corporation
-# All rights reserved. This program and the accompanying materials
-# are licensed and made available under the terms and conditions of the BSD License
-# which accompanies this distribution. The full text of the license may be found at
-# http://opensource.org/licenses/bsd-license.php
-#
-# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#
-# Module Name:
-#
-# IvtAsm.S
-#
-# Abstract:
-#
-# Interrupt Vector Table
-#
-#------------------------------------------------------------------------------
-
-#
-# Interrupt Vector Table
-#
-
-.macro SingleIdtVectorMacro vectorNum
- call ASM_PFX(CommonInterruptEntry)
- .short \vectorNum
- nop
-.endm
-
-.macro EightIdtVectors firstVectorNum
- SingleIdtVectorMacro \firstVectorNum
- SingleIdtVectorMacro "(\firstVectorNum+1)"
- SingleIdtVectorMacro "(\firstVectorNum+2)"
- SingleIdtVectorMacro "(\firstVectorNum+3)"
- SingleIdtVectorMacro "(\firstVectorNum+4)"
- SingleIdtVectorMacro "(\firstVectorNum+5)"
- SingleIdtVectorMacro "(\firstVectorNum+6)"
- SingleIdtVectorMacro "(\firstVectorNum+7)"
-.endm
-
-.macro SixtyFourIdtVectors firstVectorNum
- EightIdtVectors \firstVectorNum
- EightIdtVectors "(\firstVectorNum+0x08)"
- EightIdtVectors "(\firstVectorNum+0x10)"
- EightIdtVectors "(\firstVectorNum+0x18)"
- EightIdtVectors "(\firstVectorNum+0x20)"
- EightIdtVectors "(\firstVectorNum+0x28)"
- EightIdtVectors "(\firstVectorNum+0x30)"
- EightIdtVectors "(\firstVectorNum+0x38)"
-.endm
-
-ASM_GLOBAL ASM_PFX(AsmIdtVector00)
-.align 8
-ASM_PFX(AsmIdtVector00):
- SixtyFourIdtVectors 0x00
- SixtyFourIdtVectors 0x40
- SixtyFourIdtVectors 0x80
- SixtyFourIdtVectors 0xC0
-ASM_GLOBAL ASM_PFX(AsmCommonIdtEnd)
-ASM_PFX(AsmCommonIdtEnd):
- .byte 0
-
-
+#------------------------------------------------------------------------------\r
+#\r
+# Copyright (c) 2006 - 2009, Intel Corporation\r
+# All rights reserved. This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution. The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+# Module Name:\r
+#\r
+# IvtAsm.S\r
+#\r
+# Abstract:\r
+#\r
+# Interrupt Vector Table\r
+#\r
+#------------------------------------------------------------------------------\r
+\r
+#\r
+# Interrupt Vector Table\r
+#\r
+\r
+.macro SingleIdtVectorMacro vectorNum\r
+ call ASM_PFX(CommonInterruptEntry)\r
+ .short \vectorNum\r
+ nop\r
+.endm\r
+\r
+.macro EightIdtVectors firstVectorNum\r
+ SingleIdtVectorMacro \firstVectorNum\r
+ SingleIdtVectorMacro "(\firstVectorNum+1)"\r
+ SingleIdtVectorMacro "(\firstVectorNum+2)"\r
+ SingleIdtVectorMacro "(\firstVectorNum+3)"\r
+ SingleIdtVectorMacro "(\firstVectorNum+4)"\r
+ SingleIdtVectorMacro "(\firstVectorNum+5)"\r
+ SingleIdtVectorMacro "(\firstVectorNum+6)"\r
+ SingleIdtVectorMacro "(\firstVectorNum+7)"\r
+.endm\r
+\r
+.macro SixtyFourIdtVectors firstVectorNum\r
+ EightIdtVectors \firstVectorNum\r
+ EightIdtVectors "(\firstVectorNum+0x08)"\r
+ EightIdtVectors "(\firstVectorNum+0x10)"\r
+ EightIdtVectors "(\firstVectorNum+0x18)"\r
+ EightIdtVectors "(\firstVectorNum+0x20)"\r
+ EightIdtVectors "(\firstVectorNum+0x28)"\r
+ EightIdtVectors "(\firstVectorNum+0x30)"\r
+ EightIdtVectors "(\firstVectorNum+0x38)"\r
+.endm\r
+\r
+ASM_GLOBAL ASM_PFX(AsmIdtVector00)\r
+.align 8\r
+ASM_PFX(AsmIdtVector00):\r
+ SixtyFourIdtVectors 0x00\r
+ SixtyFourIdtVectors 0x40\r
+ SixtyFourIdtVectors 0x80\r
+ SixtyFourIdtVectors 0xC0\r
+ASM_GLOBAL ASM_PFX(AsmCommonIdtEnd)\r
+ASM_PFX(AsmCommonIdtEnd):\r
+ .byte 0\r
+\r
+\r
-# TITLE CpuAsm.S:
-
-#------------------------------------------------------------------------------
-#*
-#* Copyright 2008 - 2009, Intel Corporation
-#* All rights reserved. This program and the accompanying materials
-#* are licensed and made available under the terms and conditions of the BSD License
-#* which accompanies this distribution. The full text of the license may be found at
-#* http://opensource.org/licenses/bsd-license.php
-#*
-#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#*
-#* CpuAsm.S
-#*
-#* Abstract:
-#*
-#------------------------------------------------------------------------------
-
-
-#text SEGMENT
-
-
-#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
-
-
-#
-# point to the external interrupt vector table
-#
-ExternalVectorTablePtr:
- .byte 0, 0, 0, 0, 0, 0, 0, 0
-
-ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)
-ASM_PFX(InitializeExternalVectorTablePtr):
- lea ExternalVectorTablePtr(%rip), %rax # save vector number
- mov %rcx, (%rax)
- ret
-
-
-#------------------------------------------------------------------------------
-# VOID
-# SetCodeSelector (
-# UINT16 Selector
-# );
-#------------------------------------------------------------------------------
-ASM_GLOBAL ASM_PFX(SetCodeSelector)
-ASM_PFX(SetCodeSelector):
- subq $0x10, %rsp
- leaq setCodeSelectorLongJump(%rip), %rax
- movq %rax, (%rsp)
- movw %cx, 4(%rsp)
- .byte 0xFF, 0x2C, 0x24 # jmp (%rsp) note:fword jmp
-setCodeSelectorLongJump:
- addq $0x10, %rsp
- ret
-
-#------------------------------------------------------------------------------
-# VOID
-# SetDataSelectors (
-# UINT16 Selector
-# );
-#------------------------------------------------------------------------------
-ASM_GLOBAL ASM_PFX(SetDataSelectors)
-ASM_PFX(SetDataSelectors):
- movw %cx, %ss
- movw %cx, %ds
- movw %cx, %es
- movw %cx, %fs
- movw %cx, %gs
- ret
-
-#---------------------------------------;
-# CommonInterruptEntry ;
-#---------------------------------------;
-# The follow algorithm is used for the common interrupt routine.
-
-ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
-ASM_PFX(CommonInterruptEntry):
- cli
- #
- # All interrupt handlers are invoked through interrupt gates, so
- # IF flag automatically cleared at the entry point
- #
- #
- # Calculate vector number
- #
- xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.
- movzwl (%rcx), %ecx
- cmp $32, %ecx # Intel reserved vector for exceptions?
- jae NoErrorCode
- pushq %rax
- leaq ASM_PFX(mErrorCodeFlag)(%rip), %rax
- bt %ecx, (%rax)
- popq %rax
- jc CommonInterruptEntry_al_0000
-
-NoErrorCode:
-
- #
- # Push a dummy error code on the stack
- # to maintain coherent stack map
- #
- pushq (%rsp)
- movq $0, 8(%rsp)
-CommonInterruptEntry_al_0000:
- pushq %rbp
- movq %rsp, %rbp
-
- #
- # Stack:
- # +---------------------+ <-- 16-byte aligned ensured by processor
- # + Old SS +
- # +---------------------+
- # + Old RSP +
- # +---------------------+
- # + RFlags +
- # +---------------------+
- # + CS +
- # +---------------------+
- # + RIP +
- # +---------------------+
- # + Error Code +
- # +---------------------+
- # + RCX / Vector Number +
- # +---------------------+
- # + RBP +
- # +---------------------+ <-- RBP, 16-byte aligned
- #
-
-
- #
- # Since here the stack pointer is 16-byte aligned, so
- # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
- # is 16-byte aligned
- #
-
-#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
- pushq %r15
- pushq %r14
- pushq %r13
- pushq %r12
- pushq %r11
- pushq %r10
- pushq %r9
- pushq %r8
- pushq %rax
- pushq 8(%rbp) # RCX
- pushq %rdx
- pushq %rbx
- pushq 48(%rbp) # RSP
- pushq (%rbp) # RBP
- pushq %rsi
- pushq %rdi
-
-#; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
- movzwq 56(%rbp), %rax
- pushq %rax # for ss
- movzwq 32(%rbp), %rax
- pushq %rax # for cs
- movq %ds, %rax
- pushq %rax
- movq %es, %rax
- pushq %rax
- movq %fs, %rax
- pushq %rax
- movq %gs, %rax
- pushq %rax
-
- movq %rcx, 8(%rbp) # save vector number
-
-#; UINT64 Rip;
- pushq 24(%rbp)
-
-#; UINT64 Gdtr[2], Idtr[2];
- xorq %rax, %rax
- pushq %rax
- pushq %rax
- sidt (%rsp)
- xchgq 2(%rsp), %rax
- xchgq (%rsp), %rax
- xchgq 8(%rsp), %rax
-
- xorq %rax, %rax
- pushq %rax
- pushq %rax
- sgdt (%rsp)
- xchgq 2(%rsp), %rax
- xchgq (%rsp), %rax
- xchgq 8(%rsp), %rax
-
-#; UINT64 Ldtr, Tr;
- xorq %rax, %rax
- str %ax
- pushq %rax
- sldt %ax
- pushq %rax
-
-#; UINT64 RFlags;
- pushq 40(%rbp)
-
-#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
- movq %cr8, %rax
- pushq %rax
- movq %cr4, %rax
- orq $0x208, %rax
- movq %rax, %cr4
- pushq %rax
- mov %cr3, %rax
- pushq %rax
- mov %cr2, %rax
- pushq %rax
- xorq %rax, %rax
- pushq %rax
- mov %cr0, %rax
- pushq %rax
-
-#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- movq %dr7, %rax
- pushq %rax
-#; clear Dr7 while executing debugger itself
- xorq %rax, %rax
- movq %rax, %dr7
-
- movq %dr6, %rax
- pushq %rax
-#; insure all status bits in dr6 are clear...
- xorq %rax, %rax
- movq %rax, %dr6
-
- movq %dr3, %rax
- pushq %rax
- movq %dr2, %rax
- pushq %rax
- movq %dr1, %rax
- pushq %rax
- movq %dr0, %rax
- pushq %rax
-
-#; FX_SAVE_STATE_X64 FxSaveState;
- subq $512, %rsp
- movq %rsp, %rdi
- .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi]
-
-#; UINT32 ExceptionData;
- pushq 16(%rbp)
-
-#; call into exception handler
- movq 8(%rbp), %rcx
- leaq ExternalVectorTablePtr(%rip), %rax
- movl (%eax), %eax
- movq (%rax,%rcx,8), %rax
- orq %rax, %rax # NULL?
-
- je nonNullValue#
-
-#; Prepare parameter and call
-# mov rcx, [rbp + 8]
- mov %rsp, %rdx
- #
- # Per X64 calling convention, allocate maximum parameter stack space
- # and make sure RSP is 16-byte aligned
- #
- subq $40, %rsp
- call *%rax
- addq $40, %rsp
-
-nonNullValue:
- cli
-#; UINT64 ExceptionData;
- addq $8, %rsp
-
-#; FX_SAVE_STATE_X64 FxSaveState;
-
- movq %rsp, %rsi
- .byte 0x0f, 0x0ae, 0x0E # fxrstor [rsi]
- addq $512, %rsp
-
-#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
- popq %rax
- movq %rax, %dr0
- popq %rax
- movq %rax, %dr1
- popq %rax
- movq %rax, %dr2
- popq %rax
- movq %rax, %dr3
-#; skip restore of dr6. We cleared dr6 during the context save.
- addq $8, %rsp
- popq %rax
- movq %rax, %dr7
-
-#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
- popq %rax
- movq %rax, %cr0
- addq $8, %rsp # not for Cr1
- popq %rax
- movq %rax, %cr2
- popq %rax
- movq %rax, %cr3
- popq %rax
- movq %rax, %cr4
- popq %rax
- movq %rax, %cr8
-
-#; UINT64 RFlags;
- popq 40(%rbp)
-
-#; UINT64 Ldtr, Tr;
-#; UINT64 Gdtr[2], Idtr[2];
-#; Best not let anyone mess with these particular registers...
- addq $48, %rsp
-
-#; UINT64 Rip;
- popq 24(%rbp)
-
-#; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
- popq %rax
- # mov %rax, %gs ; not for gs
- popq %rax
- # mov %rax, %fs ; not for fs
- # (X64 will not use fs and gs, so we do not restore it)
- popq %rax
- movq %rax, %es
- popq %rax
- movq %rax, %ds
- popq 32(%rbp) # for cs
- popq 56(%rbp) # for ss
-
-#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
-#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
- popq %rdi
- popq %rsi
- addq $8, %rsp # not for rbp
- popq 48(%rbp) # for rsp
- popq %rbx
- popq %rdx
- popq %rcx
- popq %rax
- popq %r8
- popq %r9
- popq %r10
- popq %r11
- popq %r12
- popq %r13
- popq %r14
- popq %r15
-
- movq %rbp, %rsp
- popq %rbp
- addq $16, %rsp
- iretq
-
-
-#text ENDS
-
-#END
-
-
+# TITLE CpuAsm.S: \r
+\r
+#------------------------------------------------------------------------------\r
+#*\r
+#* Copyright 2008 - 2009, Intel Corporation\r
+#* All rights reserved. This program and the accompanying materials\r
+#* are licensed and made available under the terms and conditions of the BSD License\r
+#* which accompanies this distribution. The full text of the license may be found at\r
+#* http://opensource.org/licenses/bsd-license.php\r
+#*\r
+#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#*\r
+#* CpuAsm.S\r
+#*\r
+#* Abstract:\r
+#*\r
+#------------------------------------------------------------------------------\r
+\r
+\r
+#text SEGMENT\r
+\r
+\r
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions\r
+\r
+\r
+#\r
+# point to the external interrupt vector table\r
+#\r
+ExternalVectorTablePtr:\r
+ .byte 0, 0, 0, 0, 0, 0, 0, 0\r
+\r
+ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)\r
+ASM_PFX(InitializeExternalVectorTablePtr):\r
+ lea ExternalVectorTablePtr(%rip), %rax # save vector number\r
+ mov %rcx, (%rax) \r
+ ret\r
+\r
+\r
+#------------------------------------------------------------------------------\r
+# VOID\r
+# SetCodeSelector (\r
+# UINT16 Selector\r
+# );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(SetCodeSelector)\r
+ASM_PFX(SetCodeSelector):\r
+ subq $0x10, %rsp \r
+ leaq setCodeSelectorLongJump(%rip), %rax \r
+ movq %rax, (%rsp) \r
+ movw %cx, 4(%rsp)\r
+ .byte 0xFF, 0x2C, 0x24 # jmp (%rsp) note:fword jmp\r
+setCodeSelectorLongJump:\r
+ addq $0x10, %rsp\r
+ ret\r
+\r
+#------------------------------------------------------------------------------\r
+# VOID\r
+# SetDataSelectors (\r
+# UINT16 Selector\r
+# );\r
+#------------------------------------------------------------------------------\r
+ASM_GLOBAL ASM_PFX(SetDataSelectors)\r
+ASM_PFX(SetDataSelectors):\r
+ movw %cx, %ss\r
+ movw %cx, %ds\r
+ movw %cx, %es\r
+ movw %cx, %fs\r
+ movw %cx, %gs\r
+ ret\r
+\r
+#---------------------------------------;\r
+# CommonInterruptEntry ;\r
+#---------------------------------------;\r
+# The follow algorithm is used for the common interrupt routine.\r
+\r
+ASM_GLOBAL ASM_PFX(CommonInterruptEntry)\r
+ASM_PFX(CommonInterruptEntry):\r
+ cli\r
+ #\r
+ # All interrupt handlers are invoked through interrupt gates, so\r
+ # IF flag automatically cleared at the entry point\r
+ #\r
+ #\r
+ # Calculate vector number\r
+ #\r
+ xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.\r
+ movzwl (%rcx), %ecx \r
+ cmp $32, %ecx # Intel reserved vector for exceptions?\r
+ jae NoErrorCode\r
+ pushq %rax\r
+ leaq ASM_PFX(mErrorCodeFlag)(%rip), %rax\r
+ bt %ecx, (%rax) \r
+ popq %rax\r
+ jc CommonInterruptEntry_al_0000\r
+\r
+NoErrorCode:\r
+\r
+ #\r
+ # Push a dummy error code on the stack\r
+ # to maintain coherent stack map\r
+ #\r
+ pushq (%rsp)\r
+ movq $0, 8(%rsp)\r
+CommonInterruptEntry_al_0000:\r
+ pushq %rbp\r
+ movq %rsp, %rbp\r
+\r
+ #\r
+ # Stack:\r
+ # +---------------------+ <-- 16-byte aligned ensured by processor\r
+ # + Old SS +\r
+ # +---------------------+\r
+ # + Old RSP +\r
+ # +---------------------+\r
+ # + RFlags +\r
+ # +---------------------+\r
+ # + CS +\r
+ # +---------------------+\r
+ # + RIP +\r
+ # +---------------------+\r
+ # + Error Code +\r
+ # +---------------------+\r
+ # + RCX / Vector Number +\r
+ # +---------------------+\r
+ # + RBP +\r
+ # +---------------------+ <-- RBP, 16-byte aligned\r
+ #\r
+\r
+\r
+ #\r
+ # Since here the stack pointer is 16-byte aligned, so\r
+ # EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64\r
+ # is 16-byte aligned\r
+ #\r
+\r
+#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
+ pushq %r15\r
+ pushq %r14\r
+ pushq %r13\r
+ pushq %r12\r
+ pushq %r11\r
+ pushq %r10\r
+ pushq %r9\r
+ pushq %r8\r
+ pushq %rax\r
+ pushq 8(%rbp) # RCX\r
+ pushq %rdx\r
+ pushq %rbx\r
+ pushq 48(%rbp) # RSP\r
+ pushq (%rbp) # RBP\r
+ pushq %rsi\r
+ pushq %rdi\r
+\r
+#; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
+ movzwq 56(%rbp), %rax\r
+ pushq %rax # for ss\r
+ movzwq 32(%rbp), %rax\r
+ pushq %rax # for cs\r
+ movq %ds, %rax\r
+ pushq %rax\r
+ movq %es, %rax\r
+ pushq %rax\r
+ movq %fs, %rax\r
+ pushq %rax\r
+ movq %gs, %rax\r
+ pushq %rax\r
+\r
+ movq %rcx, 8(%rbp) # save vector number\r
+\r
+#; UINT64 Rip;\r
+ pushq 24(%rbp)\r
+\r
+#; UINT64 Gdtr[2], Idtr[2];\r
+ xorq %rax, %rax\r
+ pushq %rax\r
+ pushq %rax\r
+ sidt (%rsp)\r
+ xchgq 2(%rsp), %rax\r
+ xchgq (%rsp), %rax\r
+ xchgq 8(%rsp), %rax\r
+\r
+ xorq %rax, %rax\r
+ pushq %rax\r
+ pushq %rax\r
+ sgdt (%rsp)\r
+ xchgq 2(%rsp), %rax\r
+ xchgq (%rsp), %rax\r
+ xchgq 8(%rsp), %rax\r
+\r
+#; UINT64 Ldtr, Tr;\r
+ xorq %rax, %rax\r
+ str %ax\r
+ pushq %rax\r
+ sldt %ax\r
+ pushq %rax\r
+\r
+#; UINT64 RFlags;\r
+ pushq 40(%rbp)\r
+\r
+#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
+ movq %cr8, %rax\r
+ pushq %rax\r
+ movq %cr4, %rax\r
+ orq $0x208, %rax \r
+ movq %rax, %cr4 \r
+ pushq %rax\r
+ mov %cr3, %rax \r
+ pushq %rax\r
+ mov %cr2, %rax \r
+ pushq %rax\r
+ xorq %rax, %rax\r
+ pushq %rax\r
+ mov %cr0, %rax \r
+ pushq %rax\r
+\r
+#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+ movq %dr7, %rax\r
+ pushq %rax\r
+#; clear Dr7 while executing debugger itself\r
+ xorq %rax, %rax\r
+ movq %rax, %dr7\r
+\r
+ movq %dr6, %rax\r
+ pushq %rax\r
+#; insure all status bits in dr6 are clear...\r
+ xorq %rax, %rax\r
+ movq %rax, %dr6\r
+\r
+ movq %dr3, %rax\r
+ pushq %rax\r
+ movq %dr2, %rax\r
+ pushq %rax\r
+ movq %dr1, %rax\r
+ pushq %rax\r
+ movq %dr0, %rax\r
+ pushq %rax\r
+\r
+#; FX_SAVE_STATE_X64 FxSaveState;\r
+ subq $512, %rsp\r
+ movq %rsp, %rdi\r
+ .byte 0x0f, 0x0ae, 0x07 #fxsave [rdi]\r
+\r
+#; UINT32 ExceptionData;\r
+ pushq 16(%rbp)\r
+\r
+#; call into exception handler\r
+ movq 8(%rbp), %rcx\r
+ leaq ExternalVectorTablePtr(%rip), %rax\r
+ movl (%eax), %eax\r
+ movq (%rax,%rcx,8), %rax\r
+ orq %rax, %rax # NULL?\r
+\r
+ je nonNullValue#\r
+\r
+#; Prepare parameter and call\r
+# mov rcx, [rbp + 8]\r
+ mov %rsp, %rdx\r
+ #\r
+ # Per X64 calling convention, allocate maximum parameter stack space\r
+ # and make sure RSP is 16-byte aligned\r
+ #\r
+ subq $40, %rsp \r
+ call *%rax\r
+ addq $40, %rsp\r
+\r
+nonNullValue:\r
+ cli\r
+#; UINT64 ExceptionData;\r
+ addq $8, %rsp\r
+\r
+#; FX_SAVE_STATE_X64 FxSaveState;\r
+\r
+ movq %rsp, %rsi\r
+ .byte 0x0f, 0x0ae, 0x0E # fxrstor [rsi]\r
+ addq $512, %rsp\r
+\r
+#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
+ popq %rax\r
+ movq %rax, %dr0\r
+ popq %rax\r
+ movq %rax, %dr1\r
+ popq %rax\r
+ movq %rax, %dr2\r
+ popq %rax\r
+ movq %rax, %dr3\r
+#; skip restore of dr6. We cleared dr6 during the context save.\r
+ addq $8, %rsp\r
+ popq %rax\r
+ movq %rax, %dr7\r
+\r
+#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
+ popq %rax\r
+ movq %rax, %cr0\r
+ addq $8, %rsp # not for Cr1\r
+ popq %rax\r
+ movq %rax, %cr2\r
+ popq %rax\r
+ movq %rax, %cr3\r
+ popq %rax\r
+ movq %rax, %cr4\r
+ popq %rax\r
+ movq %rax, %cr8\r
+\r
+#; UINT64 RFlags;\r
+ popq 40(%rbp)\r
+\r
+#; UINT64 Ldtr, Tr;\r
+#; UINT64 Gdtr[2], Idtr[2];\r
+#; Best not let anyone mess with these particular registers...\r
+ addq $48, %rsp\r
+\r
+#; UINT64 Rip;\r
+ popq 24(%rbp)\r
+\r
+#; UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
+ popq %rax\r
+ # mov %rax, %gs ; not for gs\r
+ popq %rax\r
+ # mov %rax, %fs ; not for fs\r
+ # (X64 will not use fs and gs, so we do not restore it)\r
+ popq %rax\r
+ movq %rax, %es\r
+ popq %rax\r
+ movq %rax, %ds\r
+ popq 32(%rbp) # for cs\r
+ popq 56(%rbp) # for ss\r
+\r
+#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
+#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
+ popq %rdi\r
+ popq %rsi\r
+ addq $8, %rsp # not for rbp\r
+ popq 48(%rbp) # for rsp\r
+ popq %rbx\r
+ popq %rdx\r
+ popq %rcx\r
+ popq %rax\r
+ popq %r8\r
+ popq %r9\r
+ popq %r10\r
+ popq %r11\r
+ popq %r12\r
+ popq %r13\r
+ popq %r14\r
+ popq %r15\r
+\r
+ movq %rbp, %rsp\r
+ popq %rbp\r
+ addq $16, %rsp\r
+ iretq\r
+\r
+\r
+#text ENDS\r
+\r
+#END\r
+\r
+\r