NASM has replaced ASM and S files.
1. Remove ASM from all modules.
2. Remove S files from the drivers only.
3. https://bugzilla.tianocore.org/show_bug.cgi?id=881
After NASM is updated, S files can be removed from Library.
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Liming Gao <liming.gao@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
# PPI to discover and dispatch the DXE Foundation and components that are\r
# needed to run the DXE Foundation.\r
#\r
-# Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
#\r
# This program and the accompanying materials\r
X64/VirtualMemory.c\r
Ia32/DxeLoadFunc.c\r
Ia32/IdtVectorAsm.nasm\r
- Ia32/IdtVectorAsm.asm\r
- Ia32/IdtVectorAsm.S\r
\r
[Sources.X64]\r
X64/VirtualMemory.h\r
+++ /dev/null
-#/** @file\r
-# \r
-# IDT vector entry.\r
-# \r
-# Copyright (c) 2007 - 2009, Intel Corporation. All rights reserved.<BR>\r
-# 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
-#**/\r
-\r
- .text\r
- .code32\r
-\r
-\r
- .p2align 3\r
- ASM_GLOBAL ASM_PFX(AsmGetVectorTemplatInfo)\r
- ASM_GLOBAL ASM_PFX(AsmVectorFixup)\r
-/*\r
-;\r
-;-----------------------------------------------------------------------\r
-; Template of IDT Vector Handlers. \r
-;\r
-;-----------------------------------------------------------------------\r
-*/\r
-VectorTemplateBase:\r
- pushl %eax\r
- .byte 0x6a # push #VectorNum\r
-VectorNum:\r
- .byte 0\r
- movl CommonInterruptEntry, %eax\r
- jmp *%eax\r
-VectorTemplateEnd:\r
-\r
-\r
-ASM_PFX(AsmGetVectorTemplatInfo):\r
- movl 4(%esp), %ecx\r
- movl $VectorTemplateBase, (%ecx)\r
- movl $(VectorTemplateEnd - VectorTemplateBase), %eax\r
- ret\r
-\r
-ASM_PFX(AsmVectorFixup):\r
- movl 8(%esp), %eax\r
- movl 4(%esp), %ecx\r
- movb %al, (VectorNum - VectorTemplateBase)(%ecx)\r
- ret\r
-\r
-/*\r
-; The follow algorithm is used for the common interrupt routine.\r
-\r
-;\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
-; + Vector Number +\r
-; +---------------------+\r
-*/\r
-\r
-CommonInterruptEntry: \r
- cli\r
-1:\r
- jmp 1b\r
-\r
-\r
-\r
-\r
+++ /dev/null
-;/** @file\r
-; \r
-; IDT vector entry.\r
-; \r
-; Copyright (c) 2007 - 2008, Intel Corporation. All rights reserved.<BR>\r
-; 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
-;**/\r
-\r
- .686p\r
- .model flat,C\r
- .code\r
-\r
-;\r
-;------------------------------------------------------------------------------\r
-; Generic IDT Vector Handlers for the Host. \r
-;\r
-;------------------------------------------------------------------------------\r
-\r
-ALIGN 8\r
-PUBLIC AsmGetVectorTemplatInfo\r
-PUBLIC AsmVectorFixup\r
-\r
-PUBLIC AsmVectorFixup\r
-\r
-@VectorTemplateBase:\r
- push eax\r
- db 6ah ; push #VectorNumber\r
-@VectorNum:\r
- db 0\r
- mov eax, CommonInterruptEntry\r
- jmp eax\r
-@VectorTemplateEnd:\r
-\r
-\r
-AsmGetVectorTemplatInfo PROC\r
- mov ecx, [esp + 4]\r
- mov [ecx], @VectorTemplateBase\r
- mov eax, (@VectorTemplateEnd - @VectorTemplateBase)\r
- ret\r
-AsmGetVectorTemplatInfo ENDP\r
-\r
-\r
-AsmVectorFixup PROC\r
- mov eax, dword ptr [esp + 8]\r
- mov ecx, [esp + 4]\r
- mov [ecx + (@VectorNum - @VectorTemplateBase)], al\r
- ret\r
-AsmVectorFixup ENDP\r
-\r
-\r
-;---------------------------------------;\r
-; CommonInterruptEntry ;\r
-;---------------------------------------;\r
-; The follow algorithm is used for the common interrupt routine.\r
-\r
-;\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
-; + Vector Number +\r
-; +---------------------+\r
-\r
-CommonInterruptEntry PROC \r
- cli\r
- \r
- jmp $\r
-CommonInterruptEntry ENDP\r
-\r
-END\r
-\r
-\r
# This is a standalone Boot Script Executor. Standalone means it does not\r
# depends on any PEI or DXE service.\r
#\r
-# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
# Copyright (c) 2017, AMD Incorporated. All rights reserved.<BR>\r
#\r
# This program and the accompanying materials are\r
[Sources.X64]\r
X64/SetIdtEntry.c \r
X64/S3Asm.nasm\r
- X64/S3Asm.asm\r
- X64/S3Asm.S\r
\r
[Sources.Ia32]\r
IA32/SetIdtEntry.c \r
IA32/S3Asm.nasm\r
- IA32/S3Asm.asm\r
- IA32/S3Asm.S\r
\r
[Packages]\r
MdePkg/MdePkg.dec\r
+++ /dev/null
-## @file\r
-#\r
-# Copyright (c) 2010, Intel Corporation. All rights reserved.<BR>\r
-#\r
-# This program and the accompanying materials are\r
-# 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
-##\r
-\r
-#-----------------------------------------\r
-#VOID\r
-#AsmTransferControl (\r
-# IN UINT32 S3WakingVector,\r
-# IN UINT32 AcpiLowMemoryBase\r
-# );\r
-#-----------------------------------------\r
-\r
-ASM_GLOBAL ASM_PFX(AsmTransferControl)\r
-ASM_PFX(AsmTransferControl):\r
- # S3WakingVector :DWORD\r
- # AcpiLowMemoryBase :DWORD\r
- pushl %ebp\r
- movl %esp,%ebp\r
- leal LABLE, %eax\r
- pushl $0x28 # CS\r
- pushl %eax\r
- movl 8(%ebp),%ecx\r
- shrdl $20,%ecx,%ebx\r
- andl $0xf,%ecx\r
- movw %cx,%bx\r
- movl %ebx, jmp_addr\r
- lret\r
-LABLE: \r
- .byte 0xb8,0x30,0 # mov ax, 30h as selector\r
- movw %ax,%ds\r
- movw %ax,%es\r
- movw %ax,%fs\r
- movw %ax,%gs\r
- movw %ax,%ss\r
- movl %cr0, %eax # Get control register 0 \r
- .byte 0x66\r
- .byte 0x83,0xe0,0xfe # and eax, 0fffffffeh ; Clear PE bit (bit #0)\r
- .byte 0xf,0x22,0xc0 # mov cr0, eax ; Activate real mode\r
- .byte 0xea # jmp far @jmp_addr\r
-jmp_addr: \r
- .long 0\r
-\r
-ASM_GLOBAL ASM_PFX(AsmTransferControl32)\r
-ASM_PFX(AsmTransferControl32):\r
- jmp ASM_PFX(AsmTransferControl)\r
-\r
-# dummy\r
-ASM_GLOBAL ASM_PFX(AsmTransferControl16)\r
-ASM_PFX(AsmTransferControl16):\r
-ASM_GLOBAL ASM_PFX(AsmFixAddress16)\r
-ASM_PFX(AsmFixAddress16):\r
- .long 0\r
-ASM_GLOBAL ASM_PFX(AsmJmpAddr32)\r
-ASM_PFX(AsmJmpAddr32):\r
- .long 0\r
-\r
+++ /dev/null
-;; @file\r
-; This is the assembly code for transferring to control to OS S3 waking vector\r
-; for IA32 platform\r
-;\r
-; Copyright (c) 2006, Intel Corporation. All rights reserved.<BR>\r
-;\r
-; 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
-;;\r
- .586P\r
- .model flat,C\r
- .code\r
-\r
-PUBLIC AsmFixAddress16\r
-PUBLIC AsmJmpAddr32\r
- \r
-;-----------------------------------------\r
-;VOID\r
-;AsmTransferControl (\r
-; IN UINT32 S3WakingVector,\r
-; IN UINT32 AcpiLowMemoryBase\r
-; );\r
-;-----------------------------------------\r
- \r
-AsmTransferControl PROC\r
- ; S3WakingVector :DWORD\r
- ; AcpiLowMemoryBase :DWORD\r
- push ebp\r
- mov ebp, esp \r
- lea eax, @F\r
- push 28h ; CS\r
- push eax\r
- mov ecx, [ebp + 8]\r
- shrd ebx, ecx, 20\r
- and ecx, 0fh \r
- mov bx, cx \r
- mov [@jmp_addr], ebx\r
- retf\r
-@@:\r
- DB 0b8h, 30h, 0 ; mov ax, 30h as selector\r
- mov ds, ax\r
- mov es, ax\r
- mov fs, ax\r
- mov gs, ax\r
- mov ss, ax\r
- mov eax, cr0 ; Get control register 0 \r
- DB 66h\r
- DB 83h, 0e0h, 0feh ; and eax, 0fffffffeh ; Clear PE bit (bit #0)\r
- DB 0fh, 22h, 0c0h ; mov cr0, eax ; Activate real mode\r
- DB 0eah ; jmp far @jmp_addr\r
-@jmp_addr DD ?\r
-\r
-AsmTransferControl ENDP\r
-\r
-AsmTransferControl32 PROC\r
- jmp AsmTransferControl\r
-AsmTransferControl32 ENDP\r
-\r
-; dummy\r
-AsmTransferControl16 PROC\r
-AsmFixAddress16 DD ?\r
-AsmJmpAddr32 DD ?\r
-AsmTransferControl16 ENDP\r
-\r
- END
\ No newline at end of file
+++ /dev/null
-## @file\r
-# This is the assembly code for transferring to control to OS S3 waking vector\r
-# for X64 platform\r
-#\r
-# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>\r
-#\r
-# This program and the accompanying materials are\r
-# 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
-##\r
-\r
-ASM_GLOBAL ASM_PFX(AsmTransferControl)\r
-ASM_PFX(AsmTransferControl):\r
- # rcx S3WakingVector :DWORD\r
- # rdx AcpiLowMemoryBase :DWORD\r
- lea _AsmTransferControl_al_0000(%rip), %eax \r
- movq $0x2800000000, %r8 \r
- orq %r8, %rax\r
- pushq %rax\r
- shrd $20, %ecx, %ebx\r
- andl $0x0f, %ecx \r
- movw %cx, %bx\r
- movl %ebx, jmp_addr(%rip) \r
- lret\r
-_AsmTransferControl_al_0000:\r
- .byte 0x0b8, 0x30, 0 # mov ax, 30h as selector\r
- movl %eax, %ds\r
- movl %eax, %es\r
- movl %eax, %fs\r
- movl %eax, %gs\r
- movl %eax, %ss\r
- movq %cr0, %rax\r
- movq %cr4, %rbx\r
- .byte 0x66\r
- andl $0x7ffffffe, %eax \r
- andb $0xdf, %bl \r
- movq %rax, %cr0\r
- .byte 0x66\r
- movl $0x0c0000080, %ecx \r
- rdmsr\r
- andb $0xfe, %ah \r
- wrmsr\r
- movq %rbx, %cr4\r
- .byte 0x0ea # jmp far jmp_addr\r
-jmp_addr:\r
- .long 0\r
-\r
-ASM_GLOBAL ASM_PFX(AsmTransferControl32)\r
-ASM_PFX(AsmTransferControl32):\r
- # S3WakingVector :DWORD\r
- # AcpiLowMemoryBase :DWORD\r
- pushq %rbp\r
- movl %esp,%ebp\r
- .byte 0x8d, 0x05 # lea eax, AsmTransferControl16\r
-ASM_GLOBAL ASM_PFX(AsmFixAddress16)\r
-ASM_PFX(AsmFixAddress16):\r
- .long 0\r
- pushq $0x28 # CS\r
- pushq %rax\r
- lret\r
-\r
-ASM_GLOBAL ASM_PFX(AsmTransferControl16)\r
-ASM_PFX(AsmTransferControl16):\r
- .byte 0xb8,0x30,0 # mov ax, 30h as selector\r
- movw %ax,%ds\r
- movw %ax,%es\r
- movw %ax,%fs\r
- movw %ax,%gs\r
- movw %ax,%ss\r
- movq %cr0, %rax # Get control register 0 \r
- .byte 0x66\r
- .byte 0x83,0xe0,0xfe # and eax, 0fffffffeh ; Clear PE bit (bit #0)\r
- .byte 0xf,0x22,0xc0 # mov cr0, eax ; Activate real mode\r
- .byte 0xea # jmp far AsmJmpAddr32\r
-ASM_GLOBAL ASM_PFX(AsmJmpAddr32)\r
-ASM_PFX(AsmJmpAddr32):\r
- .long 0\r
-\r
-ASM_GLOBAL ASM_PFX(PageFaultHandlerHook)\r
-ASM_PFX(PageFaultHandlerHook):\r
- pushq %rax # save all volatile registers\r
- pushq %rcx\r
- pushq %rdx\r
- pushq %r8\r
- pushq %r9\r
- pushq %r10\r
- pushq %r11\r
- # save volatile fp registers\r
- addq $-0x68, %rsp\r
- stmxcsr 0x60(%rsp)\r
- movdqa %xmm0, 0x0(%rsp) \r
- movdqa %xmm1, 0x10(%rsp) \r
- movdqa %xmm2, 0x20(%rsp) \r
- movdqa %xmm3, 0x30(%rsp) \r
- movdqa %xmm4, 0x40(%rsp) \r
- movdqa %xmm5, 0x50(%rsp) \r
-\r
- addq $-0x20, %rsp\r
- call ASM_PFX(PageFaultHandler)\r
- addq $0x20, %rsp\r
-\r
- # load volatile fp registers\r
- ldmxcsr 0x60(%rsp)\r
- movdqa 0x0(%rsp), %xmm0\r
- movdqa 0x10(%rsp), %xmm1\r
- movdqa 0x20(%rsp), %xmm2\r
- movdqa 0x30(%rsp), %xmm3\r
- movdqa 0x40(%rsp), %xmm4\r
- movdqa 0x50(%rsp), %xmm5\r
- addq $0x68, %rsp\r
-\r
- testb %al, %al\r
-\r
- popq %r11\r
- popq %r10\r
- popq %r9\r
- popq %r8\r
- popq %rdx\r
- popq %rcx\r
- popq %rax # restore all volatile registers\r
- jnz L1\r
- jmpq *ASM_PFX(mOriginalHandler)(%rip)\r
-L1:\r
- addq $0x08, %rsp # skip error code for PF\r
- iretq\r
+++ /dev/null
-;; @file\r
-; This is the assembly code for transferring to control to OS S3 waking vector\r
-; for X64 platform\r
-;\r
-; Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>\r
-;\r
-; 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
-;;\r
-\r
-EXTERN mOriginalHandler:QWORD\r
-EXTERN PageFaultHandler:PROC\r
-\r
- .code\r
- \r
-PUBLIC AsmFixAddress16\r
-PUBLIC AsmJmpAddr32\r
- \r
-AsmTransferControl PROC\r
- ; rcx S3WakingVector :DWORD\r
- ; rdx AcpiLowMemoryBase :DWORD\r
- lea eax, @F\r
- mov r8, 2800000000h\r
- or rax, r8\r
- push rax\r
- shrd ebx, ecx, 20\r
- and ecx, 0fh \r
- mov bx, cx \r
- mov [@jmp_addr], ebx\r
- retf\r
-@@:\r
- DB 0b8h, 30h, 0 ; mov ax, 30h as selector\r
- mov ds, eax\r
- mov es, eax\r
- mov fs, eax\r
- mov gs, eax\r
- mov ss, eax\r
- mov rax, cr0\r
- mov rbx, cr4 \r
- DB 66h\r
- and eax, ((NOT 080000001h) AND 0ffffffffh)\r
- and bl, NOT (1 SHL 5)\r
- mov cr0, rax\r
- DB 66h\r
- mov ecx, 0c0000080h\r
- rdmsr\r
- and ah, NOT 1\r
- wrmsr\r
- mov cr4, rbx\r
- DB 0eah ; jmp far @jmp_addr\r
-@jmp_addr DD ?\r
-AsmTransferControl ENDP\r
-\r
-AsmTransferControl32 PROC\r
- ; S3WakingVector :DWORD\r
- ; AcpiLowMemoryBase :DWORD\r
- push rbp\r
- mov ebp, esp \r
- DB 8dh, 05h ; lea eax, AsmTransferControl16\r
-AsmFixAddress16 DD ?\r
- push 28h ; CS\r
- push rax\r
- retf\r
-AsmTransferControl32 ENDP\r
-\r
-AsmTransferControl16 PROC\r
- DB 0b8h, 30h, 0 ; mov ax, 30h as selector\r
- mov ds, ax\r
- mov es, ax\r
- mov fs, ax\r
- mov gs, ax\r
- mov ss, ax\r
- mov rax, cr0 ; Get control register 0 \r
- DB 66h\r
- DB 83h, 0e0h, 0feh ; and eax, 0fffffffeh ; Clear PE bit (bit #0)\r
- DB 0fh, 22h, 0c0h ; mov cr0, eax ; Activate real mode\r
- DB 0eah ; jmp far AsmJmpAddr32\r
-AsmJmpAddr32 DD ?\r
-AsmTransferControl16 ENDP\r
-\r
-PageFaultHandlerHook PROC\r
- push rax ; save all volatile registers\r
- push rcx\r
- push rdx\r
- push r8\r
- push r9\r
- push r10\r
- push r11\r
- ; save volatile fp registers\r
- add rsp, -68h\r
- stmxcsr [rsp + 60h]\r
- movdqa [rsp + 0h], xmm0\r
- movdqa [rsp + 10h], xmm1\r
- movdqa [rsp + 20h], xmm2\r
- movdqa [rsp + 30h], xmm3\r
- movdqa [rsp + 40h], xmm4\r
- movdqa [rsp + 50h], xmm5\r
-\r
- add rsp, -20h\r
- call PageFaultHandler\r
- add rsp, 20h\r
- \r
- ; load volatile fp registers\r
- ldmxcsr [rsp + 60h]\r
- movdqa xmm0, [rsp + 0h]\r
- movdqa xmm1, [rsp + 10h]\r
- movdqa xmm2, [rsp + 20h]\r
- movdqa xmm3, [rsp + 30h]\r
- movdqa xmm4, [rsp + 40h]\r
- movdqa xmm5, [rsp + 50h]\r
- add rsp, 68h\r
-\r
- test al, al\r
- \r
- pop r11\r
- pop r10\r
- pop r9\r
- pop r8\r
- pop rdx\r
- pop rcx\r
- pop rax ; restore all volatile registers\r
- jnz @F\r
- jmp mOriginalHandler\r
-@@:\r
- add rsp, 08h ; skip error code for PF\r
- iretq\r
-PageFaultHandlerHook ENDP\r
-\r
- END\r
# This external input must be validated carefully to avoid security issue like\r
# buffer overflow, integer overflow.\r
#\r
-# Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved.<BR>\r
#\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions\r
[Sources]\r
X64/X64Entry.c\r
X64/PageFaultHandler.nasm\r
- X64/PageFaultHandler.asm\r
- X64/PageFaultHandler.S\r
Common/CapsuleCoalesce.c\r
\r
[Packages]\r
+++ /dev/null
-## @file\r
-# This is the assembly code for page fault handler hook.\r
-#\r
-# Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
-#\r
-# This program and the accompanying materials are\r
-# 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
-##\r
-\r
-ASM_GLOBAL ASM_PFX(PageFaultHandlerHook)\r
-ASM_PFX(PageFaultHandlerHook):\r
- addq $-0x10, %rsp\r
- # save rax\r
- movq %rax, 0x08(%rsp)\r
-\r
- # pushq %rax # save all volatile registers\r
- pushq %rcx\r
- pushq %rdx\r
- pushq %r8\r
- pushq %r9\r
- pushq %r10\r
- pushq %r11\r
- # save volatile fp registers\r
- # 68h + 08h(for alignment)\r
- addq $-0x70, %rsp\r
- stmxcsr 0x60(%rsp)\r
- movdqa %xmm0, 0x0(%rsp) \r
- movdqa %xmm1, 0x10(%rsp) \r
- movdqa %xmm2, 0x20(%rsp) \r
- movdqa %xmm3, 0x30(%rsp) \r
- movdqa %xmm4, 0x40(%rsp) \r
- movdqa %xmm5, 0x50(%rsp) \r
-\r
- addq $-0x20, %rsp\r
- call ASM_PFX(PageFaultHandler)\r
- addq $0x20, %rsp\r
-\r
- # load volatile fp registers\r
- ldmxcsr 0x60(%rsp)\r
- movdqa 0x0(%rsp), %xmm0\r
- movdqa 0x10(%rsp), %xmm1\r
- movdqa 0x20(%rsp), %xmm2\r
- movdqa 0x30(%rsp), %xmm3\r
- movdqa 0x40(%rsp), %xmm4\r
- movdqa 0x50(%rsp), %xmm5\r
- addq $0x70, %rsp\r
-\r
- popq %r11\r
- popq %r10\r
- popq %r9\r
- popq %r8\r
- popq %rdx\r
- popq %rcx\r
- # popq %rax # restore all volatile registers\r
-\r
- addq $0x10, %rsp\r
-\r
- # rax returned from PageFaultHandler is NULL or OriginalHandler address\r
- # NULL if the page fault is handled by PageFaultHandler\r
- # OriginalHandler address if the page fault is not handled by PageFaultHandler\r
- testq %rax, %rax\r
-\r
- # save OriginalHandler address\r
- movq %rax, -0x10(%rsp)\r
- # restore rax\r
- movq -0x08(%rsp), %rax\r
-\r
- jz L1\r
-\r
- # jump to OriginalHandler\r
- jmpq *-0x10(%rsp)\r
-\r
-L1:\r
- addq $0x08, %rsp # skip error code for PF\r
- iretq\r
+++ /dev/null
-;; @file\r
-; This is the assembly code for page fault handler hook.\r
-;\r
-; Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\r
-;\r
-; 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
-;;\r
-\r
-EXTERN PageFaultHandler:PROC\r
-\r
- .code\r
-\r
-PageFaultHandlerHook PROC\r
- add rsp, -10h\r
- ; save rax\r
- mov [rsp + 08h], rax\r
-\r
- ;push rax ; save all volatile registers\r
- push rcx\r
- push rdx\r
- push r8\r
- push r9\r
- push r10\r
- push r11\r
- ; save volatile fp registers\r
- ; 68h + 08h(for alignment)\r
- add rsp, -70h\r
- stmxcsr [rsp + 60h]\r
- movdqa [rsp + 0h], xmm0\r
- movdqa [rsp + 10h], xmm1\r
- movdqa [rsp + 20h], xmm2\r
- movdqa [rsp + 30h], xmm3\r
- movdqa [rsp + 40h], xmm4\r
- movdqa [rsp + 50h], xmm5\r
-\r
- add rsp, -20h\r
- call PageFaultHandler\r
- add rsp, 20h\r
-\r
- ; load volatile fp registers\r
- ldmxcsr [rsp + 60h]\r
- movdqa xmm0, [rsp + 0h]\r
- movdqa xmm1, [rsp + 10h]\r
- movdqa xmm2, [rsp + 20h]\r
- movdqa xmm3, [rsp + 30h]\r
- movdqa xmm4, [rsp + 40h]\r
- movdqa xmm5, [rsp + 50h]\r
- add rsp, 70h\r
-\r
- pop r11\r
- pop r10\r
- pop r9\r
- pop r8\r
- pop rdx\r
- pop rcx\r
- ;pop rax ; restore all volatile registers\r
-\r
- add rsp, 10h\r
-\r
- ; rax returned from PageFaultHandler is NULL or OriginalHandler address\r
- ; NULL if the page fault is handled by PageFaultHandler\r
- ; OriginalHandler address if the page fault is not handled by PageFaultHandler\r
- test rax, rax\r
-\r
- ; save OriginalHandler address\r
- mov [rsp - 10h], rax\r
- ; restore rax\r
- mov rax, [rsp - 08h]\r
-\r
- jz @F\r
-\r
- ; jump to OriginalHandler\r
- jmp qword ptr [rsp - 10h]\r
-\r
-@@:\r
- add rsp, 08h ; skip error code for PF\r
- iretq\r
-PageFaultHandlerHook ENDP\r
-\r
- END\r
# provides debug-agent to periodically gain control during operation of the machine to\r
# check for asynchronous commands form the host.\r
#\r
-# Copyright (c) 2006 - 2016, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
#\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
Ia32/PlDebugSupport.h\r
Ia32/PlDebugSupportIa32.c\r
Ia32/AsmFuncs.nasm\r
- Ia32/AsmFuncs.S\r
- Ia32/AsmFuncs.asm\r
\r
[Sources.X64]\r
Ia32/DebugSupport.h\r
X64/PlDebugSupport.h\r
X64/PlDebugSupportX64.c\r
X64/AsmFuncs.nasm\r
- X64/AsmFuncs.S\r
- X64/AsmFuncs.asm\r
\r
[Sources.IPF]\r
Ipf/PlDebugSupport.h\r
+++ /dev/null
-#/**@file\r
-# Low leve IA32 specific debug support functions.\r
-#\r
-# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
-# 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
-#**/\r
-\r
-ASM_GLOBAL ASM_PFX(OrigVector)\r
-ASM_GLOBAL ASM_PFX(InterruptEntryStub)\r
-ASM_GLOBAL ASM_PFX(StubSize)\r
-ASM_GLOBAL ASM_PFX(CommonIdtEntry)\r
-ASM_GLOBAL ASM_PFX(FxStorSupport)\r
-\r
-ASM_PFX(StubSize): .long ASM_PFX(InterruptEntryStubEnd) - ASM_PFX(InterruptEntryStub)\r
-ASM_PFX(AppEsp): .long 0x11111111 # ?\r
-ASM_PFX(DebugEsp): .long 0x22222222 # ?\r
-ASM_PFX(ExtraPush): .long 0x33333333 # ?\r
-ASM_PFX(ExceptData): .long 0x44444444 # ?\r
-ASM_PFX(Eflags): .long 0x55555555 # ?\r
-ASM_PFX(OrigVector): .long 0x66666666 # ?\r
-\r
-#------------------------------------------------------------------------------\r
-# BOOLEAN\r
-# FxStorSupport (\r
-# void\r
-# )\r
-#\r
-# Abstract: Returns TRUE if FxStor instructions are supported\r
-#\r
-ASM_GLOBAL ASM_PFX(FxStorSupport)\r
-ASM_PFX(FxStorSupport):\r
-#\r
-# cpuid corrupts ebx which must be preserved per the C calling convention\r
-#\r
- push %ebx\r
- mov $0x1,%eax\r
- cpuid\r
- mov %edx,%eax\r
- and $0x1000000,%eax\r
- shr $0x18,%eax\r
- pop %ebx\r
- ret\r
-#------------------------------------------------------------------------------\r
-# void\r
-# Vect2Desc (\r
-# DESCRIPTOR * DestDesc,\r
-# void (*Vector) (void)\r
-# )\r
-#\r
-# Abstract: Encodes an IDT descriptor with the given physical address\r
-#\r
-\r
-ASM_GLOBAL ASM_PFX(Vect2Desc)\r
-ASM_PFX(Vect2Desc):\r
- push %ebp\r
- mov %esp,%ebp\r
- mov 0xc(%ebp),%eax\r
- mov 0x8(%ebp),%ecx\r
- mov %ax,(%ecx)\r
- movw $0x20,0x2(%ecx)\r
- movw $0x8e00,0x4(%ecx)\r
- shr $0x10,%eax\r
- mov %ax,0x6(%ecx)\r
- leave\r
- ret\r
-\r
-ASM_GLOBAL ASM_PFX(InterruptEntryStub)\r
-ASM_PFX(InterruptEntryStub):\r
- mov %esp,0x0 # save stack top\r
- mov $0x0,%esp # switch to debugger stack\r
- push $0x0 # push vector number - will be modified before installed\r
- jmp ASM_PFX(CommonIdtEntry) # jump CommonIdtEntry\r
-ASM_GLOBAL ASM_PFX(InterruptEntryStubEnd)\r
-ASM_PFX(InterruptEntryStubEnd):\r
-\r
-#------------------------------------------------------------------------------\r
-# CommonIdtEntry\r
-#\r
-# Abstract: This code is not a function, but is the common part for all IDT\r
-# vectors.\r
-#\r
-ASM_GLOBAL ASM_PFX(CommonIdtEntry)\r
-ASM_PFX(CommonIdtEntry):\r
-##\r
-## At this point, the stub has saved the current application stack esp into AppEsp\r
-## and switched stacks to the debug stack, where it pushed the vector number\r
-##\r
-## The application stack looks like this:\r
-##\r
-## ...\r
-## (last application stack entry)\r
-## eflags from interrupted task\r
-## CS from interrupted task\r
-## EIP from interrupted task\r
-## Error code <-------------------- Only present for some exeption types\r
-##\r
-##\r
-\r
-\r
-## The stub switched us to the debug stack and pushed the interrupt number.\r
-##\r
-## Next, construct the context record. It will be build on the debug stack by\r
-## pushing the registers in the correct order so as to create the context structure\r
-## on the debug stack. The context record must be built from the end back to the\r
-## beginning because the stack grows down...\r
-#\r
-## For reference, the context record looks like this:\r
-##\r
-## typedef\r
-## struct {\r
-## UINT32 ExceptionData;\r
-## FX_SAVE_STATE_IA32 FxSaveState;\r
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-## UINT32 Cr0, Cr2, Cr3, Cr4;\r
-## UINT32 EFlags;\r
-## UINT32 Ldtr, Tr;\r
-## UINT32 Gdtr[2], Idtr[2];\r
-## UINT32 Eip;\r
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
-## } SYSTEM_CONTEXT_IA32; // 32 bit system context record\r
-\r
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- pusha\r
-## Save interrupt state eflags register...\r
- pushf\r
- pop %eax\r
-## We need to determine if any extra data was pushed by the exception, and if so, save it\r
-## To do this, we check the exception number pushed by the stub, and cache the\r
-## result in a variable since we'll need this again.\r
- mov %eax,0x0\r
- cmpl $0x8,0x0\r
- jne ASM_PFX(CommonIdtEntry+0x20)\r
- movl $0x1,0x0\r
- jmp ASM_PFX(CommonIdtEntry+0xa8)\r
- cmpl $0xa,0x0\r
- jne ASM_PFX(CommonIdtEntry+0x35)\r
- movl $0x1,0x0\r
- jmp ASM_PFX(CommonIdtEntry+0xa8)\r
- cmpl $0xb,0x0\r
- jne ASM_PFX(CommonIdtEntry+0x4a)\r
- movl $0x1,0x0\r
- jmp ASM_PFX(CommonIdtEntry+0xa8)\r
- cmpl $0xc,0x0\r
- jne ASM_PFX(CommonIdtEntry+0x5f)\r
- movl $0x1,0x0\r
- jmp ASM_PFX(CommonIdtEntry+0xa8)\r
- cmpl $0xd,0x0\r
- jne ASM_PFX(CommonIdtEntry+0x74)\r
- movl $0x1,0x0\r
- jmp ASM_PFX(CommonIdtEntry+0xa8)\r
- cmpl $0xe,0x0\r
- jne ASM_PFX(CommonIdtEntry+0x89)\r
- movl $0x1,0x0\r
- jmp ASM_PFX(CommonIdtEntry+0xa8)\r
- cmpl $0x11,0x0\r
- jne ASM_PFX(CommonIdtEntry+0x9e)\r
- movl $0x1,0x0\r
- jmp ASM_PFX(CommonIdtEntry+0xa8)\r
- movl $0x0,0x0\r
-## If there's some extra data, save it also, and modify the saved AppEsp to effectively\r
-## pop this value off the application's stack.\r
-\r
- cmpl $0x1,0x0\r
- jne ASM_PFX(CommonIdtEntry+0xc8)\r
- mov 0x0,%eax\r
- mov (%eax),%ebx\r
- mov %ebx,0x0\r
- add $0x4,%eax\r
- mov %eax,0x0\r
- jmp ASM_PFX(CommonIdtEntry+0xd2)\r
- movl $0x0,0x0\r
-## The "pushad" above pushed the debug stack esp. Since what we're actually doing\r
-## is building the context record on the debug stack, we need to save the pushed\r
-## debug ESP, and replace it with the application's last stack entry...\r
- mov 0xc(%esp),%eax\r
- mov %eax,0x0\r
- mov 0x0,%eax\r
- add $0xc,%eax\r
- # application stack has eflags, cs, & eip, so\r
- # last actual application stack entry is\r
- # 12 bytes into the application stack.\r
- mov %eax,0xc(%esp)\r
-## continue building context record\r
-## UINT32 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
- mov %ss,%eax\r
- push %eax\r
- \r
- # CS from application is one entry back in application stack\r
- mov 0x0,%eax\r
- movzwl 0x4(%eax),%eax\r
- push %eax\r
- mov %ds,%eax\r
- push %eax\r
- mov %es,%eax\r
- push %eax\r
- mov %fs,%eax\r
- push %eax\r
- mov %gs,%eax\r
- push %eax\r
-\r
-## UINT32 Eip;\r
- # Eip from application is on top of application stack\r
- mov 0x0,%eax\r
- pushl (%eax)\r
-\r
-## UINT32 Gdtr[2], Idtr[2];\r
- push $0x0\r
- push $0x0\r
- sidtl (%esp)\r
- push $0x0\r
- push $0x0\r
- sgdtl (%esp)\r
-\r
-## UINT32 Ldtr, Tr;\r
- xor %eax,%eax\r
- str %eax\r
- push %eax\r
- sldt %eax\r
- push %eax\r
-\r
-## UINT32 EFlags;\r
-## Eflags from application is two entries back in application stack\r
- mov 0x0,%eax\r
- pushl 0x8(%eax)\r
-\r
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
-## insure FXSAVE/FXRSTOR is enabled in CR4...\r
-## ... while we're at it, make sure DE is also enabled...\r
- mov %cr4,%eax\r
- or $0x208,%eax\r
- mov %eax,%cr4\r
- push %eax\r
- mov %cr3,%eax\r
- push %eax\r
- mov %cr2,%eax\r
- push %eax\r
- push $0x0\r
- mov %cr0,%eax\r
- push %eax\r
-\r
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- mov %db7,%eax\r
- push %eax\r
-\r
-## clear Dr7 while executing debugger itself\r
- xor %eax,%eax\r
- mov %eax,%db7\r
- mov %db6,%eax\r
- push %eax\r
-\r
-## insure all status bits in dr6 are clear...\r
- xor %eax,%eax\r
- mov %eax,%db6\r
- mov %db3,%eax\r
- push %eax\r
- mov %db2,%eax\r
- push %eax\r
- mov %db1,%eax\r
- push %eax\r
- mov %db0,%eax\r
- push %eax\r
-\r
-## FX_SAVE_STATE_IA32 FxSaveState;\r
- sub $0x200,%esp\r
- mov %esp,%edi\r
- # IMPORTANT!! The debug stack has been carefully constructed to\r
- # insure that esp and edi are 16 byte aligned when we get here.\r
- # They MUST be. If they are not, a GP fault will occur.\r
- fxsave (%edi)\r
-\r
-## UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
- cld\r
- \r
-## UINT32 ExceptionData;\r
- mov 0x0,%eax\r
- push %eax\r
-\r
-# call to C code which will in turn call registered handler\r
-# pass in the vector number\r
- mov %esp,%eax\r
- push %eax\r
- mov 0x0,%eax\r
- push %eax\r
- call ASM_PFX(CommonIdtEntry+0x184)\r
- add $0x8,%esp\r
-\r
-# restore context...\r
-## UINT32 ExceptionData;\r
- add $0x4,%esp\r
-\r
-## FX_SAVE_STATE_IA32 FxSaveState;\r
- mov %esp,%esi\r
- fxrstor (%esi)\r
- add $0x200,%esp\r
-\r
-## UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- pop %eax\r
- mov %eax,%db0\r
- pop %eax\r
- mov %eax,%db1\r
- pop %eax\r
- mov %eax,%db2\r
- pop %eax\r
- mov %eax,%db3\r
-\r
-## skip restore of dr6. We cleared dr6 during the context save.\r
- add $0x4,%esp\r
- pop %eax\r
- mov %eax,%db7\r
-\r
-## UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- pop %eax\r
- mov %eax,%cr0\r
- add $0x4,%esp\r
- pop %eax\r
- mov %eax,%cr2\r
- pop %eax\r
- mov %eax,%cr3\r
- pop %eax\r
- mov %eax,%cr4\r
-\r
-## UINT32 EFlags;\r
- mov 0x0,%eax\r
- popl 0x8(%eax)\r
-\r
-## UINT32 Ldtr, Tr;\r
-## UINT32 Gdtr[2], Idtr[2];\r
-## Best not let anyone mess with these particular registers...\r
- add $0x18,%esp\r
-\r
-## UINT32 Eip;\r
- popl (%eax)\r
-\r
-## UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs;\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
-\r
- pop %gs\r
- pop %fs\r
- pop %es\r
- pop %ds\r
- popl 0x4(%eax)\r
- pop %ss\r
- mov 0xc(%esp),%ebx\r
-\r
-## The next stuff to restore is the general purpose registers that were pushed\r
-## using the "pushad" instruction.\r
-##\r
-## The value of ESP as stored in the context record is the application ESP\r
-## including the 3 entries on the application stack caused by the exception\r
-## itself. It may have been modified by the debug agent, so we need to\r
-## determine if we need to relocate the application stack.\r
-\r
- mov 0x0,%eax # move the potentially modified AppEsp into ebx\r
- add $0xc,%eax\r
- cmp %eax,%ebx\r
- je ASM_PFX(CommonIdtEntry+0x202)\r
- mov 0x0,%eax\r
- mov (%eax),%ecx # EIP\r
- mov %ecx,(%ebx)\r
- mov 0x4(%eax),%ecx # CS\r
- mov %ecx,0x4(%ebx)\r
- mov 0x8(%eax),%ecx # EFLAGS\r
- mov %ecx,0x8(%ebx)\r
- \r
- mov %ebx,%eax # modify the saved AppEsp to the new AppEsp\r
- mov %eax,0x0\r
- mov 0x0,%eax # restore the DebugEsp on the debug stack\r
- # so our "popad" will not cause a stack switch\r
- mov %eax,0xc(%esp) \r
- cmpl $0x68,0x0\r
- jne PhonyIretd+0xd\r
-## Restore eflags so when we chain, the flags will be exactly as if we were never here.\r
-## We gin up the stack to do an iretd so we can get ALL the flags.\r
- mov 0x0,%eax\r
- mov 0x8(%eax),%ebx\r
- and $0xfffffcff,%ebx # special handling for IF and TF\r
- push %ebx\r
- push %cs\r
- push $0x0\r
- iret\r
-\r
-PhonyIretd:\r
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- popa\r
-\r
-## Switch back to application stack\r
- mov 0x0,%esp\r
- jmp *0x0\r
-## Jump to original handler\r
-## UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- popa\r
-## Switch back to application stack\r
- mov 0x0,%esp\r
-\r
-## We're outa here...\r
- iret\r
+++ /dev/null
-;/** @file\r
-; Low leve IA32 specific debug support functions.\r
-;\r
-; Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
-; 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
-;**/\r
-\r
-.586p\r
-.MODEL FLAT, C\r
-\r
-EXCPT32_DIVIDE_ERROR EQU 0\r
-EXCPT32_DEBUG EQU 1\r
-EXCPT32_NMI EQU 2\r
-EXCPT32_BREAKPOINT EQU 3\r
-EXCPT32_OVERFLOW EQU 4\r
-EXCPT32_BOUND EQU 5\r
-EXCPT32_INVALID_OPCODE EQU 6\r
-EXCPT32_DOUBLE_FAULT EQU 8\r
-EXCPT32_INVALID_TSS EQU 10\r
-EXCPT32_SEG_NOT_PRESENT EQU 11\r
-EXCPT32_STACK_FAULT EQU 12\r
-EXCPT32_GP_FAULT EQU 13\r
-EXCPT32_PAGE_FAULT EQU 14\r
-EXCPT32_FP_ERROR EQU 16\r
-EXCPT32_ALIGNMENT_CHECK EQU 17\r
-EXCPT32_MACHINE_CHECK EQU 18\r
-EXCPT32_SIMD EQU 19\r
-\r
-FXSTOR_FLAG EQU 01000000h ; bit cpuid 24 of feature flags\r
-\r
-;; The FXSTOR and FXRSTOR commands are used for saving and restoring the x87,\r
-;; MMX, SSE, SSE2, etc registers. The initialization of the debugsupport driver\r
-;; MUST check the CPUID feature flags to see that these instructions are available\r
-;; and fail to init if they are not.\r
-\r
-;; fxstor [edi]\r
-FXSTOR_EDI MACRO\r
- db 0fh, 0aeh, 00000111y ; mod = 00, reg/op = 000, r/m = 111 = [edi]\r
-ENDM\r
-\r
-;; fxrstor [esi]\r
-FXRSTOR_ESI MACRO\r
- db 0fh, 0aeh, 00001110y ; mod = 00, reg/op = 001, r/m = 110 = [esi]\r
-ENDM\r
-.DATA\r
-\r
-public OrigVector, InterruptEntryStub, StubSize, CommonIdtEntry, FxStorSupport\r
-\r
-StubSize dd InterruptEntryStubEnd - InterruptEntryStub\r
-AppEsp dd 11111111h ; ?\r
-DebugEsp dd 22222222h ; ?\r
-ExtraPush dd 33333333h ; ?\r
-ExceptData dd 44444444h ; ?\r
-Eflags dd 55555555h ; ?\r
-OrigVector dd 66666666h ; ?\r
-\r
-;; The declarations below define the memory region that will be used for the debug stack.\r
-;; The context record will be built by pushing register values onto this stack.\r
-;; It is imparitive that alignment be carefully managed, since the FXSTOR and\r
-;; FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned.\r
-;;\r
-;; The stub will switch stacks from the application stack to the debuger stack\r
-;; and pushes the exception number.\r
-;;\r
-;; Then we building the context record on the stack. Since the stack grows down,\r
-;; we push the fields of the context record from the back to the front. There\r
-;; are 132 bytes of stack used prior allocating the 512 bytes of stack to be\r
-;; used as the memory buffer for the fxstor instruction. Therefore address of\r
-;; the buffer used for the FXSTOR instruction is &Eax - 132 - 512, which\r
-;; must be 16 byte aligned.\r
-;;\r
-;; We carefully locate the stack to make this happen.\r
-;;\r
-;; For reference, the context structure looks like this:\r
-;; struct {\r
-;; UINT32 ExceptionData;\r
-;; FX_SAVE_STATE_IA32 FxSaveState; // 512 bytes, must be 16 byte aligned\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
-;; UINT32 EFlags;\r
-;; UINT32 Ldtr, Tr;\r
-;; UINT32 Gdtr[2], Idtr[2];\r
-;; UINT32 Eip;\r
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
-;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record\r
-\r
-\r
-align 16\r
-DebugStackEnd db "DbgStkEnd >>>>>>" ;; 16 byte long string - must be 16 bytes to preserve alignment\r
- dd 1ffdh dup (000000000h) ;; 32K should be enough stack\r
- ;; This allocation is coocked to insure\r
- ;; that the the buffer for the FXSTORE instruction\r
- ;; will be 16 byte aligned also.\r
- ;;\r
-ExceptionNumber dd ? ;; first entry will be the vector number pushed by the stub\r
-\r
-DebugStackBegin db "<<<< DbgStkBegin" ;; initial debug ESP == DebugStackBegin, set in stub\r
-\r
-.CODE\r
-\r
-externdef InterruptDistrubutionHub:near\r
-\r
-;------------------------------------------------------------------------------\r
-; BOOLEAN\r
-; FxStorSupport (\r
-; void\r
-; )\r
-;\r
-; Abstract: Returns TRUE if FxStor instructions are supported\r
-;\r
-FxStorSupport PROC C PUBLIC\r
-\r
-;\r
-; cpuid corrupts ebx which must be preserved per the C calling convention\r
-;\r
- push ebx\r
- mov eax, 1\r
- cpuid\r
- mov eax, edx\r
- and eax, FXSTOR_FLAG\r
- shr eax, 24\r
- pop ebx\r
- ret\r
-FxStorSupport ENDP\r
-\r
-\r
-\r
-;------------------------------------------------------------------------------\r
-; void\r
-; Vect2Desc (\r
-; DESCRIPTOR * DestDesc,\r
-; void (*Vector) (void)\r
-; )\r
-;\r
-; Abstract: Encodes an IDT descriptor with the given physical address\r
-;\r
-Vect2Desc PROC C PUBLIC DestPtr:DWORD, Vector:DWORD\r
-\r
- mov eax, Vector\r
- mov ecx, DestPtr\r
- mov word ptr [ecx], ax ; write bits 15..0 of offset\r
- mov dx, cs\r
- mov word ptr [ecx+2], dx ; SYS_CODE_SEL from GDT\r
- mov word ptr [ecx+4], 0e00h OR 8000h ; type = 386 interrupt gate, present\r
- shr eax, 16\r
- mov word ptr [ecx+6], ax ; write bits 31..16 of offset\r
-\r
- ret\r
-\r
-Vect2Desc ENDP\r
-\r
-\r
-\r
-;------------------------------------------------------------------------------\r
-; InterruptEntryStub\r
-;\r
-; Abstract: This code is not a function, but is a small piece of code that is\r
-; copied and fixed up once for each IDT entry that is hooked.\r
-;\r
-InterruptEntryStub::\r
- mov AppEsp, esp ; save stack top\r
- mov esp, offset DebugStackBegin ; switch to debugger stack\r
- push 0 ; push vector number - will be modified before installed\r
- db 0e9h ; jump rel32\r
- dd 0 ; fixed up to relative address of CommonIdtEntry\r
-InterruptEntryStubEnd:\r
-\r
-\r
-\r
-;------------------------------------------------------------------------------\r
-; CommonIdtEntry\r
-;\r
-; Abstract: This code is not a function, but is the common part for all IDT\r
-; vectors.\r
-;\r
-CommonIdtEntry::\r
-;;\r
-;; At this point, the stub has saved the current application stack esp into AppEsp\r
-;; and switched stacks to the debug stack, where it pushed the vector number\r
-;;\r
-;; The application stack looks like this:\r
-;;\r
-;; ...\r
-;; (last application stack entry)\r
-;; eflags from interrupted task\r
-;; CS from interrupted task\r
-;; EIP from interrupted task\r
-;; Error code <-------------------- Only present for some exeption types\r
-;;\r
-;;\r
-\r
-\r
-;; The stub switched us to the debug stack and pushed the interrupt number.\r
-;;\r
-;; Next, construct the context record. It will be build on the debug stack by\r
-;; pushing the registers in the correct order so as to create the context structure\r
-;; on the debug stack. The context record must be built from the end back to the\r
-;; beginning because the stack grows down...\r
-;\r
-;; For reference, the context record looks like this:\r
-;;\r
-;; typedef\r
-;; struct {\r
-;; UINT32 ExceptionData;\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-;; UINT32 Cr0, Cr2, Cr3, Cr4;\r
-;; UINT32 EFlags;\r
-;; UINT32 Ldtr, Tr;\r
-;; UINT32 Gdtr[2], Idtr[2];\r
-;; UINT32 Eip;\r
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
-;; } SYSTEM_CONTEXT_IA32; // 32 bit system context record\r
-\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- pushad\r
-\r
-;; Save interrupt state eflags register...\r
- pushfd\r
- pop eax\r
- mov dword ptr Eflags, eax\r
-\r
-;; We need to determine if any extra data was pushed by the exception, and if so, save it\r
-;; To do this, we check the exception number pushed by the stub, and cache the\r
-;; result in a variable since we'll need this again.\r
- .IF ExceptionNumber == EXCPT32_DOUBLE_FAULT\r
- mov ExtraPush, 1\r
- .ELSEIF ExceptionNumber == EXCPT32_INVALID_TSS\r
- mov ExtraPush, 1\r
- .ELSEIF ExceptionNumber == EXCPT32_SEG_NOT_PRESENT\r
- mov ExtraPush, 1\r
- .ELSEIF ExceptionNumber == EXCPT32_STACK_FAULT\r
- mov ExtraPush, 1\r
- .ELSEIF ExceptionNumber == EXCPT32_GP_FAULT\r
- mov ExtraPush, 1\r
- .ELSEIF ExceptionNumber == EXCPT32_PAGE_FAULT\r
- mov ExtraPush, 1\r
- .ELSEIF ExceptionNumber == EXCPT32_ALIGNMENT_CHECK\r
- mov ExtraPush, 1\r
- .ELSE\r
- mov ExtraPush, 0\r
- .ENDIF\r
-\r
-;; If there's some extra data, save it also, and modify the saved AppEsp to effectively\r
-;; pop this value off the application's stack.\r
- .IF ExtraPush == 1\r
- mov eax, AppEsp\r
- mov ebx, [eax]\r
- mov ExceptData, ebx\r
- add eax, 4\r
- mov AppEsp, eax\r
- .ELSE\r
- mov ExceptData, 0\r
- .ENDIF\r
-\r
-;; The "pushad" above pushed the debug stack esp. Since what we're actually doing\r
-;; is building the context record on the debug stack, we need to save the pushed\r
-;; debug ESP, and replace it with the application's last stack entry...\r
- mov eax, [esp + 12]\r
- mov DebugEsp, eax\r
- mov eax, AppEsp\r
- add eax, 12\r
- ; application stack has eflags, cs, & eip, so\r
- ; last actual application stack entry is\r
- ; 12 bytes into the application stack.\r
- mov [esp + 12], eax\r
-\r
-;; continue building context record\r
-;; UINT32 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
- mov eax, ss\r
- push eax\r
-\r
- ; CS from application is one entry back in application stack\r
- mov eax, AppEsp\r
- movzx eax, word ptr [eax + 4]\r
- push eax\r
-\r
- mov eax, ds\r
- push eax\r
- mov eax, es\r
- push eax\r
- mov eax, fs\r
- push eax\r
- mov eax, gs\r
- push eax\r
-\r
-;; UINT32 Eip;\r
- ; Eip from application is on top of application stack\r
- mov eax, AppEsp\r
- push dword ptr [eax]\r
-\r
-;; UINT32 Gdtr[2], Idtr[2];\r
- push 0\r
- push 0\r
- sidt fword ptr [esp]\r
- push 0\r
- push 0\r
- sgdt fword ptr [esp]\r
-\r
-;; UINT32 Ldtr, Tr;\r
- xor eax, eax\r
- str ax\r
- push eax\r
- sldt ax\r
- push eax\r
-\r
-;; UINT32 EFlags;\r
-;; Eflags from application is two entries back in application stack\r
- mov eax, AppEsp\r
- push dword ptr [eax + 8]\r
-\r
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
-;; insure FXSAVE/FXRSTOR is enabled in CR4...\r
-;; ... while we're at it, make sure DE is also enabled...\r
- mov eax, cr4\r
- or eax, 208h\r
- mov cr4, eax\r
- push eax\r
- mov eax, cr3\r
- push eax\r
- mov eax, cr2\r
- push eax\r
- push 0\r
- mov eax, cr0\r
- push eax\r
-\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- mov eax, dr7\r
- push eax\r
-;; clear Dr7 while executing debugger itself\r
- xor eax, eax\r
- mov dr7, eax\r
-\r
- mov eax, dr6\r
- push eax\r
-;; insure all status bits in dr6 are clear...\r
- xor eax, eax\r
- mov dr6, eax\r
-\r
- mov eax, dr3\r
- push eax\r
- mov eax, dr2\r
- push eax\r
- mov eax, dr1\r
- push eax\r
- mov eax, dr0\r
- push eax\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
- sub esp, 512\r
- mov edi, esp\r
- ; IMPORTANT!! The debug stack has been carefully constructed to\r
- ; insure that esp and edi are 16 byte aligned when we get here.\r
- ; They MUST be. If they are not, a GP fault will occur.\r
- FXSTOR_EDI\r
-\r
-;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear\r
- cld\r
-\r
-;; UINT32 ExceptionData;\r
- mov eax, ExceptData\r
- push eax\r
-\r
-; call to C code which will in turn call registered handler\r
-; pass in the vector number\r
- mov eax, esp\r
- push eax\r
- mov eax, ExceptionNumber\r
- push eax\r
- call InterruptDistrubutionHub\r
- add esp, 8\r
-\r
-; restore context...\r
-;; UINT32 ExceptionData;\r
- add esp, 4\r
-\r
-;; FX_SAVE_STATE_IA32 FxSaveState;\r
- mov esi, esp\r
- FXRSTOR_ESI\r
- add esp, 512\r
-\r
-;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- pop eax\r
- mov dr0, eax\r
- pop eax\r
- mov dr1, eax\r
- pop eax\r
- mov dr2, eax\r
- pop eax\r
- mov dr3, eax\r
-;; skip restore of dr6. We cleared dr6 during the context save.\r
- add esp, 4\r
- pop eax\r
- mov dr7, eax\r
-\r
-;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;\r
- pop eax\r
- mov cr0, eax\r
- add esp, 4\r
- pop eax\r
- mov cr2, eax\r
- pop eax\r
- mov cr3, eax\r
- pop eax\r
- mov cr4, eax\r
-\r
-;; UINT32 EFlags;\r
- mov eax, AppEsp\r
- pop dword ptr [eax + 8]\r
-\r
-;; UINT32 Ldtr, Tr;\r
-;; UINT32 Gdtr[2], Idtr[2];\r
-;; Best not let anyone mess with these particular registers...\r
- add esp, 24\r
-\r
-;; UINT32 Eip;\r
- pop dword ptr [eax]\r
-\r
-;; UINT32 SegGs, SegFs, SegEs, SegDs, SegCs, SegSs;\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
-\r
- pop gs\r
- pop fs\r
- pop es\r
- pop ds\r
- pop [eax + 4]\r
- pop ss\r
-\r
-;; The next stuff to restore is the general purpose registers that were pushed\r
-;; using the "pushad" instruction.\r
-;;\r
-;; The value of ESP as stored in the context record is the application ESP\r
-;; including the 3 entries on the application stack caused by the exception\r
-;; itself. It may have been modified by the debug agent, so we need to\r
-;; determine if we need to relocate the application stack.\r
-\r
- mov ebx, [esp + 12] ; move the potentially modified AppEsp into ebx\r
- mov eax, AppEsp\r
- add eax, 12\r
- cmp ebx, eax\r
- je NoAppStackMove\r
-\r
- mov eax, AppEsp\r
- mov ecx, [eax] ; EIP\r
- mov [ebx], ecx\r
-\r
- mov ecx, [eax + 4] ; CS\r
- mov [ebx + 4], ecx\r
-\r
- mov ecx, [eax + 8] ; EFLAGS\r
- mov [ebx + 8], ecx\r
-\r
- mov eax, ebx ; modify the saved AppEsp to the new AppEsp\r
- mov AppEsp, eax\r
-NoAppStackMove:\r
- mov eax, DebugEsp ; restore the DebugEsp on the debug stack\r
- ; so our "popad" will not cause a stack switch\r
- mov [esp + 12], eax\r
-\r
- cmp ExceptionNumber, 068h\r
- jne NoChain\r
-\r
-Chain:\r
-\r
-;; Restore eflags so when we chain, the flags will be exactly as if we were never here.\r
-;; We gin up the stack to do an iretd so we can get ALL the flags.\r
- mov eax, AppEsp\r
- mov ebx, [eax + 8]\r
- and ebx, NOT 300h ; special handling for IF and TF\r
- push ebx\r
- push cs\r
- push PhonyIretd\r
- iretd\r
-PhonyIretd:\r
-\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- popad\r
-\r
-;; Switch back to application stack\r
- mov esp, AppEsp\r
-\r
-;; Jump to original handler\r
- jmp OrigVector\r
-\r
-NoChain:\r
-;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;\r
- popad\r
-\r
-;; Switch back to application stack\r
- mov esp, AppEsp\r
-\r
-;; We're outa here...\r
- iretd\r
-END\r
-\r
-\r
-\r
+++ /dev/null
-///**@file\r
-// Low leve x64 specific debug support functions.\r
-//\r
-// Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
-// Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>\r
-// 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
-//**/\r
-\r
-ASM_GLOBAL ASM_PFX(OrigVector)\r
-ASM_GLOBAL ASM_PFX(InterruptEntryStub)\r
-ASM_GLOBAL ASM_PFX(StubSize)\r
-ASM_GLOBAL ASM_PFX(CommonIdtEntry)\r
-ASM_GLOBAL ASM_PFX(FxStorSupport)\r
-\r
-.data\r
-\r
-ASM_PFX(StubSize): .long ASM_PFX(InterruptEntryStubEnd) - ASM_PFX(InterruptEntryStub)\r
-ASM_PFX(AppRsp): .long 0x11111111 # ?\r
- .long 0x11111111 # ?\r
-ASM_PFX(DebugRsp): .long 0x22222222 # ?\r
- .long 0x22222222 # ?\r
-ASM_PFX(ExtraPush): .long 0x33333333 # ?\r
- .long 0x33333333 # ?\r
-ASM_PFX(ExceptData): .long 0x44444444 # ?\r
- .long 0x44444444 # ?\r
-ASM_PFX(Rflags): .long 0x55555555 # ?\r
- .long 0x55555555 # ?\r
-ASM_PFX(OrigVector): .long 0x66666666 # ?\r
- .long 0x66666666 # ?\r
-\r
-// The declarations below define the memory region that will be used for the debug stack.\r
-// The context record will be built by pushing register values onto this stack.\r
-// It is imparitive that alignment be carefully managed, since the FXSTOR and\r
-// FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned.\r
-//\r
-// The stub will switch stacks from the application stack to the debuger stack\r
-// and pushes the exception number.\r
-//\r
-// Then we building the context record on the stack. Since the stack grows down,\r
-// we push the fields of the context record from the back to the front. There\r
-// are 336 bytes of stack used prior allocating the 512 bytes of stack to be\r
-// used as the memory buffer for the fxstor instruction. Therefore address of\r
-// the buffer used for the FXSTOR instruction is &Eax - 336 - 512, which\r
-// must be 16 byte aligned.\r
-//\r
-// We carefully locate the stack to make this happen.\r
-//\r
-// For reference, the context structure looks like this:\r
-// struct {\r
-// UINT64 ExceptionData;\r
-// FX_SAVE_STATE_X64 FxSaveState; // 512 bytes, must be 16 byte aligned\r
-// UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-// UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
-// UINT64 RFlags;\r
-// UINT64 Ldtr, Tr;\r
-// UINT64 Gdtr[2], Idtr[2];\r
-// UINT64 Rip;\r
-// UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
-// UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-// UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
-// } SYSTEM_CONTEXT_X64; // 64 bit system context record\r
-\r
-.p2align 4\r
-DebugStackEnd : .ascii "DbgStkEnd >>>>>>" # 16 byte long string - must be 16 bytes to preserve alignment\r
- .fill 0x1ffc, 4, 0x00000000\r
- # 32K should be enough stack\r
- # This allocation is coocked to insure\r
- # that the the buffer for the FXSTORE instruction\r
- # will be 16 byte aligned also.\r
- #\r
-ASM_PFX(ExceptionNumber): .long 0x77777777 # first entry will be the vector number pushed by the stub\r
- .long 0x77777777 # ?\r
-\r
-DebugStackBegin : .ascii "<<<< DbgStkBegin" # initial debug ESP == DebugStackBegin, set in stub\r
-\r
-\r
-.text\r
-\r
-//------------------------------------------------------------------------------\r
-// BOOLEAN\r
-// FxStorSupport (\r
-// void\r
-// )\r
-//\r
-// Abstract: Returns TRUE if FxStor instructions are supported\r
-//\r
-ASM_GLOBAL ASM_PFX(FxStorSupport)\r
-ASM_PFX(FxStorSupport):\r
-//\r
-// cpuid corrupts rbx which must be preserved per the C calling convention\r
-//\r
- pushq %rbx\r
- movq $1, %rax\r
- cpuid\r
- movl %edx, %eax\r
- andq $0x01000000, %rax\r
- shrq $24, %rax\r
- popq %rbx\r
- ret\r
-//------------------------------------------------------------------------------\r
-// void\r
-// Vect2Desc (\r
-// IA32_IDT_GATE_DESCRIPTOR * DestDesc, // rcx\r
-// void (*Vector) (void) // rdx\r
-// )\r
-//\r
-// Abstract: Encodes an IDT descriptor with the given physical address\r
-//\r
-ASM_GLOBAL ASM_PFX(Vect2Desc)\r
-ASM_PFX(Vect2Desc):\r
- movq %rdx, %rax\r
- movw %ax, (%rcx) # write bits 15..0 of offset\r
- movw %cs, %dx\r
- movw %dx, 2(%rcx) # SYS_CODE_SEL from GDT\r
- movw $(0x0e00 | 0x8000), 4(%rcx) # type = 386 interrupt gate, present\r
- shrq $16, %rax\r
- movw %ax, 6(%rcx) # write bits 31..16 of offset\r
- shrq $16, %rax\r
- movl %eax, 8(%rcx) # write bits 63..32 of offset\r
-\r
- ret\r
-\r
-//------------------------------------------------------------------------------\r
-// InterruptEntryStub\r
-//\r
-// Abstract: This code is not a function, but is a small piece of code that is\r
-// copied and fixed up once for each IDT entry that is hooked.\r
-//\r
-ASM_GLOBAL ASM_PFX(InterruptEntryStub)\r
-ASM_PFX(InterruptEntryStub):\r
-\r
- pushq $0 # push vector number - will be modified before installed\r
- jmp ASM_PFX(CommonIdtEntry)\r
-\r
-ASM_GLOBAL ASM_PFX(InterruptEntryStubEnd)\r
-ASM_PFX(InterruptEntryStubEnd):\r
-\r
-//------------------------------------------------------------------------------\r
-// CommonIdtEntry\r
-//\r
-// Abstract: This code is not a function, but is the common part for all IDT\r
-// vectors.\r
-//\r
-ASM_GLOBAL ASM_PFX(CommonIdtEntry)\r
-//\r
-// At this point, the stub has saved the current application stack esp into AppRsp\r
-// and switched stacks to the debug stack, where it pushed the vector number\r
-//\r
-// The application stack looks like this:\r
-//\r
-// ...\r
-// (last application stack entry)\r
-// [16 bytes alignment, do not care it]\r
-// SS from interrupted task\r
-// RSP from interrupted task\r
-// rflags from interrupted task\r
-// CS from interrupted task\r
-// RIP from interrupted task\r
-// Error code <-------------------- Only present for some exeption types\r
-//\r
-// Vector Number <----------------- pushed in our IDT Entry\r
-//\r
-\r
-\r
-// The stub switched us to the debug stack and pushed the interrupt number.\r
-//\r
-// Next, construct the context record. It will be build on the debug stack by\r
-// pushing the registers in the correct order so as to create the context structure\r
-// on the debug stack. The context record must be built from the end back to the\r
-// beginning because the stack grows down...\r
-//\r
-// For reference, the context record looks like this:\r
-//\r
-// typedef\r
-// struct {\r
-// UINT64 ExceptionData;\r
-// FX_SAVE_STATE_X64 FxSaveState;\r
-// UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-// UINT64 Cr0, Cr2, Cr3, Cr4, Cr8;\r
-// UINT64 RFlags;\r
-// UINT64 Ldtr, Tr;\r
-// UINT64 Gdtr[2], Idtr[2];\r
-// UINT64 Rip;\r
-// UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
-// UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-// UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
-// } SYSTEM_CONTEXT_X64; // 64\r
-ASM_PFX(CommonIdtEntry):\r
-// NOTE: we save rsp here to prevent compiler put rip reference cause error AppRsp\r
- pushq %rax\r
- movq (8)(%rsp), %rax # save vector number\r
- movq %rax, ASM_PFX(ExceptionNumber)(%rip) # save vector number\r
- popq %rax\r
- addq $8, %rsp # pop vector number\r
- movq %rsp, ASM_PFX(AppRsp)(%rip) # save stack top\r
- movq DebugStackBegin(%rip), %rsp # switch to debugger stack\r
- subq $8, %rsp # leave space for vector number\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 %rcx\r
- pushq %rdx\r
- pushq %rbx\r
- pushq %rsp\r
- pushq %rbp\r
- pushq %rsi\r
- pushq %rdi\r
-// Save interrupt state rflags register...\r
- pushfq\r
- popq %rax\r
- movq %rax, ASM_PFX(Rflags)(%rip)\r
-// We need to determine if any extra data was pushed by the exception, and if so, save it\r
-// To do this, we check the exception number pushed by the stub, and cache the\r
-// result in a variable since we'll need this again.\r
- cmpl $0, ASM_PFX(ExceptionNumber)(%rip)\r
- jz ExtraPushOne\r
- cmpl $10, ASM_PFX(ExceptionNumber)(%rip)\r
- jz ExtraPushOne\r
- cmpl $11, ASM_PFX(ExceptionNumber)(%rip)\r
- jz ExtraPushOne\r
- cmpl $12, ASM_PFX(ExceptionNumber)(%rip)\r
- jz ExtraPushOne\r
- cmpl $13, ASM_PFX(ExceptionNumber)(%rip)\r
- jz ExtraPushOne\r
- cmpl $14, ASM_PFX(ExceptionNumber)(%rip)\r
- jz ExtraPushOne\r
- cmpl $17, ASM_PFX(ExceptionNumber)(%rip)\r
- jz ExtraPushOne\r
- movl $0, ASM_PFX(ExtraPush)(%rip)\r
- movl $0, ASM_PFX(ExceptData)(%rip)\r
- jmp ExtraPushDone\r
-ExtraPushOne:\r
- movl $1, ASM_PFX(ExtraPush)(%rip)\r
-\r
-// If there's some extra data, save it also, and modify the saved AppRsp to effectively\r
-// pop this value off the application's stack.\r
- movq ASM_PFX(AppRsp)(%rip), %rax\r
- movq (%rax), %rbx\r
- movq %rbx, ASM_PFX(ExceptData)(%rip)\r
- addq $8, %rax\r
- movq %rax, ASM_PFX(AppRsp)(%rip)\r
-\r
-ExtraPushDone:\r
-\r
-// The "push" above pushed the debug stack rsp. Since what we're actually doing\r
-// is building the context record on the debug stack, we need to save the pushed\r
-// debug RSP, and replace it with the application's last stack entry...\r
- movq 24(%rsp), %rax\r
- movq %rax, ASM_PFX(DebugRsp)(%rip)\r
- movq ASM_PFX(AppRsp)(%rip), %rax\r
- movq 24(%rax), %rax\r
- # application stack has ss, rsp, rflags, cs, & rip, so\r
- # last actual application stack entry is saved at offset\r
- # 24 bytes from stack top.\r
- movq %rax, 24(%rsp)\r
-\r
-// continue building context record\r
-// UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
- mov %ss, %rax\r
- pushq %rax\r
- # CS from application is one entry back in application stack\r
- movq ASM_PFX(AppRsp)(%rip), %rax\r
- movzwq 8(%rax), %rax\r
- pushq %rax\r
-\r
- mov %ds, %rax\r
- pushq %rax\r
- mov %es, %rax\r
- pushq %rax\r
- mov %fs, %rax\r
- pushq %rax\r
- mov %gs, %rax\r
- pushq %rax\r
-// UINT64 Rip;\r
- # Rip from application is on top of application stack\r
- movq ASM_PFX(AppRsp)(%rip), %rax\r
- pushq (%rax)\r
-// UINT64 Gdtr[2], Idtr[2];\r
- push $0\r
- push $0\r
- sidtq (%rsp)\r
- push $0\r
- push $0\r
- sgdtq (%rsp)\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
-// Rflags from application is two entries back in application stack\r
- movq ASM_PFX(AppRsp)(%rip), %rax\r
- pushq 16(%rax)\r
-// UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
-// insure FXSAVE/FXRSTOR is enabled in CR4...\r
-// ... while we're at it, make sure DE is also enabled...\r
- movq %cr8, %rax\r
- pushq %rax\r
- movq %cr4, %rax\r
- orq $0x208, %rax\r
- movq %rax, %cr4\r
- pushq %rax\r
- movq %cr3, %rax\r
- pushq %rax\r
- movq %cr2, %rax\r
- pushq %rax\r
- push $0\r
- movq %cr0, %rax\r
- pushq %rax\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
- # IMPORTANT!! The debug stack has been carefully constructed to\r
- # insure that rsp and rdi are 16 byte aligned when we get here.\r
- # They MUST be. If they are not, a GP fault will occur.\r
-\r
- # FXSTOR_RDI\r
- fxsave (%rdi)\r
-\r
-// UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
- cld\r
- \r
-// UINT64 ExceptionData;\r
- movq ASM_PFX(ExceptData)(%rip), %rax\r
- pushq %rax\r
-\r
-// call to C code which will in turn call registered handler\r
-// pass in the vector number\r
- movq %rsp, %rdx\r
- movq ASM_PFX(ExceptionNumber)(%rip), %rcx\r
- subq $40, %rsp\r
- call ASM_PFX(InterruptDistrubutionHub)\r
- addq $40, %rsp\r
-// restore context...\r
-// UINT64 ExceptionData;\r
- addq $8, %rsp\r
-\r
-// FX_SAVE_STATE_X64 FxSaveState;\r
- movq %rsp, %rsi\r
-\r
- # FXRSTOR_RSI\r
- fxrstor (%rsi)\r
-\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
-\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\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
-// UINT64 RFlags;\r
- movq ASM_PFX(AppRsp)(%rip), %rax\r
- popq 16(%rax)\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
-// UINT64 Rip;\r
- popq (%rax)\r
-\r
-// UINT64 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
-\r
- popq %rax\r
- # mov %rax, %gs\r
- popq %rax\r
- # mov %rax, %fs\r
- popq %rax\r
- mov %rax, %es\r
- popq %rax\r
- mov %rax, %ds\r
- movq ASM_PFX(AppRsp)(%rip), %rax\r
- popq 8(%rax)\r
- popq %rax\r
- mov %rax, %ss\r
-## The next stuff to restore is the general purpose registers that were pushed\r
-## using the "push" instruction.\r
-##\r
-## The value of RSP as stored in the context record is the application RSP\r
-## including the 5 entries on the application stack caused by the exception\r
-## itself. It may have been modified by the debug agent, so we need to\r
-## determine if we need to relocate the application stack.\r
-\r
- movq 24(%rsp), %rbx # move the potentially modified AppRsp into rbx\r
- movq ASM_PFX(AppRsp)(%rip), %rax\r
- movq 24(%rax), %rax\r
- cmpq %rax, %rbx\r
- je NoAppStackMove\r
-\r
- movq ASM_PFX(AppRsp)(%rip), %rax\r
- movq (%rax), %rcx # RIP\r
- movq %rcx, (%rbx)\r
-\r
- movq 8(%rax), %rcx # CS\r
- movq %rcx, 8(%rbx)\r
-\r
- movq 16(%rax), %rcx # RFLAGS\r
- movq %rcx, 16(%rbx)\r
-\r
- movq 24(%rax), %rcx # RSP\r
- movq %rcx, 24(%rbx)\r
-\r
- movq 32(%rax), %rcx # SS\r
- movq %rcx, 32(%rbx)\r
-\r
- movq %rbx, %rax # modify the saved AppRsp to the new AppRsp\r
- movq %rax, ASM_PFX(AppRsp)(%rip)\r
-NoAppStackMove:\r
- movq ASM_PFX(DebugRsp)(%rip), %rax # restore the DebugRsp on the debug stack\r
- # so our "pop" will not cause a stack switch\r
- movq %rax, 24(%rsp)\r
-\r
- cmpl $0x068, ASM_PFX(ExceptionNumber)(%rip)\r
- jne NoChain\r
-\r
-Chain:\r
-\r
-// Restore rflags so when we chain, the flags will be exactly as if we were never here.\r
-// We gin up the stack to do an iretq so we can get ALL the flags.\r
- movq ASM_PFX(AppRsp)(%rip), %rax\r
- movq 40(%rax), %rbx\r
- pushq %rbx\r
- mov %ss, %rax\r
- pushq %rax\r
- movq %rsp, %rax\r
- addq $16, %rax\r
- pushq %rax\r
- movq ASM_PFX(AppRsp)(%rip), %rax\r
- movq 16(%rax), %rbx\r
- andq $0xfffffffffffffcff, %rbx # special handling for IF and TF\r
- pushq %rbx\r
- mov %cs, %rax\r
- pushq %rax\r
- movq PhonyIretq(%rip), %rax\r
- pushq %rax\r
- iretq\r
-PhonyIretq:\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
- popq %rbp\r
- popq %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
-// Switch back to application stack\r
- movq ASM_PFX(AppRsp)(%rip), %rsp\r
-// Jump to original handler\r
- jmp ASM_PFX(OrigVector)\r
-NoChain:\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
- popq %rbp\r
- popq %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
-// Switch back to application stack\r
- movq ASM_PFX(AppRsp)(%rip), %rsp\r
-\r
-// We're outa here...\r
- iret\r
+++ /dev/null
-;/** @file\r
-; Low level x64 routines used by the debug support driver.\r
-;\r
-; Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
-; 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
-;**/\r
-\r
-EXCPT64_DIVIDE_ERROR EQU 0\r
-EXCPT64_DEBUG EQU 1\r
-EXCPT64_NMI EQU 2\r
-EXCPT64_BREAKPOINT EQU 3\r
-EXCPT64_OVERFLOW EQU 4\r
-EXCPT64_BOUND EQU 5\r
-EXCPT64_INVALID_OPCODE EQU 6\r
-EXCPT64_DOUBLE_FAULT EQU 8\r
-EXCPT64_INVALID_TSS EQU 10\r
-EXCPT64_SEG_NOT_PRESENT EQU 11\r
-EXCPT64_STACK_FAULT EQU 12\r
-EXCPT64_GP_FAULT EQU 13\r
-EXCPT64_PAGE_FAULT EQU 14\r
-EXCPT64_FP_ERROR EQU 16\r
-EXCPT64_ALIGNMENT_CHECK EQU 17\r
-EXCPT64_MACHINE_CHECK EQU 18\r
-EXCPT64_SIMD EQU 19\r
-\r
-FXSTOR_FLAG EQU 01000000h ; bit cpuid 24 of feature flags\r
-\r
-;; The FXSTOR and FXRSTOR commands are used for saving and restoring the x87,\r
-;; MMX, SSE, SSE2, etc registers. The initialization of the debugsupport driver\r
-;; MUST check the CPUID feature flags to see that these instructions are available\r
-;; and fail to init if they are not.\r
-\r
-;; fxstor [rdi]\r
-FXSTOR_RDI MACRO\r
- db 0fh, 0aeh, 00000111y ; mod = 00, reg/op = 000, r/m = 111 = [rdi]\r
-ENDM\r
-\r
-;; fxrstor [rsi]\r
-FXRSTOR_RSI MACRO\r
- db 0fh, 0aeh, 00001110y ; mod = 00, reg/op = 001, r/m = 110 = [rsi]\r
-ENDM\r
-\r
-data SEGMENT\r
-\r
-public OrigVector, InterruptEntryStub, StubSize, CommonIdtEntry, FxStorSupport\r
-\r
-StubSize dd InterruptEntryStubEnd - InterruptEntryStub\r
-AppRsp dq 1111111111111111h ; ?\r
-DebugRsp dq 2222222222222222h ; ?\r
-ExtraPush dq 3333333333333333h ; ?\r
-ExceptData dq 4444444444444444h ; ?\r
-Rflags dq 5555555555555555h ; ?\r
-OrigVector dq 6666666666666666h ; ?\r
-\r
-;; The declarations below define the memory region that will be used for the debug stack.\r
-;; The context record will be built by pushing register values onto this stack.\r
-;; It is imparitive that alignment be carefully managed, since the FXSTOR and\r
-;; FXRSTOR instructions will GP fault if their memory operand is not 16 byte aligned.\r
-;;\r
-;; The stub will switch stacks from the application stack to the debuger stack\r
-;; and pushes the exception number.\r
-;;\r
-;; Then we building the context record on the stack. Since the stack grows down,\r
-;; we push the fields of the context record from the back to the front. There\r
-;; are 336 bytes of stack used prior allocating the 512 bytes of stack to be\r
-;; used as the memory buffer for the fxstor instruction. Therefore address of\r
-;; the buffer used for the FXSTOR instruction is &Eax - 336 - 512, which\r
-;; must be 16 byte aligned.\r
-;;\r
-;; We carefully locate the stack to make this happen.\r
-;;\r
-;; For reference, the context structure looks like this:\r
-;; struct {\r
-;; UINT64 ExceptionData;\r
-;; FX_SAVE_STATE_X64 FxSaveState; // 512 bytes, must be 16 byte aligned\r
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
-;; UINT64 RFlags;\r
-;; UINT64 Ldtr, Tr;\r
-;; UINT64 Gdtr[2], Idtr[2];\r
-;; UINT64 Rip;\r
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
-;; } SYSTEM_CONTEXT_X64; // 64 bit system context record\r
-\r
-align 16\r
-DebugStackEnd db "DbgStkEnd >>>>>>" ;; 16 byte long string - must be 16 bytes to preserve alignment\r
- dd 1ffch dup (000000000h) ;; 32K should be enough stack\r
- ;; This allocation is coocked to insure\r
- ;; that the the buffer for the FXSTORE instruction\r
- ;; will be 16 byte aligned also.\r
- ;;\r
-ExceptionNumber dq ? ;; first entry will be the vector number pushed by the stub\r
-\r
-DebugStackBegin db "<<<< DbgStkBegin" ;; initial debug ESP == DebugStackBegin, set in stub\r
-\r
-data ENDS\r
-\r
-text SEGMENT\r
-\r
-externdef InterruptDistrubutionHub:near\r
-\r
-;------------------------------------------------------------------------------\r
-; BOOLEAN\r
-; FxStorSupport (\r
-; void\r
-; )\r
-;\r
-; Abstract: Returns TRUE if FxStor instructions are supported\r
-;\r
-FxStorSupport PROC PUBLIC\r
-\r
-;\r
-; cpuid corrupts rbx which must be preserved per the C calling convention\r
-;\r
- push rbx\r
- mov rax, 1\r
- cpuid\r
- mov eax, edx\r
- and rax, FXSTOR_FLAG\r
- shr rax, 24\r
- pop rbx\r
- ret\r
-FxStorSupport ENDP\r
-\r
-;------------------------------------------------------------------------------\r
-; void\r
-; Vect2Desc (\r
-; IA32_IDT_GATE_DESCRIPTOR * DestDesc, // rcx\r
-; void (*Vector) (void) // rdx\r
-; )\r
-;\r
-; Abstract: Encodes an IDT descriptor with the given physical address\r
-;\r
-Vect2Desc PROC PUBLIC\r
-\r
- mov rax, rdx\r
- mov word ptr [rcx], ax ; write bits 15..0 of offset\r
- mov dx, cs\r
- mov word ptr [rcx+2], dx ; SYS_CODE_SEL from GDT\r
- mov word ptr [rcx+4], 0e00h OR 8000h ; type = 386 interrupt gate, present\r
- shr rax, 16\r
- mov word ptr [rcx+6], ax ; write bits 31..16 of offset\r
- shr rax, 16\r
- mov dword ptr [rcx+8], eax ; write bits 63..32 of offset\r
-\r
- ret\r
-\r
-Vect2Desc ENDP\r
-\r
-\r
-\r
-;------------------------------------------------------------------------------\r
-; InterruptEntryStub\r
-;\r
-; Abstract: This code is not a function, but is a small piece of code that is\r
-; copied and fixed up once for each IDT entry that is hooked.\r
-;\r
-InterruptEntryStub::\r
- push 0 ; push vector number - will be modified before installed\r
- db 0e9h ; jump rel32\r
- dd 0 ; fixed up to relative address of CommonIdtEntry\r
-InterruptEntryStubEnd:\r
-\r
-\r
-\r
-;------------------------------------------------------------------------------\r
-; CommonIdtEntry\r
-;\r
-; Abstract: This code is not a function, but is the common part for all IDT\r
-; vectors.\r
-;\r
-CommonIdtEntry::\r
-;;\r
-;; At this point, the stub has saved the current application stack esp into AppRsp\r
-;; and switched stacks to the debug stack, where it pushed the vector number\r
-;;\r
-;; The application stack looks like this:\r
-;;\r
-;; ...\r
-;; (last application stack entry)\r
-;; [16 bytes alignment, do not care it]\r
-;; SS from interrupted task\r
-;; RSP from interrupted task\r
-;; rflags from interrupted task\r
-;; CS from interrupted task\r
-;; RIP from interrupted task\r
-;; Error code <-------------------- Only present for some exeption types\r
-;;\r
-;; Vector Number <----------------- pushed in our IDT Entry\r
-;;\r
-\r
-\r
-;; The stub switched us to the debug stack and pushed the interrupt number.\r
-;;\r
-;; Next, construct the context record. It will be build on the debug stack by\r
-;; pushing the registers in the correct order so as to create the context structure\r
-;; on the debug stack. The context record must be built from the end back to the\r
-;; beginning because the stack grows down...\r
-;\r
-;; For reference, the context record looks like this:\r
-;;\r
-;; typedef\r
-;; struct {\r
-;; UINT64 ExceptionData;\r
-;; FX_SAVE_STATE_X64 FxSaveState;\r
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
-;; UINT64 Cr0, Cr2, Cr3, Cr4, Cr8;\r
-;; UINT64 RFlags;\r
-;; UINT64 Ldtr, Tr;\r
-;; UINT64 Gdtr[2], Idtr[2];\r
-;; UINT64 Rip;\r
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;\r
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
-;; } SYSTEM_CONTEXT_X64; // 64 bit system context record\r
-\r
-;; NOTE: we save rsp here to prevent compiler put rip reference cause error AppRsp\r
- push rax\r
- mov rax, qword ptr [rsp][8] ; save vector number\r
- mov ExceptionNumber, rax ; save vector number\r
- pop rax\r
- add rsp, 8 ; pop vector number\r
- mov AppRsp, rsp ; save stack top\r
- mov rsp, offset DebugStackBegin ; switch to debugger stack\r
- sub rsp, 8 ; leave space for vector number\r
-\r
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- push r15\r
- push r14\r
- push r13\r
- push r12\r
- push r11\r
- push r10\r
- push r9\r
- push r8\r
- push rax\r
- push rcx\r
- push rdx\r
- push rbx\r
- push rsp\r
- push rbp\r
- push rsi\r
- push rdi\r
-\r
-;; Save interrupt state rflags register...\r
- pushfq\r
- pop rax\r
- mov qword ptr Rflags, rax\r
-\r
-;; We need to determine if any extra data was pushed by the exception, and if so, save it\r
-;; To do this, we check the exception number pushed by the stub, and cache the\r
-;; result in a variable since we'll need this again.\r
- cmp ExceptionNumber, EXCPT64_DOUBLE_FAULT\r
- jz ExtraPushOne\r
- cmp ExceptionNumber, EXCPT64_INVALID_TSS\r
- jz ExtraPushOne\r
- cmp ExceptionNumber, EXCPT64_SEG_NOT_PRESENT\r
- jz ExtraPushOne\r
- cmp ExceptionNumber, EXCPT64_STACK_FAULT\r
- jz ExtraPushOne\r
- cmp ExceptionNumber, EXCPT64_GP_FAULT\r
- jz ExtraPushOne\r
- cmp ExceptionNumber, EXCPT64_PAGE_FAULT\r
- jz ExtraPushOne\r
- cmp ExceptionNumber, EXCPT64_ALIGNMENT_CHECK\r
- jz ExtraPushOne\r
- mov ExtraPush, 0\r
- mov ExceptData, 0\r
- jmp ExtraPushDone\r
-ExtraPushOne:\r
- mov ExtraPush, 1\r
-\r
-;; If there's some extra data, save it also, and modify the saved AppRsp to effectively\r
-;; pop this value off the application's stack.\r
- mov rax, AppRsp\r
- mov rbx, [rax]\r
- mov ExceptData, rbx\r
- add rax, 8\r
- mov AppRsp, rax\r
-\r
-ExtraPushDone:\r
-\r
-;; The "push" above pushed the debug stack rsp. Since what we're actually doing\r
-;; is building the context record on the debug stack, we need to save the pushed\r
-;; debug RSP, and replace it with the application's last stack entry...\r
- mov rax, [rsp + 24]\r
- mov DebugRsp, rax\r
- mov rax, AppRsp\r
- mov rax, QWORD PTR [rax + 24]\r
- ; application stack has ss, rsp, rflags, cs, & rip, so\r
- ; last actual application stack entry is saved at offset\r
- ; 24 bytes from stack top.\r
- mov [rsp + 24], rax\r
-\r
-;; continue building context record\r
-;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero\r
- mov rax, ss\r
- push rax\r
-\r
- ; CS from application is one entry back in application stack\r
- mov rax, AppRsp\r
- movzx rax, word ptr [rax + 8]\r
- push rax\r
-\r
- mov rax, ds\r
- push rax\r
- mov rax, es\r
- push rax\r
- mov rax, fs\r
- push rax\r
- mov rax, gs\r
- push rax\r
-\r
-;; UINT64 Rip;\r
- ; Rip from application is on top of application stack\r
- mov rax, AppRsp\r
- push qword ptr [rax]\r
-\r
-;; UINT64 Gdtr[2], Idtr[2];\r
- push 0\r
- push 0\r
- sidt fword ptr [rsp]\r
- push 0\r
- push 0\r
- sgdt fword ptr [rsp]\r
-\r
-;; UINT64 Ldtr, Tr;\r
- xor rax, rax\r
- str ax\r
- push rax\r
- sldt ax\r
- push rax\r
-\r
-;; UINT64 RFlags;\r
-;; Rflags from application is two entries back in application stack\r
- mov rax, AppRsp\r
- push qword ptr [rax + 16]\r
-\r
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
-;; insure FXSAVE/FXRSTOR is enabled in CR4...\r
-;; ... while we're at it, make sure DE is also enabled...\r
- mov rax, cr8\r
- push rax\r
- mov rax, cr4\r
- or rax, 208h\r
- mov cr4, rax\r
- push rax\r
- mov rax, cr3\r
- push rax\r
- mov rax, cr2\r
- push rax\r
- push 0\r
- mov rax, cr0\r
- push rax\r
-\r
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- mov rax, dr7\r
- push rax\r
-;; clear Dr7 while executing debugger itself\r
- xor rax, rax\r
- mov dr7, rax\r
-\r
- mov rax, dr6\r
- push rax\r
-;; insure all status bits in dr6 are clear...\r
- xor rax, rax\r
- mov dr6, rax\r
-\r
- mov rax, dr3\r
- push rax\r
- mov rax, dr2\r
- push rax\r
- mov rax, dr1\r
- push rax\r
- mov rax, dr0\r
- push rax\r
-\r
-;; FX_SAVE_STATE_X64 FxSaveState;\r
- sub rsp, 512\r
- mov rdi, rsp\r
- ; IMPORTANT!! The debug stack has been carefully constructed to\r
- ; insure that rsp and rdi are 16 byte aligned when we get here.\r
- ; They MUST be. If they are not, a GP fault will occur.\r
- FXSTOR_RDI\r
-\r
-;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear\r
- cld\r
-\r
-;; UINT64 ExceptionData;\r
- mov rax, ExceptData\r
- push rax\r
-\r
-; call to C code which will in turn call registered handler\r
-; pass in the vector number\r
- mov rdx, rsp\r
- mov rcx, ExceptionNumber\r
- sub rsp, 40\r
- call InterruptDistrubutionHub\r
- add rsp, 40\r
-\r
-; restore context...\r
-;; UINT64 ExceptionData;\r
- add rsp, 8\r
-\r
-;; FX_SAVE_STATE_X64 FxSaveState;\r
- mov rsi, rsp\r
- FXRSTOR_RSI\r
- add rsp, 512\r
-\r
-;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;\r
- pop rax\r
- mov dr0, rax\r
- pop rax\r
- mov dr1, rax\r
- pop rax\r
- mov dr2, rax\r
- pop rax\r
- mov dr3, rax\r
-;; skip restore of dr6. We cleared dr6 during the context save.\r
- add rsp, 8\r
- pop rax\r
- mov dr7, rax\r
-\r
-;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;\r
- pop rax\r
- mov cr0, rax\r
- add rsp, 8\r
- pop rax\r
- mov cr2, rax\r
- pop rax\r
- mov cr3, rax\r
- pop rax\r
- mov cr4, rax\r
- pop rax\r
- mov cr8, rax\r
-\r
-;; UINT64 RFlags;\r
- mov rax, AppRsp\r
- pop qword ptr [rax + 16]\r
-\r
-;; UINT64 Ldtr, Tr;\r
-;; UINT64 Gdtr[2], Idtr[2];\r
-;; Best not let anyone mess with these particular registers...\r
- add rsp, 48\r
-\r
-;; UINT64 Rip;\r
- pop qword ptr [rax]\r
-\r
-;; UINT64 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
-\r
- pop rax\r
- ; mov gs, rax\r
- pop rax\r
- ; mov fs, rax\r
- pop rax\r
- mov es, rax\r
- pop rax\r
- mov ds, rax\r
- mov rax, AppRsp\r
- pop qword ptr [rax + 8]\r
- pop rax\r
- mov ss, rax\r
-\r
-;; The next stuff to restore is the general purpose registers that were pushed\r
-;; using the "push" instruction.\r
-;;\r
-;; The value of RSP as stored in the context record is the application RSP\r
-;; including the 5 entries on the application stack caused by the exception\r
-;; itself. It may have been modified by the debug agent, so we need to\r
-;; determine if we need to relocate the application stack.\r
-\r
- mov rbx, [rsp + 24] ; move the potentially modified AppRsp into rbx\r
- mov rax, AppRsp\r
- mov rax, QWORD PTR [rax + 24]\r
- cmp rbx, rax\r
- je NoAppStackMove\r
-\r
- mov rax, AppRsp\r
- mov rcx, [rax] ; RIP\r
- mov [rbx], rcx\r
-\r
- mov rcx, [rax + 8] ; CS\r
- mov [rbx + 8], rcx\r
-\r
- mov rcx, [rax + 16] ; RFLAGS\r
- mov [rbx + 16], rcx\r
-\r
- mov rcx, [rax + 24] ; RSP\r
- mov [rbx + 24], rcx\r
-\r
- mov rcx, [rax + 32] ; SS\r
- mov [rbx + 32], rcx\r
-\r
- mov rax, rbx ; modify the saved AppRsp to the new AppRsp\r
- mov AppRsp, rax\r
-NoAppStackMove:\r
- mov rax, DebugRsp ; restore the DebugRsp on the debug stack\r
- ; so our "pop" will not cause a stack switch\r
- mov [rsp + 24], rax\r
-\r
- cmp ExceptionNumber, 068h\r
- jne NoChain\r
-\r
-Chain:\r
-\r
-;; Restore rflags so when we chain, the flags will be exactly as if we were never here.\r
-;; We gin up the stack to do an iretq so we can get ALL the flags.\r
- mov rax, AppRsp\r
- mov rbx, [rax + 40]\r
- push rbx\r
- mov rax, ss\r
- push rax\r
- mov rax, rsp\r
- add rax, 16\r
- push rax\r
- mov rax, AppRsp\r
- mov rbx, [rax + 16]\r
- and rbx, NOT 300h ; special handling for IF and TF\r
- push rbx\r
- mov rax, cs\r
- push rax\r
- mov rax, offset PhonyIretq\r
- push rax\r
- iretq\r
-PhonyIretq:\r
-\r
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- pop rdi\r
- pop rsi\r
- pop rbp\r
- pop rsp\r
- pop rbx\r
- pop rdx\r
- pop rcx\r
- pop rax\r
- pop r8\r
- pop r9\r
- pop r10\r
- pop r11\r
- pop r12\r
- pop r13\r
- pop r14\r
- pop r15\r
-\r
-;; Switch back to application stack\r
- mov rsp, AppRsp\r
-\r
-;; Jump to original handler\r
- jmp OrigVector\r
-\r
-NoChain:\r
-;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;\r
-;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;\r
- pop rdi\r
- pop rsi\r
- pop rbp\r
- pop rsp\r
- pop rbx\r
- pop rdx\r
- pop rcx\r
- pop rax\r
- pop r8\r
- pop r9\r
- pop r10\r
- pop r11\r
- pop r12\r
- pop r13\r
- pop r14\r
- pop r15\r
-\r
-;; Switch back to application stack\r
- mov rsp, AppRsp\r
-\r
-;; We're outa here...\r
- iretq\r
-text ENDS\r
-\r
-END\r
-\r
-\r
-\r
## @file\r
# EFI Byte Code (EBC) Debugger.\r
#\r
-# Copyright (c) 2007 - 2016, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2018, Intel Corporation. All rights reserved.<BR>\r
#\r
# This program and the accompanying materials\r
# are licensed and made available under the terms and conditions of the BSD License\r
[Sources.Ia32]\r
Ia32/EbcSupport.c\r
Ia32/EbcLowLevel.nasm\r
- Ia32/EbcLowLevel.S\r
- Ia32/EbcLowLevel.asm\r
\r
[Sources.X64]\r
X64/EbcSupport.c\r
X64/EbcLowLevel.nasm\r
- X64/EbcLowLevel.S\r
- X64/EbcLowLevel.asm\r
\r
[Sources.IPF]\r
Ipf/EbcSupport.h\r
# device drivers.\r
#\r
# Copyright (c) 2015, The Linux Foundation. All rights reserved.\r
-# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
# 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
[Sources.Ia32]\r
Ia32/EbcSupport.c\r
Ia32/EbcLowLevel.nasm\r
- Ia32/EbcLowLevel.S\r
- Ia32/EbcLowLevel.asm\r
\r
[Sources.X64]\r
X64/EbcSupport.c\r
X64/EbcLowLevel.nasm\r
- X64/EbcLowLevel.S\r
- X64/EbcLowLevel.asm\r
\r
[Sources.IPF]\r
Ipf/EbcSupport.h\r
+++ /dev/null
-#/** @file\r
-# \r
-# Low level IA32 specific EBC support routines.\r
-# \r
-# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
-# 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
-#**/\r
-\r
-ASM_GLOBAL ASM_PFX(CopyMem)\r
-ASM_GLOBAL ASM_PFX(EbcInterpret)\r
-ASM_GLOBAL ASM_PFX(ExecuteEbcImageEntryPoint)\r
-\r
-ASM_GLOBAL ASM_PFX(EbcLLCALLEXNative)\r
-ASM_PFX(EbcLLCALLEXNative):\r
- push %ebp\r
- push %ebx\r
- mov %esp,%ebp\r
- mov 0xc(%esp),%ecx\r
- mov 0x14(%esp),%eax\r
- mov 0x10(%esp),%edx\r
- sub %edx,%eax\r
- sub %eax,%esp\r
- mov %esp,%ebx\r
- push %ecx\r
- push %eax\r
- push %edx\r
- push %ebx\r
- call ASM_PFX(CopyMem)\r
- pop %eax\r
- pop %eax\r
- pop %eax\r
- pop %ecx\r
- call *%ecx\r
- mov %ebp,%esp\r
- mov %ebp,%esp\r
- pop %ebx\r
- pop %ebp\r
- ret\r
-\r
-ASM_GLOBAL ASM_PFX(EbcLLEbcInterpret)\r
-ASM_PFX(EbcLLEbcInterpret):\r
- # Construct new stack\r
- push %ebp\r
- mov %esp, %ebp\r
- push %esi\r
- push %edi\r
- sub $0x40, %esp\r
- push %eax\r
- mov %ebp, %esi\r
- add $0x8, %esi\r
- mov %esp, %edi\r
- add $0x4, %edi\r
- mov $0x10, %ecx\r
- rep movsd\r
- \r
- # call C-code\r
- call ASM_PFX(EbcInterpret)\r
- add $0x44, %esp\r
- pop %edi\r
- pop %esi\r
- pop %ebp\r
- ret\r
-\r
-ASM_GLOBAL ASM_PFX(EbcLLExecuteEbcImageEntryPoint)\r
-ASM_PFX(EbcLLExecuteEbcImageEntryPoint):\r
- # Construct new stack\r
- mov %eax, -0xC(%esp)\r
- mov 0x4(%esp), %eax\r
- mov %eax, -0x8(%esp)\r
- mov 0x8(%esp), %eax\r
- mov %eax, -0x4(%esp)\r
- # call C-code\r
- sub $0xC, %esp\r
- call ASM_PFX(ExecuteEbcImageEntryPoint)\r
- add $0xC, %esp\r
- ret\r
+++ /dev/null
-;/** @file\r
-; \r
-; This code provides low level routines that support the Virtual Machine\r
-; for option ROMs.\r
-; \r
-; Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
-; 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
-;**/\r
-\r
- page ,132\r
- title VM ASSEMBLY LANGUAGE ROUTINES\r
-\r
-;---------------------------------------------------------------------------\r
-; Equate files needed.\r
-;---------------------------------------------------------------------------\r
-\r
-.XLIST\r
-\r
-.LIST\r
-\r
-;---------------------------------------------------------------------------\r
-; Assembler options\r
-;---------------------------------------------------------------------------\r
-\r
-.686p\r
-.model flat, C\r
-.code\r
-CopyMem PROTO Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD\r
-EbcInterpret PROTO\r
-ExecuteEbcImageEntryPoint PROTO\r
-\r
-;****************************************************************************\r
-; EbcLLCALLEXNative\r
-;\r
-; This function is called to execute an EBC CALLEX instruction\r
-; to native code.\r
-; This instruction requires that we thunk out to external native\r
-; code. For IA32, we simply switch stacks and jump to the\r
-; specified function. On return, we restore the stack pointer\r
-; to its original location.\r
-;\r
-; Destroys no working registers.\r
-;****************************************************************************\r
-; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)\r
-EbcLLCALLEXNative PROC PUBLIC\r
- push ebp\r
- push ebx\r
- mov ebp, esp ; standard function prolog\r
-\r
- ; Get function address in a register\r
- ; mov ecx, FuncAddr => mov ecx, dword ptr [FuncAddr]\r
- mov ecx, dword ptr [esp + 0Ch]\r
-\r
- ; Set stack pointer to new value\r
- ; mov eax, NewStackPointer => mov eax, dword ptr [NewSp]\r
- mov eax, dword ptr [esp + 14h]\r
- mov edx, dword ptr [esp + 10h]\r
- sub eax, edx\r
- sub esp, eax\r
- mov ebx, esp\r
- push ecx\r
- push eax\r
- push edx\r
- push ebx\r
- call CopyMem\r
- pop eax\r
- pop eax\r
- pop eax\r
- pop ecx\r
-\r
- ; Now call the external routine\r
- call ecx\r
-\r
- ; ebp is preserved by the callee. In this function it\r
- ; equals the original esp, so set them equal\r
- mov esp, ebp\r
-\r
- ; Standard function epilog\r
- mov esp, ebp\r
- pop ebx\r
- pop ebp\r
- ret\r
-EbcLLCALLEXNative ENDP\r
-\r
-;****************************************************************************\r
-; EbcLLEbcInterpret\r
-;\r
-; Begin executing an EBC image.\r
-;****************************************************************************\r
-; UINT64 EbcLLEbcInterpret(VOID)\r
-EbcLLEbcInterpret PROC PUBLIC\r
- ;\r
- ;; mov eax, 0xca112ebc\r
- ;; mov eax, EbcEntryPoint\r
- ;; mov ecx, EbcLLEbcInterpret\r
- ;; jmp ecx\r
- ;\r
- ; Caller uses above instruction to jump here\r
- ; The stack is below:\r
- ; +-----------+\r
- ; | RetAddr |\r
- ; +-----------+\r
- ; |EntryPoint | (EAX)\r
- ; +-----------+\r
- ; | Arg1 | <- EDI\r
- ; +-----------+\r
- ; | Arg2 |\r
- ; +-----------+\r
- ; | ... |\r
- ; +-----------+\r
- ; | Arg16 |\r
- ; +-----------+\r
- ; | EDI |\r
- ; +-----------+\r
- ; | ESI |\r
- ; +-----------+\r
- ; | EBP | <- EBP\r
- ; +-----------+\r
- ; | RetAddr | <- ESP is here\r
- ; +-----------+\r
- ; | Arg1 | <- ESI\r
- ; +-----------+\r
- ; | Arg2 |\r
- ; +-----------+\r
- ; | ... |\r
- ; +-----------+\r
- ; | Arg16 |\r
- ; +-----------+\r
- ; \r
-\r
- ; Construct new stack\r
- push ebp\r
- mov ebp, esp\r
- push esi\r
- push edi\r
- sub esp, 40h\r
- push eax\r
- mov esi, ebp\r
- add esi, 8\r
- mov edi, esp\r
- add edi, 4\r
- mov ecx, 16\r
- rep movsd\r
- \r
- ; call C-code\r
- call EbcInterpret\r
- add esp, 44h\r
- pop edi\r
- pop esi\r
- pop ebp\r
- ret\r
-EbcLLEbcInterpret ENDP\r
-\r
-;****************************************************************************\r
-; EbcLLExecuteEbcImageEntryPoint\r
-;\r
-; Begin executing an EBC image.\r
-;****************************************************************************\r
-; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)\r
-EbcLLExecuteEbcImageEntryPoint PROC PUBLIC\r
- ;\r
- ;; mov eax, 0xca112ebc\r
- ;; mov eax, EbcEntryPoint\r
- ;; mov ecx, EbcLLExecuteEbcImageEntryPoint\r
- ;; jmp ecx\r
- ;\r
- ; Caller uses above instruction to jump here\r
- ; The stack is below:\r
- ; +-----------+\r
- ; | RetAddr |\r
- ; +-----------+\r
- ; |EntryPoint | (EAX)\r
- ; +-----------+\r
- ; |ImageHandle|\r
- ; +-----------+\r
- ; |SystemTable|\r
- ; +-----------+\r
- ; | RetAddr | <- ESP is here\r
- ; +-----------+\r
- ; |ImageHandle|\r
- ; +-----------+\r
- ; |SystemTable|\r
- ; +-----------+\r
- ; \r
- \r
- ; Construct new stack\r
- mov [esp - 0Ch], eax\r
- mov eax, [esp + 04h]\r
- mov [esp - 08h], eax\r
- mov eax, [esp + 08h]\r
- mov [esp - 04h], eax\r
- \r
- ; call C-code\r
- sub esp, 0Ch\r
- call ExecuteEbcImageEntryPoint\r
- add esp, 0Ch\r
- ret\r
-EbcLLExecuteEbcImageEntryPoint ENDP\r
-\r
-END\r
+++ /dev/null
-#/** @file\r
-# \r
-# This code provides low level routines that support the Virtual Machine\r
-# for option ROMs.\r
-# \r
-# Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.<BR>\r
-# 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
-#**/\r
-\r
-#---------------------------------------------------------------------------\r
-# Equate files needed.\r
-#---------------------------------------------------------------------------\r
-\r
-ASM_GLOBAL ASM_PFX(CopyMem);\r
-ASM_GLOBAL ASM_PFX(EbcInterpret);\r
-ASM_GLOBAL ASM_PFX(ExecuteEbcImageEntryPoint);\r
-\r
-#****************************************************************************\r
-# EbcLLCALLEX\r
-#\r
-# This function is called to execute an EBC CALLEX instruction.\r
-# This instruction requires that we thunk out to external native\r
-# code. For x64, we switch stacks, copy the arguments to the stack\r
-# and jump to the specified function.\r
-# On return, we restore the stack pointer to its original location.\r
-#\r
-# Destroys no working registers.\r
-#****************************************************************************\r
-# VOID EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)\r
-ASM_GLOBAL ASM_PFX(EbcLLCALLEXNative);\r
-ASM_PFX(EbcLLCALLEXNative):\r
- push %rbp\r
- push %rbx\r
- mov %rsp, %rbp\r
- # Function prolog\r
-\r
- # Copy FuncAddr to a preserved register.\r
- mov %rcx, %rbx\r
-\r
- # Set stack pointer to new value\r
- sub %rdx, %r8 \r
- \r
- #\r
- # Fix X64 native function call prolog. Prepare space for at least 4 arguments,\r
- # even if the native function's arguments are less than 4.\r
- #\r
- # From MSDN x64 Software Conventions, Overview of x64 Calling Conventions:\r
- # "The caller is responsible for allocating space for parameters to the\r
- # callee, and must always allocate sufficient space for the 4 register\r
- # parameters, even if the callee doesn't have that many parameters.\r
- # This aids in the simplicity of supporting C unprototyped functions,\r
- # and vararg C/C++ functions."\r
- #\r
- cmp $0x20, %r8\r
- jae skip_expansion\r
- mov $0x20, %r8\r
-skip_expansion:\r
- \r
- sub %r8, %rsp \r
- \r
- #\r
- # Fix X64 native function call 16-byte alignment.\r
- #\r
- # From MSDN x64 Software Conventions, Stack Usage:\r
- # "The stack will always be maintained 16-byte aligned, except within \r
- # the prolog (for example, after the return address is pushed)."\r
- #\r
- and $0xFFFFFFFFFFFFFFF0, %rsp\r
- \r
- mov %rsp, %rcx\r
- sub $0x20, %rsp \r
- call ASM_PFX(CopyMem)\r
- add $0x20, %rsp\r
-\r
- # Considering the worst case, load 4 potiential arguments\r
- # into registers.\r
- mov (%rsp), %rcx\r
- mov 0x8(%rsp), %rdx\r
- mov 0x10(%rsp), %r8\r
- mov 0x18(%rsp), %r9\r
-\r
- # Now call the external routine\r
- call *%rbx\r
-\r
- # Function epilog\r
- mov %rbp, %rsp\r
- pop %rbx\r
- pop %rbp\r
- ret\r
-\r
-ASM_GLOBAL ASM_PFX(EbcLLEbcInterpret);\r
-ASM_PFX(EbcLLEbcInterpret):\r
- # save old parameter to stack\r
- mov %rcx, 0x8(%rsp)\r
- mov %rdx, 0x10(%rsp)\r
- mov %r8, 0x18(%rsp)\r
- mov %r9, 0x20(%rsp)\r
-\r
- # Construct new stack\r
- push %rbp\r
- mov %rsp, %rbp\r
- push %rsi\r
- push %rdi\r
- push %rbx\r
- sub $0x80, %rsp\r
- push %r10\r
- mov %rbp, %rsi\r
- add $0x10, %rsi\r
- mov %rsp, %rdi\r
- add $0x8, %rdi\r
- mov $0x10, %rcx\r
- rep movsq\r
- \r
- # build new paramater calling convention\r
- mov 0x18(%rsp), %r9\r
- mov 0x10(%rsp), %r8\r
- mov 0x8(%rsp), %rdx\r
- mov %r10, %rcx\r
-\r
- # call C-code\r
- call ASM_PFX(EbcInterpret)\r
- add $0x88, %esp\r
- pop %rbx\r
- pop %rdi\r
- pop %rsi\r
- pop %rbp\r
- ret\r
-\r
-ASM_GLOBAL ASM_PFX(EbcLLExecuteEbcImageEntryPoint);\r
-ASM_PFX(EbcLLExecuteEbcImageEntryPoint):\r
- # build new paramater calling convention\r
- mov %rdx, %r8\r
- mov %rcx, %rdx\r
- mov %r10, %rcx\r
-\r
- # call C-code\r
- sub $0x28, %rsp\r
- call ASM_PFX(ExecuteEbcImageEntryPoint)\r
- add $0x28, %rsp\r
- ret\r
+++ /dev/null
-;/** @file\r
-; \r
-; This code provides low level routines that support the Virtual Machine.\r
-; for option ROMs.\r
-; \r
-; Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>\r
-; Copyright (c) 2014 Hewlett-Packard Development Company, L.P.<BR>\r
-; 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
-;**/\r
-\r
- page ,132\r
- title VM ASSEMBLY LANGUAGE ROUTINES\r
-\r
-;---------------------------------------------------------------------------\r
-; Equate files needed.\r
-;---------------------------------------------------------------------------\r
-\r
-.CODE\r
-\r
-CopyMem PROTO Destination:PTR DWORD, Source:PTR DWORD, Count:DWORD\r
-EbcInterpret PROTO\r
-ExecuteEbcImageEntryPoint PROTO\r
-\r
-;****************************************************************************\r
-; EbcLLCALLEX\r
-;\r
-; This function is called to execute an EBC CALLEX instruction.\r
-; This instruction requires that we thunk out to external native\r
-; code. For x64, we switch stacks, copy the arguments to the stack\r
-; and jump to the specified function.\r
-; On return, we restore the stack pointer to its original location.\r
-;\r
-; Destroys no working registers.\r
-;****************************************************************************\r
-; INT64 EbcLLCALLEXNative(UINTN FuncAddr, UINTN NewStackPointer, VOID *FramePtr)\r
-EbcLLCALLEXNative PROC PUBLIC\r
- push rbp\r
- push rbx\r
- mov rbp, rsp\r
- ; Function prolog\r
-\r
- ; Copy FuncAddr to a preserved register.\r
- mov rbx, rcx\r
-\r
- ; Set stack pointer to new value\r
- sub r8, rdx\r
-\r
- ;\r
- ; Fix X64 native function call prolog. Prepare space for at least 4 arguments,\r
- ; even if the native function's arguments are less than 4.\r
- ;\r
- ; From MSDN x64 Software Conventions, Overview of x64 Calling Conventions:\r
- ; "The caller is responsible for allocating space for parameters to the\r
- ; callee, and must always allocate sufficient space for the 4 register\r
- ; parameters, even if the callee doesn't have that many parameters.\r
- ; This aids in the simplicity of supporting C unprototyped functions,\r
- ; and vararg C/C++ functions."\r
- ;\r
- cmp r8, 20h\r
- jae skip_expansion\r
- mov r8, 20h\r
-skip_expansion:\r
- \r
- sub rsp, r8\r
-\r
- ;\r
- ; Fix X64 native function call 16-byte alignment.\r
- ;\r
- ; From MSDN x64 Software Conventions, Stack Usage:\r
- ; "The stack will always be maintained 16-byte aligned, except within \r
- ; the prolog (for example, after the return address is pushed)."\r
- ;\r
- and rsp, NOT 0fh\r
-\r
- mov rcx, rsp\r
- sub rsp, 20h\r
- call CopyMem\r
- add rsp, 20h\r
-\r
- ; Considering the worst case, load 4 potiential arguments\r
- ; into registers.\r
- mov rcx, qword ptr [rsp]\r
- mov rdx, qword ptr [rsp+8h]\r
- mov r8, qword ptr [rsp+10h]\r
- mov r9, qword ptr [rsp+18h]\r
-\r
- ; Now call the external routine\r
- call rbx\r
-\r
- ; Function epilog\r
- mov rsp, rbp\r
- pop rbx\r
- pop rbp\r
- ret\r
-EbcLLCALLEXNative ENDP\r
-\r
-;****************************************************************************\r
-; EbcLLEbcInterpret\r
-;\r
-; Begin executing an EBC image.\r
-;****************************************************************************\r
-; UINT64 EbcLLEbcInterpret(VOID)\r
-EbcLLEbcInterpret PROC PUBLIC\r
- ;\r
- ;; mov rax, ca112ebccall2ebch\r
- ;; mov r10, EbcEntryPoint\r
- ;; mov r11, EbcLLEbcInterpret\r
- ;; jmp r11\r
- ;\r
- ; Caller uses above instruction to jump here\r
- ; The stack is below:\r
- ; +-----------+\r
- ; | RetAddr |\r
- ; +-----------+\r
- ; |EntryPoint | (R10)\r
- ; +-----------+\r
- ; | Arg1 | <- RDI\r
- ; +-----------+\r
- ; | Arg2 |\r
- ; +-----------+\r
- ; | ... |\r
- ; +-----------+\r
- ; | Arg16 |\r
- ; +-----------+\r
- ; | Dummy |\r
- ; +-----------+\r
- ; | RDI |\r
- ; +-----------+\r
- ; | RSI |\r
- ; +-----------+\r
- ; | RBP | <- RBP\r
- ; +-----------+\r
- ; | RetAddr | <- RSP is here\r
- ; +-----------+\r
- ; | Scratch1 | (RCX) <- RSI\r
- ; +-----------+\r
- ; | Scratch2 | (RDX)\r
- ; +-----------+\r
- ; | Scratch3 | (R8)\r
- ; +-----------+\r
- ; | Scratch4 | (R9)\r
- ; +-----------+\r
- ; | Arg5 |\r
- ; +-----------+\r
- ; | Arg6 |\r
- ; +-----------+\r
- ; | ... |\r
- ; +-----------+\r
- ; | Arg16 |\r
- ; +-----------+\r
- ;\r
-\r
- ; save old parameter to stack\r
- mov [rsp + 08h], rcx\r
- mov [rsp + 10h], rdx\r
- mov [rsp + 18h], r8\r
- mov [rsp + 20h], r9\r
-\r
- ; Construct new stack\r
- push rbp\r
- mov rbp, rsp\r
- push rsi\r
- push rdi\r
- push rbx\r
- sub rsp, 80h\r
- push r10\r
- mov rsi, rbp\r
- add rsi, 10h\r
- mov rdi, rsp\r
- add rdi, 8\r
- mov rcx, 16\r
- rep movsq\r
- \r
- ; build new paramater calling convention\r
- mov r9, [rsp + 18h]\r
- mov r8, [rsp + 10h]\r
- mov rdx, [rsp + 08h]\r
- mov rcx, r10\r
-\r
- ; call C-code\r
- call EbcInterpret\r
- add rsp, 88h\r
- pop rbx\r
- pop rdi\r
- pop rsi\r
- pop rbp\r
- ret\r
-EbcLLEbcInterpret ENDP\r
-\r
-;****************************************************************************\r
-; EbcLLExecuteEbcImageEntryPoint\r
-;\r
-; Begin executing an EBC image.\r
-;****************************************************************************\r
-; UINT64 EbcLLExecuteEbcImageEntryPoint(VOID)\r
-EbcLLExecuteEbcImageEntryPoint PROC PUBLIC\r
- ;\r
- ;; mov rax, ca112ebccall2ebch\r
- ;; mov r10, EbcEntryPoint\r
- ;; mov r11, EbcLLExecuteEbcImageEntryPoint\r
- ;; jmp r11\r
- ;\r
- ; Caller uses above instruction to jump here\r
- ; The stack is below:\r
- ; +-----------+\r
- ; | RetAddr |\r
- ; +-----------+\r
- ; |EntryPoint | (R10)\r
- ; +-----------+\r
- ; |ImageHandle|\r
- ; +-----------+\r
- ; |SystemTable|\r
- ; +-----------+\r
- ; | Dummy |\r
- ; +-----------+\r
- ; | Dummy |\r
- ; +-----------+\r
- ; | RetAddr | <- RSP is here\r
- ; +-----------+\r
- ; |ImageHandle| (RCX)\r
- ; +-----------+\r
- ; |SystemTable| (RDX)\r
- ; +-----------+\r
- ; \r
-\r
- ; build new paramater calling convention\r
- mov r8, rdx\r
- mov rdx, rcx\r
- mov rcx, r10\r
-\r
- ; call C-code\r
- sub rsp, 28h\r
- call ExecuteEbcImageEntryPoint\r
- add rsp, 28h\r
- ret\r
-EbcLLExecuteEbcImageEntryPoint ENDP\r
-\r
-END\r
-\r