Implement software interrupt dispatch table and secondary handler lookup
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
#include <xtstruct.h>
|
#include <xtstruct.h>
|
||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
|
#include ARCH_HEADER(xtstruct.h)
|
||||||
|
|
||||||
|
|
||||||
/* Control Register 0 constants */
|
/* Control Register 0 constants */
|
||||||
@@ -390,6 +391,9 @@ typedef enum _CPUID_REQUESTS
|
|||||||
CPUID_GET_STANDARD7_FEATURES
|
CPUID_GET_STANDARD7_FEATURES
|
||||||
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
||||||
|
|
||||||
|
/* Interrupt handler */
|
||||||
|
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
|
||||||
|
|
||||||
/* Processor identification information */
|
/* Processor identification information */
|
||||||
typedef struct _CPU_IDENTIFICATION
|
typedef struct _CPU_IDENTIFICATION
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -523,6 +523,7 @@ typedef struct _KPROCESSOR_BLOCK
|
|||||||
KAFFINITY SetMember;
|
KAFFINITY SetMember;
|
||||||
ULONG StallScaleFactor;
|
ULONG StallScaleFactor;
|
||||||
UCHAR CpuNumber;
|
UCHAR CpuNumber;
|
||||||
|
PINTERRUPT_HANDLER InterruptDispatchTable[256];
|
||||||
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
||||||
|
|
||||||
/* Thread Environment Block (TEB) structure definition */
|
/* Thread Environment Block (TEB) structure definition */
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <xtdefs.h>
|
#include <xtdefs.h>
|
||||||
#include <xtstruct.h>
|
#include <xtstruct.h>
|
||||||
#include <xttypes.h>
|
#include <xttypes.h>
|
||||||
|
#include ARCH_HEADER(xtstruct.h)
|
||||||
|
|
||||||
|
|
||||||
/* Control Register 0 constants */
|
/* Control Register 0 constants */
|
||||||
@@ -355,6 +356,9 @@ typedef enum _CPUID_REQUESTS
|
|||||||
CPUID_GET_STANDARD7_FEATURES
|
CPUID_GET_STANDARD7_FEATURES
|
||||||
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
} CPUID_REQUESTS, *PCPUID_REQUESTS;
|
||||||
|
|
||||||
|
/* Interrupt handler */
|
||||||
|
typedef VOID (*PINTERRUPT_HANDLER)(PKTRAP_FRAME TrapFrame);
|
||||||
|
|
||||||
/* Processor identification information */
|
/* Processor identification information */
|
||||||
typedef struct _CPU_IDENTIFICATION
|
typedef struct _CPU_IDENTIFICATION
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -478,6 +478,7 @@ typedef struct _KPROCESSOR_BLOCK
|
|||||||
KAFFINITY SetMember;
|
KAFFINITY SetMember;
|
||||||
ULONG StallScaleFactor;
|
ULONG StallScaleFactor;
|
||||||
UCHAR CpuNumber;
|
UCHAR CpuNumber;
|
||||||
|
PINTERRUPT_HANDLER InterruptDispatchTable[256];
|
||||||
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
} KPROCESSOR_BLOCK, *PKPROCESSOR_BLOCK;
|
||||||
|
|
||||||
/* Thread Environment Block (TEB) structure definition */
|
/* Thread Environment Block (TEB) structure definition */
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ Dispatch\Type\Vector:
|
|||||||
call ArDispatchTrap
|
call ArDispatchTrap
|
||||||
.else
|
.else
|
||||||
/* Pass to the interrupt dispatcher */
|
/* Pass to the interrupt dispatcher */
|
||||||
call ArDispatchTrap
|
call ArDispatchInterrupt
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
/* Restore the original trap frame stack pointer */
|
/* Restore the original trap frame stack pointer */
|
||||||
|
|||||||
@@ -29,3 +29,6 @@ KTSS AR::ProcSup::InitialTss;
|
|||||||
|
|
||||||
/* Initial kernel NMI stack */
|
/* Initial kernel NMI stack */
|
||||||
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
||||||
|
|
||||||
|
/* Unhandled interrupt routine */
|
||||||
|
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
||||||
|
|||||||
@@ -9,6 +9,44 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches the interrupt provided by common interrupt handler.
|
||||||
|
*
|
||||||
|
* @param TrapFrame
|
||||||
|
* Supplies a kernel trap frame pushed by common interrupt handler on the stack.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
PINTERRUPT_HANDLER Handler;
|
||||||
|
|
||||||
|
/* Read the handler pointer from the CPU's interrupt dispatch table */
|
||||||
|
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadGSQuadWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
|
||||||
|
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
|
||||||
|
|
||||||
|
/* Check if the interrupt has a handler registered */
|
||||||
|
if(Handler != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Call the handler */
|
||||||
|
Handler(TrapFrame);
|
||||||
|
}
|
||||||
|
else if(UnhandledInterruptRoutine != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Call the unhandled interrupt routine */
|
||||||
|
UnhandledInterruptRoutine(TrapFrame);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Dispatcher not initialized, print a debug message */
|
||||||
|
DebugPrint(L"ERROR: Caught unhandled interrupt: 0x%.2llX\n", TrapFrame->Vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatches the trap provided by common trap handler.
|
* Dispatches the trap provided by common trap handler.
|
||||||
*
|
*
|
||||||
@@ -642,3 +680,21 @@ AR::Traps::InitializeSystemCallMsrs(VOID)
|
|||||||
/* Enable system call extensions (SCE) in EFER MSR */
|
/* Enable system call extensions (SCE) in EFER MSR */
|
||||||
CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);
|
CpuFunc::WriteModelSpecificRegister(X86_MSR_EFER, CpuFunc::ReadModelSpecificRegister(X86_MSR_EFER) | X86_MSR_EFER_SCE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the unhandled interrupt routine used for vectors that have no handler registered.
|
||||||
|
*
|
||||||
|
* @param Handler
|
||||||
|
* Supplies the pointer to the interrupt handler routine.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)
|
||||||
|
{
|
||||||
|
/* Set the unhandled interrupt routine */
|
||||||
|
UnhandledInterruptRoutine = Handler;
|
||||||
|
}
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ Dispatch\Type\Vector:
|
|||||||
call _ArDispatchTrap
|
call _ArDispatchTrap
|
||||||
.else
|
.else
|
||||||
/* Pass to the interrupt dispatcher */
|
/* Pass to the interrupt dispatcher */
|
||||||
call _ArDispatchTrap
|
call _ArDispatchInterrupt
|
||||||
.endif
|
.endif
|
||||||
|
|
||||||
/* Clean up the stack */
|
/* Clean up the stack */
|
||||||
|
|||||||
@@ -35,3 +35,6 @@ UCHAR AR::ProcSup::NmiStack[KERNEL_STACK_SIZE] = {};
|
|||||||
|
|
||||||
/* NMI task gate */
|
/* NMI task gate */
|
||||||
UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
|
UCHAR AR::ProcSup::NonMaskableInterruptTss[KTSS_IO_MAPS];
|
||||||
|
|
||||||
|
/* Unhandled interrupt routine */
|
||||||
|
PINTERRUPT_HANDLER AR::Traps::UnhandledInterruptRoutine = NULLPTR;
|
||||||
|
|||||||
@@ -9,6 +9,44 @@
|
|||||||
#include <xtos.hh>
|
#include <xtos.hh>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatches the interrupt provided by common interrupt handler.
|
||||||
|
*
|
||||||
|
* @param TrapFrame
|
||||||
|
* Supplies a kernel trap frame pushed by common interrupt handler on the stack.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
AR::Traps::DispatchInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
PINTERRUPT_HANDLER Handler;
|
||||||
|
|
||||||
|
/* Read the handler pointer from the CPU's interrupt dispatch table */
|
||||||
|
Handler = (PINTERRUPT_HANDLER)AR::CpuFunc::ReadFSDualWord(FIELD_OFFSET(KPROCESSOR_BLOCK, InterruptDispatchTable) +
|
||||||
|
(TrapFrame->Vector * sizeof(PINTERRUPT_HANDLER)));
|
||||||
|
|
||||||
|
/* Check if the interrupt has a handler registered */
|
||||||
|
if(Handler != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Call the handler */
|
||||||
|
Handler(TrapFrame);
|
||||||
|
}
|
||||||
|
else if(UnhandledInterruptRoutine != NULLPTR)
|
||||||
|
{
|
||||||
|
/* Call the unhandled interrupt routine */
|
||||||
|
UnhandledInterruptRoutine(TrapFrame);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Dispatcher not initialized, print a debug message */
|
||||||
|
DebugPrint(L"ERROR: Caught unhandled interrupt: 0x%.2lX\n", TrapFrame->Vector);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dispatches the trap provided by common trap handler.
|
* Dispatches the trap provided by common trap handler.
|
||||||
*
|
*
|
||||||
@@ -589,3 +627,21 @@ AR::Traps::HandleTrapFF(IN PKTRAP_FRAME TrapFrame)
|
|||||||
DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n");
|
DebugPrint(L"Handled Unexpected-Interrupt (0xFF)!\n");
|
||||||
KE::Crash::Panic(0xFF);
|
KE::Crash::Panic(0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the unhandled interrupt routine used for vectors that have no handler registered.
|
||||||
|
*
|
||||||
|
* @param Handler
|
||||||
|
* Supplies the pointer to the interrupt handler routine.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
AR::Traps::SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler)
|
||||||
|
{
|
||||||
|
/* Set the unhandled interrupt routine */
|
||||||
|
UnhandledInterruptRoutine = Handler;
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* PROJECT: ExectOS
|
* PROJECT: ExectOS
|
||||||
* COPYRIGHT: See COPYING.md in the top level directory
|
* COPYRIGHT: See COPYING.md in the top level directory
|
||||||
* FILE: xtoskrnl/hl/amd64/irq.cc
|
* FILE: xtoskrnl/hl/amd64/irq.cc
|
||||||
* DESCRIPTION: Interrupts support for amd64 architecture
|
* DESCRIPTION: Interrupts support for AMD64 architecture
|
||||||
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
* DEVELOPERS: Rafal Kupiec <belliash@codingworkshop.eu.org>
|
||||||
* Aiken Harris <harraiken91@gmail.com>
|
* Aiken Harris <harraiken91@gmail.com>
|
||||||
*/
|
*/
|
||||||
@@ -11,13 +11,62 @@
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets new interrupt handler for the existing IDT entry.
|
* Returns the registered interrupt handler for the specified IDT vector.
|
||||||
|
*
|
||||||
|
* @param Vector
|
||||||
|
* Supplies the interrupt vector number.
|
||||||
|
*
|
||||||
|
* @return This routine returns the pointer to the IDT interrupt handler routine.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PVOID
|
||||||
|
HL::Irq::QueryInterruptHandler(IN ULONG Vector)
|
||||||
|
{
|
||||||
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
|
PKIDTENTRY IdtEntry;
|
||||||
|
|
||||||
|
/* Get current processor block and IDT entry */
|
||||||
|
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||||
|
IdtEntry = &ProcessorBlock->IdtBase[Vector];
|
||||||
|
|
||||||
|
/* Return address of the interrupt handler */
|
||||||
|
return (PVOID)((ULONGLONG)IdtEntry->OffsetHigh << 32 |
|
||||||
|
(ULONGLONG)IdtEntry->OffsetMiddle << 16 |
|
||||||
|
(ULONGLONG)IdtEntry->OffsetLow);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the registered interrupt handler for the specified vector.
|
||||||
|
*
|
||||||
|
* @param Vector
|
||||||
|
* Supplies the interrupt vector number.
|
||||||
|
*
|
||||||
|
* @return This routine returns the pointer to the interrupt handler routine.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PVOID
|
||||||
|
HL::Irq::QuerySystemInterruptHandler(IN ULONG Vector)
|
||||||
|
{
|
||||||
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
|
|
||||||
|
/* Get current processor block */
|
||||||
|
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||||
|
|
||||||
|
return (PVOID)ProcessorBlock->InterruptDispatchTable[Vector];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers new interrupt handler for the existing IDT entry.
|
||||||
*
|
*
|
||||||
* @param HalVector
|
* @param HalVector
|
||||||
* Supplies the HAL vector number.
|
* Supplies the interrupt vector number.
|
||||||
*
|
*
|
||||||
* @param Handler
|
* @param Handler
|
||||||
* Supplies the new interrupt handler.
|
* Supplies the pointer to the interrupt handler routine.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -25,8 +74,8 @@
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
HL::Irq::SetInterruptHandler(IN ULONG Vector,
|
HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
|
||||||
IN PVOID Handler)
|
IN PVOID Handler)
|
||||||
{
|
{
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
|
|
||||||
@@ -42,3 +91,54 @@ HL::Irq::SetInterruptHandler(IN ULONG Vector,
|
|||||||
KIDT_ACCESS_RING0,
|
KIDT_ACCESS_RING0,
|
||||||
AMD64_INTERRUPT_GATE);
|
AMD64_INTERRUPT_GATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the interrupt handler for the specified vector.
|
||||||
|
*
|
||||||
|
* @param HalVector
|
||||||
|
* Supplies the interrupt vector number.
|
||||||
|
*
|
||||||
|
* @param Handler
|
||||||
|
* Supplies the pointer to the interrupt handler routine.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
HL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector,
|
||||||
|
IN PINTERRUPT_HANDLER Handler)
|
||||||
|
{
|
||||||
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
|
|
||||||
|
/* Get current processor block */
|
||||||
|
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||||
|
|
||||||
|
/* Update interrupt handler in the processor's interrupt dispatch table */
|
||||||
|
ProcessorBlock->InterruptDispatchTable[Vector] = Handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unexpected or unmapped system interrupts.
|
||||||
|
*
|
||||||
|
* @param TrapFrame
|
||||||
|
* Supplies a kernel trap frame pushed by common interrupt handler.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
|
||||||
|
/* Disable interrupts */
|
||||||
|
AR::CpuFunc::ClearInterruptFlag();
|
||||||
|
|
||||||
|
/* Print debug message and raise kernel panic */
|
||||||
|
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2llX)!\n", TrapFrame->Vector);
|
||||||
|
KE::Crash::Panic(0x47, TrapFrame->Vector, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|||||||
@@ -11,13 +11,60 @@
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets new interrupt handler for the existing IDT entry.
|
* Returns the registered interrupt handler for the specified IDT vector.
|
||||||
|
*
|
||||||
|
* @param Vector
|
||||||
|
* Supplies the interrupt vector number.
|
||||||
|
*
|
||||||
|
* @return This routine returns the pointer to the IDT interrupt handler routine.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PVOID
|
||||||
|
HL::Irq::QueryInterruptHandler(IN ULONG Vector)
|
||||||
|
{
|
||||||
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
|
PKIDTENTRY IdtEntry;
|
||||||
|
|
||||||
|
/* Get current processor block and IDT entry */
|
||||||
|
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||||
|
IdtEntry = &ProcessorBlock->IdtBase[Vector];
|
||||||
|
|
||||||
|
/* Return address of the interrupt handler */
|
||||||
|
return (PVOID)(((IdtEntry->ExtendedOffset << 16) & 0xFFFF0000) | (IdtEntry->Offset & 0xFFFF));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the registered interrupt handler for the specified vector.
|
||||||
|
*
|
||||||
|
* @param Vector
|
||||||
|
* Supplies the interrupt vector number.
|
||||||
|
*
|
||||||
|
* @return This routine returns the pointer to the interrupt handler routine.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
PVOID
|
||||||
|
HL::Irq::QuerySystemInterruptHandler(IN ULONG Vector)
|
||||||
|
{
|
||||||
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
|
|
||||||
|
/* Get current processor block */
|
||||||
|
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||||
|
|
||||||
|
return (PVOID)ProcessorBlock->InterruptDispatchTable[Vector];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers new interrupt handler for the existing IDT entry.
|
||||||
*
|
*
|
||||||
* @param HalVector
|
* @param HalVector
|
||||||
* Supplies the HAL vector number.
|
* Supplies the interrupt vector number.
|
||||||
*
|
*
|
||||||
* @param Handler
|
* @param Handler
|
||||||
* Supplies the new interrupt handler.
|
* Supplies the pointer to the interrupt handler routine.
|
||||||
*
|
*
|
||||||
* @return This routine does not return any value.
|
* @return This routine does not return any value.
|
||||||
*
|
*
|
||||||
@@ -25,8 +72,8 @@
|
|||||||
*/
|
*/
|
||||||
XTAPI
|
XTAPI
|
||||||
VOID
|
VOID
|
||||||
HL::Irq::SetInterruptHandler(IN ULONG Vector,
|
HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
|
||||||
IN PVOID Handler)
|
IN PVOID Handler)
|
||||||
{
|
{
|
||||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
|
|
||||||
@@ -42,3 +89,54 @@ HL::Irq::SetInterruptHandler(IN ULONG Vector,
|
|||||||
KIDT_ACCESS_RING0,
|
KIDT_ACCESS_RING0,
|
||||||
I686_INTERRUPT_GATE);
|
I686_INTERRUPT_GATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers the interrupt handler for the specified vector.
|
||||||
|
*
|
||||||
|
* @param HalVector
|
||||||
|
* Supplies the interrupt vector number.
|
||||||
|
*
|
||||||
|
* @param Handler
|
||||||
|
* Supplies the pointer to the interrupt handler routine.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTAPI
|
||||||
|
VOID
|
||||||
|
HL::Irq::RegisterSystemInterruptHandler(IN ULONG Vector,
|
||||||
|
IN PINTERRUPT_HANDLER Handler)
|
||||||
|
{
|
||||||
|
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||||
|
|
||||||
|
/* Get current processor block */
|
||||||
|
ProcessorBlock = KE::Processor::GetCurrentProcessorBlock();
|
||||||
|
|
||||||
|
/* Update interrupt handler in the processor's interrupt dispatch table */
|
||||||
|
ProcessorBlock->InterruptDispatchTable[Vector] = Handler;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles unexpected or unmapped system interrupts.
|
||||||
|
*
|
||||||
|
* @param TrapFrame
|
||||||
|
* Supplies a kernel trap frame pushed by common interrupt handler.
|
||||||
|
*
|
||||||
|
* @return This routine does not return any value.
|
||||||
|
*
|
||||||
|
* @since XT 1.0
|
||||||
|
*/
|
||||||
|
XTCDECL
|
||||||
|
VOID
|
||||||
|
HL::Irq::HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame)
|
||||||
|
{
|
||||||
|
UNIMPLEMENTED;
|
||||||
|
|
||||||
|
/* Disable interrupts */
|
||||||
|
AR::CpuFunc::ClearInterruptFlag();
|
||||||
|
|
||||||
|
/* Print debug message and raise kernel panic */
|
||||||
|
DebugPrint(L"ERROR: Caught unexpected interrupt (0x%.2lX)!\n", TrapFrame->Vector);
|
||||||
|
KE::Crash::Panic(0x47, TrapFrame->Vector, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|||||||
@@ -223,7 +223,7 @@ HL::Pic::InitializeApic(VOID)
|
|||||||
WriteApicRegister(APIC_LINT1, LvtRegister.Long);
|
WriteApicRegister(APIC_LINT1, LvtRegister.Long);
|
||||||
|
|
||||||
/* Register interrupt handlers */
|
/* Register interrupt handlers */
|
||||||
HL::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
HL::Irq::RegisterInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
||||||
|
|
||||||
/* Clear any pre-existing errors */
|
/* Clear any pre-existing errors */
|
||||||
WriteApicRegister(APIC_ESR, 0);
|
WriteApicRegister(APIC_ESR, 0);
|
||||||
@@ -307,7 +307,7 @@ HL::Pic::InitializeLegacyPic(VOID)
|
|||||||
HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF);
|
HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF);
|
||||||
|
|
||||||
/* Register interrupt handler */
|
/* Register interrupt handler */
|
||||||
HL::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
HL::Irq::RegisterInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -17,9 +17,14 @@ namespace AR
|
|||||||
{
|
{
|
||||||
class Traps
|
class Traps
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
STATIC PINTERRUPT_HANDLER UnhandledInterruptRoutine;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
STATIC XTCDECL VOID DispatchInterrupt(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("ArDispatchInterrupt");
|
||||||
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("ArDispatchTrap");
|
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("ArDispatchTrap");
|
||||||
STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID);
|
STATIC XTCDECL VOID InitializeSystemCallMsrs(VOID);
|
||||||
|
STATIC XTCDECL VOID SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
STATIC XTCDECL VOID HandleSystemCall32(VOID);
|
STATIC XTCDECL VOID HandleSystemCall32(VOID);
|
||||||
|
|||||||
@@ -17,8 +17,13 @@ namespace AR
|
|||||||
{
|
{
|
||||||
class Traps
|
class Traps
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
|
STATIC PINTERRUPT_HANDLER UnhandledInterruptRoutine;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
STATIC XTCDECL VOID DispatchInterrupt(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("_ArDispatchInterrupt");
|
||||||
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("_ArDispatchTrap");
|
STATIC XTCDECL VOID DispatchTrap(IN PKTRAP_FRAME TrapFrame) XTSYMBOL("_ArDispatchTrap");
|
||||||
|
STATIC XTCDECL VOID SetUnhandledInterruptRoutine(PINTERRUPT_HANDLER Handler);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame);
|
STATIC XTCDECL VOID HandleTrap00(IN PKTRAP_FRAME TrapFrame);
|
||||||
|
|||||||
@@ -18,8 +18,13 @@ namespace HL
|
|||||||
class Irq
|
class Irq
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
STATIC XTAPI VOID SetInterruptHandler(IN ULONG Vector,
|
STATIC XTAPI PVOID QueryInterruptHandler(IN ULONG Vector);
|
||||||
IN PVOID Handler);
|
STATIC XTAPI PVOID QuerySystemInterruptHandler(IN ULONG Vector);
|
||||||
|
STATIC XTCDECL VOID HandleUnexpectedInterrupt(IN PKTRAP_FRAME TrapFrame);
|
||||||
|
STATIC XTAPI VOID RegisterInterruptHandler(IN ULONG Vector,
|
||||||
|
IN PVOID Handler);
|
||||||
|
STATIC XTAPI VOID RegisterSystemInterruptHandler(IN ULONG Vector,
|
||||||
|
IN PINTERRUPT_HANDLER Handler);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user