diff --git a/xtoskrnl/CMakeLists.txt b/xtoskrnl/CMakeLists.txt index 90a0cfe..f296af1 100644 --- a/xtoskrnl/CMakeLists.txt +++ b/xtoskrnl/CMakeLists.txt @@ -11,6 +11,7 @@ list(APPEND XTOSKRNL_SOURCE ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/cpufunc.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/globals.c ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/procsup.c + ${XTOSKRNL_SOURCE_DIR}/ar/${ARCH}/traps.c ${XTOSKRNL_SOURCE_DIR}/hl/cport.c ${XTOSKRNL_SOURCE_DIR}/hl/efifb.c ${XTOSKRNL_SOURCE_DIR}/hl/${ARCH}/ioport.c diff --git a/xtoskrnl/ar/amd64/procsup.c b/xtoskrnl/ar/amd64/procsup.c index f064d12..bc653f3 100644 --- a/xtoskrnl/ar/amd64/procsup.c +++ b/xtoskrnl/ar/amd64/procsup.c @@ -37,9 +37,10 @@ ArInitializeProcessor(VOID) /* Initialize processor block */ ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, (PVOID)KeInitializationBlock->KernelFaultStack); - /* Initialize GDT and TSS */ + /* Initialize GDT, IDT and TSS */ ArpInitializeGdt(ProcessorBlock); ArpInitializeTss(ProcessorBlock); + ArpInitializeIdt(ProcessorBlock); /* Set GDT and IDT descriptors */ GdtDescriptor.Base = Gdt; @@ -87,6 +88,36 @@ ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_SYS_TSS, (ULONGLONG)ProcessorBlock->TssBase, sizeof(KTSS), AMD64_TSS, KGDT_DPL_SYSTEM, 0); } +/** + * Initializes the kernel's Interrupt Descriptor Table (GDT). + * + * @param ProcessorBlock + * Supplies a pointer to the processor block to use. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) +{ + UINT Vector; + + /* Fill in all vectors */ + for(Vector = 0; Vector < IDT_ENTRIES; Vector++) + { + /* Set the IDT to handle unexpected interrupts */ + ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + } + + /* Setup IDT handlers for known interrupts and traps */ + ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpHandleTrap02, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); + ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpHandleTrap08, KGDT_R0_CODE, KIDT_IST_PANIC, KIDT_ACCESS_RING0); + ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpHandleTrap0D, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); + ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpHandleTrap0E, KGDT_R0_CODE, KIDT_IST_RESERVED, KIDT_ACCESS_RING0); +} + /** * Initializes processor block. * @@ -269,3 +300,48 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, GdtEntry->Bits.Type = (Type & 0x1F); GdtEntry->MustBeZero = 0; } + +/** + * Fills in a call, interrupt, task or trap gate entry. + * + * @param Idt + * Supplies a pointer to IDT structure, where gate is located. + * + * @param Vector + * Supplies a gate vector pointing to the interrupt gate in the IDT + * + * @param Handler + * Supplies a pointer to the interrupt handler of the specified gate. + * + * @param Selector + * Supplies the code selector the gate should run in. + * + * @param Ist + * Supplies the interrupt stack table entry the gate should run in. + * + * @param Access + * Supplies the gate access rights. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ArpSetIdtGate(IN PKIDTENTRY Idt, + IN USHORT Vector, + IN PVOID Handler, + IN USHORT Selector, + IN USHORT Ist, + IN USHORT Access) +{ + /* Setup the gate */ + Idt[Vector].OffsetLow = (ULONG_PTR)Handler; + Idt[Vector].OffsetMiddle = ((ULONG_PTR)Handler >> 16); + Idt[Vector].OffsetHigh = (ULONG_PTR)Handler >> 32; + Idt[Vector].Dpl = Access; + Idt[Vector].IstIndex = Ist; + Idt[Vector].Present = 1; + Idt[Vector].Selector = Selector; + Idt[Vector].Type = 0xE; +} diff --git a/xtoskrnl/ar/amd64/traps.c b/xtoskrnl/ar/amd64/traps.c new file mode 100644 index 0000000..86d0881 --- /dev/null +++ b/xtoskrnl/ar/amd64/traps.c @@ -0,0 +1,85 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ar/amd64/traps.c + * DESCRIPTION: AMD64 system traps + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Handles the trap 0x02 (Non Maskable Interrupt) gracefully. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +ArpHandleTrap02() +{ + LdrPrint(L"Handled Non-Maskable Interrupt (0x02)!\n"); + for(;;); +} + +/** + * Handles the trap 0x08 (Double Fault) gracefully. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +ArpHandleTrap08() +{ + LdrPrint(L"Handled Double Fault exception (0x08)!\n"); + for(;;); +} + +/** + * Handles the trap 0x0E (Page Fault) gracefully. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +ArpHandleTrap0D() +{ + LdrPrint(L"Handled General Protection Fault (0x0D)!\n"); + for(;;); +} + +/** + * Handles the trap 0x0E (Page Fault) gracefully. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +ArpHandleTrap0E() +{ + LdrPrint(L"Handled Page Fault exception (0x0E)!\n"); + for(;;); +} + +/** + * Handles the trap 0xFF (Unexpected Interrupt) gracefully. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +ArpHandleTrapFF() +{ + LdrPrint(L"Handled Unexpected Interrupt (0xFF)!\n"); + for(;;); +} diff --git a/xtoskrnl/ar/i686/procsup.c b/xtoskrnl/ar/i686/procsup.c index eab558c..52b2901 100644 --- a/xtoskrnl/ar/i686/procsup.c +++ b/xtoskrnl/ar/i686/procsup.c @@ -37,9 +37,10 @@ ArInitializeProcessor(VOID) /* Initialize processor block */ ArpInitializeProcessorBlock(ProcessorBlock, Gdt, Idt, Tss, (PVOID)KeInitializationBlock->KernelFaultStack); - /* Initialize GDT and TSS */ + /* Initialize GDT, IDT and TSS */ ArpInitializeGdt(ProcessorBlock); ArpInitializeTss(ProcessorBlock); + ArpInitializeIdt(ProcessorBlock); /* Set GDT and IDT descriptors */ GdtDescriptor.Base = Gdt; @@ -89,6 +90,36 @@ ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock) ArpSetGdtEntry(ProcessorBlock->GdtBase, KGDT_VDBS, 0xB8000, 0x3FFF, KGDT_TYPE_DATA, KGDT_DPL_SYSTEM, 0); } +/** + * Initializes the kernel's Interrupt Descriptor Table (GDT). + * + * @param ProcessorBlock + * Supplies a pointer to the processor block to use. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock) +{ + UINT Vector; + + /* Fill in all vectors */ + for(Vector = 0; Vector < IDT_ENTRIES; Vector++) + { + /* Set the IDT to handle unexpected interrupts */ + ArpSetIdtGate(ProcessorBlock->IdtBase, Vector, ArpHandleTrapFF, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + } + + /* Setup IDT handlers for known interrupts and traps */ + ArpSetIdtGate(ProcessorBlock->IdtBase, 0x02, ArpHandleTrap02, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + ArpSetIdtGate(ProcessorBlock->IdtBase, 0x08, ArpHandleTrap08, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0D, ArpHandleTrap0D, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); + ArpSetIdtGate(ProcessorBlock->IdtBase, 0x0E, ArpHandleTrap0E, KGDT_R0_CODE, 0, KIDT_INTERRUPT | KIDT_ACCESS_RING0); +} + /** * Initializes processor block. * @@ -327,6 +358,47 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, GdtEntry->Bits.Type = (Type & 0x1F); } +/** + * Fills in a call, interrupt, task or trap gate entry. + * + * @param Idt + * Supplies a pointer to IDT structure, where gate is located. + * + * @param Vector + * Supplies a gate vector pointing to the interrupt gate in the IDT + * + * @param Handler + * Supplies a pointer to the interrupt handler of the specified gate. + * + * @param Selector + * Supplies the code selector the gate should run in. + * + * @param Ist + * Supplies the interrupt stack table entry the gate should run in. + * + * @param Access + * Supplies the gate access rights. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTAPI +VOID +ArpSetIdtGate(IN PKIDTENTRY Idt, + IN USHORT Vector, + IN PVOID Handler, + IN USHORT Selector, + IN USHORT Ist, + IN USHORT Access) +{ + /* Setup the gate */ + Idt[Vector].Offset = (USHORT)((ULONG)Handler & 0xFFFF); + Idt[Vector].ExtendedOffset = (USHORT)((ULONG)Handler >> 16); + Idt[Vector].Access = 0x8000 | (Access << 8); + Idt[Vector].Selector = Selector; +} + /** * Initializes the Non-Maskable Interrupt TSS entry in the Global Descriptor Table. * diff --git a/xtoskrnl/ar/i686/traps.c b/xtoskrnl/ar/i686/traps.c new file mode 100644 index 0000000..eb74aa4 --- /dev/null +++ b/xtoskrnl/ar/i686/traps.c @@ -0,0 +1,85 @@ +/** + * PROJECT: ExectOS + * COPYRIGHT: See COPYING.md in the top level directory + * FILE: xtoskrnl/ar/i686/traps.c + * DESCRIPTION: I686 system traps + * DEVELOPERS: Rafal Kupiec + */ + +#include + + +/** + * Handles the trap 0x02 (Non Maskable Interrupt) gracefully. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +ArpHandleTrap02() +{ + LdrPrint(L"Handled Non-Maskable Interrupt (0x02)!\n"); + for(;;); +} + +/** + * Handles the trap 0x08 (Double Fault) gracefully. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +ArpHandleTrap08() +{ + LdrPrint(L"Handled Double Fault exception (0x08)!\n"); + for(;;); +} + +/** + * Handles the trap 0x0E (Page Fault) gracefully. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +ArpHandleTrap0D() +{ + LdrPrint(L"Handled General Protection Fault (0x0D)!\n"); + for(;;); +} + +/** + * Handles the trap 0x0E (Page Fault) gracefully. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +ArpHandleTrap0E() +{ + LdrPrint(L"Handled Page Fault exception (0x0E)!\n"); + for(;;); +} + +/** + * Handles the trap 0xFF (Unexpected Interrupt) gracefully. + * + * @return This routine does not return any value. + * + * @since XT 1.0 + */ +XTCDECL +VOID +ArpHandleTrapFF() +{ + LdrPrint(L"Handled Unexpected Interrupt (0xFF)!\n"); + for(;;); +} diff --git a/xtoskrnl/includes/arpfuncs.h b/xtoskrnl/includes/arpfuncs.h index fbc00ee..36334f1 100644 --- a/xtoskrnl/includes/arpfuncs.h +++ b/xtoskrnl/includes/arpfuncs.h @@ -12,10 +12,34 @@ #include +XTCDECL +VOID +ArpHandleTrap02(); + +XTCDECL +VOID +ArpHandleTrap08(); + +XTCDECL +VOID +ArpHandleTrap0D(); + +XTCDECL +VOID +ArpHandleTrap0E(); + +XTCDECL +VOID +ArpHandleTrapFF(); + XTAPI VOID ArpInitializeGdt(IN PKPROCESSOR_BLOCK ProcessorBlock); +XTAPI +VOID +ArpInitializeIdt(IN PKPROCESSOR_BLOCK ProcessorBlock); + XTAPI VOID ArpInitializeProcessorBlock(OUT PKPROCESSOR_BLOCK ProcessorBlock, @@ -42,6 +66,15 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, IN UCHAR Dpl, IN UCHAR SegmentMode); +XTAPI +VOID +ArpSetIdtGate(IN PKIDTENTRY Idt, + IN USHORT Vector, + IN PVOID Handler, + IN USHORT Selector, + IN USHORT Ist, + IN USHORT Access); + XTAPI VOID ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock);