From 020a7e0b2d2e3bbeef1f04cf25c011ac56c73f80 Mon Sep 17 00:00:00 2001 From: Alex Ionescu Date: Sun, 17 Oct 2004 05:20:29 +0000 Subject: [PATCH] Fixed definition of KPCR_TIB to match W32API/NT5 defintion. Fixed bug in Makefile (fixed by Filip) svn path=/trunk/; revision=11307 --- reactos/ntoskrnl/Makefile | 5 - reactos/ntoskrnl/include/internal/i386/ps.h | 567 ++++++++-------- reactos/ntoskrnl/ke/i386/kernel.c | 687 ++++++++++---------- 3 files changed, 628 insertions(+), 631 deletions(-) diff --git a/reactos/ntoskrnl/Makefile b/reactos/ntoskrnl/Makefile index 73f499e1474..113a7a6c726 100644 --- a/reactos/ntoskrnl/Makefile +++ b/reactos/ntoskrnl/Makefile @@ -36,13 +36,8 @@ else OBJECTS_KDBG := endif -ifeq ($(strip $(SDK_PATH_INC)),) TARGET_ASFLAGS = -I./include TARGET_CFLAGS = -I./include $(CFLAGS_KDBG) -Wall -Werror $(CFLAGS_OPT) -else -TARGET_ASFLAGS = -I./include -I$(SDK_PATH_INC) -TARGET_CFLAGS = -I./include -I$(SDK_PATH_INC) -D__NTOSKRNL__ $(CFLAGS_KDBG) -Wall -Werror $(CFLAGS_OPT) -endif # require os code to explicitly request A/W version of structs/functions TARGET_CFLAGS += -D_DISABLE_TIDENTS diff --git a/reactos/ntoskrnl/include/internal/i386/ps.h b/reactos/ntoskrnl/include/internal/i386/ps.h index 2c4979ca98b..d9af2b45321 100644 --- a/reactos/ntoskrnl/include/internal/i386/ps.h +++ b/reactos/ntoskrnl/include/internal/i386/ps.h @@ -1,283 +1,284 @@ -/* - * ReactOS kernel - * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -#ifndef __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H -#define __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H - -/* - * Defines for accessing KPCR and KTHREAD structure members - */ -#define KTHREAD_INITIAL_STACK 0x18 -#define KTHREAD_STACK_LIMIT 0x1C -#define KTHREAD_TEB 0x20 -#define KTHREAD_KERNEL_STACK 0x28 -#define KTHREAD_APCSTATE_PROCESS 0x44 -#define KTHREAD_SERVICE_TABLE 0xDC -#define KTHREAD_PREVIOUS_MODE 0x137 -#define KTHREAD_TRAP_FRAME 0x128 -#define KTHREAD_CALLBACK_STACK 0x120 - - -#define KPROCESS_DIRECTORY_TABLE_BASE 0x18 -#define KPROCESS_LDT_DESCRIPTOR0 0x20 -#define KPROCESS_LDT_DESCRIPTOR1 0x24 -#define KPROCESS_IOPM_OFFSET 0x30 - -#define KPCR_BASE 0xFF000000 - -#define KPCR_EXCEPTION_LIST 0x0 -#define KPCR_SELF 0x18 -#define KPCR_TSS 0x3C -#define KPCR_CURRENT_THREAD 0x124 - -#ifndef __ASM__ - -#include "fpu.h" - -#pragma pack(push,4) - -// Fixme: Use correct types? -typedef struct _KPROCESSOR_STATE { - PCONTEXT ContextFrame; - PVOID SpecialRegisters; -} KPROCESSOR_STATE; - -/* ProcessoR Control Block */ -typedef struct _KPRCB { - USHORT MinorVersion; - USHORT MajorVersion; - struct _KTHREAD *CurrentThread; - struct _KTHREAD *NextThread; - struct _KTHREAD *IdleThread; - UCHAR Number; - UCHAR Reserved; - USHORT BuildType; - ULONG SetMember; - UCHAR CpuType; - UCHAR CpuID; - USHORT CpuStep; - KPROCESSOR_STATE ProcessorState; - ULONG KernelReserved[16]; - ULONG HalReserved[16]; - UCHAR PrcbPad0[92]; - PVOID LockQueue[33]; // Used for Queued Spinlocks - struct _KTHREAD *NpxThread; - ULONG InterruptCount; - ULONG KernelTime; - ULONG UserTime; - ULONG DpcTime; - ULONG DebugDpcTime; - ULONG InterruptTime; - ULONG AdjustDpcThreshold; - ULONG PageColor; - UCHAR SkipTick; - UCHAR DebuggerSavedIRQL; - UCHAR Spare1[6]; - struct _KNODE *ParentNode; - ULONG MultiThreadProcessorSet; - struct _KPRCB *MultiThreadSetMaster; - ULONG ThreadStartCount[2]; - ULONG CcFastReadNoWait; - ULONG CcFastReadWait; - ULONG CcFastReadNotPossible; - ULONG CcCopyReadNoWait; - ULONG CcCopyReadWait; - ULONG CcCopyReadNoWaitMiss; - ULONG KeAlignmentFixupCount; - ULONG SpareCounter0; - ULONG KeDcacheFlushCount; - ULONG KeExceptionDispatchCount; - ULONG KeFirstLevelTbFills; - ULONG KeFloatingEmulationCount; - ULONG KeIcacheFlushCount; - ULONG KeSecondLevelTbFills; - ULONG KeSystemCalls; - ULONG IoReadOperationCount; - ULONG IoWriteOperationCount; - ULONG IoOtherOperationCount; - LARGE_INTEGER IoReadTransferCount; - LARGE_INTEGER IoWriteTransferCount; - LARGE_INTEGER IoOtherTransferCount; - ULONG SpareCounter1[8]; - PP_LOOKASIDE_LIST PPLookasideList[16]; - PP_LOOKASIDE_LIST PPNPagedLookasideList[32]; - PP_LOOKASIDE_LIST PPPagedLookasideList[32]; - ULONG PacketBarrier; - ULONG ReverseStall; - PVOID IpiFrame; - UCHAR PrcbPad2[52]; - PVOID CurrentPacket[3]; - ULONG TargetSet; - ULONG_PTR WorkerRoutine; - ULONG IpiFrozen; - UCHAR PrcbPad3[40]; - ULONG RequestSummary; - struct _KPRCB *SignalDone; - UCHAR PrcbPad4[56]; - struct _KDPC_DATA DpcData[2]; - PVOID DpcStack; - ULONG MaximumDpcQueueDepth; - ULONG DpcRequestRate; - ULONG MinimumDpcRate; - UCHAR DpcInterruptRequested; - UCHAR DpcThreadRequested; - UCHAR DpcRoutineActive; - UCHAR DpcThreadActive; - ULONG PrcbLock; - ULONG DpcLastCount; - ULONG TimerHand; - ULONG TimerRequest; - PVOID DpcThread; - struct _KEVENT *DpcEvent; - UCHAR ThreadDpcEnable; - UCHAR QuantumEnd; - UCHAR PrcbPad50; - UCHAR IdleSchedule; - ULONG DpcSetEventRequest; - UCHAR PrcbPad5[18]; - LONG TickOffset; - struct _KDPC* CallDpc; - ULONG PrcbPad7[8]; - LIST_ENTRY WaitListHead; - ULONG ReadySummary; - ULONG SelectNextLast; - LIST_ENTRY DispatcherReadyListHead[32]; - SINGLE_LIST_ENTRY DeferredReadyListHead; - ULONG PrcbPad72[11]; - PVOID ChainedInterruptList; - LONG LookasideIrpFloat; - LONG MmPageFaultCount; - LONG MmCopyOnWriteCount; - LONG MmTransitionCount; - LONG MmCacheTransitionCount; - LONG MmDemandZeroCount; - LONG MmPageReadCount; - LONG MmPageReadIoCount; - LONG MmCacheReadCount; - LONG MmCacheIoCount; - LONG MmDirtyPagesWriteCount; - LONG MmDirtyWriteIoCount; - LONG MmMappedPagesWriteCount; - LONG MmMappedWriteIoCount; - ULONG SpareFields0[1]; - UCHAR VendorString[13]; - UCHAR InitialApicId; - UCHAR LogicalProcessorsPerPhysicalProcessor; - ULONG MHz; - ULONG FeatureBits; - LARGE_INTEGER UpdateSignature; - LARGE_INTEGER IsrTime; - LARGE_INTEGER SpareField1; - FX_SAVE_AREA NpxSaveArea; - PROCESSOR_POWER_STATE PowerState; -} KPRCB, *PKRCB; - -#pragma pack(pop) - -#ifndef __USE_W32API - -#pragma pack(push,4) -/* - * Processor Control Region Thread Information Block - */ -typedef struct _KPCR_TIB { - PVOID ExceptionList; /* 00 */ - PVOID StackBase; /* 04 */ - PVOID StackLimit; /* 08 */ - PVOID SubSystemTib; /* 0C */ - union { - PVOID FiberData; /* 10 */ - DWORD Version; /* 10 */ - }; - PVOID ArbitraryUserPointer; /* 14 */ -} KPCR_TIB, *PKPCR_TIB; /* 18 */ - -/* - * Processor Control Region - */ -typedef struct _KPCR { - KPCR_TIB Tib; /* 00 */ - struct _KPCR *Self; /* 18 */ - struct _KPRCB *PCRCB; /* 1C */ - KIRQL Irql; /* 20 */ - ULONG IRR; /* 24 */ - ULONG IrrActive; /* 28 */ - ULONG IDR; /* 2C */ - PVOID KdVersionBlock; /* 30 */ - PUSHORT IDT; /* 34 */ - PUSHORT GDT; /* 38 */ - struct _KTSS *TSS; /* 3C */ - USHORT MajorVersion; /* 40 */ - USHORT MinorVersion; /* 42 */ - KAFFINITY SetMember; /* 44 */ - ULONG StallScaleFactor; /* 48 */ - UCHAR DebugActive; /* 4C */ - UCHAR ProcessorNumber; /* 4D */ - UCHAR Reserved; /* 4E */ - UCHAR L2CacheAssociativity; /* 4F */ - ULONG VdmAlert; /* 50 */ - ULONG KernelReserved[14]; /* 54 */ - ULONG L2CacheSize; /* 8C */ - ULONG HalReserved[16]; /* 90 */ - ULONG InterruptMode; /* D0 */ - UCHAR KernelReserved2[0x4C]; /* D4 */ - KPRCB PrcbData; /* 120 */ -} KPCR, *PKPCR; - -#pragma pack(pop) -#endif /* __USE_W32API */ - - -#ifndef __USE_W32API - -static inline PKPCR KeGetCurrentKPCR(VOID) -{ - ULONG value; - -#if defined(__GNUC__) - __asm__ __volatile__ ("movl %%fs:0x18, %0\n\t" - : "=r" (value) - : /* no inputs */ - ); -#elif defined(_MSC_VER) - __asm mov eax, fs:0x18; - __asm mov value, eax; -#else -#error Unknown compiler for inline assembler -#endif - return((PKPCR)value); -} - -#endif /* __USE_W32API */ - -VOID -Ki386ContextSwitch(struct _KTHREAD* NewThread, - struct _KTHREAD* OldThread); -NTSTATUS -Ke386InitThread(struct _KTHREAD* Thread, PKSTART_ROUTINE fn, - PVOID StartContext); -NTSTATUS -Ke386InitThreadWithContext(struct _KTHREAD* Thread, PCONTEXT Context); -NTSTATUS -Ki386ValidateUserContext(PCONTEXT Context); - -#endif /* __ASM__ */ - -#endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H */ - -/* EOF */ +/* + * ReactOS kernel + * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +#ifndef __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H +#define __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H + +/* + * Defines for accessing KPCR and KTHREAD structure members + */ +#define KTHREAD_INITIAL_STACK 0x18 +#define KTHREAD_STACK_LIMIT 0x1C +#define KTHREAD_TEB 0x20 +#define KTHREAD_KERNEL_STACK 0x28 +#define KTHREAD_APCSTATE_PROCESS 0x44 +#define KTHREAD_SERVICE_TABLE 0xDC +#define KTHREAD_PREVIOUS_MODE 0x137 +#define KTHREAD_TRAP_FRAME 0x128 +#define KTHREAD_CALLBACK_STACK 0x120 + + +#define KPROCESS_DIRECTORY_TABLE_BASE 0x18 +#define KPROCESS_LDT_DESCRIPTOR0 0x20 +#define KPROCESS_LDT_DESCRIPTOR1 0x24 +#define KPROCESS_IOPM_OFFSET 0x30 + +#define KPCR_BASE 0xFF000000 + +#define KPCR_EXCEPTION_LIST 0x0 +#define KPCR_SELF 0x18 +#define KPCR_TSS 0x40 +#define KPCR_CURRENT_THREAD 0x124 + +#ifndef __ASM__ + +#include "fpu.h" + +#pragma pack(push,4) + +// Fixme: Use correct types? +typedef struct _KPROCESSOR_STATE { + PCONTEXT ContextFrame; + PVOID SpecialRegisters; +} KPROCESSOR_STATE; + +/* ProcessoR Control Block */ +typedef struct _KPRCB { + USHORT MinorVersion; + USHORT MajorVersion; + struct _KTHREAD *CurrentThread; + struct _KTHREAD *NextThread; + struct _KTHREAD *IdleThread; + UCHAR Number; + UCHAR Reserved; + USHORT BuildType; + ULONG SetMember; + UCHAR CpuType; + UCHAR CpuID; + USHORT CpuStep; + KPROCESSOR_STATE ProcessorState; + ULONG KernelReserved[16]; + ULONG HalReserved[16]; + UCHAR PrcbPad0[92]; + PVOID LockQueue[33]; // Used for Queued Spinlocks + struct _KTHREAD *NpxThread; + ULONG InterruptCount; + ULONG KernelTime; + ULONG UserTime; + ULONG DpcTime; + ULONG DebugDpcTime; + ULONG InterruptTime; + ULONG AdjustDpcThreshold; + ULONG PageColor; + UCHAR SkipTick; + UCHAR DebuggerSavedIRQL; + UCHAR Spare1[6]; + struct _KNODE *ParentNode; + ULONG MultiThreadProcessorSet; + struct _KPRCB *MultiThreadSetMaster; + ULONG ThreadStartCount[2]; + ULONG CcFastReadNoWait; + ULONG CcFastReadWait; + ULONG CcFastReadNotPossible; + ULONG CcCopyReadNoWait; + ULONG CcCopyReadWait; + ULONG CcCopyReadNoWaitMiss; + ULONG KeAlignmentFixupCount; + ULONG SpareCounter0; + ULONG KeDcacheFlushCount; + ULONG KeExceptionDispatchCount; + ULONG KeFirstLevelTbFills; + ULONG KeFloatingEmulationCount; + ULONG KeIcacheFlushCount; + ULONG KeSecondLevelTbFills; + ULONG KeSystemCalls; + ULONG IoReadOperationCount; + ULONG IoWriteOperationCount; + ULONG IoOtherOperationCount; + LARGE_INTEGER IoReadTransferCount; + LARGE_INTEGER IoWriteTransferCount; + LARGE_INTEGER IoOtherTransferCount; + ULONG SpareCounter1[8]; + PP_LOOKASIDE_LIST PPLookasideList[16]; + PP_LOOKASIDE_LIST PPNPagedLookasideList[32]; + PP_LOOKASIDE_LIST PPPagedLookasideList[32]; + ULONG PacketBarrier; + ULONG ReverseStall; + PVOID IpiFrame; + UCHAR PrcbPad2[52]; + PVOID CurrentPacket[3]; + ULONG TargetSet; + ULONG_PTR WorkerRoutine; + ULONG IpiFrozen; + UCHAR PrcbPad3[40]; + ULONG RequestSummary; + struct _KPRCB *SignalDone; + UCHAR PrcbPad4[56]; + struct _KDPC_DATA DpcData[2]; + PVOID DpcStack; + ULONG MaximumDpcQueueDepth; + ULONG DpcRequestRate; + ULONG MinimumDpcRate; + UCHAR DpcInterruptRequested; + UCHAR DpcThreadRequested; + UCHAR DpcRoutineActive; + UCHAR DpcThreadActive; + ULONG PrcbLock; + ULONG DpcLastCount; + ULONG TimerHand; + ULONG TimerRequest; + PVOID DpcThread; + struct _KEVENT *DpcEvent; + UCHAR ThreadDpcEnable; + UCHAR QuantumEnd; + UCHAR PrcbPad50; + UCHAR IdleSchedule; + ULONG DpcSetEventRequest; + UCHAR PrcbPad5[18]; + LONG TickOffset; + struct _KDPC* CallDpc; + ULONG PrcbPad7[8]; + LIST_ENTRY WaitListHead; + ULONG ReadySummary; + ULONG SelectNextLast; + LIST_ENTRY DispatcherReadyListHead[32]; + SINGLE_LIST_ENTRY DeferredReadyListHead; + ULONG PrcbPad72[11]; + PVOID ChainedInterruptList; + LONG LookasideIrpFloat; + LONG MmPageFaultCount; + LONG MmCopyOnWriteCount; + LONG MmTransitionCount; + LONG MmCacheTransitionCount; + LONG MmDemandZeroCount; + LONG MmPageReadCount; + LONG MmPageReadIoCount; + LONG MmCacheReadCount; + LONG MmCacheIoCount; + LONG MmDirtyPagesWriteCount; + LONG MmDirtyWriteIoCount; + LONG MmMappedPagesWriteCount; + LONG MmMappedWriteIoCount; + ULONG SpareFields0[1]; + UCHAR VendorString[13]; + UCHAR InitialApicId; + UCHAR LogicalProcessorsPerPhysicalProcessor; + ULONG MHz; + ULONG FeatureBits; + LARGE_INTEGER UpdateSignature; + LARGE_INTEGER IsrTime; + LARGE_INTEGER SpareField1; + FX_SAVE_AREA NpxSaveArea; + PROCESSOR_POWER_STATE PowerState; +} KPRCB, *PKRCB; + +#pragma pack(pop) + +#ifndef __USE_W32API + +#pragma pack(push,4) +/* + * Processor Control Region Thread Information Block + */ +typedef struct _KPCR_TIB { + PVOID ExceptionList; /* 00 */ + PVOID StackBase; /* 04 */ + PVOID StackLimit; /* 08 */ + PVOID SubSystemTib; /* 0C */ + union { + PVOID FiberData; /* 10 */ + DWORD Version; /* 10 */ + }; + PVOID ArbitraryUserPointer; /* 14 */ + struct _KPCR_TIB* Self; /* 18 */ +} KPCR_TIB, *PKPCR_TIB; /* 18 */ + +/* + * Processor Control Region + */ +typedef struct _KPCR { + KPCR_TIB Tib; /* 00 */ + struct _KPCR *Self; /* 18 */ + struct _KPRCB *PCRCB; /* 1C */ + KIRQL Irql; /* 20 */ + ULONG IRR; /* 24 */ + ULONG IrrActive; /* 28 */ + ULONG IDR; /* 2C */ + PVOID KdVersionBlock; /* 30 */ + PUSHORT IDT; /* 34 */ + PUSHORT GDT; /* 38 */ + struct _KTSS *TSS; /* 3C */ + USHORT MajorVersion; /* 40 */ + USHORT MinorVersion; /* 42 */ + KAFFINITY SetMember; /* 44 */ + ULONG StallScaleFactor; /* 48 */ + UCHAR DebugActive; /* 4C */ + UCHAR ProcessorNumber; /* 4D */ + UCHAR Reserved; /* 4E */ + UCHAR L2CacheAssociativity; /* 4F */ + ULONG VdmAlert; /* 50 */ + ULONG KernelReserved[14]; /* 54 */ + ULONG L2CacheSize; /* 8C */ + ULONG HalReserved[16]; /* 90 */ + ULONG InterruptMode; /* D0 */ + UCHAR KernelReserved2[0x48]; /* D4 */ + KPRCB PrcbData; /* 120 */ +} KPCR, *PKPCR; + +#pragma pack(pop) +#endif /* __USE_W32API */ + + +#ifndef __USE_W32API + +static inline PKPCR KeGetCurrentKPCR(VOID) +{ + ULONG value; + +#if defined(__GNUC__) + __asm__ __volatile__ ("movl %%fs:0x18, %0\n\t" + : "=r" (value) + : /* no inputs */ + ); +#elif defined(_MSC_VER) + __asm mov eax, fs:0x18; + __asm mov value, eax; +#else +#error Unknown compiler for inline assembler +#endif + return((PKPCR)value); +} + +#endif /* __USE_W32API */ + +VOID +Ki386ContextSwitch(struct _KTHREAD* NewThread, + struct _KTHREAD* OldThread); +NTSTATUS +Ke386InitThread(struct _KTHREAD* Thread, PKSTART_ROUTINE fn, + PVOID StartContext); +NTSTATUS +Ke386InitThreadWithContext(struct _KTHREAD* Thread, PCONTEXT Context); +NTSTATUS +Ki386ValidateUserContext(PCONTEXT Context); + +#endif /* __ASM__ */ + +#endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H */ + +/* EOF */ diff --git a/reactos/ntoskrnl/ke/i386/kernel.c b/reactos/ntoskrnl/ke/i386/kernel.c index e104bea853d..f004c0e01c9 100644 --- a/reactos/ntoskrnl/ke/i386/kernel.c +++ b/reactos/ntoskrnl/ke/i386/kernel.c @@ -1,343 +1,344 @@ -/* - * ReactOS kernel - * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ -/* - * PROJECT: ReactOS kernel - * FILE: ntoskrnl/ke/i386/kernel.c - * PURPOSE: Initializes the kernel - * PROGRAMMER: David Welch (welch@mcmail.com) - * UPDATE HISTORY: - * Created 22/05/98 - */ - -/* INCLUDES *****************************************************************/ - -#include -#define NDEBUG -#include - -/* GLOBALS *******************************************************************/ - -ULONG KiPcrInitDone = 0; -static ULONG PcrsAllocated = 0; -static PFN_TYPE PcrPages[MAXIMUM_PROCESSORS]; -ULONG Ke386CpuidFlags, Ke386CpuidFlags2, Ke386CpuidExFlags; -ULONG Ke386Cpuid = 0x300; -ULONG Ke386CacheAlignment; -CHAR Ke386CpuidVendor[13] = {0,}; -CHAR Ke386CpuidModel[49] = {0,}; -ULONG Ke386L1CacheSize; -ULONG Ke386L2CacheSize; -BOOLEAN Ke386NoExecute = FALSE; -BOOLEAN Ke386Pae = FALSE; - -/* FUNCTIONS *****************************************************************/ - -VOID INIT_FUNCTION STATIC -Ki386GetCpuId(VOID) -{ - ULONG OrigFlags, Flags, FinalFlags; - ULONG MaxCpuidLevel; - ULONG Dummy, Ebx, Ecx, Edx; - - Ke386CpuidFlags = Ke386CpuidFlags2 = Ke386CpuidExFlags = 0; - Ke386CacheAlignment = 32; - - /* Try to toggle the id bit in eflags. */ - __asm__ ("pushfl\n\t" - "popl %0\n\t" - : "=r" (OrigFlags)); - Flags = OrigFlags ^ X86_EFLAGS_ID; - __asm__ ("pushl %1\n\t" - "popfl\n\t" - "pushfl\n\t" - "popl %0\n\t" - : "=r" (FinalFlags) - : "r" (Flags)); - if ((OrigFlags & X86_EFLAGS_ID) == (FinalFlags & X86_EFLAGS_ID)) - { - /* No cpuid supported. */ - return; - } - - /* Get the vendor name and the maximum cpuid level supported. */ - Ki386Cpuid(0, &MaxCpuidLevel, (PULONG)&Ke386CpuidVendor[0], (PULONG)&Ke386CpuidVendor[8], (PULONG)&Ke386CpuidVendor[4]); - if (MaxCpuidLevel > 0) - { - /* Get the feature flags. */ - Ki386Cpuid(1, &Ke386Cpuid, &Ebx, &Ke386CpuidFlags2, &Ke386CpuidFlags); - /* Get the cache alignment, if it is available */ - if (Ke386CpuidFlags & (1<<19)) - { - Ke386CacheAlignment = ((Ebx >> 8) & 0xff) * 8; - } - } - - /* Get the maximum extended cpuid level supported. */ - Ki386Cpuid(0x80000000, &MaxCpuidLevel, &Dummy, &Dummy, &Dummy); - if (MaxCpuidLevel > 0) - { - /* Get the extended feature flags. */ - Ki386Cpuid(0x80000001, &Dummy, &Dummy, &Dummy, &Ke386CpuidExFlags); - } - - /* Get the model name. */ - if (MaxCpuidLevel >= 0x80000004) - { - PULONG v = (PULONG)&Ke386CpuidModel; - Ki386Cpuid(0x80000002, v, v + 1, v + 2, v + 3); - Ki386Cpuid(0x80000003, v + 4, v + 5, v + 6, v + 7); - Ki386Cpuid(0x80000004, v + 8, v + 9, v + 10, v + 11); - } - - /* Get the L1 cache size */ - if (MaxCpuidLevel >= 0x80000005) - { - Ki386Cpuid(0x80000005, &Dummy, &Dummy, &Ecx, &Edx); - Ke386L1CacheSize = (Ecx >> 24)+(Edx >> 24); - if ((Ecx & 0xff) > 0) - { - Ke386CacheAlignment = Ecx & 0xff; - } - } - - /* Get the L2 cache size */ - if (MaxCpuidLevel >= 0x80000006) - { - Ki386Cpuid(0x80000006, &Dummy, &Dummy, &Ecx, &Dummy); - Ke386L2CacheSize = Ecx >> 16; - } -} - -VOID INIT_FUNCTION -KePrepareForApplicationProcessorInit(ULONG Id) -{ - MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &PcrPages[Id]); - KiGdtPrepareForApplicationProcessorInit(Id); -} - -VOID -KeApplicationProcessorInit(VOID) -{ - PKPCR Pcr; - ULONG Offset; - - /* - * Create a PCR for this processor - */ - Offset = InterlockedIncrement((LONG *)&PcrsAllocated) - 1; - Pcr = (PKPCR)(KPCR_BASE + (Offset * PAGE_SIZE)); - MmCreateVirtualMappingForKernel((PVOID)Pcr, - PAGE_READWRITE, - &PcrPages[Offset], - 1); - memset(Pcr, 0, PAGE_SIZE); - Pcr->ProcessorNumber = (UCHAR)Offset; - Pcr->Self = Pcr; - Pcr->Irql = HIGH_LEVEL; - - /* Mark the end of the exception handler list */ - Pcr->Tib.ExceptionList = (PVOID)-1; - - /* - * Initialize the GDT - */ - KiInitializeGdt(Pcr); - - /* - * It is now safe to process interrupts - */ - KeLowerIrql(DISPATCH_LEVEL); - - /* - * Initialize the TSS - */ - Ki386ApplicationProcessorInitializeTSS(); - - /* - * Initialize a default LDT - */ - Ki386InitializeLdt(); - - if (Ke386CpuidFlags & X86_FEATURE_PGE) - { - /* Enable global pages */ - Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE); - } - - /* Enable PAE mode */ - if (Ke386CpuidFlags & X86_FEATURE_PAE) - { - MiEnablePAE(NULL); - } - - /* Now we can enable interrupts. */ - Ke386EnableInterrupts(); -} - -VOID INIT_FUNCTION -KeInit1(PCHAR CommandLine, PULONG LastKernelAddress) -{ - PKPCR KPCR; - BOOLEAN Pae = FALSE; - BOOLEAN NoExecute = FALSE; - PCHAR p1, p2; - extern USHORT KiBootGdt[]; - extern KTSS KiBootTss; - - KiCheckFPU(); - - KiInitializeGdt (NULL); - Ki386BootInitializeTSS(); - KeInitExceptions (); - KeInitInterrupts (); - - /* - * Initialize the initial PCR region. We can't allocate a page - * with MmAllocPage() here because MmInit1() has not yet been - * called, so we use a predefined page in low memory - */ - KPCR = (PKPCR)KPCR_BASE; - memset(KPCR, 0, PAGE_SIZE); - KPCR->Self = (PKPCR)KPCR_BASE; - KPCR->Irql = HIGH_LEVEL; - KPCR->GDT = KiBootGdt; - KPCR->IDT = (PUSHORT)KiIdt; - KPCR->TSS = &KiBootTss; - KPCR->ProcessorNumber = 0; - KiPcrInitDone = 1; - PcrsAllocated++; - - /* Mark the end of the exception handler list */ - KPCR->Tib.ExceptionList = (PVOID)-1; - - Ki386InitializeLdt(); - - /* Get processor information. */ - Ki386GetCpuId(); - - if (Ke386CpuidFlags & X86_FEATURE_PGE) - { - ULONG Flags; - /* Enable global pages */ - Ke386SaveFlags(Flags); - Ke386DisableInterrupts(); - Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE); - Ke386RestoreFlags(Flags); - } - - /* Search for pae and noexecute */ - p1 = (PCHAR)KeLoaderBlock.CommandLine; - while(*p1 && (p2 = strchr(p1, '/'))) - { - p2++; - if (!_strnicmp(p2, "PAE", 3)) - { - if (p2[3] == ' ' || p2[3] == 0) - { - p2 += 3; - Pae = TRUE; - } - } - else if (!_strnicmp(p2, "NOEXECUTE", 9)) - { - if (p2[9] == ' ' || p2[9] == '=' || p2[9] == 0) - { - p2 += 9; - NoExecute = TRUE; - } - } - p1 = p2; - } - - /* - * FIXME: - * Make the detection of the noexecute feature more portable. - */ - if(((Ke386Cpuid >> 8) & 0xf) == 0xf && - 0 == strcmp("AuthenticAMD", Ke386CpuidVendor)) - { - if (NoExecute) - { - ULONG Flags, l, h; - Ke386SaveFlags(Flags); - Ke386DisableInterrupts(); - - Ke386Rdmsr(0xc0000080, l, h); - l |= (1 << 11); - Ke386Wrmsr(0xc0000080, l, h); - Ke386NoExecute = TRUE; - Ke386RestoreFlags(Flags); - } - } - else - { - NoExecute=FALSE; - } - - - /* Enable PAE mode */ - if ((Pae && (Ke386CpuidFlags & X86_FEATURE_PAE)) || NoExecute) - { - MiEnablePAE((PVOID*)LastKernelAddress); - } -} - -VOID INIT_FUNCTION -KeInit2(VOID) -{ - KeInitDpc(); - KeInitializeBugCheck(); - KeInitializeDispatcher(); - KeInitializeTimerImpl(); - - if (Ke386CpuidFlags & X86_FEATURE_PAE) - { - DPRINT1("CPU supports PAE mode\n"); - if (Ke386Pae) - { - DPRINT1("CPU runs in PAE mode\n"); - if (Ke386NoExecute) - { - DPRINT1("NoExecute is enabled\n"); - } - } - else - { - DPRINT1("CPU doesn't run in PAE mode\n"); - } - } - if (Ke386CpuidVendor[0]) - { - DPRINT1("CPU Vendor: %s\n", Ke386CpuidVendor); - } - if (Ke386CpuidModel[0]) - { - DPRINT1("CPU Model: %s\n", Ke386CpuidModel); - } - - DPRINT1("Ke386CacheAlignment: %d\n", Ke386CacheAlignment); - if (Ke386L1CacheSize) - { - DPRINT1("Ke386L1CacheSize: %dkB\n", Ke386L1CacheSize); - } - if (Ke386L2CacheSize) - { - DPRINT1("Ke386L2CacheSize: %dkB\n", Ke386L2CacheSize); - } -} +/* + * ReactOS kernel + * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* + * PROJECT: ReactOS kernel + * FILE: ntoskrnl/ke/i386/kernel.c + * PURPOSE: Initializes the kernel + * PROGRAMMER: David Welch (welch@mcmail.com) + * UPDATE HISTORY: + * Created 22/05/98 + */ + +/* INCLUDES *****************************************************************/ + +#include +#define NDEBUG +#include + +/* GLOBALS *******************************************************************/ + +ULONG KiPcrInitDone = 0; +static ULONG PcrsAllocated = 0; +static PFN_TYPE PcrPages[MAXIMUM_PROCESSORS]; +ULONG Ke386CpuidFlags, Ke386CpuidFlags2, Ke386CpuidExFlags; +ULONG Ke386Cpuid = 0x300; +ULONG Ke386CacheAlignment; +CHAR Ke386CpuidVendor[13] = {0,}; +CHAR Ke386CpuidModel[49] = {0,}; +ULONG Ke386L1CacheSize; +ULONG Ke386L2CacheSize; +BOOLEAN Ke386NoExecute = FALSE; +BOOLEAN Ke386Pae = FALSE; + +/* FUNCTIONS *****************************************************************/ + +VOID INIT_FUNCTION STATIC +Ki386GetCpuId(VOID) +{ + ULONG OrigFlags, Flags, FinalFlags; + ULONG MaxCpuidLevel; + ULONG Dummy, Ebx, Ecx, Edx; + + Ke386CpuidFlags = Ke386CpuidFlags2 = Ke386CpuidExFlags = 0; + Ke386CacheAlignment = 32; + + /* Try to toggle the id bit in eflags. */ + __asm__ ("pushfl\n\t" + "popl %0\n\t" + : "=r" (OrigFlags)); + Flags = OrigFlags ^ X86_EFLAGS_ID; + __asm__ ("pushl %1\n\t" + "popfl\n\t" + "pushfl\n\t" + "popl %0\n\t" + : "=r" (FinalFlags) + : "r" (Flags)); + if ((OrigFlags & X86_EFLAGS_ID) == (FinalFlags & X86_EFLAGS_ID)) + { + /* No cpuid supported. */ + return; + } + + /* Get the vendor name and the maximum cpuid level supported. */ + Ki386Cpuid(0, &MaxCpuidLevel, (PULONG)&Ke386CpuidVendor[0], (PULONG)&Ke386CpuidVendor[8], (PULONG)&Ke386CpuidVendor[4]); + if (MaxCpuidLevel > 0) + { + /* Get the feature flags. */ + Ki386Cpuid(1, &Ke386Cpuid, &Ebx, &Ke386CpuidFlags2, &Ke386CpuidFlags); + /* Get the cache alignment, if it is available */ + if (Ke386CpuidFlags & (1<<19)) + { + Ke386CacheAlignment = ((Ebx >> 8) & 0xff) * 8; + } + } + + /* Get the maximum extended cpuid level supported. */ + Ki386Cpuid(0x80000000, &MaxCpuidLevel, &Dummy, &Dummy, &Dummy); + if (MaxCpuidLevel > 0) + { + /* Get the extended feature flags. */ + Ki386Cpuid(0x80000001, &Dummy, &Dummy, &Dummy, &Ke386CpuidExFlags); + } + + /* Get the model name. */ + if (MaxCpuidLevel >= 0x80000004) + { + PULONG v = (PULONG)&Ke386CpuidModel; + Ki386Cpuid(0x80000002, v, v + 1, v + 2, v + 3); + Ki386Cpuid(0x80000003, v + 4, v + 5, v + 6, v + 7); + Ki386Cpuid(0x80000004, v + 8, v + 9, v + 10, v + 11); + } + + /* Get the L1 cache size */ + if (MaxCpuidLevel >= 0x80000005) + { + Ki386Cpuid(0x80000005, &Dummy, &Dummy, &Ecx, &Edx); + Ke386L1CacheSize = (Ecx >> 24)+(Edx >> 24); + if ((Ecx & 0xff) > 0) + { + Ke386CacheAlignment = Ecx & 0xff; + } + } + + /* Get the L2 cache size */ + if (MaxCpuidLevel >= 0x80000006) + { + Ki386Cpuid(0x80000006, &Dummy, &Dummy, &Ecx, &Dummy); + Ke386L2CacheSize = Ecx >> 16; + } +} + +VOID INIT_FUNCTION +KePrepareForApplicationProcessorInit(ULONG Id) +{ + MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &PcrPages[Id]); + KiGdtPrepareForApplicationProcessorInit(Id); +} + +VOID +KeApplicationProcessorInit(VOID) +{ + PKPCR KPCR; + ULONG Offset; + + /* + * Create a PCR for this processor + */ + Offset = InterlockedIncrement((LONG *)&PcrsAllocated) - 1; + KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGE_SIZE)); + MmCreateVirtualMappingForKernel((PVOID)KPCR, + PAGE_READWRITE, + &PcrPages[Offset], + 1); + memset(KPCR, 0, PAGE_SIZE); + KPCR->ProcessorNumber = (UCHAR)Offset; + KPCR->Tib.Self = &KPCR->Tib; + KPCR->Irql = HIGH_LEVEL; + + /* Mark the end of the exception handler list */ + KPCR->Tib.ExceptionList = (PVOID)-1; + + /* + * Initialize the GDT + */ + KiInitializeGdt(KPCR); + + /* + * It is now safe to process interrupts + */ + KeLowerIrql(DISPATCH_LEVEL); + + /* + * Initialize the TSS + */ + Ki386ApplicationProcessorInitializeTSS(); + + /* + * Initialize a default LDT + */ + Ki386InitializeLdt(); + + if (Ke386CpuidFlags & X86_FEATURE_PGE) + { + /* Enable global pages */ + Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE); + } + + /* Enable PAE mode */ + if (Ke386CpuidFlags & X86_FEATURE_PAE) + { + MiEnablePAE(NULL); + } + + /* Now we can enable interrupts. */ + Ke386EnableInterrupts(); +} + +VOID INIT_FUNCTION +KeInit1(PCHAR CommandLine, PULONG LastKernelAddress) +{ + PKPCR KPCR; + BOOLEAN Pae = FALSE; + BOOLEAN NoExecute = FALSE; + PCHAR p1, p2; + extern USHORT KiBootGdt[]; + extern KTSS KiBootTss; + + KiCheckFPU(); + + KiInitializeGdt (NULL); + Ki386BootInitializeTSS(); + KeInitExceptions (); + KeInitInterrupts (); + + /* + * Initialize the initial PCR region. We can't allocate a page + * with MmAllocPage() here because MmInit1() has not yet been + * called, so we use a predefined page in low memory + */ + KPCR = (PKPCR)KPCR_BASE; + memset(KPCR, 0, PAGE_SIZE); + KPCR->Self = (PKPCR)KPCR_BASE; + KPCR->Irql = HIGH_LEVEL; + KPCR->Tib.Self = &KPCR->Tib; + KPCR->GDT = KiBootGdt; + KPCR->IDT = (PUSHORT)KiIdt; + KPCR->TSS = &KiBootTss; + KPCR->ProcessorNumber = 0; + KiPcrInitDone = 1; + PcrsAllocated++; + + /* Mark the end of the exception handler list */ + KPCR->Tib.ExceptionList = (PVOID)-1; + + Ki386InitializeLdt(); + + /* Get processor information. */ + Ki386GetCpuId(); + + if (Ke386CpuidFlags & X86_FEATURE_PGE) + { + ULONG Flags; + /* Enable global pages */ + Ke386SaveFlags(Flags); + Ke386DisableInterrupts(); + Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE); + Ke386RestoreFlags(Flags); + } + + /* Search for pae and noexecute */ + p1 = (PCHAR)KeLoaderBlock.CommandLine; + while(*p1 && (p2 = strchr(p1, '/'))) + { + p2++; + if (!_strnicmp(p2, "PAE", 3)) + { + if (p2[3] == ' ' || p2[3] == 0) + { + p2 += 3; + Pae = TRUE; + } + } + else if (!_strnicmp(p2, "NOEXECUTE", 9)) + { + if (p2[9] == ' ' || p2[9] == '=' || p2[9] == 0) + { + p2 += 9; + NoExecute = TRUE; + } + } + p1 = p2; + } + + /* + * FIXME: + * Make the detection of the noexecute feature more portable. + */ + if(((Ke386Cpuid >> 8) & 0xf) == 0xf && + 0 == strcmp("AuthenticAMD", Ke386CpuidVendor)) + { + if (NoExecute) + { + ULONG Flags, l, h; + Ke386SaveFlags(Flags); + Ke386DisableInterrupts(); + + Ke386Rdmsr(0xc0000080, l, h); + l |= (1 << 11); + Ke386Wrmsr(0xc0000080, l, h); + Ke386NoExecute = TRUE; + Ke386RestoreFlags(Flags); + } + } + else + { + NoExecute=FALSE; + } + + + /* Enable PAE mode */ + if ((Pae && (Ke386CpuidFlags & X86_FEATURE_PAE)) || NoExecute) + { + MiEnablePAE((PVOID*)LastKernelAddress); + } +} + +VOID INIT_FUNCTION +KeInit2(VOID) +{ + KeInitDpc(); + KeInitializeBugCheck(); + KeInitializeDispatcher(); + KeInitializeTimerImpl(); + + if (Ke386CpuidFlags & X86_FEATURE_PAE) + { + DPRINT1("CPU supports PAE mode\n"); + if (Ke386Pae) + { + DPRINT1("CPU runs in PAE mode\n"); + if (Ke386NoExecute) + { + DPRINT1("NoExecute is enabled\n"); + } + } + else + { + DPRINT1("CPU doesn't run in PAE mode\n"); + } + } + if (Ke386CpuidVendor[0]) + { + DPRINT1("CPU Vendor: %s\n", Ke386CpuidVendor); + } + if (Ke386CpuidModel[0]) + { + DPRINT1("CPU Model: %s\n", Ke386CpuidModel); + } + + DPRINT1("Ke386CacheAlignment: %d\n", Ke386CacheAlignment); + if (Ke386L1CacheSize) + { + DPRINT1("Ke386L1CacheSize: %dkB\n", Ke386L1CacheSize); + } + if (Ke386L2CacheSize) + { + DPRINT1("Ke386L2CacheSize: %dkB\n", Ke386L2CacheSize); + } +}