Author: ion Date: Sun Sep 3 10:51:03 2006 New Revision: 23894
URL: http://svn.reactos.org/svn/reactos?rev=23894&view=rev Log: - Fix KTSS definition. - Add GetSegment inlines (ie: GetSs, GetDs, etc) - Fix up definition of KiBootGdt to use KGDTENTRY instead of USHORT. Also define KiGdtDescriptor using KDESCRIPTOR. - Remove GDT initialization code completely. The GDT is already initialized on boot. - Remove tss.c and add KiInitializeTss(2) to setup a TSS and proper IOPM/Interrupt Direction map settings for V86/VDM. - Copy the TSS code over but prettyify it to use NT/NDK structures instead of ugly USHORT typecasts.
Removed: trunk/reactos/ntoskrnl/ke/i386/tss.c Modified: trunk/reactos/include/ndk/i386/ketypes.h trunk/reactos/ntoskrnl/include/internal/i386/ke.h trunk/reactos/ntoskrnl/include/internal/ke.h trunk/reactos/ntoskrnl/ke/i386/cpu.c trunk/reactos/ntoskrnl/ke/i386/gdt.c trunk/reactos/ntoskrnl/ke/i386/kernel.c trunk/reactos/ntoskrnl/ntoskrnl.rbuild
Modified: trunk/reactos/include/ndk/i386/ketypes.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ndk/i386/ketypes.h?... ============================================================================== --- trunk/reactos/include/ndk/i386/ketypes.h (original) +++ trunk/reactos/include/ndk/i386/ketypes.h Sun Sep 3 10:51:03 2006 @@ -647,7 +647,6 @@ UCHAR IoMap[8196]; } KIIO_ACCESS_MAP;
-#include <pshpack1.h> typedef struct _KTSS { USHORT Backlink; @@ -658,7 +657,15 @@ ULONG NotUsed1[4]; ULONG CR3; ULONG Eip; - ULONG NotUsed2[9]; + ULONG EFlags; + ULONG Eax; + ULONG Ecx; + ULONG Edx; + ULONG Ebx; + ULONG Esp; + ULONG Ebp; + ULONG Esi; + ULONG Edi; USHORT Es; USHORT Reserved2; USHORT Cs; @@ -678,7 +685,6 @@ KIIO_ACCESS_MAP IoMaps[1]; UCHAR IntDirectionMap[32]; } KTSS, *PKTSS; -#include <poppack.h>
// // i386 CPUs don't have exception frames
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/i386/ke.h (original) +++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h Sun Sep 3 10:51:03 2006 @@ -57,7 +57,8 @@ VOID Ki386ApplicationProcessorInitializeTSS(VOID); VOID -Ki386BootInitializeTSS(VOID); +NTAPI +Ki386InitializeTss(VOID); VOID KiGdtPrepareForApplicationProcessorInit(ULONG Id); VOID @@ -151,6 +152,12 @@ #define Ke386SaveFlags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */) #define Ke386RestoreFlags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
+#define _Ke386GetSeg(N) ({ \ + unsigned int __d; \ + __asm__("movl %%" #N ",%0\n\t" :"=r" (__d)); \ + __d; \ + }) + #define _Ke386GetCr(N) ({ \ unsigned int __d; \ __asm__("movl %%cr" #N ",%0\n\t" :"=r" (__d)); \ @@ -164,6 +171,7 @@ #define Ke386SetCr2(X) _Ke386SetCr(2,X) #define Ke386GetCr4() _Ke386GetCr(4) #define Ke386SetCr4(X) _Ke386SetCr(4,X) +#define Ke386GetSs() _Ke386GetSeg(ss)
static inline LONG Ke386TestAndClearBit(ULONG BitPos, volatile PULONG Addr) {
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/k... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ke.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ke.h Sun Sep 3 10:51:03 2006 @@ -95,6 +95,7 @@ extern ULONG KeI386EFlagsOrMaskV86; extern BOOLEAN KeI386VirtualIntExtensions; extern KIDTENTRY KiIdt[]; +extern KGDTENTRY KiBootGdt[]; extern FAST_MUTEX KernelAddressSpaceLock; extern ULONG KiMaximumDpcQueueDepth; extern ULONG KiMinimumDpcRate; @@ -116,6 +117,8 @@ extern PKPRCB KiProcessorBlock[]; extern ULONG KiMask32Array[MAXIMUM_PRIORITY]; extern ULONG IdleProcessorMask; +extern ULONG trap_stack_top; +extern VOID KiTrap8(VOID);
/* MACROS *************************************************************************/
@@ -184,7 +187,13 @@ /* One of the Reserved Wait Blocks, this one is for the Thread's Timer */ #define TIMER_WAIT_BLOCK 0x3L
+/* IOPM Definitions */ +#define IO_ACCESS_MAP_NONE 0 #define IOPM_OFFSET FIELD_OFFSET(KTSS, IoMaps[0].IoMap) +#define KiComputeIopmOffset(MapNumber) \ + (MapNumber == IO_ACCESS_MAP_NONE) ? \ + (USHORT)(sizeof(KTSS)) : \ + (USHORT)(FIELD_OFFSET(KTSS, IoMaps[MapNumber-1].IoMap))
#define SIZE_OF_FX_REGISTERS 32
Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/cpu.c (original) +++ trunk/reactos/ntoskrnl/ke/i386/cpu.c Sun Sep 3 10:51:03 2006 @@ -19,6 +19,12 @@ #define EFLAGS_ID 0x200000
/* GLOBALS *******************************************************************/ + +/* The Boot TSS */ +KTSS KiBootTss; + +/* The TSS to use for Double Fault Traps (INT 0x9) */ +UCHAR KiDoubleFaultTSS[KTSS_IO_MAPS];
ULONG KeI386CpuType; ULONG KeI386CpuStep; @@ -457,6 +463,117 @@
/* Set new Cr0 */ Ke386SetCr0(Cr0); +} + +VOID +NTAPI +KiInitializeTSS2(IN PKTSS Tss, + IN PKGDTENTRY TssEntry OPTIONAL) +{ + PUCHAR p; + + /* Make sure the GDT Entry is valid */ + if (TssEntry) + { + /* Set the Limit */ + TssEntry->LimitLow = sizeof(KTSS) - 1; + TssEntry->HighWord.Bits.LimitHi &= 0xF0; + } + + /* Now clear the I/O Map */ + RtlFillMemory(Tss->IoMaps[0].IoMap, 8096, -1); + + /* Initialize Interrupt Direction Maps */ + p = (PUCHAR)(Tss->IoMaps[0].DirectionMap); + RtlZeroMemory(p, 32); + + /* Add DPMI support for interrupts */ + p[0] = 4; + p[3] = 0x18; + p[4] = 0x18; + + /* Initialize the default Interrupt Direction Map */ + p = Tss->IntDirectionMap; + RtlZeroMemory(Tss->IntDirectionMap, 32); + + /* Add DPMI support */ + p[0] = 4; + p[3] = 0x18; + p[4] = 0x18; +} + +VOID +NTAPI +KiInitializeTSS(IN PKTSS Tss) +{ + /* Set an invalid map base */ + Tss->IoMapBase = KiComputeIopmOffset(IO_ACCESS_MAP_NONE); + + /* Disable traps during Task Switches */ + Tss->Flags = 0; + + /* Set LDT and Ring 0 SS */ + Tss->LDT = 0; + Tss->Ss0 = KGDT_R0_DATA; +} + +VOID +NTAPI +Ki386InitializeTss(VOID) +{ + PKTSS Tss; + PKGDTENTRY TssEntry; + PKIDTENTRY TaskGateEntry; + PKIDT_ACCESS TaskGateAccess; + + /* Initialize the boot TSS. */ + Tss = &KiBootTss; + TssEntry = &KiBootGdt[KGDT_TSS / sizeof(KGDTENTRY)]; + KiInitializeTSS2(Tss, TssEntry); + KiInitializeTSS(Tss); + + /* Initialize a descriptor for the TSS */ + TssEntry->HighWord.Bits.Type = I386_TSS; + TssEntry->HighWord.Bits.Pres = 1; + TssEntry->HighWord.Bits.Dpl = 0; + TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF); + TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16); + TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24); + + /* Load the task register */ + __asm__("ltr %%ax":: "a" (KGDT_TSS)); + + /* Setup the Task Gate for Double Fault Traps */ + TaskGateEntry = &KiIdt[8]; + TaskGateAccess = (PKIDT_ACCESS)&TaskGateEntry->Access; +#if 0 + TaskGateAccess->SegmentType = I386_TASK_GATE; + TaskGateAccess->Present = 1; + TaskGateAccess->Dpl = 0; + TaskGateEntry->Selector = KGDT_DF_TSS; +#endif + + /* Initialize the TSS used for handling double faults. */ + Tss = (PKTSS)KiDoubleFaultTSS; + KiInitializeTSS(Tss); + Tss->CR3 = _Ke386GetCr(3); + Tss->Esp0 = trap_stack_top; + Tss->Eip = PtrToUlong(KiTrap8); + Tss->Cs = KGDT_R0_CODE; + Tss->Fs = KGDT_R0_PCR; + Tss->Ss = Ke386GetSs(); + Tss->Es = KGDT_R3_DATA | RPL_MASK; + Tss->Ds = KGDT_R3_DATA | RPL_MASK; + + /* Setup the Double Trap TSS entry in the GDT */ + TssEntry = &KiBootGdt[KGDT_DF_TSS / sizeof(KGDTENTRY)]; + TssEntry->HighWord.Bits.Type = I386_TSS; + TssEntry->HighWord.Bits.Pres = 1; + TssEntry->HighWord.Bits.Dpl = 0; + TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF); + TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16); + TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24); + TssEntry->LimitLow = KTSS_IO_MAPS; }
VOID INIT_FUNCTION
Modified: trunk/reactos/ntoskrnl/ke/i386/gdt.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/gdt.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/gdt.c (original) +++ trunk/reactos/ntoskrnl/ke/i386/gdt.c Sun Sep 3 10:51:03 2006 @@ -12,134 +12,30 @@
#include <ntoskrnl.h> #define NDEBUG -#include <internal/debug.h> +#include <debug.h>
/* GLOBALS *******************************************************************/
-PUSHORT KiGdtArray[MAXIMUM_PROCESSORS]; - -USHORT KiBootGdt[11 * 4] = +KGDTENTRY KiBootGdt[11] = { - 0x0, 0x0, 0x0, 0x0, /* Null */ - 0xffff, 0x0, 0x9a00, 0xcf, /* Kernel CS */ - 0xffff, 0x0, 0x9200, 0xcf, /* Kernel DS */ - 0xffff, 0x0, 0xfa00, 0xcf, /* User CS */ - 0xffff, 0x0, 0xf200, 0xcf, /* User DS */ - 0x0, 0x0, 0x0, 0x0, /* TSS */ - 0x0fff, 0x0000, 0x9200, 0xff00, /* PCR */ - 0x0fff, 0x0, 0xf200, 0x0, /* TEB */ - 0x0, 0x0, 0x0, 0x0, /* Reserved */ - 0x0, 0x0, 0x0, 0x0, /* LDT */ - 0x0, 0x0, 0x0, 0x0 /* Trap TSS */ + {0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* Null */ + {0xffff, 0x0000, {{0x00, 0x9a, 0xcf, 0x00}}}, /* Kernel CS */ + {0xffff, 0x0000, {{0x00, 0x92, 0xcf, 0x00}}}, /* Kernel DS */ + {0xffff, 0x0000, {{0x00, 0xfa, 0xcf, 0x00}}}, /* User CS */ + {0xffff, 0x0000, {{0x00, 0xf2, 0xcf, 0x00}}}, /* User DS */ + {0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* TSS */ + {0x0fff, 0x0000, {{0x00, 0x92, 0x00, 0xff}}}, /* PCR */ + {0x0fff, 0x0000, {{0x00, 0xf2, 0x00, 0x00}}}, /* TEB */ + {0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* Reserved */ + {0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* LDT */ + {0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}} /* Trap TSS */ };
- -#include <pshpack1.h> - -struct LocalGdtDescriptor_t -{ - USHORT Length; - ULONG Base; -} KiGdtDescriptor = { 11 * 8, (ULONG)KiBootGdt }; - -#include <poppack.h> - +KDESCRIPTOR KiGdtDescriptor = {sizeof(KiBootGdt), (ULONG)KiBootGdt};
static KSPIN_LOCK GdtLock;
/* FUNCTIONS *****************************************************************/ - -VOID -KiInitializeGdt(PKPCR Pcr) -{ - PUSHORT Gdt; - struct LocalGdtDescriptor_t Descriptor; - ULONG Entry; - ULONG Base; - - if (Pcr == NULL) - { - KiGdtArray[0] = KiBootGdt; - return; - } - - /* - * Allocate a GDT - */ - Gdt = KiGdtArray[Pcr->Number]; - if (Gdt == NULL) - { - DbgPrint("No GDT (%d)\n", Pcr->Number); - KEBUGCHECK(0); - } - - /* - * Copy the boot processor's GDT onto this processor's GDT. Note that - * the only entries that can change are the PCR, TEB and LDT descriptors. - * We will be initializing these later so their current values are - * irrelevant. - */ - memcpy(Gdt, KiBootGdt, sizeof(USHORT) * 4 * 11); - Pcr->GDT = Gdt; - - /* - * Set the base address of the PCR - */ - Base = (ULONG)Pcr; - Entry = KGDT_R0_PCR / 2; - Gdt[Entry + 1] = (USHORT)(((ULONG)Base) & 0xffff); - - Gdt[Entry + 2] = Gdt[Entry + 2] & ~(0xff); - Gdt[Entry + 2] = (USHORT)(Gdt[Entry + 2] | ((((ULONG)Base) & 0xff0000) >> 16)); - - Gdt[Entry + 3] = Gdt[Entry + 3] & ~(0xff00); - Gdt[Entry + 3] = (USHORT)(Gdt[Entry + 3] | ((((ULONG)Base) & 0xff000000) >> 16)); - - /* - * Load the GDT - */ - Descriptor.Length = 8 * 11; - Descriptor.Base = (ULONG)Gdt; -#if defined(__GNUC__) - __asm__ ("lgdt %0\n\t" : /* no output */ : "m" (Descriptor)); - - /* - * Reload the selectors - */ - __asm__ ("movl %0, %%ds\n\t" - "movl %0, %%es\n\t" - "movl %1, %%fs\n\t" - "xor %%ax, %%ax\n\t" - "movw %%ax, %%gs\n\t" - : /* no output */ - : "a" (KGDT_R3_DATA | RPL_MASK), "d" (KGDT_R0_PCR)); - __asm__ ("pushl %0\n\t" - "pushl $.l4\n\t" - "lret\n\t" - ".l4:\n\t" - : /* no output */ - : "a" (KGDT_R0_CODE)); -#elif defined(_MSC_VER) - __asm - { - lgdt Descriptor; - mov ax, KGDT_R3_DATA | RPL_MASK; - mov dx, KGDT_R0_PCR; - mov ds, ax; - mov es, ax; - mov fs, dx; - xor ax, ax - mov gs, ax; - push KGDT_R0_CODE; - push offset l4 ; - retf -l4: - } -#else -#error Unknown compiler for inline assembler -#endif -} -
/* * @unimplemented
Modified: trunk/reactos/ntoskrnl/ke/i386/kernel.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/kernel.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/kernel.c (original) +++ trunk/reactos/ntoskrnl/ke/i386/kernel.c Sun Sep 3 10:51:03 2006 @@ -515,13 +515,10 @@ Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr6 = 0; Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr7 = 0;
- /* - * Low-level GDT, TSS and LDT Setup, most of which Freeldr should have done - * instead, and we should only add some extra information. This would be - * required for future NTLDR compatibility. - */ - KiInitializeGdt(NULL); - Ki386BootInitializeTSS(); + /* Setup the boot (Freeldr should've done), double fault and NMI TSS */ + Ki386InitializeTss(); + + /* Setup the LDT */ Ki386InitializeLdt();
/* Setup CPU-related fields */
Removed: trunk/reactos/ntoskrnl/ke/i386/tss.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/tss.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/tss.c (original) +++ trunk/reactos/ntoskrnl/ke/i386/tss.c (removed) @@ -1,119 +1,0 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/i386/tss.c - * PURPOSE: TSS managment - * - * PROGRAMMERS: David Welch (welch@cwcom.net) - */ - -/* INCLUDES *****************************************************************/ - -#include <ntoskrnl.h> -#define NDEBUG -#include <internal/debug.h> - -#if defined (ALLOC_PRAGMA) -#pragma alloc_text(INIT, Ki386BootInitializeTSS) -#endif - -/* GLOBALS *******************************************************************/ - -typedef struct _KTSSNOIOPM -{ - UCHAR TssData[KTSS_IO_MAPS]; -} KTSSNOIOPM; - -static KTSS* Ki386TssArray[MAXIMUM_PROCESSORS]; -PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS]; -static KTSSNOIOPM* Ki386TrapTssArray[MAXIMUM_PROCESSORS]; -static PVOID Ki386TrapStackArray[MAXIMUM_PROCESSORS]; - -KTSS KiBootTss; -static KTSSNOIOPM KiBootTrapTss; - -extern USHORT KiBootGdt[]; -extern ULONG init_stack; -extern ULONG init_stack_top; -extern VOID KiTrap8(VOID); - -/* FUNCTIONS *****************************************************************/ - -VOID INIT_FUNCTION -Ki386BootInitializeTSS(VOID) -{ - ULONG cr3_; - extern unsigned int trap_stack, trap_stack_top; - unsigned int base, length; - PKTSS Tss; - - Ke386GetPageTableDirectory(cr3_); - - Ki386TssArray[0] = &KiBootTss; - Ki386TrapTssArray[0] = &KiBootTrapTss; - Ki386TrapStackArray[0] = (PVOID)trap_stack; - Ki386InitialStackArray[0] = (PVOID)init_stack; - - /* Initialize the boot TSS. */ - KiBootTss.Esp0 = (ULONG)init_stack_top - sizeof(FX_SAVE_AREA); - KiBootTss.Ss0 = KGDT_R0_DATA; - KiBootTss.IoMapBase = 0xFFFF; /* No i/o bitmap */ - KiBootTss.LDT = KGDT_LDT; - - /* - * Initialize a descriptor for the TSS - */ - base = (unsigned int)&KiBootTss; - length = sizeof(KiBootTss) - 1; - - KiBootGdt[(KGDT_TSS / 2) + 0] = (length & 0xFFFF); - KiBootGdt[(KGDT_TSS / 2) + 1] = (base & 0xFFFF); - KiBootGdt[(KGDT_TSS / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8900; - KiBootGdt[(KGDT_TSS / 2) + 3] = ((length & 0xF0000) >> 16) | - ((base & 0xFF000000) >> 16); - - /* Initialize the TSS used for handling double faults. */ - Tss = (PKTSS)&KiBootTrapTss; - Tss->Flags = 0; - Tss->Esp0 = (ULONG)trap_stack_top; /* FIXME: - sizeof(FX_SAVE_AREA)? */ - Tss->Ss0 = KGDT_R0_DATA; - Tss->Cs = KGDT_R0_CODE; - Tss->Eip = (ULONG)KiTrap8; - Tss->Ds = KGDT_R0_DATA; - Tss->Es = KGDT_R0_DATA; - Tss->Fs = KGDT_R0_PCR; - Tss->IoMapBase = 0xFFFF; /* No i/o bitmap */ - Tss->LDT = 0x0; - - /* - * Initialize a descriptor for the trap TSS. - */ - base = (unsigned int)&KiBootTrapTss; - length = sizeof(KiBootTrapTss) - 1; - - KiBootGdt[(KGDT_DF_TSS / 2) + 0] = (length & 0xFFFF); - KiBootGdt[(KGDT_DF_TSS / 2) + 1] = (base & 0xFFFF); - KiBootGdt[(KGDT_DF_TSS / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8900; - KiBootGdt[(KGDT_DF_TSS / 2) + 3] = ((length & 0xF0000) >> 16) | - ((base & 0xFF000000) >> 16); - - /* - * Load the task register - */ -#if defined(__GNUC__) - __asm__("ltr %%ax" - : /* no output */ - : "a" (KGDT_TSS)); -#elif defined(_MSC_VER) - __asm mov ax, KGDT_TSS - __asm ltr ax -#else -#error Unknown compiler for inline assembler -#endif -} - - - - -
Modified: trunk/reactos/ntoskrnl/ntoskrnl.rbuild URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ntoskrnl.rbuild?re... ============================================================================== --- trunk/reactos/ntoskrnl/ntoskrnl.rbuild (original) +++ trunk/reactos/ntoskrnl/ntoskrnl.rbuild Sun Sep 3 10:51:03 2006 @@ -38,7 +38,6 @@ <file>ldt.c</file> <file>thread.c</file> <file>trap.s</file> - <file>tss.c</file> <file>usercall_asm.S</file> <file>v86vdm.c</file> <file>v86m_sup.S</file>