1. Separated DxeSmmCpuExceptionHandlerLib.inf into 2 instance DxeCpuExceptionHandlerLib.inf and SmmCpuExceptionHandlerLib.inf.

2. Updated CPU Exception Handler Library instance according to the new CPU Exception Handler Library class definitions.
3. Updated CPU Exception Handler Library instance to handle the vector attributes defined in PI 1.2.1.

Signed-off-by: Jeff Fan <jeff.fan@intel.com>
Reviewed-by: Jiewen Yao <jiewen.yao@intel.com>
Reviewed-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Hot Tian <hot.tian@intel.com>



git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@14885 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
Jeff Fan
2013-11-22 06:24:41 +00:00
committed by vanjeff
parent 57f360f261
commit e41aad1521
27 changed files with 1906 additions and 3036 deletions

View File

@@ -1,7 +1,7 @@
/** @file
IA32 CPU Exception Hanlder functons.
Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
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
@@ -15,49 +15,87 @@
#include "CpuExceptionCommon.h"
/**
Internal function to setup CPU exception handlers.
Return address map of exception handler template so that C code can generate
exception tables.
@param IdtEntry Pointer to IDT entry to be updated.
@param InterruptHandler IDT handler value.
**/
VOID
InternalSetupCpuExceptionHandlers (
VOID
ArchUpdateIdtEntry (
IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry,
IN UINTN InterruptHandler
)
{
IA32_DESCRIPTOR IdtDescriptor;
UINTN IdtSize;
EXCEPTION_HANDLER_TEMPLATE_MAP TemplateMap;
UINT16 CodeSegment;
IA32_IDT_GATE_DESCRIPTOR *IdtEntry;
UINTN Index;
UINTN InterruptHandler;;
IdtEntry->Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
IdtEntry->Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
IdtEntry->Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
}
//
// Read IDT descriptor and calculate IDT size
//
AsmReadIdtr (&IdtDescriptor);
IdtSize = (IdtDescriptor.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
if (IdtSize > CPU_EXCEPTION_NUM) {
//
// CPU exeption library only setup CPU_EXCEPTION_NUM exception handler at most
//
IdtSize = CPU_EXCEPTION_NUM;
}
/**
Read IDT handler value from IDT entry.
//
// Use current CS as the segment selector of interrupt gate in IDT
//
CodeSegment = AsmReadCs ();
IdtEntry = (IA32_IDT_GATE_DESCRIPTOR *) IdtDescriptor.Base;
@param IdtEntry Pointer to IDT entry to be read.
GetTemplateAddressMap (&TemplateMap);
**/
UINTN
ArchGetIdtHandler (
IN IA32_IDT_GATE_DESCRIPTOR *IdtEntry
)
{
return (UINTN)IdtEntry->Bits.OffsetLow + (((UINTN)IdtEntry->Bits.OffsetHigh) << 16);
}
for (Index = 0; Index < IdtSize; Index ++) {
InterruptHandler = TemplateMap.ExceptionStart + Index * TemplateMap.ExceptionStubHeaderSize;
IdtEntry[Index].Bits.OffsetLow = (UINT16)(UINTN)InterruptHandler;
IdtEntry[Index].Bits.OffsetHigh = (UINT16)((UINTN)InterruptHandler >> 16);
IdtEntry[Index].Bits.Selector = CodeSegment;
IdtEntry[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
}
/**
Save CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
@param ExceptionType Exception type.
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
**/
VOID
ArchSaveExceptionContext (
IN UINTN ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
IA32_EFLAGS32 Eflags;
//
// Save Exception context in global variable
//
mReservedVectors[ExceptionType].OldFlags = SystemContext.SystemContextIa32->Eflags;
mReservedVectors[ExceptionType].OldCs = SystemContext.SystemContextIa32->Cs;
mReservedVectors[ExceptionType].OldIp = SystemContext.SystemContextIa32->Eip;
mReservedVectors[ExceptionType].ExceptionData = SystemContext.SystemContextIa32->ExceptionData;
//
// Clear IF flag to avoid old IDT handler enable interrupt by IRET
//
Eflags.UintN = SystemContext.SystemContextIa32->Eflags;
Eflags.Bits.IF = 0;
SystemContext.SystemContextIa32->Eflags = Eflags.UintN;
//
// Modify the EIP in stack, then old IDT handler will return to the stub code
//
SystemContext.SystemContextIa32->Eip = (UINTN) mReservedVectors[ExceptionType].HookAfterStubHeaderCode;
}
/**
Restore CPU exception context when handling EFI_VECTOR_HANDOFF_HOOK_AFTER case.
@param ExceptionType Exception type.
@param SystemContext Pointer to EFI_SYSTEM_CONTEXT.
**/
VOID
ArchRestoreExceptionContext (
IN UINTN ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
SystemContext.SystemContextIa32->Eflags = mReservedVectors[ExceptionType].OldFlags;
SystemContext.SystemContextIa32->Cs = mReservedVectors[ExceptionType].OldCs;
SystemContext.SystemContextIa32->Eip = mReservedVectors[ExceptionType].OldIp;
SystemContext.SystemContextIa32->ExceptionData = mReservedVectors[ExceptionType].ExceptionData;
}
/**
@@ -68,7 +106,7 @@ InternalSetupCpuExceptionHandlers (
**/
VOID
DumpCpuContent (
IN UINTN ExceptionType,
IN EFI_EXCEPTION_TYPE ExceptionType,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{

View File

@@ -0,0 +1,44 @@
/** @file
Ia32 arch definition for CPU Exception Handler Library.
Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
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.
**/
#ifndef _ARCH_CPU_INTERRUPT_DEFS_H_
#define _ARCH_CPU_INTERRUPT_DEFS_H_
typedef struct {
EFI_SYSTEM_CONTEXT_IA32 SystemContext;
BOOLEAN ExceptionDataFlag;
UINTN OldIdtHandler;
} EXCEPTION_HANDLER_CONTEXT;
//
// Register Structure Definitions
//
typedef struct {
EFI_STATUS_CODE_DATA Header;
EFI_SYSTEM_CONTEXT_IA32 SystemContext;
} CPU_STATUS_CODE_TEMPLATE;
typedef struct {
SPIN_LOCK SpinLock;
UINT32 ApicId;
UINT32 Attribute;
UINTN ExceptonHandler;
UINTN OldFlags;
UINTN OldCs;
UINTN OldIp;
UINTN ExceptionData;
UINT8 HookAfterStubHeaderCode[HOOKAFTER_STUB_SIZE];
} RESERVED_VECTORS_DATA;
#endif

View File

@@ -1,6 +1,6 @@
#------------------------------------------------------------------------------
#*
#* Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
#* Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
#* 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
@@ -18,16 +18,15 @@
#------------------------------------------------------------------------------
#.MMX
#.XMM
ASM_GLOBAL ASM_PFX(CommonExceptionHandler)
ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
ASM_GLOBAL ASM_PFX(HookAfterStubEnd)
#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
#EXTRN ASM_PFX(mDoFarReturnFlag):DWORD # Do far return flag
.text
@@ -35,101 +34,250 @@ ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
# exception handler stub table
#
Exception0Handle:
pushl $0
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 0
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception1Handle:
pushl $1
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 1
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception2Handle:
pushl $2
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 2
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception3Handle:
pushl $3
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 3
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception4Handle:
pushl $4
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 4
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception5Handle:
pushl $5
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 5
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception6Handle:
pushl $6
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 6
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception7Handle:
pushl $7
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 7
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception8Handle:
pushl $8
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 8
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception9Handle:
pushl $9
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 9
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception10Handle:
pushl $10
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 10
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception11Handle:
pushl $11
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 11
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception12Handle:
pushl $12
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 12
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception13Handle:
pushl $13
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 13
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception14Handle:
pushl $14
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 14
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception15Handle:
pushl $15
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 15
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception16Handle:
pushl $16
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 16
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception17Handle:
pushl $17
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 17
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception18Handle:
pushl $18
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 18
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception19Handle:
pushl $19
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 19
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception20Handle:
pushl $20
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 20
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception21Handle:
pushl $21
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 21
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception22Handle:
pushl $22
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 22
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception23Handle:
pushl $23
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 23
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception24Handle:
pushl $24
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 24
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception25Handle:
pushl $25
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 25
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception26Handle:
pushl $26
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 26
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception27Handle:
pushl $27
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 27
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception28Handle:
pushl $28
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 28
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception29Handle:
pushl $29
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 29
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception30Handle:
pushl $30
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 30
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
Exception31Handle:
pushl $31
jmp ASM_PFX(CommonInterruptEntry)
.byte 0x6a # push #VectorNum
.byte 31
pushl %eax
.byte 0xB8
.long ASM_PFX(CommonInterruptEntry)
jmp *%eax
HookAfterStubBegin:
.byte 0x6a # push
VectorNum:
.byte 0 # 0 will be fixed
pushl %eax
.byte 0xB8 # movl ASM_PFX(HookAfterStubHeaderEnd), %eax
.long ASM_PFX(HookAfterStubHeaderEnd)
jmp *%eax
ASM_GLOBAL ASM_PFX(HookAfterStubHeaderEnd)
HookAfterStubHeaderEnd:
popl %eax
subl $8, %esp # reserve room for filling exception data later
pushl 8(%esp)
xchgl (%esp), %ecx # get vector number
bt %ecx, ASM_PFX(mErrorCodeFlag)
jnc NoErrorData
pushl (%esp) # addition push if exception data needed
NoErrorData:
xchg (%esp), %ecx # restore ecx
pushl %eax
#---------------------------------------;
# CommonInterruptEntry ;
@@ -139,19 +287,17 @@ Exception31Handle:
ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
ASM_PFX(CommonInterruptEntry):
cli
popl %eax
#
# 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.
# Get vector number from top of stack
#
xchgl (%esp), %ecx
andl $0x0FFFF, %ecx
andl $0x0FF, %ecx # Vector number should be less than 256
cmpl $32, %ecx # Intel reserved vector for exceptions?
jae NoErrorCode
bt %ecx, ASM_PFX(mErrorCodeFlag)
@@ -241,6 +387,10 @@ ErrorCodeAndVectorOnStack:
andl $0x0fffffff0, %esp
subl $12, %esp
subl $8, %esp
pushl $0 # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
pushl $0 # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
pushl %eax
pushl %ecx
@@ -405,18 +555,41 @@ ErrorCodeAndVectorOnStack:
popl %ecx
popl %eax
popl -8(%ebp)
popl -4(%ebp)
movl %ebp, %esp
popl %ebp
addl $8, %esp
cmpl $0, -16(%esp) # check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
jz DoReturn
cmpl $1, -20(%esp) # check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
jz ErrorCode
jmp *-16(%esp)
ErrorCode:
subl $4, %esp
jmp *-12(%esp)
DoReturn:
cmpl $0, ASM_PFX(mDoFarReturnFlag)
jz DoIret
pushl 8(%esp) # save EFLAGS
addl $16, %esp
pushl -8(%esp) # save CS in new location
pushl -8(%esp) # save EIP in new location
pushl -8(%esp) # save EFLAGS in new location
popfl # restore EFLAGS
retf # far return
DoIret:
iretl
#---------------------------------------;
# _GetTemplateAddressMap ;
#----------------------------------------------------------------------------;
# _AsmGetTemplateAddressMap ;
#---------------------------------------;
#
# Protocol prototype
# GetTemplateAddressMap (
# AsmGetTemplateAddressMap (
# EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
# );
#
@@ -443,8 +616,8 @@ ErrorCodeAndVectorOnStack:
#-------------------------------------------------------------------------------------
# AsmGetAddressMap (&AddressMap);
#-------------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(GetTemplateAddressMap)
ASM_PFX(GetTemplateAddressMap):
ASM_GLOBAL ASM_PFX(AsmGetTemplateAddressMap)
ASM_PFX(AsmGetTemplateAddressMap):
pushl %ebp
movl %esp,%ebp
@@ -453,8 +626,17 @@ ASM_PFX(GetTemplateAddressMap):
movl 0x8(%ebp), %ebx
movl $Exception0Handle, (%ebx)
movl $(Exception1Handle - Exception0Handle), 0x4(%ebx)
movl $(HookAfterStubBegin), 0x8(%ebx)
popal
popl %ebp
ret
#-------------------------------------------------------------------------------------
# AsmVectorNumFixup (*VectorBase, VectorNum);
#-------------------------------------------------------------------------------------
ASM_GLOBAL ASM_PFX(AsmVectorNumFixup)
ASM_PFX(AsmVectorNumFixup):
movl 8(%esp), %eax
movl 4(%esp), %ecx
movb %al, (VectorNum - HookAfterStubBegin)(%ecx)
ret

View File

@@ -1,5 +1,5 @@
;------------------------------------------------------------------------------ ;
; Copyright (c) 2012, Intel Corporation. All rights reserved.<BR>
; Copyright (c) 2012 - 2013, Intel Corporation. All rights reserved.<BR>
; 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
@@ -30,133 +30,77 @@ CommonExceptionHandler PROTO C
.data
CommonEntryAddr DD CommonInterruptEntry
EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
EXTRN mDoFarReturnFlag:DWORD ; Do far return flag
.code
ALIGN 8
;
; exception handler stub table
;
Exception0Handle:
push 0
jmp dword ptr [CommonEntryAddr]
Exception1Handle:
push 1
jmp dword ptr [CommonEntryAddr]
Exception2Handle:
push 2
jmp dword ptr [CommonEntryAddr]
Exception3Handle:
push 3
jmp dword ptr [CommonEntryAddr]
Exception4Handle:
push 4
jmp dword ptr [CommonEntryAddr]
Exception5Handle:
push 5
jmp dword ptr [CommonEntryAddr]
Exception6Handle:
push 6
jmp dword ptr [CommonEntryAddr]
Exception7Handle:
push 7
jmp dword ptr [CommonEntryAddr]
Exception8Handle:
push 8
jmp dword ptr [CommonEntryAddr]
Exception9Handle:
push 9
jmp dword ptr [CommonEntryAddr]
Exception10Handle:
push 10
jmp dword ptr [CommonEntryAddr]
Exception11Handle:
push 11
jmp dword ptr [CommonEntryAddr]
Exception12Handle:
push 12
jmp dword ptr [CommonEntryAddr]
Exception13Handle:
push 13
jmp dword ptr [CommonEntryAddr]
Exception14Handle:
push 14
jmp dword ptr [CommonEntryAddr]
Exception15Handle:
push 15
jmp dword ptr [CommonEntryAddr]
Exception16Handle:
push 16
jmp dword ptr [CommonEntryAddr]
Exception17Handle:
push 17
jmp dword ptr [CommonEntryAddr]
Exception18Handle:
push 18
jmp dword ptr [CommonEntryAddr]
Exception19Handle:
push 19
jmp dword ptr [CommonEntryAddr]
Exception20Handle:
push 20
jmp dword ptr [CommonEntryAddr]
Exception21Handle:
push 21
jmp dword ptr [CommonEntryAddr]
Exception22Handle:
push 22
jmp dword ptr [CommonEntryAddr]
Exception23Handle:
push 23
jmp dword ptr [CommonEntryAddr]
Exception24Handle:
push 24
jmp dword ptr [CommonEntryAddr]
Exception25Handle:
push 25
jmp dword ptr [CommonEntryAddr]
Exception26Handle:
push 26
jmp dword ptr [CommonEntryAddr]
Exception27Handle:
push 27
jmp dword ptr [CommonEntryAddr]
Exception28Handle:
push 28
jmp dword ptr [CommonEntryAddr]
Exception29Handle:
push 29
jmp dword ptr [CommonEntryAddr]
Exception30Handle:
push 30
jmp dword ptr [CommonEntryAddr]
Exception31Handle:
push 31
jmp dword ptr [CommonEntryAddr]
AsmIdtVectorBegin:
REPEAT 32
db 6ah ; push #VectorNum
db ($ - AsmIdtVectorBegin) / ((AsmIdtVectorEnd - AsmIdtVectorBegin) / 32) ; VectorNum
push eax
mov eax, CommonInterruptEntry
jmp eax
ENDM
AsmIdtVectorEnd:
HookAfterStubBegin:
db 6ah ; push
VectorNum:
db 0 ; 0 will be fixed
push eax
mov eax, HookAfterStubHeaderEnd
jmp eax
HookAfterStubHeaderEnd:
pop eax
sub esp, 8 ; reserve room for filling exception data later
push [esp + 8]
xchg ecx, [esp] ; get vector number
bt mErrorCodeFlag, ecx
jnc @F
push [esp] ; addition push if exception data needed
@@:
xchg ecx, [esp] ; restore ecx
push eax
;----------------------------------------------------------------------------;
; CommonInterruptEntry ;
;----------------------------------------------------------------------------;
; The follow algorithm is used for the common interrupt routine.
; Entry from each interrupt with a push eax and eax=interrupt number
; Stack:
; +---------------------+
; + EFlags +
; +---------------------+
; + CS +
; +---------------------+
; + EIP +
; +---------------------+
; + Error Code +
; +---------------------+
; + Vector Number +
; +---------------------+
; + EBP +
; +---------------------+ <-- EBP
CommonInterruptEntry PROC PUBLIC
cli
pop eax
;
; 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.
; Get vector number from top of stack
;
xchg ecx, [esp]
and ecx, 0FFFFh
and ecx, 0FFh ; Vector number should be less than 256
cmp ecx, 32 ; Intel reserved vector for exceptions?
jae NoErrorCode
bt mErrorCodeFlag, ecx
@@ -246,6 +190,10 @@ ErrorCodeAndVectorOnStack:
and esp, 0fffffff0h
sub esp, 12
sub esp, 8
push 0 ; clear EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
push 0 ; clear EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
;; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
push eax
push ecx
@@ -411,19 +359,42 @@ ErrorCodeAndVectorOnStack:
pop ecx
pop eax
pop dword ptr [ebp - 8]
pop dword ptr [ebp - 4]
mov esp, ebp
pop ebp
add esp, 8
cmp dword ptr [esp - 16], 0 ; check EXCEPTION_HANDLER_CONTEXT.OldIdtHandler
jz DoReturn
cmp dword ptr [esp - 20], 1 ; check EXCEPTION_HANDLER_CONTEXT.ExceptionDataFlag
jz ErrorCode
jmp dword ptr [esp - 16]
ErrorCode:
sub esp, 4
jmp dword ptr [esp - 12]
DoReturn:
cmp mDoFarReturnFlag, 0 ; Check if need to do far return instead of IRET
jz DoIret
push [esp + 8] ; save EFLAGS
add esp, 16
push [esp - 8] ; save CS in new location
push [esp - 8] ; save EIP in new location
push [esp - 8] ; save EFLAGS in new location
popfd ; restore EFLAGS
retf ; far return
DoIret:
iretd
CommonInterruptEntry ENDP
;---------------------------------------;
; _GetTemplateAddressMap ;
; _AsmGetTemplateAddressMap ;
;----------------------------------------------------------------------------;
;
; Protocol prototype
; GetTemplateAddressMap (
; AsmGetTemplateAddressMap (
; EXCEPTION_HANDLER_TEMPLATE_MAP *AddressMap
; );
;
@@ -447,18 +418,28 @@ CommonInterruptEntry ENDP
;
; Destroys: Nothing
;-----------------------------------------------------------------------------;
GetTemplateAddressMap proc near public
AsmGetTemplateAddressMap proc near public
push ebp ; C prolog
mov ebp, esp
pushad
mov ebx, dword ptr [ebp+08h]
mov dword ptr [ebx], Exception0Handle
mov dword ptr [ebx+4h], Exception1Handle - Exception0Handle
mov ebx, dword ptr [ebp + 08h]
mov dword ptr [ebx], AsmIdtVectorBegin
mov dword ptr [ebx + 4h], (AsmIdtVectorEnd - AsmIdtVectorBegin) / 32
mov dword ptr [ebx + 8h], HookAfterStubBegin
popad
pop ebp
ret
GetTemplateAddressMap ENDP
AsmGetTemplateAddressMap ENDP
;-------------------------------------------------------------------------------------
; AsmVectorNumFixup (*VectorBase, VectorNum);
;-------------------------------------------------------------------------------------
AsmVectorNumFixup proc near public
mov eax, dword ptr [esp + 8]
mov ecx, [esp + 4]
mov [ecx + (VectorNum - HookAfterStubBegin)], al
ret
AsmVectorNumFixup ENDP
END