summaryrefslogtreecommitdiff
path: root/UefiCpuPkg/CpuDxe/Ia32
diff options
context:
space:
mode:
Diffstat (limited to 'UefiCpuPkg/CpuDxe/Ia32')
-rwxr-xr-xUefiCpuPkg/CpuDxe/Ia32/CpuAsm.S395
-rwxr-xr-xUefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm384
-rwxr-xr-xUefiCpuPkg/CpuDxe/Ia32/IvtAsm.S66
-rwxr-xr-xUefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm51
4 files changed, 896 insertions, 0 deletions
diff --git a/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
new file mode 100755
index 0000000000..69fe215637
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.S
@@ -0,0 +1,395 @@
+#
+# ConvertAsm.py: Automatically generated from CpuAsm.asm
+#
+# TITLE CpuAsm.asm:
+
+#------------------------------------------------------------------------------
+#*
+#* Copyright 2006 - 2009, Intel Corporation
+#* All rights reserved. This program and the accompanying materials
+#* are licensed and made available under the terms and conditions of the BSD License
+#* which accompanies this distribution. The full text of the license may be found at
+#* http://opensource.org/licenses/bsd-license.php
+#*
+#* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+#* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#*
+#* CpuAsm.S
+#*
+#* Abstract:
+#*
+#------------------------------------------------------------------------------
+
+
+#.MMX
+#.XMM
+
+#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
+
+
+#
+# point to the external interrupt vector table
+#
+ExternalVectorTablePtr:
+ .byte 0, 0, 0, 0
+
+.intel_syntax
+ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)
+ASM_PFX(InitializeExternalVectorTablePtr):
+ mov eax, [esp+4]
+ mov ExternalVectorTablePtr, eax
+ ret
+
+#------------------------------------------------------------------------------
+# VOID
+# SetCodeSelector (
+# UINT16 Selector
+# );
+#------------------------------------------------------------------------------
+.intel_syntax
+ASM_GLOBAL ASM_PFX(SetCodeSelector)
+ASM_PFX(SetCodeSelector):
+ mov %ecx, [%esp+4]
+ sub %esp, 0x10
+ lea %eax, setCodeSelectorLongJump
+ mov [%esp], %eax
+ mov [%esp+4], %cx
+ jmp fword ptr [%esp]
+setCodeSelectorLongJump:
+ add %esp, 0x10
+ ret
+
+#------------------------------------------------------------------------------
+# VOID
+# SetDataSelectors (
+# UINT16 Selector
+# );
+#------------------------------------------------------------------------------
+.intel_syntax
+ASM_GLOBAL ASM_PFX(SetDataSelectors)
+ASM_PFX(SetDataSelectors):
+ mov %ecx, [%esp+4]
+ mov %ss, %cx
+ mov %ds, %cx
+ mov %es, %cx
+ mov %fs, %cx
+ mov %gs, %cx
+ ret
+
+#---------------------------------------;
+# CommonInterruptEntry ;
+#---------------------------------------;
+# The follow algorithm is used for the common interrupt routine.
+
+.intel_syntax
+ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
+ASM_PFX(CommonInterruptEntry):
+ cli
+ #
+ # All interrupt handlers are invoked through interrupt gates, so
+ # IF flag automatically cleared at the entry point
+ #
+
+ #
+ # Calculate vector number
+ #
+ # Get the return address of call, actually, it is the
+ # address of vector number.
+ #
+ xchg ecx, [esp]
+ mov cx, [ecx]
+ and ecx, 0x0FFFF
+ cmp ecx, 32 # Intel reserved vector for exceptions?
+ jae NoErrorCode
+ bt ASM_PFX(mErrorCodeFlag), ecx
+ jc HasErrorCode
+
+NoErrorCode:
+
+ #
+ # Stack:
+ # +---------------------+
+ # + EFlags +
+ # +---------------------+
+ # + CS +
+ # +---------------------+
+ # + EIP +
+ # +---------------------+
+ # + ECX +
+ # +---------------------+ <-- ESP
+ #
+ # Registers:
+ # ECX - Vector Number
+ #
+
+ #
+ # Put Vector Number on stack
+ #
+ push ecx
+
+ #
+ # Put 0 (dummy) error code on stack, and restore ECX
+ #
+ xor ecx, ecx # ECX = 0
+ xchg ecx, [esp+4]
+
+ jmp ErrorCodeAndVectorOnStack
+
+HasErrorCode:
+
+ #
+ # Stack:
+ # +---------------------+
+ # + EFlags +
+ # +---------------------+
+ # + CS +
+ # +---------------------+
+ # + EIP +
+ # +---------------------+
+ # + Error Code +
+ # +---------------------+
+ # + ECX +
+ # +---------------------+ <-- ESP
+ #
+ # Registers:
+ # ECX - Vector Number
+ #
+
+ #
+ # Put Vector Number on stack and restore ECX
+ #
+ xchg ecx, [esp]
+
+ #
+ # Fall through to join main routine code
+ # at ErrorCodeAndVectorOnStack
+ #
+CommonInterruptEntry_al_0000:
+ jmp CommonInterruptEntry_al_0000
+
+ErrorCodeAndVectorOnStack:
+ push ebp
+ mov ebp, esp
+
+ #
+ # Stack:
+ # +---------------------+
+ # + EFlags +
+ # +---------------------+
+ # + CS +
+ # +---------------------+
+ # + EIP +
+ # +---------------------+
+ # + Error Code +
+ # +---------------------+
+ # + Vector Number +
+ # +---------------------+
+ # + EBP +
+ # +---------------------+ <-- EBP
+ #
+
+ #
+ # Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
+ # is 16-byte aligned
+ #
+ and esp, 0x0fffffff0
+ sub esp, 12
+
+#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ push eax
+ push ecx
+ push edx
+ push ebx
+ lea ecx, [ebp + 6 * 4]
+ push ecx # ESP
+ push dword ptr [ebp] # EBP
+ push esi
+ push edi
+
+#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
+ mov eax, ss
+ push eax
+ movzx eax, word ptr [ebp + 4 * 4]
+ push eax
+ mov eax, ds
+ push eax
+ mov eax, es
+ push eax
+ mov eax, fs
+ push eax
+ mov eax, gs
+ push eax
+
+#; UINT32 Eip;
+ mov eax, [ebp + 3 * 4]
+ push eax
+
+#; UINT32 Gdtr[2], Idtr[2];
+ sub esp, 8
+ sidt [esp]
+ mov eax, [esp + 2]
+ xchg eax, [esp]
+ and eax, 0x0FFFF
+ mov [esp+4], eax
+
+ sub esp, 8
+ sgdt [esp]
+ mov eax, [esp + 2]
+ xchg eax, [esp]
+ and eax, 0x0FFFF
+ mov [esp+4], eax
+
+#; UINT32 Ldtr, Tr;
+ xor eax, eax
+ str ax
+ push eax
+ sldt ax
+ push eax
+
+#; UINT32 EFlags;
+ mov eax, [ebp + 5 * 4]
+ push eax
+
+#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
+ mov eax, cr4
+ or eax, 0x208
+ mov cr4, eax
+ push eax
+ mov eax, cr3
+ push eax
+ mov eax, cr2
+ push eax
+ xor eax, eax
+ push eax
+ mov eax, cr0
+ push eax
+
+#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ mov eax, dr7
+ push eax
+#; clear Dr7 while executing debugger itself
+ xor eax, eax
+ mov dr7, eax
+
+ mov eax, dr6
+ push eax
+#; insure all status bits in dr6 are clear...
+ xor eax, eax
+ mov dr6, eax
+
+ mov eax, dr3
+ push eax
+ mov eax, dr2
+ push eax
+ mov eax, dr1
+ push eax
+ mov eax, dr0
+ push eax
+
+#; FX_SAVE_STATE_IA32 FxSaveState;
+ sub esp, 512
+ mov edi, esp
+ .byte 0x0f, 0x0ae, 0x07 #fxsave [edi]
+
+#; UINT32 ExceptionData;
+ push dword ptr [ebp + 2 * 4]
+
+#; call into exception handler
+ mov eax, ExternalVectorTablePtr # get the interrupt vectors base
+ or eax, eax # NULL?
+ jz nullExternalExceptionHandler
+
+ mov ecx, [ebp + 4]
+ mov eax, [eax + ecx * 4]
+ or eax, eax # NULL?
+ jz nullExternalExceptionHandler
+
+#; Prepare parameter and call
+ mov edx, esp
+ push edx
+ mov edx, dword ptr [ebp + 1 * 4]
+ push edx
+
+ #
+ # Call External Exception Handler
+ #
+ call eax
+ add esp, 8
+
+nullExternalExceptionHandler:
+
+ cli
+#; UINT32 ExceptionData;
+ add esp, 4
+
+#; FX_SAVE_STATE_IA32 FxSaveState;
+ mov esi, esp
+ .byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]
+ add esp, 512
+
+#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ pop eax
+ mov dr0, eax
+ pop eax
+ mov dr1, eax
+ pop eax
+ mov dr2, eax
+ pop eax
+ mov dr3, eax
+#; skip restore of dr6. We cleared dr6 during the context save.
+ add esp, 4
+ pop eax
+ mov dr7, eax
+
+#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
+ pop eax
+ mov cr0, eax
+ add esp, 4 # not for Cr1
+ pop eax
+ mov cr2, eax
+ pop eax
+ mov cr3, eax
+ pop eax
+ mov cr4, eax
+
+#; UINT32 EFlags;
+ pop dword ptr [ebp + 5 * 4]
+
+#; UINT32 Ldtr, Tr;
+#; UINT32 Gdtr[2], Idtr[2];
+#; Best not let anyone mess with these particular registers...
+ add esp, 24
+
+#; UINT32 Eip;
+ pop dword ptr [ebp + 3 * 4]
+
+#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
+#; NOTE - modified segment registers could hang the debugger... We
+#; could attempt to insulate ourselves against this possibility,
+#; but that poses risks as well.
+#;
+ pop gs
+ pop fs
+ pop es
+ pop ds
+ pop dword ptr [ebp + 4 * 4]
+ pop ss
+
+#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ pop edi
+ pop esi
+ add esp, 4 # not for ebp
+ add esp, 4 # not for esp
+ pop ebx
+ pop edx
+ pop ecx
+ pop eax
+
+ mov esp, ebp
+ pop ebp
+ add esp, 8
+ iretd
+
+
+#END
+
diff --git a/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm
new file mode 100755
index 0000000000..dfcbc0deff
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/Ia32/CpuAsm.asm
@@ -0,0 +1,384 @@
+ TITLE CpuAsm.asm:
+;------------------------------------------------------------------------------
+;*
+;* Copyright 2006 - 2009, Intel Corporation
+;* All rights reserved. This program and the accompanying materials
+;* are licensed and made available under the terms and conditions of the BSD License
+;* which accompanies this distribution. The full text of the license may be found at
+;* http://opensource.org/licenses/bsd-license.php
+;*
+;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;*
+;* CpuAsm.asm
+;*
+;* Abstract:
+;*
+;------------------------------------------------------------------------------
+
+ .686
+ .model flat,C
+ .code
+
+EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
+
+;
+; point to the external interrupt vector table
+;
+ExternalVectorTablePtr DWORD 0
+
+InitializeExternalVectorTablePtr PROC PUBLIC
+ mov eax, [esp+4]
+ mov ExternalVectorTablePtr, eax
+ ret
+InitializeExternalVectorTablePtr ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; SetCodeSelector (
+; UINT16 Selector
+; );
+;------------------------------------------------------------------------------
+SetCodeSelector PROC PUBLIC
+ mov ecx, [esp+4]
+ sub esp, 0x10
+ lea eax, setCodeSelectorLongJump
+ mov [esp], eax
+ mov [esp+4], cx
+ jmp fword ptr [esp]
+setCodeSelectorLongJump:
+ add esp, 0x10
+ ret
+SetCodeSelector ENDP
+
+;------------------------------------------------------------------------------
+; VOID
+; SetDataSelectors (
+; UINT16 Selector
+; );
+;------------------------------------------------------------------------------
+SetDataSelectors PROC PUBLIC
+ mov ecx, [esp+4]
+ mov ss, cx
+ mov ds, cx
+ mov es, cx
+ mov fs, cx
+ mov gs, cx
+ ret
+SetDataSelectors ENDP
+
+;---------------------------------------;
+; CommonInterruptEntry ;
+;---------------------------------------;
+; The follow algorithm is used for the common interrupt routine.
+
+CommonInterruptEntry PROC PUBLIC
+ cli
+ ;
+ ; All interrupt handlers are invoked through interrupt gates, so
+ ; IF flag automatically cleared at the entry point
+ ;
+
+ ;
+ ; Calculate vector number
+ ;
+ ; Get the return address of call, actually, it is the
+ ; address of vector number.
+ ;
+ xchg ecx, [esp]
+ mov cx, [ecx]
+ and ecx, 0FFFFh
+ cmp ecx, 32 ; Intel reserved vector for exceptions?
+ jae NoErrorCode
+ bt mErrorCodeFlag, ecx
+ jc HasErrorCode
+
+NoErrorCode:
+
+ ;
+ ; Stack:
+ ; +---------------------+
+ ; + EFlags +
+ ; +---------------------+
+ ; + CS +
+ ; +---------------------+
+ ; + EIP +
+ ; +---------------------+
+ ; + ECX +
+ ; +---------------------+ <-- ESP
+ ;
+ ; Registers:
+ ; ECX - Vector Number
+ ;
+
+ ;
+ ; Put Vector Number on stack
+ ;
+ push ecx
+
+ ;
+ ; Put 0 (dummy) error code on stack, and restore ECX
+ ;
+ xor ecx, ecx ; ECX = 0
+ xchg ecx, [esp+4]
+
+ jmp ErrorCodeAndVectorOnStack
+
+HasErrorCode:
+
+ ;
+ ; Stack:
+ ; +---------------------+
+ ; + EFlags +
+ ; +---------------------+
+ ; + CS +
+ ; +---------------------+
+ ; + EIP +
+ ; +---------------------+
+ ; + Error Code +
+ ; +---------------------+
+ ; + ECX +
+ ; +---------------------+ <-- ESP
+ ;
+ ; Registers:
+ ; ECX - Vector Number
+ ;
+
+ ;
+ ; Put Vector Number on stack and restore ECX
+ ;
+ xchg ecx, [esp]
+
+ ;
+ ; Fall through to join main routine code
+ ; at ErrorCodeAndVectorOnStack
+ ;
+@@:
+ jmp @B
+
+ErrorCodeAndVectorOnStack:
+ push ebp
+ mov ebp, esp
+
+ ;
+ ; Stack:
+ ; +---------------------+
+ ; + EFlags +
+ ; +---------------------+
+ ; + CS +
+ ; +---------------------+
+ ; + EIP +
+ ; +---------------------+
+ ; + Error Code +
+ ; +---------------------+
+ ; + Vector Number +
+ ; +---------------------+
+ ; + EBP +
+ ; +---------------------+ <-- EBP
+ ;
+
+ ;
+ ; Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
+ ; is 16-byte aligned
+ ;
+ and esp, 0fffffff0h
+ sub esp, 12
+
+;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ push eax
+ push ecx
+ push edx
+ push ebx
+ lea ecx, [ebp + 6 * 4]
+ push ecx ; ESP
+ push dword ptr [ebp] ; EBP
+ push esi
+ push edi
+
+;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
+ mov eax, ss
+ push eax
+ movzx eax, word ptr [ebp + 4 * 4]
+ push eax
+ mov eax, ds
+ push eax
+ mov eax, es
+ push eax
+ mov eax, fs
+ push eax
+ mov eax, gs
+ push eax
+
+;; UINT32 Eip;
+ mov eax, [ebp + 3 * 4]
+ push eax
+
+;; UINT32 Gdtr[2], Idtr[2];
+ sub esp, 8
+ sidt [esp]
+ mov eax, [esp + 2]
+ xchg eax, [esp]
+ and eax, 0FFFFh
+ mov [esp+4], eax
+
+ sub esp, 8
+ sgdt [esp]
+ mov eax, [esp + 2]
+ xchg eax, [esp]
+ and eax, 0FFFFh
+ mov [esp+4], eax
+
+;; UINT32 Ldtr, Tr;
+ xor eax, eax
+ str ax
+ push eax
+ sldt ax
+ push eax
+
+;; UINT32 EFlags;
+ mov eax, [ebp + 5 * 4]
+ push eax
+
+;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
+ mov eax, cr4
+ or eax, 208h
+ mov cr4, eax
+ push eax
+ mov eax, cr3
+ push eax
+ mov eax, cr2
+ push eax
+ xor eax, eax
+ push eax
+ mov eax, cr0
+ push eax
+
+;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ mov eax, dr7
+ push eax
+;; clear Dr7 while executing debugger itself
+ xor eax, eax
+ mov dr7, eax
+
+ mov eax, dr6
+ push eax
+;; insure all status bits in dr6 are clear...
+ xor eax, eax
+ mov dr6, eax
+
+ mov eax, dr3
+ push eax
+ mov eax, dr2
+ push eax
+ mov eax, dr1
+ push eax
+ mov eax, dr0
+ push eax
+
+;; FX_SAVE_STATE_IA32 FxSaveState;
+ sub esp, 512
+ mov edi, esp
+ db 0fh, 0aeh, 07h ;fxsave [edi]
+
+;; UINT32 ExceptionData;
+ push dword ptr [ebp + 2 * 4]
+
+;; call into exception handler
+ mov eax, ExternalVectorTablePtr ; get the interrupt vectors base
+ or eax, eax ; NULL?
+ jz nullExternalExceptionHandler
+
+ mov ecx, [ebp + 4]
+ mov eax, [eax + ecx * 4]
+ or eax, eax ; NULL?
+ jz nullExternalExceptionHandler
+
+;; Prepare parameter and call
+ mov edx, esp
+ push edx
+ mov edx, dword ptr [ebp + 1 * 4]
+ push edx
+
+ ;
+ ; Call External Exception Handler
+ ;
+ call eax
+ add esp, 8
+
+nullExternalExceptionHandler:
+
+ cli
+;; UINT32 ExceptionData;
+ add esp, 4
+
+;; FX_SAVE_STATE_IA32 FxSaveState;
+ mov esi, esp
+ db 0fh, 0aeh, 0eh ; fxrstor [esi]
+ add esp, 512
+
+;; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
+ pop eax
+ mov dr0, eax
+ pop eax
+ mov dr1, eax
+ pop eax
+ mov dr2, eax
+ pop eax
+ mov dr3, eax
+;; skip restore of dr6. We cleared dr6 during the context save.
+ add esp, 4
+ pop eax
+ mov dr7, eax
+
+;; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
+ pop eax
+ mov cr0, eax
+ add esp, 4 ; not for Cr1
+ pop eax
+ mov cr2, eax
+ pop eax
+ mov cr3, eax
+ pop eax
+ mov cr4, eax
+
+;; UINT32 EFlags;
+ pop dword ptr [ebp + 5 * 4]
+
+;; UINT32 Ldtr, Tr;
+;; UINT32 Gdtr[2], Idtr[2];
+;; Best not let anyone mess with these particular registers...
+ add esp, 24
+
+;; UINT32 Eip;
+ pop dword ptr [ebp + 3 * 4]
+
+;; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
+;; NOTE - modified segment registers could hang the debugger... We
+;; could attempt to insulate ourselves against this possibility,
+;; but that poses risks as well.
+;;
+ pop gs
+ pop fs
+ pop es
+ pop ds
+ pop dword ptr [ebp + 4 * 4]
+ pop ss
+
+;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
+ pop edi
+ pop esi
+ add esp, 4 ; not for ebp
+ add esp, 4 ; not for esp
+ pop ebx
+ pop edx
+ pop ecx
+ pop eax
+
+ mov esp, ebp
+ pop ebp
+ add esp, 8
+ iretd
+
+CommonInterruptEntry ENDP
+
+END
diff --git a/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S b/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S
new file mode 100755
index 0000000000..2a6341a989
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.S
@@ -0,0 +1,66 @@
+#------------------------------------------------------------------------------
+#
+# Copyright (c) 2006 - 2009, Intel Corporation
+# All rights reserved. This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+#
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+# Module Name:
+#
+# IvtAsm.S
+#
+# Abstract:
+#
+# Interrupt Vector Table
+#
+#------------------------------------------------------------------------------
+
+#
+# Interrupt Vector Table
+#
+
+.macro SingleIdtVectorMacro vectorNum
+ .intel_syntax
+ call ASM_PFX(CommonInterruptEntry)
+ .short \vectorNum
+ nop
+.endm
+
+.macro EightIdtVectors firstVectorNum
+ SingleIdtVectorMacro \firstVectorNum
+ SingleIdtVectorMacro "(\firstVectorNum+1)"
+ SingleIdtVectorMacro "(\firstVectorNum+2)"
+ SingleIdtVectorMacro "(\firstVectorNum+3)"
+ SingleIdtVectorMacro "(\firstVectorNum+4)"
+ SingleIdtVectorMacro "(\firstVectorNum+5)"
+ SingleIdtVectorMacro "(\firstVectorNum+6)"
+ SingleIdtVectorMacro "(\firstVectorNum+7)"
+.endm
+
+.macro SixtyFourIdtVectors firstVectorNum
+ EightIdtVectors \firstVectorNum
+ EightIdtVectors "(\firstVectorNum+0x08)"
+ EightIdtVectors "(\firstVectorNum+0x10)"
+ EightIdtVectors "(\firstVectorNum+0x18)"
+ EightIdtVectors "(\firstVectorNum+0x20)"
+ EightIdtVectors "(\firstVectorNum+0x28)"
+ EightIdtVectors "(\firstVectorNum+0x30)"
+ EightIdtVectors "(\firstVectorNum+0x38)"
+.endm
+
+ASM_GLOBAL ASM_PFX(AsmIdtVector00)
+.align 8
+ASM_PFX(AsmIdtVector00):
+ SixtyFourIdtVectors 0x00
+ SixtyFourIdtVectors 0x40
+ SixtyFourIdtVectors 0x80
+ SixtyFourIdtVectors 0xC0
+ASM_GLOBAL ASM_PFX(AsmCommonIdtEnd)
+ASM_PFX(AsmCommonIdtEnd):
+ .byte 0
+
+
diff --git a/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm b/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm
new file mode 100755
index 0000000000..e5dfaace8c
--- /dev/null
+++ b/UefiCpuPkg/CpuDxe/Ia32/IvtAsm.asm
@@ -0,0 +1,51 @@
+ TITLE IvtAsm.asm:
+;------------------------------------------------------------------------------
+;*
+;* Copyright 2008 - 2009, Intel Corporation
+;* All rights reserved. This program and the accompanying materials
+;* are licensed and made available under the terms and conditions of the BSD License
+;* which accompanies this distribution. The full text of the license may be found at
+;* http://opensource.org/licenses/bsd-license.php
+;*
+;* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+;* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+;*
+;* IvtAsm.asm
+;*
+;* Abstract:
+;*
+;------------------------------------------------------------------------------
+
+#include <Base.h>
+
+#ifdef MDE_CPU_IA32
+ .686
+ .model flat,C
+#endif
+ .code
+
+;------------------------------------------------------------------------------
+; Generic IDT Vector Handlers for the Host. They are all the same so they
+; will compress really well.
+;
+; By knowing the return address for Vector 00 you can can calculate the
+; vector number by looking at the call CommonInterruptEntry return address.
+; (return address - (AsmIdtVector00 + 5))/8 == IDT index
+;
+;------------------------------------------------------------------------------
+
+EXTRN CommonInterruptEntry:PROC
+
+ALIGN 8
+
+PUBLIC AsmIdtVector00
+
+AsmIdtVector00 LABEL BYTE
+REPEAT 256
+ call CommonInterruptEntry
+ dw ($ - AsmIdtVector00 - 5) / 8 ; vector number
+ nop
+ENDM
+
+END
+