Implement software interrupt dispatch table and secondary handler lookup
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
* PROJECT: ExectOS
|
||||
* COPYRIGHT: See COPYING.md in the top level directory
|
||||
* 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>
|
||||
* 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
|
||||
* Supplies the HAL vector number.
|
||||
* Supplies the interrupt vector number.
|
||||
*
|
||||
* @param Handler
|
||||
* Supplies the new interrupt handler.
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -25,8 +74,8 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Irq::SetInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
|
||||
@@ -42,3 +91,54 @@ HL::Irq::SetInterruptHandler(IN ULONG Vector,
|
||||
KIDT_ACCESS_RING0,
|
||||
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
|
||||
* Supplies the HAL vector number.
|
||||
* Supplies the interrupt vector number.
|
||||
*
|
||||
* @param Handler
|
||||
* Supplies the new interrupt handler.
|
||||
* Supplies the pointer to the interrupt handler routine.
|
||||
*
|
||||
* @return This routine does not return any value.
|
||||
*
|
||||
@@ -25,8 +72,8 @@
|
||||
*/
|
||||
XTAPI
|
||||
VOID
|
||||
HL::Irq::SetInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
HL::Irq::RegisterInterruptHandler(IN ULONG Vector,
|
||||
IN PVOID Handler)
|
||||
{
|
||||
PKPROCESSOR_BLOCK ProcessorBlock;
|
||||
|
||||
@@ -42,3 +89,54 @@ HL::Irq::SetInterruptHandler(IN ULONG Vector,
|
||||
KIDT_ACCESS_RING0,
|
||||
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);
|
||||
|
||||
/* Register interrupt handlers */
|
||||
HL::Irq::SetInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
||||
HL::Irq::RegisterInterruptHandler(APIC_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
||||
|
||||
/* Clear any pre-existing errors */
|
||||
WriteApicRegister(APIC_ESR, 0);
|
||||
@@ -307,7 +307,7 @@ HL::Pic::InitializeLegacyPic(VOID)
|
||||
HL::IoPort::WritePort8(PIC2_DATA_PORT, 0xFF);
|
||||
|
||||
/* Register interrupt handler */
|
||||
HL::Irq::SetInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
||||
HL::Irq::RegisterInterruptHandler(PIC1_VECTOR_SPURIOUS, (PVOID)ArHandleSpuriousInterrupt);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user