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
CPU DXE Module.
Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2008 - 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
@@ -17,16 +17,11 @@
//
// Global Variables
//
IA32_IDT_GATE_DESCRIPTOR gIdtTable[INTERRUPT_VECTOR_NUMBER] = { { { 0 } } };
EFI_CPU_INTERRUPT_HANDLER ExternalVectorTable[0x100];
BOOLEAN InterruptState = FALSE;
EFI_HANDLE mCpuHandle = NULL;
BOOLEAN mIsFlushingGCD;
UINT64 mValidMtrrAddressMask = MTRR_LIB_CACHE_VALID_ADDRESS;
UINT64 mValidMtrrBitsMask = MTRR_LIB_MSR_VALID_MASK;
IA32_IDT_GATE_DESCRIPTOR *mOrigIdtEntry = NULL;
UINT16 mOrigIdtEntryCount = 0;
FIXED_MTRR mFixedMtrrTable[] = {
{
@@ -100,259 +95,10 @@ EFI_CPU_ARCH_PROTOCOL gCpu = {
4 // DmaBufferAlignment
};
//
// Error code flag indicating whether or not an error code will be
// pushed on the stack if an exception occurs.
//
// 1 means an error code will be pushed, otherwise 0
//
// bit 0 - exception 0
// bit 1 - exception 1
// etc.
//
UINT32 mErrorCodeFlag = 0x00027d00;
//
// Local function prototypes
//
/**
Set Interrupt Descriptor Table Handler Address.
@param Index The Index of the interrupt descriptor table handle.
@param Handler Handler address.
**/
VOID
SetInterruptDescriptorTableHandlerAddress (
IN UINTN Index,
IN VOID *Handler OPTIONAL
);
//
// CPU Arch Protocol Functions
//
/**
Common exception handler.
@param InterruptType Exception type
@param SystemContext EFI_SYSTEM_CONTEXT
**/
VOID
EFIAPI
CommonExceptionHandler (
IN EFI_EXCEPTION_TYPE InterruptType,
IN EFI_SYSTEM_CONTEXT SystemContext
)
{
#if defined (MDE_CPU_IA32)
DEBUG ((
EFI_D_ERROR,
"!!!! IA32 Exception Type - %08x !!!!\n",
InterruptType
));
if ((mErrorCodeFlag & (1 << InterruptType)) != 0) {
DEBUG ((
EFI_D_ERROR,
"ExceptionData - %08x\n",
SystemContext.SystemContextIa32->ExceptionData
));
}
DEBUG ((
EFI_D_ERROR,
"CS - %04x, EIP - %08x, EFL - %08x, SS - %04x\n",
SystemContext.SystemContextIa32->Cs,
SystemContext.SystemContextIa32->Eip,
SystemContext.SystemContextIa32->Eflags,
SystemContext.SystemContextIa32->Ss
));
DEBUG ((
EFI_D_ERROR,
"DS - %04x, ES - %04x, FS - %04x, GS - %04x\n",
SystemContext.SystemContextIa32->Ds,
SystemContext.SystemContextIa32->Es,
SystemContext.SystemContextIa32->Fs,
SystemContext.SystemContextIa32->Gs
));
DEBUG ((
EFI_D_ERROR,
"EAX - %08x, EBX - %08x, ECX - %08x, EDX - %08x\n",
SystemContext.SystemContextIa32->Eax,
SystemContext.SystemContextIa32->Ebx,
SystemContext.SystemContextIa32->Ecx,
SystemContext.SystemContextIa32->Edx
));
DEBUG ((
EFI_D_ERROR,
"ESP - %08x, EBP - %08x, ESI - %08x, EDI - %08x\n",
SystemContext.SystemContextIa32->Esp,
SystemContext.SystemContextIa32->Ebp,
SystemContext.SystemContextIa32->Esi,
SystemContext.SystemContextIa32->Edi
));
DEBUG ((
EFI_D_ERROR,
"GDT - %08x LIM - %04x, IDT - %08x LIM - %04x\n",
SystemContext.SystemContextIa32->Gdtr[0],
SystemContext.SystemContextIa32->Gdtr[1],
SystemContext.SystemContextIa32->Idtr[0],
SystemContext.SystemContextIa32->Idtr[1]
));
DEBUG ((
EFI_D_ERROR,
"LDT - %08x, TR - %08x\n",
SystemContext.SystemContextIa32->Ldtr,
SystemContext.SystemContextIa32->Tr
));
DEBUG ((
EFI_D_ERROR,
"CR0 - %08x, CR2 - %08x, CR3 - %08x, CR4 - %08x\n",
SystemContext.SystemContextIa32->Cr0,
SystemContext.SystemContextIa32->Cr2,
SystemContext.SystemContextIa32->Cr3,
SystemContext.SystemContextIa32->Cr4
));
DEBUG ((
EFI_D_ERROR,
"DR0 - %08x, DR1 - %08x, DR2 - %08x, DR3 - %08x\n",
SystemContext.SystemContextIa32->Dr0,
SystemContext.SystemContextIa32->Dr1,
SystemContext.SystemContextIa32->Dr2,
SystemContext.SystemContextIa32->Dr3
));
DEBUG ((
EFI_D_ERROR,
"DR6 - %08x, DR7 - %08x\n",
SystemContext.SystemContextIa32->Dr6,
SystemContext.SystemContextIa32->Dr7
));
#elif defined (MDE_CPU_X64)
DEBUG ((
EFI_D_ERROR,
"!!!! X64 Exception Type - %016lx !!!!\n",
(UINT64)InterruptType
));
if ((mErrorCodeFlag & (1 << InterruptType)) != 0) {
DEBUG ((
EFI_D_ERROR,
"ExceptionData - %016lx\n",
SystemContext.SystemContextX64->ExceptionData
));
}
DEBUG ((
EFI_D_ERROR,
"RIP - %016lx, RFL - %016lx\n",
SystemContext.SystemContextX64->Rip,
SystemContext.SystemContextX64->Rflags
));
DEBUG ((
EFI_D_ERROR,
"RAX - %016lx, RCX - %016lx, RDX - %016lx\n",
SystemContext.SystemContextX64->Rax,
SystemContext.SystemContextX64->Rcx,
SystemContext.SystemContextX64->Rdx
));
DEBUG ((
EFI_D_ERROR,
"RBX - %016lx, RSP - %016lx, RBP - %016lx\n",
SystemContext.SystemContextX64->Rbx,
SystemContext.SystemContextX64->Rsp,
SystemContext.SystemContextX64->Rbp
));
DEBUG ((
EFI_D_ERROR,
"RSI - %016lx, RDI - %016lx\n",
SystemContext.SystemContextX64->Rsi,
SystemContext.SystemContextX64->Rdi
));
DEBUG ((
EFI_D_ERROR,
"R8 - %016lx, R9 - %016lx, R10 - %016lx\n",
SystemContext.SystemContextX64->R8,
SystemContext.SystemContextX64->R9,
SystemContext.SystemContextX64->R10
));
DEBUG ((
EFI_D_ERROR,
"R11 - %016lx, R12 - %016lx, R13 - %016lx\n",
SystemContext.SystemContextX64->R11,
SystemContext.SystemContextX64->R12,
SystemContext.SystemContextX64->R13
));
DEBUG ((
EFI_D_ERROR,
"R14 - %016lx, R15 - %016lx\n",
SystemContext.SystemContextX64->R14,
SystemContext.SystemContextX64->R15
));
DEBUG ((
EFI_D_ERROR,
"CS - %04lx, DS - %04lx, ES - %04lx, FS - %04lx, GS - %04lx, SS - %04lx\n",
SystemContext.SystemContextX64->Cs,
SystemContext.SystemContextX64->Ds,
SystemContext.SystemContextX64->Es,
SystemContext.SystemContextX64->Fs,
SystemContext.SystemContextX64->Gs,
SystemContext.SystemContextX64->Ss
));
DEBUG ((
EFI_D_ERROR,
"GDT - %016lx; %04lx, IDT - %016lx; %04lx\n",
SystemContext.SystemContextX64->Gdtr[0],
SystemContext.SystemContextX64->Gdtr[1],
SystemContext.SystemContextX64->Idtr[0],
SystemContext.SystemContextX64->Idtr[1]
));
DEBUG ((
EFI_D_ERROR,
"LDT - %016lx, TR - %016lx\n",
SystemContext.SystemContextX64->Ldtr,
SystemContext.SystemContextX64->Tr
));
DEBUG ((
EFI_D_ERROR,
"CR0 - %016lx, CR2 - %016lx, CR3 - %016lx\n",
SystemContext.SystemContextX64->Cr0,
SystemContext.SystemContextX64->Cr2,
SystemContext.SystemContextX64->Cr3
));
DEBUG ((
EFI_D_ERROR,
"CR4 - %016lx, CR8 - %016lx\n",
SystemContext.SystemContextX64->Cr4,
SystemContext.SystemContextX64->Cr8
));
DEBUG ((
EFI_D_ERROR,
"DR0 - %016lx, DR1 - %016lx, DR2 - %016lx\n",
SystemContext.SystemContextX64->Dr0,
SystemContext.SystemContextX64->Dr1,
SystemContext.SystemContextX64->Dr2
));
DEBUG ((
EFI_D_ERROR,
"DR3 - %016lx, DR6 - %016lx, DR7 - %016lx\n",
SystemContext.SystemContextX64->Dr3,
SystemContext.SystemContextX64->Dr6,
SystemContext.SystemContextX64->Dr7
));
#else
#error CPU type not supported for exception information dump!
#endif
//
// Hang the system with CpuSleep so the processor will enter a lower power
// state.
//
while (TRUE) {
CpuSleep ();
};
}
/**
Flush CPU data cache. If the instruction cache is fully coherent
with all DMA operations then function can just return EFI_SUCCESS.
@@ -510,29 +256,7 @@ CpuRegisterInterruptHandler (
IN EFI_CPU_INTERRUPT_HANDLER InterruptHandler
)
{
if (InterruptType < 0 || InterruptType > 0xff) {
return EFI_UNSUPPORTED;
}
if (InterruptHandler == NULL && ExternalVectorTable[InterruptType] == NULL) {
return EFI_INVALID_PARAMETER;
}
if (InterruptHandler != NULL && ExternalVectorTable[InterruptType] != NULL) {
return EFI_ALREADY_STARTED;
}
if (InterruptHandler != NULL) {
SetInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType, NULL);
} else {
//
// Restore the original IDT handler address if InterruptHandler is NULL.
//
RestoreInterruptDescriptorTableHandlerAddress ((UINTN)InterruptType);
}
ExternalVectorTable[InterruptType] = InterruptHandler;
return EFI_SUCCESS;
return RegisterCpuInterruptHandler (InterruptType, InterruptHandler);
}
@@ -1060,57 +784,6 @@ RefreshGcdMemoryAttributes (
mIsFlushingGCD = FALSE;
}
/**
Set Interrupt Descriptor Table Handler Address.
@param Index The Index of the interrupt descriptor table handle.
@param Handler Handler address.
**/
VOID
SetInterruptDescriptorTableHandlerAddress (
IN UINTN Index,
IN VOID *Handler OPTIONAL
)
{
UINTN UintnHandler;
if (Handler != NULL) {
UintnHandler = (UINTN) Handler;
} else {
UintnHandler = ((UINTN) AsmIdtVector00) + (8 * Index);
}
gIdtTable[Index].Bits.OffsetLow = (UINT16)UintnHandler;
gIdtTable[Index].Bits.Reserved_0 = 0;
gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
gIdtTable[Index].Bits.OffsetHigh = (UINT16)(UintnHandler >> 16);
#if defined (MDE_CPU_X64)
gIdtTable[Index].Bits.OffsetUpper = (UINT32)(UintnHandler >> 32);
gIdtTable[Index].Bits.Reserved_1 = 0;
#endif
}
/**
Restore original Interrupt Descriptor Table Handler Address.
@param Index The Index of the interrupt descriptor table handle.
**/
VOID
RestoreInterruptDescriptorTableHandlerAddress (
IN UINTN Index
)
{
if (Index < mOrigIdtEntryCount) {
gIdtTable[Index].Bits.OffsetLow = mOrigIdtEntry[Index].Bits.OffsetLow;
gIdtTable[Index].Bits.OffsetHigh = mOrigIdtEntry[Index].Bits.OffsetHigh;
#if defined (MDE_CPU_X64)
gIdtTable[Index].Bits.OffsetUpper = mOrigIdtEntry[Index].Bits.OffsetUpper;
#endif
}
}
/**
Initialize Interrupt Descriptor Table for interrupt handling.
@@ -1120,90 +793,17 @@ InitInterruptDescriptorTable (
VOID
)
{
EFI_STATUS Status;
IA32_DESCRIPTOR OldIdtPtr;
IA32_IDT_GATE_DESCRIPTOR *OldIdt;
UINTN OldIdtSize;
VOID *IdtPtrAlignmentBuffer;
IA32_DESCRIPTOR *IdtPtr;
UINTN Index;
UINT16 CurrentCs;
VOID *IntHandler;
EFI_STATUS Status;
EFI_VECTOR_HANDOFF_INFO *VectorInfoList;
EFI_VECTOR_HANDOFF_INFO *VectorInfo;
SetMem (ExternalVectorTable, sizeof(ExternalVectorTable), 0);
//
// Get original IDT address and size.
//
AsmReadIdtr ((IA32_DESCRIPTOR *) &OldIdtPtr);
if ((OldIdtPtr.Base != 0) && ((OldIdtPtr.Limit & 7) == 7)) {
OldIdt = (IA32_IDT_GATE_DESCRIPTOR*) OldIdtPtr.Base;
OldIdtSize = (OldIdtPtr.Limit + 1) / sizeof (IA32_IDT_GATE_DESCRIPTOR);
//
// Save original IDT entry and IDT entry count.
//
mOrigIdtEntry = AllocateCopyPool (OldIdtPtr.Limit + 1, (VOID *) OldIdtPtr.Base);
ASSERT (mOrigIdtEntry != NULL);
mOrigIdtEntryCount = (UINT16) OldIdtSize;
} else {
OldIdt = NULL;
OldIdtSize = 0;
VectorInfo = NULL;
Status = EfiGetSystemConfigurationTable (&gEfiVectorHandoffTableGuid, (VOID **) &VectorInfoList);
if (Status == EFI_SUCCESS && VectorInfoList != NULL) {
VectorInfo = VectorInfoList;
}
//
// Intialize IDT
//
CurrentCs = AsmReadCs();
for (Index = 0; Index < INTERRUPT_VECTOR_NUMBER; Index ++) {
//
// If the old IDT had a handler for this interrupt, then
// preserve it.
//
if (Index < OldIdtSize) {
IntHandler =
(VOID*) (
OldIdt[Index].Bits.OffsetLow +
(((UINTN) OldIdt[Index].Bits.OffsetHigh) << 16)
#if defined (MDE_CPU_X64)
+ (((UINTN) OldIdt[Index].Bits.OffsetUpper) << 32)
#endif
);
} else {
IntHandler = NULL;
}
gIdtTable[Index].Bits.Selector = CurrentCs;
gIdtTable[Index].Bits.Reserved_0 = 0;
gIdtTable[Index].Bits.GateType = IA32_IDT_GATE_TYPE_INTERRUPT_32;
SetInterruptDescriptorTableHandlerAddress (Index, IntHandler);
}
//
// Load IDT Pointer
//
IdtPtrAlignmentBuffer = AllocatePool (sizeof (*IdtPtr) + 16);
IdtPtr = ALIGN_POINTER (IdtPtrAlignmentBuffer, 16);
IdtPtr->Base = (UINT32)(((UINTN)(VOID*) gIdtTable) & (BASE_4GB-1));
IdtPtr->Limit = (UINT16) (sizeof (gIdtTable) - 1);
AsmWriteIdtr (IdtPtr);
FreePool (IdtPtrAlignmentBuffer);
//
// Initialize Exception Handlers
//
for (Index = OldIdtSize; Index < 32; Index++) {
Status = CpuRegisterInterruptHandler (&gCpu, Index, CommonExceptionHandler);
ASSERT_EFI_ERROR (Status);
}
//
// Set the pointer to the array of C based exception handling routines.
//
InitializeExternalVectorTablePtr (ExternalVectorTable);
Status = InitializeCpuInterruptHandlers (VectorInfo);
ASSERT_EFI_ERROR (Status);
}

View File

@@ -1,7 +1,7 @@
/** @file
CPU DXE Module.
Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2008 - 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,12 +30,10 @@
#include <Library/MtrrLib.h>
#include <Library/LocalApicLib.h>
#include <Library/UefiCpuLib.h>
#include <Library/UefiLib.h>
#include <Library/CpuExceptionHandlerLib.h>
#include <Guid/IdleLoopEvent.h>
//
//
//
#define INTERRUPT_VECTOR_NUMBER 256
#include <Guid/VectorHandoffTable.h>
#define EFI_MEMORY_CACHETYPE_MASK (EFI_MEMORY_UC | \
EFI_MEMORY_WC | \
@@ -220,30 +218,6 @@ CpuSetMemoryAttributes (
IN UINT64 Attributes
);
/**
Label of base address of IDT vector 0.
This is just a label of base address of IDT vector 0.
**/
VOID
EFIAPI
AsmIdtVector00 (
VOID
);
/**
Initializes the pointer to the external interrupt vector table.
@param VectorTable Address of the external interrupt vector table.
**/
VOID
EFIAPI
InitializeExternalVectorTablePtr (
EFI_CPU_INTERRUPT_HANDLER *VectorTable
);
/**
Initialize Global Descriptor Table.
@@ -277,16 +251,5 @@ SetDataSelectors (
UINT16 Selector
);
/**
Restore original Interrupt Descriptor Table Handler Address.
@param Index The Index of the interrupt descriptor table handle.
**/
VOID
RestoreInterruptDescriptorTableHandlerAddress (
IN UINTN Index
);
#endif

View File

@@ -2,7 +2,7 @@
#
# Component description file for simple CPU driver
#
# Copyright (c) 2008 - 2012, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2008 - 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
@@ -39,16 +39,14 @@
UefiDriverEntryPoint
LocalApicLib
UefiCpuLib
UefiLib
CpuExceptionHandlerLib
[Sources]
CpuDxe.c
CpuDxe.h
CpuGdt.c
Ia32/IvtAsm.asm | MSFT
Ia32/IvtAsm.asm | INTEL
Ia32/IvtAsm.S | GCC
[Sources.IA32]
Ia32/CpuAsm.asm | MSFT
Ia32/CpuAsm.asm | INTEL
@@ -64,6 +62,7 @@
[Guids]
gIdleLoopEventGuid ## CONSUMES ## GUID
gEfiVectorHandoffTableGuid ## CONSUMES ## Configuration Table
[Depex]
TRUE

View File

@@ -1,6 +1,6 @@
#------------------------------------------------------------------------------
#*
#* Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
#* Copyright (c) 2006 - 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
@@ -19,21 +19,6 @@
#.MMX
#.XMM
#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
#
# point to the external interrupt vector table
#
ExternalVectorTablePtr:
.byte 0, 0, 0, 0
ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)
ASM_PFX(InitializeExternalVectorTablePtr):
movl 4(%esp), %eax
movl %eax, ExternalVectorTablePtr
ret
#------------------------------------------------------------------------------
# VOID
# SetCodeSelector (
@@ -68,298 +53,5 @@ ASM_PFX(SetDataSelectors):
movw %cx, %gs
ret
#---------------------------------------;
# CommonInterruptEntry ;
#---------------------------------------;
# The follow algorithm is used for the common interrupt routine.
ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
ASM_PFX(CommonInterruptEntry):
cli
#
# All interrupt handlers are invoked through interrupt gates, so
# IF flag automatically cleared at the entry point
#
#
# Calculate vector number
#
# Get the return address of call, actually, it is the
# address of vector number.
#
xchgl (%esp), %ecx
movw (%ecx), %cx
andl $0x0FFFF, %ecx
cmpl $32, %ecx # Intel reserved vector for exceptions?
jae NoErrorCode
bt %ecx, ASM_PFX(mErrorCodeFlag)
jc HasErrorCode
NoErrorCode:
#
# Stack:
# +---------------------+
# + EFlags +
# +---------------------+
# + CS +
# +---------------------+
# + EIP +
# +---------------------+
# + ECX +
# +---------------------+ <-- ESP
#
# Registers:
# ECX - Vector Number
#
#
# Put Vector Number on stack
#
pushl %ecx
#
# Put 0 (dummy) error code on stack, and restore ECX
#
xorl %ecx, %ecx # ECX = 0
xchgl 4(%esp), %ecx
jmp ErrorCodeAndVectorOnStack
HasErrorCode:
#
# Stack:
# +---------------------+
# + EFlags +
# +---------------------+
# + CS +
# +---------------------+
# + EIP +
# +---------------------+
# + Error Code +
# +---------------------+
# + ECX +
# +---------------------+ <-- ESP
#
# Registers:
# ECX - Vector Number
#
#
# Put Vector Number on stack and restore ECX
#
xchgl (%esp), %ecx
ErrorCodeAndVectorOnStack:
pushl %ebp
movl %esp, %ebp
#
# Stack:
# +---------------------+
# + EFlags +
# +---------------------+
# + CS +
# +---------------------+
# + EIP +
# +---------------------+
# + Error Code +
# +---------------------+
# + Vector Number +
# +---------------------+
# + EBP +
# +---------------------+ <-- EBP
#
#
# Align stack to make sure that EFI_FX_SAVE_STATE_IA32 of EFI_SYSTEM_CONTEXT_IA32
# is 16-byte aligned
#
andl $0x0fffffff0, %esp
subl $12, %esp
#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
pushl %eax
pushl %ecx
pushl %edx
pushl %ebx
leal 24(%ebp), %ecx
pushl %ecx # ESP
pushl (%ebp) # EBP
pushl %esi
pushl %edi
#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
movl %ss, %eax
pushl %eax
movzwl 16(%ebp), %eax
pushl %eax
movl %ds, %eax
pushl %eax
movl %es, %eax
pushl %eax
movl %fs, %eax
pushl %eax
movl %gs, %eax
pushl %eax
#; UINT32 Eip;
movl 12(%ebp), %eax
pushl %eax
#; UINT32 Gdtr[2], Idtr[2];
subl $8, %esp
sidt (%esp)
movl 2(%esp), %eax
xchgl (%esp), %eax
andl $0x0FFFF, %eax
movl %eax, 4(%esp)
subl $8, %esp
sgdt (%esp)
movl 2(%esp), %eax
xchgl (%esp), %eax
andl $0x0FFFF, %eax
movl %eax, 4(%esp)
#; UINT32 Ldtr, Tr;
xorl %eax, %eax
str %ax
pushl %eax
sldt %ax
pushl %eax
#; UINT32 EFlags;
movl 20(%ebp), %eax
pushl %eax
#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
movl %cr4, %eax
orl $0x208, %eax
movl %eax, %cr4
pushl %eax
movl %cr3, %eax
pushl %eax
movl %cr2, %eax
pushl %eax
xorl %eax, %eax
pushl %eax
movl %cr0, %eax
pushl %eax
#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
movl %dr7, %eax
pushl %eax
movl %dr6, %eax
pushl %eax
movl %dr3, %eax
pushl %eax
movl %dr2, %eax
pushl %eax
movl %dr1, %eax
pushl %eax
movl %dr0, %eax
pushl %eax
#; FX_SAVE_STATE_IA32 FxSaveState;
subl $512, %esp
movl %esp, %edi
.byte 0x0f, 0x0ae, 0x07 #fxsave [edi]
#; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
cld
#; UINT32 ExceptionData;
pushl 8(%ebp)
#; call into exception handler
movl ExternalVectorTablePtr, %eax # get the interrupt vectors base
orl %eax, %eax # NULL?
jz nullExternalExceptionHandler
mov 4(%ebp), %ecx
movl (%eax,%ecx,4), %eax
orl %eax, %eax # NULL?
jz nullExternalExceptionHandler
#; Prepare parameter and call
movl %esp, %edx
pushl %edx
movl 4(%ebp), %edx
pushl %edx
#
# Call External Exception Handler
#
call *%eax
addl $8, %esp
nullExternalExceptionHandler:
cli
#; UINT32 ExceptionData;
addl $4, %esp
#; FX_SAVE_STATE_IA32 FxSaveState;
movl %esp, %esi
.byte 0x0f, 0x0ae, 0x0e # fxrstor [esi]
addl $512, %esp
#; UINT32 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
#; Skip restoration of DRx registers to support in-circuit emualators
#; or debuggers set breakpoint in interrupt/exception context
addl $24, %esp
#; UINT32 Cr0, Cr1, Cr2, Cr3, Cr4;
popl %eax
movl %eax, %cr0
addl $4, %esp # not for Cr1
popl %eax
movl %eax, %cr2
popl %eax
movl %eax, %cr3
popl %eax
movl %eax, %cr4
#; UINT32 EFlags;
popl 20(%ebp)
#; UINT32 Ldtr, Tr;
#; UINT32 Gdtr[2], Idtr[2];
#; Best not let anyone mess with these particular registers...
addl $24, %esp
#; UINT32 Eip;
popl 12(%ebp)
#; UINT32 Gs, Fs, Es, Ds, Cs, Ss;
#; NOTE - modified segment registers could hang the debugger... We
#; could attempt to insulate ourselves against this possibility,
#; but that poses risks as well.
#;
popl %gs
popl %fs
popl %es
popl %ds
popl 16(%ebp)
popl %ss
#; UINT32 Edi, Esi, Ebp, Esp, Ebx, Edx, Ecx, Eax;
popl %edi
popl %esi
addl $4, %esp # not for ebp
addl $4, %esp # not for esp
popl %ebx
popl %edx
popl %ecx
popl %eax
movl %ebp, %esp
popl %ebp
addl $8, %esp
iretl
#END

View File

@@ -1,7 +1,7 @@
TITLE CpuAsm.asm:
;------------------------------------------------------------------------------
;*
;* Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
;* Copyright (c) 2006 - 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
@@ -20,19 +20,6 @@
.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 (
@@ -67,297 +54,5 @@ SetDataSelectors PROC PUBLIC
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]
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
mov eax, dr6
push 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]
;; UEFI calling convention for IA32 requires that Direction flag in EFLAGs is clear
cld
;; 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;
;; Skip restoration of DRx registers to support in-circuit emualators
;; or debuggers set breakpoint in interrupt/exception context
add esp, 4 * 6
;; 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

