From 1ef205d47b9c7acdad7d2b388687e0bb78c3f9d8 Mon Sep 17 00:00:00 2001 From: belliash Date: Wed, 1 Feb 2023 20:36:40 +0100 Subject: [PATCH] Initialize DoubleFault and NonMaskableInterrupt TSS entries --- xtoskrnl/ar/i686/globals.c | 4 ++ xtoskrnl/ar/i686/procsup.c | 107 +++++++++++++++++++++++++++++++ xtoskrnl/includes/arpfuncs.h | 8 +++ xtoskrnl/includes/i686/globals.h | 4 ++ 4 files changed, 123 insertions(+) diff --git a/xtoskrnl/ar/i686/globals.c b/xtoskrnl/ar/i686/globals.c index 0e0e73b..c56f5eb 100644 --- a/xtoskrnl/ar/i686/globals.c +++ b/xtoskrnl/ar/i686/globals.c @@ -20,3 +20,7 @@ KPROCESSOR_BLOCK ArInitialProcessorBlock; /* Initial TSS */ KTSS ArInitialTss; + +/* Double Fault and NMI task gates */ +UCHAR ArpDoubleFaultTss[KTSS_IO_MAPS]; +UCHAR ArpNonMaskableInterruptTss[KTSS_IO_MAPS]; diff --git a/xtoskrnl/ar/i686/procsup.c b/xtoskrnl/ar/i686/procsup.c index 5d8519d..eab558c 100644 --- a/xtoskrnl/ar/i686/procsup.c +++ b/xtoskrnl/ar/i686/procsup.c @@ -193,6 +193,62 @@ ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock) /* Set LDT and SS */ ProcessorBlock->TssBase->LDT = KGDT_R0_LDT; ProcessorBlock->TssBase->Ss0 = KGDT_R0_DATA; + + /* Initialize task gates for DoubleFault trap */ + ArpSetDoubleFaultTssEntry(ProcessorBlock); + ArpSetNonMaskableInterruptTssEntry(ProcessorBlock); +} + +/** + * Initializes the DoubleFault TSS entry in the Global Descriptor Table. + * + * @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 +ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock) +{ + PKGDTENTRY TaskGateEntry, TssEntry; + PKTSS Tss; + + /* Setup task gate for DoubleFault trap */ + TaskGateEntry = (PKGDTENTRY)&ProcessorBlock->IdtBase[8]; + TaskGateEntry->Bits.Dpl = 0; + TaskGateEntry->Bits.Present = 1; + TaskGateEntry->Bits.Type = I686_TASK_GATE; + ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_DF_TSS; + + /* Initialize DoubleFault TSS and set initial state */ + Tss = (PKTSS)ArpDoubleFaultTss; + Tss->IoMapBase = sizeof(KTSS); + Tss->Flags = 0; + Tss->LDT = KGDT_R0_LDT; + Tss->CR3 = ArReadControlRegister(3); + Tss->Esp = KeInitializationBlock->KernelFaultStack; + Tss->Esp0 = KeInitializationBlock->KernelFaultStack; + Tss->Eip = PtrToUlong(ArpHandleTrap08); + Tss->Cs = KGDT_R0_CODE; + Tss->Ds = KGDT_R3_DATA | RPL_MASK; + Tss->Es = KGDT_R3_DATA | RPL_MASK; + Tss->Fs = KGDT_R0_PCR; + Tss->Ss0 = KGDT_R0_DATA; + ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); + + /* Setup DoubleFault TSS entry in Global Descriptor Table */ + TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_DF_TSS / sizeof(KGDTENTRY)])); + TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF); + TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16); + TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24); + TssEntry->LimitLow = sizeof(KTSS) - 1; + TssEntry->Bits.LimitHigh = 0; + TssEntry->Bits.Dpl = 0; + TssEntry->Bits.Present = 1; + TssEntry->Bits.Type = I686_TSS; } /** @@ -270,3 +326,54 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, GdtEntry->Bits.System = 0; GdtEntry->Bits.Type = (Type & 0x1F); } + +/** + * Initializes the Non-Maskable Interrupt TSS entry in the Global Descriptor Table. + * + * @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 +ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock) +{ + PKGDTENTRY TaskGateEntry, TssEntry; + PKTSS Tss; + + /* Setup task gate for NMI */ + TaskGateEntry = (PKGDTENTRY)&ProcessorBlock->IdtBase[2]; + TaskGateEntry->Bits.Dpl = 0; + TaskGateEntry->Bits.Present = 1; + TaskGateEntry->Bits.Type = I686_TASK_GATE; + ((PKIDTENTRY)TaskGateEntry)->Selector = KGDT_NMI_TSS; + + /* Initialize NMI TSS and set initial state */ + Tss = (PKTSS)ArpNonMaskableInterruptTss; + Tss->IoMapBase = sizeof(KTSS); + Tss->Flags = 0; + Tss->LDT = KGDT_R0_LDT; + Tss->CR3 = ArReadControlRegister(3); + Tss->Esp = KeInitializationBlock->KernelFaultStack; + Tss->Esp0 = KeInitializationBlock->KernelFaultStack; + Tss->Eip = PtrToUlong(ArpHandleTrap02); + Tss->Cs = KGDT_R0_CODE; + Tss->Ds = KGDT_R3_DATA | RPL_MASK; + Tss->Es = KGDT_R3_DATA | RPL_MASK; + Tss->Fs = KGDT_R0_PCR; + ArStoreSegment(SEGMENT_SS, (PVOID)&Tss->Ss); + + /* Setup NMI TSS entry in Global Descriptor Table */ + TssEntry = (PKGDTENTRY)(&(ProcessorBlock->GdtBase[KGDT_NMI_TSS / sizeof(KGDTENTRY)])); + TssEntry->BaseLow = ((ULONG_PTR)Tss & 0xFFFF); + TssEntry->Bytes.BaseMiddle = ((ULONG_PTR)Tss >> 16); + TssEntry->Bytes.BaseHigh = ((ULONG_PTR)Tss >> 24); + TssEntry->LimitLow = sizeof(KTSS) - 1; + TssEntry->Bits.LimitHigh = 0; + TssEntry->Bits.Dpl = 0; + TssEntry->Bits.Present = 1; + TssEntry->Bits.Type = I686_TSS; +} \ No newline at end of file diff --git a/xtoskrnl/includes/arpfuncs.h b/xtoskrnl/includes/arpfuncs.h index 24cc9d3..fbc00ee 100644 --- a/xtoskrnl/includes/arpfuncs.h +++ b/xtoskrnl/includes/arpfuncs.h @@ -28,6 +28,10 @@ XTAPI VOID ArpInitializeTss(IN PKPROCESSOR_BLOCK ProcessorBlock); +XTAPI +VOID +ArpSetDoubleFaultTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock); + XTAPI VOID ArpSetGdtEntry(IN PKGDTENTRY Gdt, @@ -38,4 +42,8 @@ ArpSetGdtEntry(IN PKGDTENTRY Gdt, IN UCHAR Dpl, IN UCHAR SegmentMode); +XTAPI +VOID +ArpSetNonMaskableInterruptTssEntry(IN PKPROCESSOR_BLOCK ProcessorBlock); + #endif /* __XTOSKRNL_ARPFUNCS_H */ diff --git a/xtoskrnl/includes/i686/globals.h b/xtoskrnl/includes/i686/globals.h index ff89338..8c01d7c 100644 --- a/xtoskrnl/includes/i686/globals.h +++ b/xtoskrnl/includes/i686/globals.h @@ -24,4 +24,8 @@ EXTERN KPROCESSOR_BLOCK ArInitialProcessorBlock; /* Initial TSS */ EXTERN KTSS ArInitialTss; +/* Double Fault and NMI task gates */ +EXTERN UCHAR ArpDoubleFaultTss[KTSS_IO_MAPS]; +EXTERN UCHAR ArpNonMaskableInterruptTss[KTSS_IO_MAPS]; + #endif /* __XTOSKRNL_I686_GLOBALS_H */