Fixed definition of KPCR_TIB to match W32API/NT5 defintion. Fixed bug in Makefile (fixed by Filip)

svn path=/trunk/; revision=11307
This commit is contained in:
Alex Ionescu 2004-10-17 05:20:29 +00:00
parent a5262fdf54
commit 020a7e0b2d
3 changed files with 628 additions and 631 deletions

View file

@ -36,13 +36,8 @@ else
OBJECTS_KDBG := OBJECTS_KDBG :=
endif endif
ifeq ($(strip $(SDK_PATH_INC)),)
TARGET_ASFLAGS = -I./include TARGET_ASFLAGS = -I./include
TARGET_CFLAGS = -I./include $(CFLAGS_KDBG) -Wall -Werror $(CFLAGS_OPT) 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 # require os code to explicitly request A/W version of structs/functions
TARGET_CFLAGS += -D_DISABLE_TIDENTS TARGET_CFLAGS += -D_DISABLE_TIDENTS

View file

@ -1,283 +1,284 @@
/* /*
* ReactOS kernel * ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
#ifndef __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H #ifndef __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H
#define __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H #define __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H
/* /*
* Defines for accessing KPCR and KTHREAD structure members * Defines for accessing KPCR and KTHREAD structure members
*/ */
#define KTHREAD_INITIAL_STACK 0x18 #define KTHREAD_INITIAL_STACK 0x18
#define KTHREAD_STACK_LIMIT 0x1C #define KTHREAD_STACK_LIMIT 0x1C
#define KTHREAD_TEB 0x20 #define KTHREAD_TEB 0x20
#define KTHREAD_KERNEL_STACK 0x28 #define KTHREAD_KERNEL_STACK 0x28
#define KTHREAD_APCSTATE_PROCESS 0x44 #define KTHREAD_APCSTATE_PROCESS 0x44
#define KTHREAD_SERVICE_TABLE 0xDC #define KTHREAD_SERVICE_TABLE 0xDC
#define KTHREAD_PREVIOUS_MODE 0x137 #define KTHREAD_PREVIOUS_MODE 0x137
#define KTHREAD_TRAP_FRAME 0x128 #define KTHREAD_TRAP_FRAME 0x128
#define KTHREAD_CALLBACK_STACK 0x120 #define KTHREAD_CALLBACK_STACK 0x120
#define KPROCESS_DIRECTORY_TABLE_BASE 0x18 #define KPROCESS_DIRECTORY_TABLE_BASE 0x18
#define KPROCESS_LDT_DESCRIPTOR0 0x20 #define KPROCESS_LDT_DESCRIPTOR0 0x20
#define KPROCESS_LDT_DESCRIPTOR1 0x24 #define KPROCESS_LDT_DESCRIPTOR1 0x24
#define KPROCESS_IOPM_OFFSET 0x30 #define KPROCESS_IOPM_OFFSET 0x30
#define KPCR_BASE 0xFF000000 #define KPCR_BASE 0xFF000000
#define KPCR_EXCEPTION_LIST 0x0 #define KPCR_EXCEPTION_LIST 0x0
#define KPCR_SELF 0x18 #define KPCR_SELF 0x18
#define KPCR_TSS 0x3C #define KPCR_TSS 0x40
#define KPCR_CURRENT_THREAD 0x124 #define KPCR_CURRENT_THREAD 0x124
#ifndef __ASM__ #ifndef __ASM__
#include "fpu.h" #include "fpu.h"
#pragma pack(push,4) #pragma pack(push,4)
// Fixme: Use correct types? // Fixme: Use correct types?
typedef struct _KPROCESSOR_STATE { typedef struct _KPROCESSOR_STATE {
PCONTEXT ContextFrame; PCONTEXT ContextFrame;
PVOID SpecialRegisters; PVOID SpecialRegisters;
} KPROCESSOR_STATE; } KPROCESSOR_STATE;
/* ProcessoR Control Block */ /* ProcessoR Control Block */
typedef struct _KPRCB { typedef struct _KPRCB {
USHORT MinorVersion; USHORT MinorVersion;
USHORT MajorVersion; USHORT MajorVersion;
struct _KTHREAD *CurrentThread; struct _KTHREAD *CurrentThread;
struct _KTHREAD *NextThread; struct _KTHREAD *NextThread;
struct _KTHREAD *IdleThread; struct _KTHREAD *IdleThread;
UCHAR Number; UCHAR Number;
UCHAR Reserved; UCHAR Reserved;
USHORT BuildType; USHORT BuildType;
ULONG SetMember; ULONG SetMember;
UCHAR CpuType; UCHAR CpuType;
UCHAR CpuID; UCHAR CpuID;
USHORT CpuStep; USHORT CpuStep;
KPROCESSOR_STATE ProcessorState; KPROCESSOR_STATE ProcessorState;
ULONG KernelReserved[16]; ULONG KernelReserved[16];
ULONG HalReserved[16]; ULONG HalReserved[16];
UCHAR PrcbPad0[92]; UCHAR PrcbPad0[92];
PVOID LockQueue[33]; // Used for Queued Spinlocks PVOID LockQueue[33]; // Used for Queued Spinlocks
struct _KTHREAD *NpxThread; struct _KTHREAD *NpxThread;
ULONG InterruptCount; ULONG InterruptCount;
ULONG KernelTime; ULONG KernelTime;
ULONG UserTime; ULONG UserTime;
ULONG DpcTime; ULONG DpcTime;
ULONG DebugDpcTime; ULONG DebugDpcTime;
ULONG InterruptTime; ULONG InterruptTime;
ULONG AdjustDpcThreshold; ULONG AdjustDpcThreshold;
ULONG PageColor; ULONG PageColor;
UCHAR SkipTick; UCHAR SkipTick;
UCHAR DebuggerSavedIRQL; UCHAR DebuggerSavedIRQL;
UCHAR Spare1[6]; UCHAR Spare1[6];
struct _KNODE *ParentNode; struct _KNODE *ParentNode;
ULONG MultiThreadProcessorSet; ULONG MultiThreadProcessorSet;
struct _KPRCB *MultiThreadSetMaster; struct _KPRCB *MultiThreadSetMaster;
ULONG ThreadStartCount[2]; ULONG ThreadStartCount[2];
ULONG CcFastReadNoWait; ULONG CcFastReadNoWait;
ULONG CcFastReadWait; ULONG CcFastReadWait;
ULONG CcFastReadNotPossible; ULONG CcFastReadNotPossible;
ULONG CcCopyReadNoWait; ULONG CcCopyReadNoWait;
ULONG CcCopyReadWait; ULONG CcCopyReadWait;
ULONG CcCopyReadNoWaitMiss; ULONG CcCopyReadNoWaitMiss;
ULONG KeAlignmentFixupCount; ULONG KeAlignmentFixupCount;
ULONG SpareCounter0; ULONG SpareCounter0;
ULONG KeDcacheFlushCount; ULONG KeDcacheFlushCount;
ULONG KeExceptionDispatchCount; ULONG KeExceptionDispatchCount;
ULONG KeFirstLevelTbFills; ULONG KeFirstLevelTbFills;
ULONG KeFloatingEmulationCount; ULONG KeFloatingEmulationCount;
ULONG KeIcacheFlushCount; ULONG KeIcacheFlushCount;
ULONG KeSecondLevelTbFills; ULONG KeSecondLevelTbFills;
ULONG KeSystemCalls; ULONG KeSystemCalls;
ULONG IoReadOperationCount; ULONG IoReadOperationCount;
ULONG IoWriteOperationCount; ULONG IoWriteOperationCount;
ULONG IoOtherOperationCount; ULONG IoOtherOperationCount;
LARGE_INTEGER IoReadTransferCount; LARGE_INTEGER IoReadTransferCount;
LARGE_INTEGER IoWriteTransferCount; LARGE_INTEGER IoWriteTransferCount;
LARGE_INTEGER IoOtherTransferCount; LARGE_INTEGER IoOtherTransferCount;
ULONG SpareCounter1[8]; ULONG SpareCounter1[8];
PP_LOOKASIDE_LIST PPLookasideList[16]; PP_LOOKASIDE_LIST PPLookasideList[16];
PP_LOOKASIDE_LIST PPNPagedLookasideList[32]; PP_LOOKASIDE_LIST PPNPagedLookasideList[32];
PP_LOOKASIDE_LIST PPPagedLookasideList[32]; PP_LOOKASIDE_LIST PPPagedLookasideList[32];
ULONG PacketBarrier; ULONG PacketBarrier;
ULONG ReverseStall; ULONG ReverseStall;
PVOID IpiFrame; PVOID IpiFrame;
UCHAR PrcbPad2[52]; UCHAR PrcbPad2[52];
PVOID CurrentPacket[3]; PVOID CurrentPacket[3];
ULONG TargetSet; ULONG TargetSet;
ULONG_PTR WorkerRoutine; ULONG_PTR WorkerRoutine;
ULONG IpiFrozen; ULONG IpiFrozen;
UCHAR PrcbPad3[40]; UCHAR PrcbPad3[40];
ULONG RequestSummary; ULONG RequestSummary;
struct _KPRCB *SignalDone; struct _KPRCB *SignalDone;
UCHAR PrcbPad4[56]; UCHAR PrcbPad4[56];
struct _KDPC_DATA DpcData[2]; struct _KDPC_DATA DpcData[2];
PVOID DpcStack; PVOID DpcStack;
ULONG MaximumDpcQueueDepth; ULONG MaximumDpcQueueDepth;
ULONG DpcRequestRate; ULONG DpcRequestRate;
ULONG MinimumDpcRate; ULONG MinimumDpcRate;
UCHAR DpcInterruptRequested; UCHAR DpcInterruptRequested;
UCHAR DpcThreadRequested; UCHAR DpcThreadRequested;
UCHAR DpcRoutineActive; UCHAR DpcRoutineActive;
UCHAR DpcThreadActive; UCHAR DpcThreadActive;
ULONG PrcbLock; ULONG PrcbLock;
ULONG DpcLastCount; ULONG DpcLastCount;
ULONG TimerHand; ULONG TimerHand;
ULONG TimerRequest; ULONG TimerRequest;
PVOID DpcThread; PVOID DpcThread;
struct _KEVENT *DpcEvent; struct _KEVENT *DpcEvent;
UCHAR ThreadDpcEnable; UCHAR ThreadDpcEnable;
UCHAR QuantumEnd; UCHAR QuantumEnd;
UCHAR PrcbPad50; UCHAR PrcbPad50;
UCHAR IdleSchedule; UCHAR IdleSchedule;
ULONG DpcSetEventRequest; ULONG DpcSetEventRequest;
UCHAR PrcbPad5[18]; UCHAR PrcbPad5[18];
LONG TickOffset; LONG TickOffset;
struct _KDPC* CallDpc; struct _KDPC* CallDpc;
ULONG PrcbPad7[8]; ULONG PrcbPad7[8];
LIST_ENTRY WaitListHead; LIST_ENTRY WaitListHead;
ULONG ReadySummary; ULONG ReadySummary;
ULONG SelectNextLast; ULONG SelectNextLast;
LIST_ENTRY DispatcherReadyListHead[32]; LIST_ENTRY DispatcherReadyListHead[32];
SINGLE_LIST_ENTRY DeferredReadyListHead; SINGLE_LIST_ENTRY DeferredReadyListHead;
ULONG PrcbPad72[11]; ULONG PrcbPad72[11];
PVOID ChainedInterruptList; PVOID ChainedInterruptList;
LONG LookasideIrpFloat; LONG LookasideIrpFloat;
LONG MmPageFaultCount; LONG MmPageFaultCount;
LONG MmCopyOnWriteCount; LONG MmCopyOnWriteCount;
LONG MmTransitionCount; LONG MmTransitionCount;
LONG MmCacheTransitionCount; LONG MmCacheTransitionCount;
LONG MmDemandZeroCount; LONG MmDemandZeroCount;
LONG MmPageReadCount; LONG MmPageReadCount;
LONG MmPageReadIoCount; LONG MmPageReadIoCount;
LONG MmCacheReadCount; LONG MmCacheReadCount;
LONG MmCacheIoCount; LONG MmCacheIoCount;
LONG MmDirtyPagesWriteCount; LONG MmDirtyPagesWriteCount;
LONG MmDirtyWriteIoCount; LONG MmDirtyWriteIoCount;
LONG MmMappedPagesWriteCount; LONG MmMappedPagesWriteCount;
LONG MmMappedWriteIoCount; LONG MmMappedWriteIoCount;
ULONG SpareFields0[1]; ULONG SpareFields0[1];
UCHAR VendorString[13]; UCHAR VendorString[13];
UCHAR InitialApicId; UCHAR InitialApicId;
UCHAR LogicalProcessorsPerPhysicalProcessor; UCHAR LogicalProcessorsPerPhysicalProcessor;
ULONG MHz; ULONG MHz;
ULONG FeatureBits; ULONG FeatureBits;
LARGE_INTEGER UpdateSignature; LARGE_INTEGER UpdateSignature;
LARGE_INTEGER IsrTime; LARGE_INTEGER IsrTime;
LARGE_INTEGER SpareField1; LARGE_INTEGER SpareField1;
FX_SAVE_AREA NpxSaveArea; FX_SAVE_AREA NpxSaveArea;
PROCESSOR_POWER_STATE PowerState; PROCESSOR_POWER_STATE PowerState;
} KPRCB, *PKRCB; } KPRCB, *PKRCB;
#pragma pack(pop) #pragma pack(pop)
#ifndef __USE_W32API #ifndef __USE_W32API
#pragma pack(push,4) #pragma pack(push,4)
/* /*
* Processor Control Region Thread Information Block * Processor Control Region Thread Information Block
*/ */
typedef struct _KPCR_TIB { typedef struct _KPCR_TIB {
PVOID ExceptionList; /* 00 */ PVOID ExceptionList; /* 00 */
PVOID StackBase; /* 04 */ PVOID StackBase; /* 04 */
PVOID StackLimit; /* 08 */ PVOID StackLimit; /* 08 */
PVOID SubSystemTib; /* 0C */ PVOID SubSystemTib; /* 0C */
union { union {
PVOID FiberData; /* 10 */ PVOID FiberData; /* 10 */
DWORD Version; /* 10 */ DWORD Version; /* 10 */
}; };
PVOID ArbitraryUserPointer; /* 14 */ PVOID ArbitraryUserPointer; /* 14 */
} KPCR_TIB, *PKPCR_TIB; /* 18 */ struct _KPCR_TIB* Self; /* 18 */
} KPCR_TIB, *PKPCR_TIB; /* 18 */
/*
* Processor Control Region /*
*/ * Processor Control Region
typedef struct _KPCR { */
KPCR_TIB Tib; /* 00 */ typedef struct _KPCR {
struct _KPCR *Self; /* 18 */ KPCR_TIB Tib; /* 00 */
struct _KPRCB *PCRCB; /* 1C */ struct _KPCR *Self; /* 18 */
KIRQL Irql; /* 20 */ struct _KPRCB *PCRCB; /* 1C */
ULONG IRR; /* 24 */ KIRQL Irql; /* 20 */
ULONG IrrActive; /* 28 */ ULONG IRR; /* 24 */
ULONG IDR; /* 2C */ ULONG IrrActive; /* 28 */
PVOID KdVersionBlock; /* 30 */ ULONG IDR; /* 2C */
PUSHORT IDT; /* 34 */ PVOID KdVersionBlock; /* 30 */
PUSHORT GDT; /* 38 */ PUSHORT IDT; /* 34 */
struct _KTSS *TSS; /* 3C */ PUSHORT GDT; /* 38 */
USHORT MajorVersion; /* 40 */ struct _KTSS *TSS; /* 3C */
USHORT MinorVersion; /* 42 */ USHORT MajorVersion; /* 40 */
KAFFINITY SetMember; /* 44 */ USHORT MinorVersion; /* 42 */
ULONG StallScaleFactor; /* 48 */ KAFFINITY SetMember; /* 44 */
UCHAR DebugActive; /* 4C */ ULONG StallScaleFactor; /* 48 */
UCHAR ProcessorNumber; /* 4D */ UCHAR DebugActive; /* 4C */
UCHAR Reserved; /* 4E */ UCHAR ProcessorNumber; /* 4D */
UCHAR L2CacheAssociativity; /* 4F */ UCHAR Reserved; /* 4E */
ULONG VdmAlert; /* 50 */ UCHAR L2CacheAssociativity; /* 4F */
ULONG KernelReserved[14]; /* 54 */ ULONG VdmAlert; /* 50 */
ULONG L2CacheSize; /* 8C */ ULONG KernelReserved[14]; /* 54 */
ULONG HalReserved[16]; /* 90 */ ULONG L2CacheSize; /* 8C */
ULONG InterruptMode; /* D0 */ ULONG HalReserved[16]; /* 90 */
UCHAR KernelReserved2[0x4C]; /* D4 */ ULONG InterruptMode; /* D0 */
KPRCB PrcbData; /* 120 */ UCHAR KernelReserved2[0x48]; /* D4 */
} KPCR, *PKPCR; KPRCB PrcbData; /* 120 */
} KPCR, *PKPCR;
#pragma pack(pop)
#endif /* __USE_W32API */ #pragma pack(pop)
#endif /* __USE_W32API */
#ifndef __USE_W32API
#ifndef __USE_W32API
static inline PKPCR KeGetCurrentKPCR(VOID)
{ static inline PKPCR KeGetCurrentKPCR(VOID)
ULONG value; {
ULONG value;
#if defined(__GNUC__)
__asm__ __volatile__ ("movl %%fs:0x18, %0\n\t" #if defined(__GNUC__)
: "=r" (value) __asm__ __volatile__ ("movl %%fs:0x18, %0\n\t"
: /* no inputs */ : "=r" (value)
); : /* no inputs */
#elif defined(_MSC_VER) );
__asm mov eax, fs:0x18; #elif defined(_MSC_VER)
__asm mov value, eax; __asm mov eax, fs:0x18;
#else __asm mov value, eax;
#error Unknown compiler for inline assembler #else
#endif #error Unknown compiler for inline assembler
return((PKPCR)value); #endif
} return((PKPCR)value);
}
#endif /* __USE_W32API */
#endif /* __USE_W32API */
VOID
Ki386ContextSwitch(struct _KTHREAD* NewThread, VOID
struct _KTHREAD* OldThread); Ki386ContextSwitch(struct _KTHREAD* NewThread,
NTSTATUS struct _KTHREAD* OldThread);
Ke386InitThread(struct _KTHREAD* Thread, PKSTART_ROUTINE fn, NTSTATUS
PVOID StartContext); Ke386InitThread(struct _KTHREAD* Thread, PKSTART_ROUTINE fn,
NTSTATUS PVOID StartContext);
Ke386InitThreadWithContext(struct _KTHREAD* Thread, PCONTEXT Context); NTSTATUS
NTSTATUS Ke386InitThreadWithContext(struct _KTHREAD* Thread, PCONTEXT Context);
Ki386ValidateUserContext(PCONTEXT Context); NTSTATUS
Ki386ValidateUserContext(PCONTEXT Context);
#endif /* __ASM__ */
#endif /* __ASM__ */
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H */
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_I386_PS_H */
/* EOF */
/* EOF */

View file

@ -1,343 +1,344 @@
/* /*
* ReactOS kernel * ReactOS kernel
* Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team * Copyright (C) 1998, 1999, 2000, 2001 ReactOS Team
* *
* This program is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or * the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* /*
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/kernel.c * FILE: ntoskrnl/ke/i386/kernel.c
* PURPOSE: Initializes the kernel * PURPOSE: Initializes the kernel
* PROGRAMMER: David Welch (welch@mcmail.com) * PROGRAMMER: David Welch (welch@mcmail.com)
* UPDATE HISTORY: * UPDATE HISTORY:
* Created 22/05/98 * Created 22/05/98
*/ */
/* INCLUDES *****************************************************************/ /* INCLUDES *****************************************************************/
#include <ntoskrnl.h> #include <ntoskrnl.h>
#define NDEBUG #define NDEBUG
#include <internal/debug.h> #include <internal/debug.h>
/* GLOBALS *******************************************************************/ /* GLOBALS *******************************************************************/
ULONG KiPcrInitDone = 0; ULONG KiPcrInitDone = 0;
static ULONG PcrsAllocated = 0; static ULONG PcrsAllocated = 0;
static PFN_TYPE PcrPages[MAXIMUM_PROCESSORS]; static PFN_TYPE PcrPages[MAXIMUM_PROCESSORS];
ULONG Ke386CpuidFlags, Ke386CpuidFlags2, Ke386CpuidExFlags; ULONG Ke386CpuidFlags, Ke386CpuidFlags2, Ke386CpuidExFlags;
ULONG Ke386Cpuid = 0x300; ULONG Ke386Cpuid = 0x300;
ULONG Ke386CacheAlignment; ULONG Ke386CacheAlignment;
CHAR Ke386CpuidVendor[13] = {0,}; CHAR Ke386CpuidVendor[13] = {0,};
CHAR Ke386CpuidModel[49] = {0,}; CHAR Ke386CpuidModel[49] = {0,};
ULONG Ke386L1CacheSize; ULONG Ke386L1CacheSize;
ULONG Ke386L2CacheSize; ULONG Ke386L2CacheSize;
BOOLEAN Ke386NoExecute = FALSE; BOOLEAN Ke386NoExecute = FALSE;
BOOLEAN Ke386Pae = FALSE; BOOLEAN Ke386Pae = FALSE;
/* FUNCTIONS *****************************************************************/ /* FUNCTIONS *****************************************************************/
VOID INIT_FUNCTION STATIC VOID INIT_FUNCTION STATIC
Ki386GetCpuId(VOID) Ki386GetCpuId(VOID)
{ {
ULONG OrigFlags, Flags, FinalFlags; ULONG OrigFlags, Flags, FinalFlags;
ULONG MaxCpuidLevel; ULONG MaxCpuidLevel;
ULONG Dummy, Ebx, Ecx, Edx; ULONG Dummy, Ebx, Ecx, Edx;
Ke386CpuidFlags = Ke386CpuidFlags2 = Ke386CpuidExFlags = 0; Ke386CpuidFlags = Ke386CpuidFlags2 = Ke386CpuidExFlags = 0;
Ke386CacheAlignment = 32; Ke386CacheAlignment = 32;
/* Try to toggle the id bit in eflags. */ /* Try to toggle the id bit in eflags. */
__asm__ ("pushfl\n\t" __asm__ ("pushfl\n\t"
"popl %0\n\t" "popl %0\n\t"
: "=r" (OrigFlags)); : "=r" (OrigFlags));
Flags = OrigFlags ^ X86_EFLAGS_ID; Flags = OrigFlags ^ X86_EFLAGS_ID;
__asm__ ("pushl %1\n\t" __asm__ ("pushl %1\n\t"
"popfl\n\t" "popfl\n\t"
"pushfl\n\t" "pushfl\n\t"
"popl %0\n\t" "popl %0\n\t"
: "=r" (FinalFlags) : "=r" (FinalFlags)
: "r" (Flags)); : "r" (Flags));
if ((OrigFlags & X86_EFLAGS_ID) == (FinalFlags & X86_EFLAGS_ID)) if ((OrigFlags & X86_EFLAGS_ID) == (FinalFlags & X86_EFLAGS_ID))
{ {
/* No cpuid supported. */ /* No cpuid supported. */
return; return;
} }
/* Get the vendor name and the maximum cpuid level supported. */ /* Get the vendor name and the maximum cpuid level supported. */
Ki386Cpuid(0, &MaxCpuidLevel, (PULONG)&Ke386CpuidVendor[0], (PULONG)&Ke386CpuidVendor[8], (PULONG)&Ke386CpuidVendor[4]); Ki386Cpuid(0, &MaxCpuidLevel, (PULONG)&Ke386CpuidVendor[0], (PULONG)&Ke386CpuidVendor[8], (PULONG)&Ke386CpuidVendor[4]);
if (MaxCpuidLevel > 0) if (MaxCpuidLevel > 0)
{ {
/* Get the feature flags. */ /* Get the feature flags. */
Ki386Cpuid(1, &Ke386Cpuid, &Ebx, &Ke386CpuidFlags2, &Ke386CpuidFlags); Ki386Cpuid(1, &Ke386Cpuid, &Ebx, &Ke386CpuidFlags2, &Ke386CpuidFlags);
/* Get the cache alignment, if it is available */ /* Get the cache alignment, if it is available */
if (Ke386CpuidFlags & (1<<19)) if (Ke386CpuidFlags & (1<<19))
{ {
Ke386CacheAlignment = ((Ebx >> 8) & 0xff) * 8; Ke386CacheAlignment = ((Ebx >> 8) & 0xff) * 8;
} }
} }
/* Get the maximum extended cpuid level supported. */ /* Get the maximum extended cpuid level supported. */
Ki386Cpuid(0x80000000, &MaxCpuidLevel, &Dummy, &Dummy, &Dummy); Ki386Cpuid(0x80000000, &MaxCpuidLevel, &Dummy, &Dummy, &Dummy);
if (MaxCpuidLevel > 0) if (MaxCpuidLevel > 0)
{ {
/* Get the extended feature flags. */ /* Get the extended feature flags. */
Ki386Cpuid(0x80000001, &Dummy, &Dummy, &Dummy, &Ke386CpuidExFlags); Ki386Cpuid(0x80000001, &Dummy, &Dummy, &Dummy, &Ke386CpuidExFlags);
} }
/* Get the model name. */ /* Get the model name. */
if (MaxCpuidLevel >= 0x80000004) if (MaxCpuidLevel >= 0x80000004)
{ {
PULONG v = (PULONG)&Ke386CpuidModel; PULONG v = (PULONG)&Ke386CpuidModel;
Ki386Cpuid(0x80000002, v, v + 1, v + 2, v + 3); Ki386Cpuid(0x80000002, v, v + 1, v + 2, v + 3);
Ki386Cpuid(0x80000003, v + 4, v + 5, v + 6, v + 7); Ki386Cpuid(0x80000003, v + 4, v + 5, v + 6, v + 7);
Ki386Cpuid(0x80000004, v + 8, v + 9, v + 10, v + 11); Ki386Cpuid(0x80000004, v + 8, v + 9, v + 10, v + 11);
} }
/* Get the L1 cache size */ /* Get the L1 cache size */
if (MaxCpuidLevel >= 0x80000005) if (MaxCpuidLevel >= 0x80000005)
{ {
Ki386Cpuid(0x80000005, &Dummy, &Dummy, &Ecx, &Edx); Ki386Cpuid(0x80000005, &Dummy, &Dummy, &Ecx, &Edx);
Ke386L1CacheSize = (Ecx >> 24)+(Edx >> 24); Ke386L1CacheSize = (Ecx >> 24)+(Edx >> 24);
if ((Ecx & 0xff) > 0) if ((Ecx & 0xff) > 0)
{ {
Ke386CacheAlignment = Ecx & 0xff; Ke386CacheAlignment = Ecx & 0xff;
} }
} }
/* Get the L2 cache size */ /* Get the L2 cache size */
if (MaxCpuidLevel >= 0x80000006) if (MaxCpuidLevel >= 0x80000006)
{ {
Ki386Cpuid(0x80000006, &Dummy, &Dummy, &Ecx, &Dummy); Ki386Cpuid(0x80000006, &Dummy, &Dummy, &Ecx, &Dummy);
Ke386L2CacheSize = Ecx >> 16; Ke386L2CacheSize = Ecx >> 16;
} }
} }
VOID INIT_FUNCTION VOID INIT_FUNCTION
KePrepareForApplicationProcessorInit(ULONG Id) KePrepareForApplicationProcessorInit(ULONG Id)
{ {
MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &PcrPages[Id]); MmRequestPageMemoryConsumer(MC_NPPOOL, TRUE, &PcrPages[Id]);
KiGdtPrepareForApplicationProcessorInit(Id); KiGdtPrepareForApplicationProcessorInit(Id);
} }
VOID VOID
KeApplicationProcessorInit(VOID) KeApplicationProcessorInit(VOID)
{ {
PKPCR Pcr; PKPCR KPCR;
ULONG Offset; ULONG Offset;
/* /*
* Create a PCR for this processor * Create a PCR for this processor
*/ */
Offset = InterlockedIncrement((LONG *)&PcrsAllocated) - 1; Offset = InterlockedIncrement((LONG *)&PcrsAllocated) - 1;
Pcr = (PKPCR)(KPCR_BASE + (Offset * PAGE_SIZE)); KPCR = (PKPCR)(KPCR_BASE + (Offset * PAGE_SIZE));
MmCreateVirtualMappingForKernel((PVOID)Pcr, MmCreateVirtualMappingForKernel((PVOID)KPCR,
PAGE_READWRITE, PAGE_READWRITE,
&PcrPages[Offset], &PcrPages[Offset],
1); 1);
memset(Pcr, 0, PAGE_SIZE); memset(KPCR, 0, PAGE_SIZE);
Pcr->ProcessorNumber = (UCHAR)Offset; KPCR->ProcessorNumber = (UCHAR)Offset;
Pcr->Self = Pcr; KPCR->Tib.Self = &KPCR->Tib;
Pcr->Irql = HIGH_LEVEL; KPCR->Irql = HIGH_LEVEL;
/* Mark the end of the exception handler list */ /* Mark the end of the exception handler list */
Pcr->Tib.ExceptionList = (PVOID)-1; KPCR->Tib.ExceptionList = (PVOID)-1;
/* /*
* Initialize the GDT * Initialize the GDT
*/ */
KiInitializeGdt(Pcr); KiInitializeGdt(KPCR);
/* /*
* It is now safe to process interrupts * It is now safe to process interrupts
*/ */
KeLowerIrql(DISPATCH_LEVEL); KeLowerIrql(DISPATCH_LEVEL);
/* /*
* Initialize the TSS * Initialize the TSS
*/ */
Ki386ApplicationProcessorInitializeTSS(); Ki386ApplicationProcessorInitializeTSS();
/* /*
* Initialize a default LDT * Initialize a default LDT
*/ */
Ki386InitializeLdt(); Ki386InitializeLdt();
if (Ke386CpuidFlags & X86_FEATURE_PGE) if (Ke386CpuidFlags & X86_FEATURE_PGE)
{ {
/* Enable global pages */ /* Enable global pages */
Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE); Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);
} }
/* Enable PAE mode */ /* Enable PAE mode */
if (Ke386CpuidFlags & X86_FEATURE_PAE) if (Ke386CpuidFlags & X86_FEATURE_PAE)
{ {
MiEnablePAE(NULL); MiEnablePAE(NULL);
} }
/* Now we can enable interrupts. */ /* Now we can enable interrupts. */
Ke386EnableInterrupts(); Ke386EnableInterrupts();
} }
VOID INIT_FUNCTION VOID INIT_FUNCTION
KeInit1(PCHAR CommandLine, PULONG LastKernelAddress) KeInit1(PCHAR CommandLine, PULONG LastKernelAddress)
{ {
PKPCR KPCR; PKPCR KPCR;
BOOLEAN Pae = FALSE; BOOLEAN Pae = FALSE;
BOOLEAN NoExecute = FALSE; BOOLEAN NoExecute = FALSE;
PCHAR p1, p2; PCHAR p1, p2;
extern USHORT KiBootGdt[]; extern USHORT KiBootGdt[];
extern KTSS KiBootTss; extern KTSS KiBootTss;
KiCheckFPU(); KiCheckFPU();
KiInitializeGdt (NULL); KiInitializeGdt (NULL);
Ki386BootInitializeTSS(); Ki386BootInitializeTSS();
KeInitExceptions (); KeInitExceptions ();
KeInitInterrupts (); KeInitInterrupts ();
/* /*
* Initialize the initial PCR region. We can't allocate a page * Initialize the initial PCR region. We can't allocate a page
* with MmAllocPage() here because MmInit1() has not yet been * with MmAllocPage() here because MmInit1() has not yet been
* called, so we use a predefined page in low memory * called, so we use a predefined page in low memory
*/ */
KPCR = (PKPCR)KPCR_BASE; KPCR = (PKPCR)KPCR_BASE;
memset(KPCR, 0, PAGE_SIZE); memset(KPCR, 0, PAGE_SIZE);
KPCR->Self = (PKPCR)KPCR_BASE; KPCR->Self = (PKPCR)KPCR_BASE;
KPCR->Irql = HIGH_LEVEL; KPCR->Irql = HIGH_LEVEL;
KPCR->GDT = KiBootGdt; KPCR->Tib.Self = &KPCR->Tib;
KPCR->IDT = (PUSHORT)KiIdt; KPCR->GDT = KiBootGdt;
KPCR->TSS = &KiBootTss; KPCR->IDT = (PUSHORT)KiIdt;
KPCR->ProcessorNumber = 0; KPCR->TSS = &KiBootTss;
KiPcrInitDone = 1; KPCR->ProcessorNumber = 0;
PcrsAllocated++; KiPcrInitDone = 1;
PcrsAllocated++;
/* Mark the end of the exception handler list */
KPCR->Tib.ExceptionList = (PVOID)-1; /* Mark the end of the exception handler list */
KPCR->Tib.ExceptionList = (PVOID)-1;
Ki386InitializeLdt();
Ki386InitializeLdt();
/* Get processor information. */
Ki386GetCpuId(); /* Get processor information. */
Ki386GetCpuId();
if (Ke386CpuidFlags & X86_FEATURE_PGE)
{ if (Ke386CpuidFlags & X86_FEATURE_PGE)
ULONG Flags; {
/* Enable global pages */ ULONG Flags;
Ke386SaveFlags(Flags); /* Enable global pages */
Ke386DisableInterrupts(); Ke386SaveFlags(Flags);
Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE); Ke386DisableInterrupts();
Ke386RestoreFlags(Flags); Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);
} Ke386RestoreFlags(Flags);
}
/* Search for pae and noexecute */
p1 = (PCHAR)KeLoaderBlock.CommandLine; /* Search for pae and noexecute */
while(*p1 && (p2 = strchr(p1, '/'))) p1 = (PCHAR)KeLoaderBlock.CommandLine;
{ while(*p1 && (p2 = strchr(p1, '/')))
p2++; {
if (!_strnicmp(p2, "PAE", 3)) p2++;
{ if (!_strnicmp(p2, "PAE", 3))
if (p2[3] == ' ' || p2[3] == 0) {
{ if (p2[3] == ' ' || p2[3] == 0)
p2 += 3; {
Pae = TRUE; p2 += 3;
} Pae = TRUE;
} }
else if (!_strnicmp(p2, "NOEXECUTE", 9)) }
{ else if (!_strnicmp(p2, "NOEXECUTE", 9))
if (p2[9] == ' ' || p2[9] == '=' || p2[9] == 0) {
{ if (p2[9] == ' ' || p2[9] == '=' || p2[9] == 0)
p2 += 9; {
NoExecute = TRUE; p2 += 9;
} NoExecute = TRUE;
} }
p1 = p2; }
} p1 = p2;
}
/*
* FIXME: /*
* Make the detection of the noexecute feature more portable. * FIXME:
*/ * Make the detection of the noexecute feature more portable.
if(((Ke386Cpuid >> 8) & 0xf) == 0xf && */
0 == strcmp("AuthenticAMD", Ke386CpuidVendor)) if(((Ke386Cpuid >> 8) & 0xf) == 0xf &&
{ 0 == strcmp("AuthenticAMD", Ke386CpuidVendor))
if (NoExecute) {
{ if (NoExecute)
ULONG Flags, l, h; {
Ke386SaveFlags(Flags); ULONG Flags, l, h;
Ke386DisableInterrupts(); Ke386SaveFlags(Flags);
Ke386DisableInterrupts();
Ke386Rdmsr(0xc0000080, l, h);
l |= (1 << 11); Ke386Rdmsr(0xc0000080, l, h);
Ke386Wrmsr(0xc0000080, l, h); l |= (1 << 11);
Ke386NoExecute = TRUE; Ke386Wrmsr(0xc0000080, l, h);
Ke386RestoreFlags(Flags); Ke386NoExecute = TRUE;
} Ke386RestoreFlags(Flags);
} }
else }
{ else
NoExecute=FALSE; {
} NoExecute=FALSE;
}
/* Enable PAE mode */
if ((Pae && (Ke386CpuidFlags & X86_FEATURE_PAE)) || NoExecute) /* Enable PAE mode */
{ if ((Pae && (Ke386CpuidFlags & X86_FEATURE_PAE)) || NoExecute)
MiEnablePAE((PVOID*)LastKernelAddress); {
} MiEnablePAE((PVOID*)LastKernelAddress);
} }
}
VOID INIT_FUNCTION
KeInit2(VOID) VOID INIT_FUNCTION
{ KeInit2(VOID)
KeInitDpc(); {
KeInitializeBugCheck(); KeInitDpc();
KeInitializeDispatcher(); KeInitializeBugCheck();
KeInitializeTimerImpl(); KeInitializeDispatcher();
KeInitializeTimerImpl();
if (Ke386CpuidFlags & X86_FEATURE_PAE)
{ if (Ke386CpuidFlags & X86_FEATURE_PAE)
DPRINT1("CPU supports PAE mode\n"); {
if (Ke386Pae) DPRINT1("CPU supports PAE mode\n");
{ if (Ke386Pae)
DPRINT1("CPU runs in PAE mode\n"); {
if (Ke386NoExecute) DPRINT1("CPU runs in PAE mode\n");
{ if (Ke386NoExecute)
DPRINT1("NoExecute is enabled\n"); {
} DPRINT1("NoExecute is enabled\n");
} }
else }
{ else
DPRINT1("CPU doesn't run in PAE mode\n"); {
} DPRINT1("CPU doesn't run in PAE mode\n");
} }
if (Ke386CpuidVendor[0]) }
{ if (Ke386CpuidVendor[0])
DPRINT1("CPU Vendor: %s\n", Ke386CpuidVendor); {
} DPRINT1("CPU Vendor: %s\n", Ke386CpuidVendor);
if (Ke386CpuidModel[0]) }
{ if (Ke386CpuidModel[0])
DPRINT1("CPU Model: %s\n", Ke386CpuidModel); {
} DPRINT1("CPU Model: %s\n", Ke386CpuidModel);
}
DPRINT1("Ke386CacheAlignment: %d\n", Ke386CacheAlignment);
if (Ke386L1CacheSize) DPRINT1("Ke386CacheAlignment: %d\n", Ke386CacheAlignment);
{ if (Ke386L1CacheSize)
DPRINT1("Ke386L1CacheSize: %dkB\n", Ke386L1CacheSize); {
} DPRINT1("Ke386L1CacheSize: %dkB\n", Ke386L1CacheSize);
if (Ke386L2CacheSize) }
{ if (Ke386L2CacheSize)
DPRINT1("Ke386L2CacheSize: %dkB\n", Ke386L2CacheSize); {
} DPRINT1("Ke386L2CacheSize: %dkB\n", Ke386L2CacheSize);
} }
}