View File

@@ -1,818 +0,0 @@
#------------------------------------------------------------------------------
#
# Copyright (c) 2006 - 2009, 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.
#
# Module Name:
#
# IvtAsm.S
#
# Abstract:
#
# Interrupt Vector Table
#
#------------------------------------------------------------------------------
#
# Interrupt Vector Table
#
ASM_GLOBAL ASM_PFX(AsmIdtVector00)
.p2align 3
ASM_PFX(AsmIdtVector00):
call ASM_PFX(CommonInterruptEntry)
.short 0x00
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x01
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x02
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x03
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x04
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x05
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x06
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x07
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x08
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x09
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x0a
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x0b
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x0c
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x0d
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x0e
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x0f
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x10
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x11
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x12
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x13
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x14
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x15
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x16
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x17
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x18
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x19
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x1a
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x1b
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x1c
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x1d
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x1e
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x1f
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x00
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x21
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x22
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x23
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x24
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x25
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x26
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x27
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x28
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x29
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x2a
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x2b
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x2c
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x2d
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x2e
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x2f
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x30
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x31
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x32
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x33
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x34
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x35
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x36
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x37
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x38
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x39
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x3a
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x3b
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x3c
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x3d
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x3e
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x3f
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x40
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x41
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x42
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x43
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x44
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x45
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x46
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x47
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x48
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x49
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x4a
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x4b
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x4c
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x4d
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x4e
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x4f
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x50
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x51
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x52
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x53
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x54
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x55
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x56
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x57
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x58
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x59
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x5a
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x5b
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x5c
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x5d
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x5e
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x5f
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x60
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x61
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x62
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x63
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x64
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x65
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x66
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x67
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x68
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x69
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x6a
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x6b
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x6c
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x6d
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x6e
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x6f
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x70
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x71
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x72
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x73
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x74
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x75
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x76
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x77
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x78
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x79
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x7a
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x7b
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x7c
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x7d
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x7e
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x7f
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x80
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x81
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x82
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x83
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x84
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x85
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x86
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x87
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x88
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x89
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x8a
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x8b
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x8c
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x8d
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x8e
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x8f
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x90
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x91
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x92
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x93
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x94
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x95
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x96
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x97
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x98
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x99
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x9a
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x9b
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x9c
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x9d
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x9e
nop
call ASM_PFX(CommonInterruptEntry)
.short 0x9f
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xa0
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xa1
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xa2
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xa3
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xa4
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xa5
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xa6
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xa7
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xa8
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xa9
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xaa
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xab
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xac
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xad
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xae
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xaf
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xb0
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xb1
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xb2
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xb3
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xb4
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xb5
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xb6
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xb7
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xb8
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xb9
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xba
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xbb
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xbc
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xbd
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xbe
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xbf
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xc0
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xc1
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xc2
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xc3
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xc4
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xc5
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xc6
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xc7
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xc8
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xc9
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xca
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xcb
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xcc
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xcd
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xce
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xcf
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xd0
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xd1
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xd2
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xd3
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xd4
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xd5
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xd6
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xd7
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xd8
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xd9
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xda
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xdb
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xdc
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xdd
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xde
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xdf
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xe0
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xe1
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xe2
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xe3
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xe4
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xe5
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xe6
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xe7
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xe8
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xe9
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xea
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xeb
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xec
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xed
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xee
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xef
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xf0
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xf1
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xf2
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xf3
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xf4
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xf5
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xf6
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xf7
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xf8
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xf9
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xfa
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xfb
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xfc
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xfd
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xfe
nop
call ASM_PFX(CommonInterruptEntry)
.short 0xff
nop
ASM_GLOBAL ASM_PFX(AsmCommonIdtEnd)
ASM_PFX(AsmCommonIdtEnd):
.byte 0

