diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index 6479ead6e84..cab282b1c43 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -96,6 +96,7 @@ extern ULONG KeI386EFlagsOrMaskV86; extern BOOLEAN KeI386VirtualIntExtensions; extern KIDTENTRY KiIdt[]; extern KGDTENTRY KiBootGdt[]; +extern KTSS KiBootTss; extern FAST_MUTEX KernelAddressSpaceLock; extern ULONG KiMaximumDpcQueueDepth; extern ULONG KiMinimumDpcRate; @@ -111,6 +112,7 @@ extern LIST_ENTRY KiTimerListHead; extern KMUTEX KiGenericCallDpcMutex; extern LIST_ENTRY KiProfileListHead, KiProfileSourceListHead; extern KSPIN_LOCK KiProfileLock; +extern LIST_ENTRY KiProcessListHead; extern LIST_ENTRY KiProcessInSwapListHead, KiProcessOutSwapListHead; extern LIST_ENTRY KiStackInSwapListHead; extern KEVENT KiSwapEvent; diff --git a/reactos/ntoskrnl/ke/i386/abios.c b/reactos/ntoskrnl/ke/i386/abios.c new file mode 100644 index 00000000000..b47feb86a94 --- /dev/null +++ b/reactos/ntoskrnl/ke/i386/abios.c @@ -0,0 +1,54 @@ +/* + * PROJECT: ReactOS Kernel + * LICENSE: GPL - See COPYING in the top level directory + * FILE: ntoskrnl/ke/i386/abios.c + * PURPOSE: Routines for ABIOS Support + * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org) + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* FUNCTIONS *****************************************************************/ + +/* + * @unimplemented + */ +NTSTATUS +STDCALL +KeI386FlatToGdtSelector(IN ULONG Base, + IN USHORT Length, + IN USHORT Selector) +{ + UNIMPLEMENTED; + return 0; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +KeI386ReleaseGdtSelectors(OUT PULONG SelArray, + IN ULONG NumOfSelectors) +{ + UNIMPLEMENTED; + return 0; +} + +/* + * @unimplemented + */ +NTSTATUS +NTAPI +KeI386AllocateGdtSelectors(OUT PULONG SelArray, + IN ULONG NumOfSelectors) +{ + UNIMPLEMENTED; + return 0; +} + +/* EOF */ diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index 16f4b9b3967..cf14ca98a9c 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -26,6 +26,27 @@ KTSS KiBootTss; /* The TSS to use for Double Fault Traps (INT 0x9) */ UCHAR KiDoubleFaultTSS[KTSS_IO_MAPS]; +/* The Boot GDT (FIXME: should have more entries */ +KGDTENTRY KiBootGdt[12] = +{ + {0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_NULL */ + {0xffff, 0x0000, {{0x00, 0x9a, 0xcf, 0x00}}}, /* KGDT_R0_CODE */ + {0xffff, 0x0000, {{0x00, 0x92, 0xcf, 0x00}}}, /* KGDT_R0_DATA */ + {0xffff, 0x0000, {{0x00, 0xfa, 0xcf, 0x00}}}, /* KGDT_R3_CODE */ + {0xffff, 0x0000, {{0x00, 0xf2, 0xcf, 0x00}}}, /* KGDT_R3_DATA*/ + {0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_TSS */ + {0x0fff, 0x0000, {{0x00, 0x92, 0x00, 0xff}}}, /* KGDT_R0_PCR */ + {0x0fff, 0x0000, {{0x00, 0xf2, 0x00, 0x00}}}, /* KGDT_R3_TEB */ + {0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_UNUSED */ + {0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_LDT */ + {0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* KGDT_DF_TSS */ + {0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}} /* KGDT_NMI_TSS */ +}; + +/* GDT Descriptor */ +KDESCRIPTOR KiGdtDescriptor = {sizeof(KiBootGdt), (ULONG)KiBootGdt}; + +/* CPU Features and Flags */ ULONG KeI386CpuType; ULONG KeI386CpuStep; ULONG KeProcessorArchitecture; @@ -42,6 +63,7 @@ ULONG Ke386GlobalPagesEnabled = FALSE; ULONG Ke386NoExecute = FALSE; BOOLEAN KiI386PentiumLockErrataPresent; +/* CPU Signatures */ CHAR CmpIntelID[] = "GenuineIntel"; CHAR CmpAmdID[] = "AuthenticAMD"; CHAR CmpCyrixID[] = "CyrixInstead"; @@ -576,7 +598,45 @@ Ki386InitializeTss(VOID) TssEntry->LimitLow = KTSS_IO_MAPS; } -VOID INIT_FUNCTION +/* This is a rather naive implementation of Ke(Save/Restore)FloatingPointState + which will not work for WDM drivers. Please feel free to improve */ +NTSTATUS +NTAPI +KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save) +{ + PFNSAVE_FORMAT FpState; + ASSERT_IRQL(DISPATCH_LEVEL); + + /* check if we are doing software emulation */ + if (!KeI386NpxPresent) return STATUS_ILLEGAL_FLOAT_CONTEXT; + + FpState = ExAllocatePool(NonPagedPool, sizeof (FNSAVE_FORMAT)); + if (!FpState) return STATUS_INSUFFICIENT_RESOURCES; + + *((PVOID *) Save) = FpState; + asm volatile("fnsave %0\n\t" : "=m" (*FpState)); + + KeGetCurrentThread()->DispatcherHeader.NpxIrql = KeGetCurrentIrql(); + return STATUS_SUCCESS; +} + +NTSTATUS +NTAPI +KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save) +{ + PFNSAVE_FORMAT FpState = *((PVOID *) Save); + + ASSERT(KeGetCurrentThread()->DispatcherHeader.NpxIrql == KeGetCurrentIrql()); + + asm volatile("fnclex\n\t"); + asm volatile("frstor %0\n\t" : "=m" (*FpState)); + + ExFreePool(FpState); + return STATUS_SUCCESS; +} + +VOID +INIT_FUNCTION Ki386SetProcessorFeatures(VOID) { OBJECT_ATTRIBUTES ObjectAttributes; @@ -667,7 +727,6 @@ Ki386SetProcessorFeatures(VOID) } } - VOID NTAPI KeFlushCurrentTb(VOID) diff --git a/reactos/ntoskrnl/ke/i386/fpu.c b/reactos/ntoskrnl/ke/i386/fpu.c deleted file mode 100644 index b6a659cc786..00000000000 --- a/reactos/ntoskrnl/ke/i386/fpu.c +++ /dev/null @@ -1,80 +0,0 @@ -/* - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/i386/fpu.c - * PURPOSE: Handles the FPU - * PROGRAMMERS: David Welch (welch@mcmail.com) - * Gregor Anich - */ - -/* INCLUDES *****************************************************************/ - -#include -#include -#define NDEBUG -#include - -/* FUNCTIONS *****************************************************************/ - -/* This is a rather naive implementation of Ke(Save/Restore)FloatingPointState - which will not work for WDM drivers. Please feel free to improve */ - -NTSTATUS STDCALL -KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save) -{ - PFNSAVE_FORMAT FpState; - - ASSERT_IRQL(DISPATCH_LEVEL); - - /* check if we are doing software emulation */ - if (!KeI386NpxPresent) - { - return STATUS_ILLEGAL_FLOAT_CONTEXT; - } - - FpState = ExAllocatePool(NonPagedPool, sizeof (FNSAVE_FORMAT)); - if (NULL == FpState) - { - return STATUS_INSUFFICIENT_RESOURCES; - } - *((PVOID *) Save) = FpState; - -#if defined(__GNUC__) - asm volatile("fnsave %0\n\t" : "=m" (*FpState)); -#elif defined(_MSC_VER) - __asm mov eax, FpState; - __asm fsave [eax]; -#else -#error Unknown compiler for inline assembler -#endif - - KeGetCurrentThread()->DispatcherHeader.NpxIrql = KeGetCurrentIrql(); - - return STATUS_SUCCESS; -} - - -NTSTATUS STDCALL -KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save) -{ - PFNSAVE_FORMAT FpState = *((PVOID *) Save); - - if (KeGetCurrentThread()->DispatcherHeader.NpxIrql != KeGetCurrentIrql()) - { - KEBUGCHECK(UNDEFINED_BUG_CODE); - } - -#if defined(__GNUC__) - asm volatile("fnclex\n\t"); - asm volatile("frstor %0\n\t" : "=m" (*FpState)); -#elif defined(_MSC_VER) - __asm mov eax, FpState; - __asm frstor [eax]; -#else -#error Unknown compiler for inline assembler -#endif - - ExFreePool(FpState); - - return STATUS_SUCCESS; -} diff --git a/reactos/ntoskrnl/ke/i386/gdt.c b/reactos/ntoskrnl/ke/i386/gdt.c deleted file mode 100644 index 256e08ccdc9..00000000000 --- a/reactos/ntoskrnl/ke/i386/gdt.c +++ /dev/null @@ -1,140 +0,0 @@ -/* $Id$ - * - * COPYRIGHT: See COPYING in the top level directory - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/i386/gdt.c - * PURPOSE: GDT managment - * - * PROGRAMMERS: David Welch (welch@cwcom.net) - */ - -/* INCLUDES *****************************************************************/ - -#include -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -KGDTENTRY KiBootGdt[11] = -{ - {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 */ -}; - -KDESCRIPTOR KiGdtDescriptor = {sizeof(KiBootGdt), (ULONG)KiBootGdt}; - -static KSPIN_LOCK GdtLock; - -/* FUNCTIONS *****************************************************************/ - -/* - * @unimplemented - */ -NTSTATUS STDCALL -KeI386FlatToGdtSelector( - IN ULONG Base, - IN USHORT Length, - IN USHORT Selector -) -{ - UNIMPLEMENTED; - return 0; -} - -/* - * @unimplemented - */ -NTSTATUS STDCALL -KeI386ReleaseGdtSelectors( - OUT PULONG SelArray, - IN ULONG NumOfSelectors -) -{ - UNIMPLEMENTED; - return 0; -} - -/* - * @unimplemented - */ -NTSTATUS STDCALL -KeI386AllocateGdtSelectors( - OUT PULONG SelArray, - IN ULONG NumOfSelectors -) -{ - UNIMPLEMENTED; - return 0; -} - -VOID -KeSetBaseGdtSelector(ULONG Entry, - PVOID Base) -{ - KIRQL oldIrql; - PUSHORT Gdt; - - DPRINT("KeSetBaseGdtSelector(Entry %x, Base %x)\n", - Entry, Base); - - KeAcquireSpinLock(&GdtLock, &oldIrql); - - Gdt = KeGetCurrentKPCR()->GDT; - Entry = (Entry & (~0x3)) / 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)); - - DPRINT("%x %x %x %x\n", - Gdt[Entry + 0], - Gdt[Entry + 1], - Gdt[Entry + 2], - Gdt[Entry + 3]); - - KeReleaseSpinLock(&GdtLock, oldIrql); -} - -VOID -KeSetGdtSelector(ULONG Entry, - ULONG Value1, - ULONG Value2) -{ - KIRQL oldIrql; - PULONG Gdt; - - DPRINT("KeSetGdtSelector(Entry %x, Value1 %x, Value2 %x)\n", - Entry, Value1, Value2); - - KeAcquireSpinLock(&GdtLock, &oldIrql); - - Gdt = (PULONG) KeGetCurrentKPCR()->GDT; - Entry = (Entry & (~0x3)) / 4; - - Gdt[Entry] = Value1; - Gdt[Entry + 1] = Value2; - - DPRINT("%x %x\n", - Gdt[Entry + 0], - Gdt[Entry + 1]); - - KeReleaseSpinLock(&GdtLock, oldIrql); -} - -/* EOF */ diff --git a/reactos/ntoskrnl/ke/i386/kernel.c b/reactos/ntoskrnl/ke/i386/kernel.c index 698e52a6952..dd820c83369 100644 --- a/reactos/ntoskrnl/ke/i386/kernel.c +++ b/reactos/ntoskrnl/ke/i386/kernel.c @@ -25,11 +25,8 @@ UCHAR KeProcessNodeSeed; ETHREAD KiInitialThread; EPROCESS KiInitialProcess; -extern LIST_ENTRY KiProcessListHead; extern ULONG Ke386GlobalPagesEnabled; -extern KGDTENTRY KiBootGdt[]; extern PVOID trap_stack, init_stack; -extern KTSS KiBootTss; /* System-defined Spinlocks */ KSPIN_LOCK KiDispatcherLock; @@ -518,9 +515,6 @@ KiSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock) /* Setup the boot (Freeldr should've done), double fault and NMI TSS */ Ki386InitializeTss(); - /* Setup the LDT */ - Ki386InitializeLdt(); - /* Setup CPU-related fields */ Pcr->Number = Cpu; Pcr->SetMember = 1 << Cpu; diff --git a/reactos/ntoskrnl/ke/i386/ldt.c b/reactos/ntoskrnl/ke/i386/ldt.c index e364b68aafb..41d1a216a75 100644 --- a/reactos/ntoskrnl/ke/i386/ldt.c +++ b/reactos/ntoskrnl/ke/i386/ldt.c @@ -17,11 +17,69 @@ /* GLOBALS *******************************************************************/ static KSPIN_LOCK LdtLock; +static KSPIN_LOCK GdtLock; /* FUNCTIONS *****************************************************************/ -/* gdt.c */ -extern VOID KeSetGdtSelector(ULONG Entry, ULONG Value1, ULONG Value2); +VOID +KeSetBaseGdtSelector(ULONG Entry, + PVOID Base) +{ + KIRQL oldIrql; + PUSHORT Gdt; + + DPRINT("KeSetBaseGdtSelector(Entry %x, Base %x)\n", + Entry, Base); + + KeAcquireSpinLock(&GdtLock, &oldIrql); + + Gdt = KeGetCurrentKPCR()->GDT; + Entry = (Entry & (~0x3)) / 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)); + + DPRINT("%x %x %x %x\n", + Gdt[Entry + 0], + Gdt[Entry + 1], + Gdt[Entry + 2], + Gdt[Entry + 3]); + + KeReleaseSpinLock(&GdtLock, oldIrql); +} + +VOID +KeSetGdtSelector(ULONG Entry, + ULONG Value1, + ULONG Value2) +{ + KIRQL oldIrql; + PULONG Gdt; + + DPRINT("KeSetGdtSelector(Entry %x, Value1 %x, Value2 %x)\n", + Entry, Value1, Value2); + + KeAcquireSpinLock(&GdtLock, &oldIrql); + + Gdt = (PULONG) KeGetCurrentKPCR()->GDT; + Entry = (Entry & (~0x3)) / 4; + + Gdt[Entry] = Value1; + Gdt[Entry + 1] = Value2; + + DPRINT("%x %x\n", + Gdt[Entry + 0], + Gdt[Entry + 1]); + + KeReleaseSpinLock(&GdtLock, oldIrql); +} BOOL PspIsDescriptorValid(PLDT_ENTRY ldt_entry) { @@ -172,20 +230,3 @@ NtSetLdtEntries (ULONG Selector1, return STATUS_SUCCESS; } -VOID -Ki386InitializeLdt(VOID) -{ - PUSHORT Gdt = KeGetCurrentKPCR()->GDT; - unsigned int base, length; - - /* - * Set up an a descriptor for the LDT - */ - base = length = 0; - - Gdt[(KGDT_LDT / 2) + 0] = (length & 0xFFFF); - Gdt[(KGDT_LDT / 2) + 1] = (base & 0xFFFF); - Gdt[(KGDT_LDT / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8200; - Gdt[(KGDT_LDT / 2) + 3] = ((length & 0xF0000) >> 16) | - ((base & 0xFF000000) >> 16); -} diff --git a/reactos/ntoskrnl/ntoskrnl.rbuild b/reactos/ntoskrnl/ntoskrnl.rbuild index 62be719c82f..49739cddab9 100644 --- a/reactos/ntoskrnl/ntoskrnl.rbuild +++ b/reactos/ntoskrnl/ntoskrnl.rbuild @@ -27,12 +27,11 @@ main_asm.S + abios.c cpu.c ctxswitch.S clock.S exp.c - fpu.c - gdt.c kernel.c ldt.c