View File

@@ -1,51 +0,0 @@
TITLE IvtAsm.asm:
;------------------------------------------------------------------------------
;*
;* Copyright (c) 2008 - 2009, 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.
;*
;* 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

View File

@@ -2,7 +2,7 @@
#------------------------------------------------------------------------------
#*
#* Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
#* Copyright (c) 2008 - 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
@@ -21,22 +21,6 @@
#text SEGMENT
#EXTRN ASM_PFX(mErrorCodeFlag):DWORD # Error code flags for exceptions
#
# point to the external interrupt vector table
#
ExternalVectorTablePtr:
.byte 0, 0, 0, 0, 0, 0, 0, 0
ASM_GLOBAL ASM_PFX(InitializeExternalVectorTablePtr)
ASM_PFX(InitializeExternalVectorTablePtr):
lea ExternalVectorTablePtr(%rip), %rax # save vector number
mov %rcx, (%rax)
ret
#------------------------------------------------------------------------------
# VOID
# SetCodeSelector (
@@ -69,275 +53,6 @@ ASM_PFX(SetDataSelectors):
movw %cx, %gs
ret
#---------------------------------------;
# CommonInterruptEntry ;
#---------------------------------------;
# The follow algorithm is used for the common interrupt routine.
ASM_GLOBAL ASM_PFX(CommonInterruptEntry)
ASM_PFX(CommonInterruptEntry):
cli
#
# All interrupt handlers are invoked through interrupt gates, so
# IF flag automatically cleared at the entry point
#
#
# Calculate vector number
#
xchgq (%rsp), %rcx # get the return address of call, actually, it is the address of vector number.
movzwl (%rcx), %ecx
cmp $32, %ecx # Intel reserved vector for exceptions?
jae NoErrorCode
pushq %rax
leaq ASM_PFX(mErrorCodeFlag)(%rip), %rax
bt %ecx, (%rax)
popq %rax
jc CommonInterruptEntry_al_0000
NoErrorCode:
#
# Push a dummy error code on the stack
# to maintain coherent stack map
#
pushq (%rsp)
movq $0, 8(%rsp)
CommonInterruptEntry_al_0000:
pushq %rbp
movq %rsp, %rbp
#
# Stack:
# +---------------------+ <-- 16-byte aligned ensured by processor
# + Old SS +
# +---------------------+
# + Old RSP +
# +---------------------+
# + RFlags +
# +---------------------+
# + CS +
# +---------------------+
# + RIP +
# +---------------------+
# + Error Code +
# +---------------------+
# + RCX / Vector Number +
# +---------------------+
# + RBP +
# +---------------------+ <-- RBP, 16-byte aligned
#
#
# Since here the stack pointer is 16-byte aligned, so
# EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
# is 16-byte aligned
#
#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %r11
pushq %r10
pushq %r9
pushq %r8
pushq %rax
pushq 8(%rbp) # RCX
pushq %rdx
pushq %rbx
pushq 48(%rbp) # RSP
pushq (%rbp) # RBP
pushq %rsi
pushq %rdi
#; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
movzwq 56(%rbp), %rax
pushq %rax # for ss
movzwq 32(%rbp), %rax
pushq %rax # for cs
movl %ds, %eax
pushq %rax
movl %es, %eax
pushq %rax
movl %fs, %eax
pushq %rax
movl %gs, %eax
pushq %rax
movq %rcx, 8(%rbp) # save vector number
#; UINT64 Rip;
pushq 24(%rbp)
#; UINT64 Gdtr[2], Idtr[2];
xorq %rax, %rax
pushq %rax
pushq %rax
sidt (%rsp)
xchgq 2(%rsp), %rax
xchgq (%rsp), %rax
xchgq 8(%rsp), %rax
xorq %rax, %rax
pushq %rax
pushq %rax
sgdt (%rsp)
xchgq 2(%rsp), %rax
xchgq (%rsp), %rax
xchgq 8(%rsp), %rax
#; UINT64 Ldtr, Tr;
xorq %rax, %rax
str %ax
pushq %rax
sldt %ax
pushq %rax
#; UINT64 RFlags;
pushq 40(%rbp)
#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
movq %cr8, %rax
pushq %rax
movq %cr4, %rax
orq $0x208, %rax
movq %rax, %cr4
pushq %rax
mov %cr3, %rax
pushq %rax
mov %cr2, %rax
pushq %rax
xorq %rax, %rax
pushq %rax
mov %cr0, %rax
pushq %rax
#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
movq %dr7, %rax
pushq %rax
movq %dr6, %rax
pushq %rax
movq %dr3, %rax
pushq %rax
movq %dr2, %rax
pushq %rax
movq %dr1, %rax
pushq %rax
movq %dr0, %rax
pushq %rax
#; FX_SAVE_STATE_X64 FxSaveState;
subq $512, %rsp
movq %rsp, %rdi
.byte 0x0f, 0x0ae, 0x07 #fxsave [rdi]
#; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
cld
#; UINT32 ExceptionData;
pushq 16(%rbp)
#; call into exception handler
movq 8(%rbp), %rcx
leaq ExternalVectorTablePtr(%rip), %rax
movl (%eax), %eax
movq (%rax,%rcx,8), %rax
orq %rax, %rax # NULL?
je nonNullValue#
#; Prepare parameter and call
# mov rcx, [rbp + 8]
mov %rsp, %rdx
#
# Per X64 calling convention, allocate maximum parameter stack space
# and make sure RSP is 16-byte aligned
#
subq $40, %rsp
call *%rax
addq $40, %rsp
nonNullValue:
cli
#; UINT64 ExceptionData;
addq $8, %rsp
#; FX_SAVE_STATE_X64 FxSaveState;
movq %rsp, %rsi
.byte 0x0f, 0x0ae, 0x0E # fxrstor [rsi]
addq $512, %rsp
#; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
#; Skip restoration of DRx registers to support in-circuit emualators
#; or debuggers set breakpoint in interrupt/exception context
addq $48, %rsp
#; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
popq %rax
movq %rax, %cr0
addq $8, %rsp # not for Cr1
popq %rax
movq %rax, %cr2
popq %rax
movq %rax, %cr3
popq %rax
movq %rax, %cr4
popq %rax
movq %rax, %cr8
#; UINT64 RFlags;
popq 40(%rbp)
#; UINT64 Ldtr, Tr;
#; UINT64 Gdtr[2], Idtr[2];
#; Best not let anyone mess with these particular registers...
addq $48, %rsp
#; UINT64 Rip;
popq 24(%rbp)
#; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
popq %rax
# mov %rax, %gs ; not for gs
popq %rax
# mov %rax, %fs ; not for fs
# (X64 will not use fs and gs, so we do not restore it)
popq %rax
movl %eax, %es
popq %rax
movl %eax, %ds
popq 32(%rbp) # for cs
popq 56(%rbp) # for ss
#; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
#; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
popq %rdi
popq %rsi
addq $8, %rsp # not for rbp
popq 48(%rbp) # for rsp
popq %rbx
popq %rdx
popq %rcx
popq %rax
popq %r8
popq %r9
popq %r10
popq %r11
popq %r12
popq %r13
popq %r14
popq %r15
movq %rbp, %rsp
popq %rbp
addq $16, %rsp
iretq
#text ENDS
#END

View File

@@ -1,7 +1,7 @@
TITLE CpuAsm.asm:
;------------------------------------------------------------------------------
;*
;* Copyright (c) 2008 - 2011, Intel Corporation. All rights reserved.<BR>
;* Copyright (c) 2008 - 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,18 +18,6 @@
.code
EXTRN mErrorCodeFlag:DWORD ; Error code flags for exceptions
;
; point to the external interrupt vector table
;
ExternalVectorTablePtr QWORD 0
InitializeExternalVectorTablePtr PROC PUBLIC
mov ExternalVectorTablePtr, rcx
ret
InitializeExternalVectorTablePtr ENDP
;------------------------------------------------------------------------------
; VOID
; SetCodeSelector (
@@ -62,270 +50,5 @@ SetDataSelectors PROC PUBLIC
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
;
xchg rcx, [rsp] ; get the return address of call, actually, it is the address of vector number.
movzx ecx, word ptr [rcx]
cmp ecx, 32 ; Intel reserved vector for exceptions?
jae NoErrorCode
bt mErrorCodeFlag, ecx
jc @F
NoErrorCode:
;
; Push a dummy error code on the stack
; to maintain coherent stack map
;
push [rsp]
mov qword ptr [rsp + 8], 0
@@:
push rbp
mov rbp, rsp
;
; Stack:
; +---------------------+ <-- 16-byte aligned ensured by processor
; + Old SS +
; +---------------------+
; + Old RSP +
; +---------------------+
; + RFlags +
; +---------------------+
; + CS +
; +---------------------+
; + RIP +
; +---------------------+
; + Error Code +
; +---------------------+
; + RCX / Vector Number +
; +---------------------+
; + RBP +
; +---------------------+ <-- RBP, 16-byte aligned
;
;
; Since here the stack pointer is 16-byte aligned, so
; EFI_FX_SAVE_STATE_X64 of EFI_SYSTEM_CONTEXT_x64
; is 16-byte aligned
;
;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
push r15
push r14
push r13
push r12
push r11
push r10
push r9
push r8
push rax
push qword ptr [rbp + 8] ; RCX
push rdx
push rbx
push qword ptr [rbp + 48] ; RSP
push qword ptr [rbp] ; RBP
push rsi
push rdi
;; UINT64 Gs, Fs, Es, Ds, Cs, Ss; insure high 16 bits of each is zero
movzx rax, word ptr [rbp + 56]
push rax ; for ss
movzx rax, word ptr [rbp + 32]
push rax ; for cs
mov rax, ds
push rax
mov rax, es
push rax
mov rax, fs
push rax
mov rax, gs
push rax
mov [rbp + 8], rcx ; save vector number
;; UINT64 Rip;
push qword ptr [rbp + 24]
;; UINT64 Gdtr[2], Idtr[2];
xor rax, rax
push rax
push rax
sidt [rsp]
xchg rax, [rsp + 2]
xchg rax, [rsp]
xchg rax, [rsp + 8]
xor rax, rax
push rax
push rax
sgdt [rsp]
xchg rax, [rsp + 2]
xchg rax, [rsp]
xchg rax, [rsp + 8]
;; UINT64 Ldtr, Tr;
xor rax, rax
str ax
push rax
sldt ax
push rax
;; UINT64 RFlags;
push qword ptr [rbp + 40]
;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
mov rax, cr8
push rax
mov rax, cr4
or rax, 208h
mov cr4, rax
push rax
mov rax, cr3
push rax
mov rax, cr2
push rax
xor rax, rax
push rax
mov rax, cr0
push rax
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
mov rax, dr7
push rax
mov rax, dr6
push rax
mov rax, dr3
push rax
mov rax, dr2
push rax
mov rax, dr1
push rax
mov rax, dr0
push rax
;; FX_SAVE_STATE_X64 FxSaveState;
sub rsp, 512
mov rdi, rsp
db 0fh, 0aeh, 07h ;fxsave [rdi]
;; UEFI calling convention for x64 requires that Direction flag in EFLAGs is clear
cld
;; UINT32 ExceptionData;
push qword ptr [rbp + 16]
;; call into exception handler
mov rcx, [rbp + 8]
mov rax, ExternalVectorTablePtr ; get the interrupt vectors base
mov rax, [rax + rcx * 8]
or rax, rax ; NULL?
je nonNullValue;
;; Prepare parameter and call
; mov rcx, [rbp + 8]
mov rdx, rsp
;
; Per X64 calling convention, allocate maximum parameter stack space
; and make sure RSP is 16-byte aligned
;
sub rsp, 4 * 8 + 8
call rax
add rsp, 4 * 8 + 8
nonNullValue:
cli
;; UINT64 ExceptionData;
add rsp, 8
;; FX_SAVE_STATE_X64 FxSaveState;
mov rsi, rsp
db 0fh, 0aeh, 0Eh ; fxrstor [rsi]
add rsp, 512
;; UINT64 Dr0, Dr1, Dr2, Dr3, Dr6, Dr7;
;; Skip restoration of DRx registers to support in-circuit emualators
;; or debuggers set breakpoint in interrupt/exception context
add rsp, 8 * 6
;; UINT64 Cr0, Cr1, Cr2, Cr3, Cr4, Cr8;
pop rax
mov cr0, rax
add rsp, 8 ; not for Cr1
pop rax
mov cr2, rax
pop rax
mov cr3, rax
pop rax
mov cr4, rax
pop rax
mov cr8, rax
;; UINT64 RFlags;
pop qword ptr [rbp + 40]
;; UINT64 Ldtr, Tr;
;; UINT64 Gdtr[2], Idtr[2];
;; Best not let anyone mess with these particular registers...
add rsp, 48
;; UINT64 Rip;
pop qword ptr [rbp + 24]
;; UINT64 Gs, Fs, Es, Ds, Cs, Ss;
pop rax
; mov gs, rax ; not for gs
pop rax
; mov fs, rax ; not for fs
; (X64 will not use fs and gs, so we do not restore it)
pop rax
mov es, rax
pop rax
mov ds, rax
pop qword ptr [rbp + 32] ; for cs
pop qword ptr [rbp + 56] ; for ss
;; UINT64 Rdi, Rsi, Rbp, Rsp, Rbx, Rdx, Rcx, Rax;
;; UINT64 R8, R9, R10, R11, R12, R13, R14, R15;
pop rdi
pop rsi
add rsp, 8 ; not for rbp
pop qword ptr [rbp + 48] ; for rsp
pop rbx
pop rdx
pop rcx
pop rax
pop r8
pop r9
pop r10
pop r11
pop r12
pop r13
pop r14
pop r15
mov rsp, rbp
pop rbp
add rsp, 16
iretq
CommonInterruptEntry ENDP
END