Big merge: thanks alex and greatlord. Not a complete merge but most
authorArt Yerkes <art.yerkes@gmail.com>
Mon, 4 Sep 2006 05:52:23 +0000 (05:52 +0000)
committerArt Yerkes <art.yerkes@gmail.com>
Mon, 4 Sep 2006 05:52:23 +0000 (05:52 +0000)
relevant things for ppc right now.
hal
ntoskrnl
include
lib/rtl
lib/cmlib
some freeldr components

svn path=/branches/powerpc/; revision=23907

50 files changed:
1  2  3  4 
reactos/ReactOS-ppc.rbuild
reactos/boot/freeldr/freeldr/arch/powerpc/mach.c
reactos/boot/freeldr/freeldr/cache/blocklist.c
reactos/boot/freeldr/freeldr/cache/cache.c
reactos/boot/freeldr/freeldr/freeldr.rbuild
reactos/boot/freeldr/freeldr/freeldr_arch.rbuild
reactos/boot/freeldr/freeldr/freeldr_base.rbuild
reactos/boot/freeldr/freeldr/freeldr_main.rbuild
reactos/boot/freeldr/freeldr/include/fs.h
reactos/boot/freeldr/freeldr/mm/mm.c
reactos/boot/freeldr/freeldr/reactos/reactos.c
reactos/include/ddk/winddk.h
reactos/include/ndk/powerpc/ketypes.h
reactos/include/ndk/pstypes.h
reactos/include/psdk/winnt.h
reactos/include/reactos/debug.h
reactos/include/reactos/libs/pseh/framebased.h
reactos/include/reactos/probe.h
reactos/lib/rtl/exception.c
reactos/lib/rtl/heap.c
reactos/lib/rtl/nls.c
reactos/lib/rtl/rtl.h
reactos/lib/string/itoa.c
reactos/lib/string/sscanf.c
reactos/lib/string/string.rbuild
reactos/ntoskrnl/ex/init.c
reactos/ntoskrnl/ex/power.c
reactos/ntoskrnl/ex/sysinfo.c
reactos/ntoskrnl/include/internal/ex.h
reactos/ntoskrnl/include/internal/ke.h
reactos/ntoskrnl/include/internal/ntoskrnl.h
reactos/ntoskrnl/include/internal/powerpc/ke.h
reactos/ntoskrnl/kd/kdmain.c
reactos/ntoskrnl/kd/wrappers/gdbstub.c
reactos/ntoskrnl/ke/bug.c
reactos/ntoskrnl/ke/dpc.c
reactos/ntoskrnl/ke/freeldr.c
reactos/ntoskrnl/ke/gmutex.c
reactos/ntoskrnl/ke/ipi.c
reactos/ntoskrnl/ke/krnlinit.c
reactos/ntoskrnl/ke/kthread.c
reactos/ntoskrnl/ke/process.c
reactos/ntoskrnl/ntoskrnl.def
reactos/ntoskrnl/ntoskrnl.rbuild
reactos/ntoskrnl/ps/debug.c
reactos/ntoskrnl/ps/idle.c
reactos/ntoskrnl/ps/psmgr.c
reactos/tools/ppc.lost+found/link-freeldr
reactos/tools/ssprintf.cpp
reactos/tools/wrc/wrc.mak

      <define name="_PPC_" />
      <define name="__PowerPC__" />
      <define name="_REACTOS_" />
-     <define name="__MINGW_IMPORT">extern</define>
 ---  <define name="__MINGW_IMPORT" empty="true" />
      <define name="stdcall" empty="true" />    
      <define name="__stdcall__" empty="true" />
      <define name="fastcall" empty="true" />
      <define name="cdecl" empty="true" />
      <define name="__cdecl__" empty="true" />
      <define name="dllimport" empty="true" />
 ---  <compilerflag>-v</compilerflag>
 +++  <define name="WORDS_BIGENDIAN" empty="true" />
++++  <compilerflag>-fsigned-char</compilerflag>
      <if property="MP" value="1">
        <define name="CONFIG_SMP" value="1" />
      </if>
    
      <include>.</include>
      <include>include</include>
 ---  <include>include/reactos</include>
 ---  <include>include/libs</include>
 ---  <include>include/drivers</include>
 ---  <include>include/subsys</include>
 ---  <include>include/ndk</include>
 ---  <include>include</include>
      <include>include/crt</include>
      <include>include/ddk</include>
 +++  <include>include/GL</include>
 +++  <include>include/ndk</include>
++++  <include>include/psdk</include>
 +++  <include>include/reactos</include>
 +++  <include>include/reactos/libs</include>
    
      <directory name="base">
        <xi:include href="base/base.rbuild" />
    #include "freeldr.h"
    #include "machine.h"
    #include "of.h"
 +++#include "mmu.h"
    
-   #define TOTAL_HEAP_NEEDED (16 * 1024 * 1024) /* 16 megs */
 ---extern void BootMain( char * );
 ---extern char *GetFreeLoaderVersionString();
++++#define TOTAL_HEAP_NEEDED (32 * 1024 * 1024) /* 32 megs */
 +++
-   extern void BootMain( char * );
-   extern char *GetFreeLoaderVersionString();
++++extern void BootMain( LPSTR CmdLine );
++++extern PCHAR GetFreeLoaderVersionString();
++++extern ULONG CacheSizeLimit;
    of_proxy ofproxy;
 ---void *PageDirectoryStart, *PageDirectoryEnd;
 +++void *PageDirectoryStart, *PageDirectoryEnd, *mem_base = 0;
    static int chosen_package, stdin_handle, part_handle = -1;
    BOOLEAN AcpiPresent = FALSE;
    char BootPath[0x100] = { 0 }, BootPart[0x100] = { 0 }, CmdLine[0x100] = { 0 };
@@@@@ -77,7 -77,7 -77,7 -77,7 +77,6 @@@@@ PCACHE_BLOCK CacheInternalFindBlock(PCA
                                // Increment the blocks access count
                                //
                                CacheBlock->AccessCount++;
----
                                return CacheBlock;
                        }
    
@@@@@ -164,6 -164,6 -164,6 -164,6 +163,7 @@@@@ BOOLEAN CacheInternalFreeBlock(PCACHE_D
        // so just return
        if (CacheBlockToFree == NULL)
        {
++++            printf("[cached] all cache blocks locked\n");
                return FALSE;
        }
    
@@@@@ -207,6 -207,6 -207,6 -207,6 +207,7 @@@@@ VOID CacheInternalCheckCacheSizeLimits(
    
    VOID CacheInternalDumpBlockList(PCACHE_DRIVE CacheDrive)
    {
++++#if 0
        PCACHE_BLOCK    CacheBlock;
    
        DbgPrint((DPRINT_CACHE, "Dumping block list for BIOS drive 0x%x.\n", CacheDrive->DriveNumber));
    
                CacheBlock = (PCACHE_BLOCK)RtlListGetNext((PLIST_ITEM)CacheBlock);
        }
++++#endif
    }
    
    VOID CacheInternalOptimizeBlockList(PCACHE_DRIVE CacheDrive, PCACHE_BLOCK CacheBlock)
@@@@@ -90,11 -90,11 -90,11 -90,11 +90,12 @@@@@ BOOLEAN CacheInitializeDrive(ULONG Driv
        CacheManagerDrive.BlockSize = MachDiskGetCacheableBlockCount(DriveNumber);
    
        CacheBlockCount = 0;
----    CacheSizeLimit = GetSystemMemorySize() / 8;
++++    //CacheSizeLimit = GetSystemMemorySize() / 8;
++++    CacheSizeLimit = 16 * 1024;
        CacheSizeCurrent = 0;
----    if (CacheSizeLimit < (64 * 1024))
++++    if (CacheSizeLimit < (16 * 1024))
        {
----            CacheSizeLimit = (64 * 1024);
++++            CacheSizeLimit = (16 * 1024);
        }
    
        CacheManagerInitialized = TRUE;
@@@@@ -284,7 -284,7 -284,7 -284,7 +285,7 @@@@@ BOOLEAN CacheForceDiskSectorsIntoCache(
                //
                // Lock the sectors into the cache
                //
----            CacheBlock->LockedInCache = TRUE;
++++            //CacheBlock->LockedInCache = TRUE;
        }
    
        return TRUE;
@@@@@ -5,7 -5,8 -5,8 -5,8 +5,8 @@@@@
        <library>freeldr_base</library>
        <library>freeldr_arch</library>
        <library>freeldr_main</library>
++++    <library>cmlib</library>
        <library>rossym</library>
        <library>string</library>
 ---    <library>cmlib</library>
        <library>rtl</library>
    </module>
        <directory name="powerpc">
                <if property="ARCH" value="powerpc">
                        <module name="freeldr_arch" type="objectlibrary">
++++                            <include base="ReactOS">include/psdk</include>
                                <include base="freeldr_base">include</include>
                                <include base="freeldr_base">cache</include>
                                <include base="ntoskrnl">include</include>
@@@@@ -1,7 -1,8 -1,8 -1,8 +1,9 @@@@@
    <module name="freeldr_base" type="objectlibrary">
++++    <include base="ReactOS">include/psdk</include>
        <include base="freeldr_base">include</include>
        <include base="freeldr_base">cache</include>
 ---    <include base="cmlib">.</include>
        <include base="ntoskrnl">include</include>
++++    <include base="cmlib">.</include>
        <define name="__USE_W32API" />
    <!--        
        <define name="DEBUG" />
        </directory>
        <directory name="reactos">
                <file>registry.c</file>
----            <file>arcname.c</file>
                <file>binhive.c</file>
++++            <file>arcname.c</file>
                <file>reactos.c</file>
        </directory>
        <directory name="rtl">
@@@@@ -1,4 -1,4 -1,4 -1,4 +1,5 @@@@@
    <module name="freeldr_main" type="objectlibrary">
++++    <include base="ReactOS">include/psdk</include>
        <include base="freeldr_main">include</include>
        <include base="ntoskrnl">include</include>
        <define name="__USE_W32API" />
    
    VOID        FileSystemError(PCSTR ErrorString);
    BOOLEAN     FsOpenBootVolume();
----BOOLEAN     FsOpenSystemVolume(PCHAR SystemPath, PCHAR RemainingPath, PULONG BootDevice);
++++BOOLEAN     FsOpenSystemVolume(char *SystemPath, char *RemainingPath, PULONG BootDevice);
    PFILE       FsOpenFile(PCSTR FileName);
    VOID        FsCloseFile(PFILE FileHandle);
    BOOLEAN     FsReadFile(PFILE FileHandle, ULONG BytesToRead, ULONG* BytesRead, PVOID Buffer);
@@@@@ -83,6 -83,6 -83,6 -83,6 +83,7 @@@@@ PVOID MmAllocateMemory(ULONG MemorySize
        {
                DbgPrint((DPRINT_MEMORY, "Memory allocation failed. Not enough free memory to allocate %d bytes. AllocationCount: %d\n", MemorySize, AllocationCount));
                UiMessageBoxCritical("Memory allocation failed: out of memory.");
++++            while(1);
                return NULL;
        }
    
@@@@@ -820,7 -820,7 -820,7 -820,7 +820,11 @@@@@ LoadAndBootReactOS(PCSTR OperatingSyste
        /*
         * Import the loaded system hive
         */
----    RegImportBinaryHive((PCHAR)Base, Size);
++++    if( !RegImportBinaryHive((PCHAR)Base, Size) )
++++    {
++++        printf("Could not load system hive\n");
++++        return;
++++    }
    
        /*
         * Initialize the 'CurrentControlSet' link
    
    #undef DbgPrint
    ULONG
-   DbgPrint(char *Fmt, ...)
 ---DbgPrint(const char *Format, ...)
++++__cdecl
++++DbgPrint(PCCH Format, ...)
    {
-     UiMessageBox(Fmt);
-     return 0;
+       va_list ap;
+       CHAR Buffer[512];
+       ULONG Length;
+   
+       va_start(ap, Format);
+   
+       /* Construct a string */
+       Length = _vsnprintf(Buffer, 512, Format, ap);
+   
+       /* Check if we went past the buffer */
+       if (Length == -1)
+       {
+               /* Terminate it if we went over-board */
+               Buffer[sizeof(Buffer) - 1] = '\n';
+   
+               /* Put maximum */
+               Length = sizeof(Buffer);
+       }
+   
+       /* Show it as a message box */
+       UiMessageBox(Buffer);
+   
+       /* Cleanup and exit */
+       va_end(ap);
+       return 0;
    }
    
    /* EOF */
@@@@@ -5268,189 -5317,9 -5317,9 -5317,9 +5317,190 @@@@@ KfReleaseSpinLock
    
    #define KeGetDcacheFillSize() 1L
    
 ---#endif /* _X86_ */
 +++#elif defined(_PPC_)
 +++
 +++typedef ULONG PFN_NUMBER, *PPFN_NUMBER;
 +++
 +++#define PASSIVE_LEVEL                      0
 +++#define LOW_LEVEL                          0
 +++#define APC_LEVEL                          1
 +++#define DISPATCH_LEVEL                     2
 +++#define PROFILE_LEVEL                     27
 +++#define CLOCK1_LEVEL                      28
 +++#define CLOCK2_LEVEL                      28
 +++#define IPI_LEVEL                         29
 +++#define SYNCH_LEVEL                  (IPI_LEVEL-1)
 +++#define POWER_LEVEL                       30
 +++#define HIGH_LEVEL                        31
 +++ 
 +++extern NTOSAPI PVOID MmHighestUserAddress;
 +++extern NTOSAPI PVOID MmSystemRangeStart;
 +++extern NTOSAPI ULONG_PTR MmUserProbeAddress;
 +++
 +++#define MM_HIGHEST_USER_ADDRESS           MmHighestUserAddress
 +++#define MM_SYSTEM_RANGE_START             MmSystemRangeStart
 +++#define MM_USER_PROBE_ADDRESS             MmUserProbeAddress
 +++#define MM_LOWEST_USER_ADDRESS            (PVOID)0x10000
 +++#define MM_LOWEST_SYSTEM_ADDRESS          (PVOID)0xC0C00000
 +++
 +++#define KI_USER_SHARED_DATA               0xffdf0000
 +++#define SharedUserData                    ((KUSER_SHARED_DATA * CONST) KI_USER_SHARED_DATA)
 +++
 +++#define EFLAG_SIGN                        0x8000
 +++#define EFLAG_ZERO                        0x4000
 +++#define EFLAG_SELECT                      (EFLAG_SIGN | EFLAG_ZERO)
 +++
 +++#define RESULT_NEGATIVE                   ((EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT)
 +++#define RESULT_ZERO                       ((~EFLAG_SIGN & EFLAG_ZERO) & EFLAG_SELECT)
 +++#define RESULT_POSITIVE                   ((~EFLAG_SIGN & ~EFLAG_ZERO) & EFLAG_SELECT)
 +++
 +++typedef struct _KPCR_TIB {
 +++  PVOID  ExceptionList;         /* 00 */
 +++  PVOID  StackBase;             /* 04 */
 +++  PVOID  StackLimit;            /* 08 */
 +++  PVOID  SubSystemTib;          /* 0C */
 +++  _ANONYMOUS_UNION union {
 +++    PVOID  FiberData;           /* 10 */
 +++    DWORD  Version;             /* 10 */
 +++  } DUMMYUNIONNAME;
 +++  PVOID  ArbitraryUserPointer;  /* 14 */
 +++  struct _KPCR_TIB *Self;       /* 18 */
 +++} KPCR_TIB, *PKPCR_TIB;         /* 1C */
 +++
 +++#define PCR_MINOR_VERSION 1
 +++#define PCR_MAJOR_VERSION 1
 +++
 +++typedef struct _KPCR {
 +++  KPCR_TIB  Tib;                /* 00 */
 +++  struct _KPCR  *Self;          /* 1C */
 +++  struct _KPRCB  *Prcb;         /* 20 */
 +++  KIRQL  Irql;                  /* 24 */
 +++  ULONG  IRR;                   /* 28 */
 +++  ULONG  IrrActive;             /* 2C */
 +++  ULONG  IDR;                   /* 30 */
 +++  PVOID  KdVersionBlock;        /* 34 */
 +++  PUSHORT  IDT;                 /* 38 */
 +++  PUSHORT  GDT;                 /* 3C */
 +++  struct _KTSS  *TSS;           /* 40 */
 +++  USHORT  MajorVersion;         /* 44 */
 +++  USHORT  MinorVersion;         /* 46 */
 +++  KAFFINITY  SetMember;         /* 48 */
 +++  ULONG  StallScaleFactor;      /* 4C */
 +++  UCHAR  SpareUnused;           /* 50 */
 +++  UCHAR  Number;                /* 51 */
 +++} KPCR, *PKPCR;                 /* 54 */
 +++
 +++#if !defined(__INTERLOCKED_DECLARED)
 +++#define __INTERLOCKED_DECLARED
 +++
 +++NTOSAPI
 +++LONG
 +++DDKFASTAPI
 +++InterlockedIncrement(
 +++  IN PLONG  VOLATILE  Addend);
 +++
 +++NTOSAPI
 +++LONG
 +++DDKFASTAPI
 +++InterlockedDecrement(
 +++  IN PLONG  VOLATILE  Addend);
 +++
 +++NTOSAPI
 +++LONG
 +++DDKFASTAPI
 +++InterlockedCompareExchange(
 +++  IN OUT PLONG  VOLATILE  Destination,
 +++  IN LONG  Exchange,
 +++  IN LONG  Comparand);
 +++
 +++NTOSAPI
 +++LONG
 +++DDKFASTAPI
 +++InterlockedExchange(
 +++  IN OUT PLONG  VOLATILE  Target,
 +++  IN LONG Value);
 +++
 +++NTOSAPI
 +++LONG
 +++DDKFASTAPI
 +++InterlockedExchangeAdd(
 +++  IN OUT PLONG VOLATILE  Addend,
 +++  IN LONG  Value);
    
 +++/*
 +++ * PVOID
 +++ * InterlockedExchangePointer(
 +++ *   IN OUT PVOID VOLATILE  *Target,
 +++ *   IN PVOID  Value)
 +++ */
 +++#define InterlockedExchangePointer(Target, Value) \
 +++  ((PVOID) InterlockedExchange((PLONG) Target, (LONG) Value))
 +++
 +++/*
 +++ * PVOID
 +++ * InterlockedCompareExchangePointer(
 +++ *   IN OUT PVOID  *Destination,
 +++ *   IN PVOID  Exchange,
 +++ *   IN PVOID  Comparand)
 +++ */
 +++#define InterlockedCompareExchangePointer(Destination, Exchange, Comparand) \
 +++  ((PVOID) InterlockedCompareExchange((PLONG) Destination, (LONG) Exchange, (LONG) Comparand))
++++#define InterlockedDecrementSizeT(a) InterlockedDecrement((LONG *)a)
 +++
 +++#endif /* !__INTERLOCKED_DECLARED */
 +++
 +++NTOSAPI
 +++VOID
 +++DDKFASTAPI
 +++KefAcquireSpinLockAtDpcLevel(
 +++  IN PKSPIN_LOCK  SpinLock);
 +++
 +++NTOSAPI
 +++VOID
 +++DDKFASTAPI
 +++KefReleaseSpinLockFromDpcLevel(
 +++  IN PKSPIN_LOCK  SpinLock);
 +++
 +++NTHALAPI
 +++KIRQL
 +++DDKFASTAPI
 +++KfAcquireSpinLock(
 +++  IN PKSPIN_LOCK SpinLock);
    
 +++NTHALAPI
 +++VOID
 +++DDKFASTAPI
 +++KfReleaseSpinLock(
 +++  IN PKSPIN_LOCK SpinLock,
 +++  IN KIRQL NewIrql);
 +++
 +++#define KeAcquireSpinLockAtDpcLevel(SpinLock) KefAcquireSpinLockAtDpcLevel(SpinLock)
 +++#define KeReleaseSpinLockFromDpcLevel(SpinLock) KefReleaseSpinLockFromDpcLevel(SpinLock)
 +++#define KeAcquireSpinLock(a,b)  *(b) = KfAcquireSpinLock(a)
 +++#define KeReleaseSpinLock(a,b)  KfReleaseSpinLock(a,b)
 +++
 +++#define RtlCopyMemoryNonTemporal RtlCopyMemory
 +++
 +++#define KeGetDcacheFillSize() 1L
 +++
 +++typedef enum _INTERLOCKED_RESULT {
 +++  ResultNegative = -1,
 +++  ResultZero = 0,
 +++  ResultPositive = 1
 +++} INTERLOCKED_RESULT;
 +++
 +++typedef struct _KFLOATING_SAVE {
 +++    ULONG Fr[32];
 +++} KFLOATING_SAVE, *PKFLOATING_SAVE;
 +++
 +++static __inline
 +++ULONG
 +++DDKAPI
 +++KeGetCurrentProcessorNumber(VOID)
 +++{
 +++    return 0; // XXX arty fixme
 +++}
 +++#endif /* _X86_ */
    
    /*
    ** Utillity functions
@@@@@ -76,57 -37,57 -37,57 -37,57 +76,100 @@@@@ typedef struct _LDT_ENTRY 
    //
    typedef struct _KTRAP_FRAME
    {
----    PVOID TrapFrame;\r
----    UCHAR OldIrql;\r
----    UCHAR PreviousMode;\r
----    UCHAR SavedApcStateIndex;\r
----    UCHAR SavedKernelApcDisable;\r
-       UCHAR ExceptionRecord[ROUND_UP(sizeof(EXCEPTION_RECORD), sizeof(ULONGLONG))];\r
 ---    UCHAR ExceptionRecord[ROUND_UP(sizeof(EXCEPTION_RECORD), ULONGLONG];\r
----    ULONG FILL2;\r
----    ULONG Gpr0;\r
----    ULONG Gpr1;\r
----    ULONG Gpr2;\r
----    ULONG Gpr3;\r
----    ULONG Gpr4;\r
----    ULONG Gpr5;\r
----    ULONG Gpr6;\r
----    ULONG Gpr7;\r
----    ULONG Gpr8;\r
----    ULONG Gpr9;\r
----    ULONG Gpr10;\r
----    ULONG Gpr11;\r
----    ULONG Gpr12;\r
----    DOUBLE Fpr0;\r
----    DOUBLE Fpr1;\r
----    DOUBLE Fpr2;\r
----    DOUBLE Fpr3;\r
----    DOUBLE Fpr4;\r
----    DOUBLE Fpr5;\r
----    DOUBLE Fpr6;\r
----    DOUBLE Fpr7;\r
----    DOUBLE Fpr8;\r
----    DOUBLE Fpr9;\r
----    DOUBLE Fpr10;\r
----    DOUBLE Fpr11;\r
----    DOUBLE Fpr12;\r
----    DOUBLE Fpr13;\r
----    DOUBLE Fpscr;\r
----    ULONG Cr;\r
----    ULONG Xer;\r
----    ULONG Msr;\r
----    ULONG Iar;\r
----    ULONG Lr;\r
----    ULONG Ctr;\r
----    ULONG Dr0;\r
----    ULONG Dr1;\r
----    ULONG Dr2;\r
----    ULONG Dr3;\r
----    ULONG Dr4;\r
----    ULONG Dr5;\r
----    ULONG Dr6;\r
++++    PVOID TrapFrame;
++++    UCHAR OldIrql;
++++    UCHAR PreviousMode;
++++    UCHAR SavedApcStateIndex;
++++    UCHAR SavedKernelApcDisable;
++++    UCHAR ExceptionRecord[ROUND_UP(sizeof(EXCEPTION_RECORD), sizeof(ULONGLONG))];
++++    ULONG FILL2;
++++    ULONG Gpr0;
++++    ULONG Gpr1;
++++    ULONG Gpr2;
++++    ULONG Gpr3;
++++    ULONG Gpr4;
++++    ULONG Gpr5;
++++    ULONG Gpr6;
++++    ULONG Gpr7;
++++    ULONG Gpr8;
++++    ULONG Gpr9;
++++    ULONG Gpr10;
++++    ULONG Gpr11;
++++    ULONG Gpr12;
++++    DOUBLE Fpr0;
++++    DOUBLE Fpr1;
++++    DOUBLE Fpr2;
++++    DOUBLE Fpr3;
++++    DOUBLE Fpr4;
++++    DOUBLE Fpr5;
++++    DOUBLE Fpr6;
++++    DOUBLE Fpr7;
++++    DOUBLE Fpr8;
++++    DOUBLE Fpr9;
++++    DOUBLE Fpr10;
++++    DOUBLE Fpr11;
++++    DOUBLE Fpr12;
++++    DOUBLE Fpr13;
++++    DOUBLE Fpscr;
++++    ULONG Cr;
++++    ULONG Xer;
++++    ULONG Msr;
++++    ULONG Iar;
++++    ULONG Lr;
++++    ULONG Ctr;
++++    ULONG Dr0;
++++    ULONG Dr1;
++++    ULONG Dr2;
++++    ULONG Dr3;
++++    ULONG Dr4;
++++    ULONG Dr5;
++++    ULONG Dr6;
        ULONG Dr7;
    } KTRAP_FRAME, *PKTRAP_FRAME;
    
++++//
++++// GDT Entry Definition
++++//
++++typedef struct _KGDTENTRY
++++{
++++    USHORT LimitLow;
++++    USHORT BaseLow;
++++    union
++++    {
++++        struct
++++        {
++++            UCHAR BaseMid;
++++            UCHAR Flags1;
++++            UCHAR Flags2;
++++            UCHAR BaseHi;
++++        } Bytes;
++++        struct
++++        {
++++            ULONG BaseMid:8;
++++            ULONG Type:5;
++++            ULONG Dpl:2;
++++            ULONG Pres:1;
++++            ULONG LimitHi:4;
++++            ULONG Sys:1;
++++            ULONG Reserved_0:1;
++++            ULONG Default_Big:1;
++++            ULONG Granularity:1;
++++            ULONG BaseHi:8;
++++        } Bits;
++++    } HighWord;
++++} KGDTENTRY, *PKGDTENTRY;
++++
++++//
++++// IDT Entry Definition
++++//
++++typedef struct _KIDTENTRY
++++{
++++    USHORT Offset;
++++    USHORT Selector;
++++    USHORT Access;
++++    USHORT ExtendedOffset;
++++} KIDTENTRY, *PKIDTENTRY;
++++
    //
    // Page Table Entry Definition
    //
@@@@@ -158,49 -119,49 -119,49 -119,49 +201,49 @@@@@ typedef struct _DESCRIPTO
    //
    typedef struct _KSPECIAL_REGISTERS
    {
----    ULONG KernelDr0;\r
----    ULONG KernelDr1;\r
----    ULONG KernelDr2;\r
----    ULONG KernelDr3;\r
----    ULONG KernelDr4;\r
----    ULONG KernelDr5;\r
----    ULONG KernelDr6;\r
----    ULONG KernelDr7;\r
----    ULONG Sprg0;\r
----    ULONG Sprg1;\r
----    ULONG Sr0;\r
----    ULONG Sr1;\r
----    ULONG Sr2;\r
----    ULONG Sr3;\r
----    ULONG Sr4;\r
----    ULONG Sr5;\r
----    ULONG Sr6;\r
----    ULONG Sr7;\r
----    ULONG Sr8;\r
----    ULONG Sr9;\r
----    ULONG Sr10;\r
----    ULONG Sr11;\r
----    ULONG Sr12;\r
----    ULONG Sr13;\r
----    ULONG Sr14;\r
----    ULONG Sr15;\r
----    ULONG DBAT0L;\r
----    ULONG DBAT0U;\r
----    ULONG DBAT1L;\r
----    ULONG DBAT1U;\r
----    ULONG DBAT2L;\r
----    ULONG DBAT2U;\r
----    ULONG DBAT3L;\r
----    ULONG DBAT3U;\r
----    ULONG IBAT0L;\r
----    ULONG IBAT0U;\r
----    ULONG IBAT1L;\r
----    ULONG IBAT1U;\r
----    ULONG IBAT2L;\r
----    ULONG IBAT2U;\r
----    ULONG IBAT3L;\r
----    ULONG IBAT3U;\r
----    ULONG Sdr1;\r
++++    ULONG KernelDr0;
++++    ULONG KernelDr1;
++++    ULONG KernelDr2;
++++    ULONG KernelDr3;
++++    ULONG KernelDr4;
++++    ULONG KernelDr5;
++++    ULONG KernelDr6;
++++    ULONG KernelDr7;
++++    ULONG Sprg0;
++++    ULONG Sprg1;
++++    ULONG Sr0;
++++    ULONG Sr1;
++++    ULONG Sr2;
++++    ULONG Sr3;
++++    ULONG Sr4;
++++    ULONG Sr5;
++++    ULONG Sr6;
++++    ULONG Sr7;
++++    ULONG Sr8;
++++    ULONG Sr9;
++++    ULONG Sr10;
++++    ULONG Sr11;
++++    ULONG Sr12;
++++    ULONG Sr13;
++++    ULONG Sr14;
++++    ULONG Sr15;
++++    ULONG DBAT0L;
++++    ULONG DBAT0U;
++++    ULONG DBAT1L;
++++    ULONG DBAT1U;
++++    ULONG DBAT2L;
++++    ULONG DBAT2U;
++++    ULONG DBAT3L;
++++    ULONG DBAT3U;
++++    ULONG IBAT0L;
++++    ULONG IBAT0U;
++++    ULONG IBAT1L;
++++    ULONG IBAT1U;
++++    ULONG IBAT2L;
++++    ULONG IBAT2U;
++++    ULONG IBAT3L;
++++    ULONG IBAT3U;
++++    ULONG Sdr1;
        ULONG Reserved[9];
    } KSPECIAL_REGISTERS, *PKSPECIAL_REGISTERS;
    
    #pragma pack(push,4)
    typedef struct _KPROCESSOR_STATE
    {
----    PCONTEXT ContextFrame;
++++    CONTEXT ContextFrame;
        KSPECIAL_REGISTERS SpecialRegisters;
----} KPROCESSOR_STATE;
++++} KPROCESSOR_STATE, *PKPROCESSOR_STATE;
    
    //
    // Processor Region Control Block
@@@@@ -234,8 -195,8 -195,8 -195,8 +277,13 @@@@@ typedef struct _KPRC
        KPROCESSOR_STATE ProcessorState;
        ULONG KernelReserved[16];
        ULONG HalReserved[16];
++++#if (NTDDI_VERSION >= NTDDI_LONGHORN)
++++    ULONG CFlushSize;
++++    UCHAR PrcbPad0[88];
++++#else
        UCHAR PrcbPad0[92];
----    PVOID LockQueue[33]; // Used for Queued Spinlocks
++++#endif
++++    KSPIN_LOCK_QUEUE LockQueue[LockQueueMaximumLock];
        struct _KTHREAD *NpxThread;
        ULONG InterruptCount;
        ULONG KernelTime;
        ULONG PageColor;
        UCHAR SkipTick;
        UCHAR DebuggerSavedIRQL;
++++#if (NTDDI_VERSION >= NTDDI_WS03)
++++    UCHAR NodeColor;
++++#if (NTDDI_VERSION >= NTDDI_LONGHORN)
++++    UCHAR PollSlot;
++++#else
++++    UCHAR Spare1;
++++#endif
++++    ULONG NodeShiftedColor;
++++#else
        UCHAR Spare1[6];
++++#endif
        struct _KNODE *ParentNode;
        ULONG MultiThreadProcessorSet;
        struct _KPRCB *MultiThreadSetMaster;
++++#if (NTDDI_VERSION >= NTDDI_WS03)
++++    ULONG SecondaryColorMask;
++++#if (NTDDI_VERSION >= NTDDI_LONGHORN)
++++    ULONG DpcTimeLimit;
++++#else
++++    LONG Sleeping;
++++#endif
++++#else
        ULONG ThreadStartCount[2];
++++#endif
        ULONG CcFastReadNoWait;
        ULONG CcFastReadWait;
        ULONG CcFastReadNotPossible;
        ULONG CcCopyReadNoWait;
        ULONG CcCopyReadWait;
        ULONG CcCopyReadNoWaitMiss;
++++#if (NTDDI_VERSION < NTDDI_LONGHORN)
        ULONG KeAlignmentFixupCount;
----    ULONG KeContextSwitches;
++++#endif
++++    ULONG SpareCounter0;
++++#if (NTDDI_VERSION < NTDDI_LONGHORN)
        ULONG KeDcacheFlushCount;
        ULONG KeExceptionDispatchCount;
        ULONG KeFirstLevelTbFills;
        ULONG KeIcacheFlushCount;
        ULONG KeSecondLevelTbFills;
        ULONG KeSystemCalls;
----    ULONG IoReadOperationCount;
----    ULONG IoWriteOperationCount;
----    ULONG IoOtherOperationCount;
++++#endif
++++    volatile ULONG IoReadOperationCount;
++++    volatile ULONG IoWriteOperationCount;
++++    volatile ULONG IoOtherOperationCount;
        LARGE_INTEGER IoReadTransferCount;
        LARGE_INTEGER IoWriteTransferCount;
        LARGE_INTEGER IoOtherTransferCount;
++++#if (NTDDI_VERSION >= NTDDI_LONGHORN)
++++    ULONG CcFastMdlReadNoWait;
++++    ULONG CcFastMdlReadWait;
++++    ULONG CcFastMdlReadNotPossible;
++++    ULONG CcMapDataNoWait;
++++    ULONG CcMapDataWait;
++++    ULONG CcPinMappedDataCount;
++++    ULONG CcPinReadNoWait;
++++    ULONG CcPinReadWait;
++++    ULONG CcMdlReadNoWait;
++++    ULONG CcMdlReadWait;
++++    ULONG CcLazyWriteHotSpots;
++++    ULONG CcLazyWriteIos;
++++    ULONG CcLazyWritePages;
++++    ULONG CcDataFlushes;
++++    ULONG CcDataPages;
++++    ULONG CcLostDelayedWrites;
++++    ULONG CcFastReadResourceMiss;
++++    ULONG CcCopyReadWaitMiss;
++++    ULONG CcFastMdlReadResourceMiss;
++++    ULONG CcMapDataNoWaitMiss;
++++    ULONG CcMapDataWaitMiss;
++++    ULONG CcPinReadNoWaitMiss;
++++    ULONG CcPinReadWaitMiss;
++++    ULONG CcMdlReadNoWaitMiss;
++++    ULONG CcMdlReadWaitMiss;
++++    ULONG CcReadAheadIos;
++++    ULONG KeAlignmentFixupCount;
++++    ULONG KeExceptionDispatchCount;
++++    ULONG KeSystemCalls;
++++    ULONG PrcbPad1[3];
++++#else
        ULONG SpareCounter1[8];
++++#endif
        PP_LOOKASIDE_LIST PPLookasideList[16];
        PP_LOOKASIDE_LIST PPNPagedLookasideList[32];
        PP_LOOKASIDE_LIST PPPagedLookasideList[32];
----    ULONG PacketBarrier;
----    ULONG ReverseStall;
++++    volatile ULONG PacketBarrier;
++++    volatile ULONG ReverseStall;
        PVOID IpiFrame;
        UCHAR PrcbPad2[52];
----    PVOID CurrentPacket[3];
----    ULONG TargetSet;
----    ULONG_PTR WorkerRoutine;
----    ULONG IpiFrozen;
++++    volatile PVOID CurrentPacket[3];
++++    volatile ULONG TargetSet;
++++    volatile PKIPI_WORKER WorkerRoutine;
++++    volatile ULONG IpiFrozen;
        UCHAR PrcbPad3[40];
----    ULONG RequestSummary;
----    struct _KPRCB *SignalDone;
++++    volatile ULONG RequestSummary;
++++    volatile 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;
++++    volatile UCHAR DpcInterruptRequested;
++++    volatile UCHAR DpcThreadRequested;
++++    volatile UCHAR DpcRoutineActive;
++++    volatile UCHAR DpcThreadActive;
        ULONG PrcbLock;
        ULONG DpcLastCount;
----    ULONG TimerHand;
----    ULONG TimerRequest;
++++    volatile ULONG TimerHand;
++++    volatile ULONG TimerRequest;
        PVOID DpcThread;
----    struct _KEVENT *DpcEvent;
++++    KEVENT DpcEvent;
        UCHAR ThreadDpcEnable;
----    BOOLEAN QuantumEnd;
++++    volatile BOOLEAN QuantumEnd;
        UCHAR PrcbPad50;
----    UCHAR IdleSchedule;
----    ULONG DpcSetEventRequest;
++++    volatile UCHAR IdleSchedule;
++++    LONG DpcSetEventRequest;
++++#if (NTDDI_VERSION >= NTDDI_LONGHORN)
++++    LONG Sleeping;
++++    ULONG PeriodicCount;
++++    ULONG PeriodicBias;
++++    UCHAR PrcbPad5[6];
++++#else
        UCHAR PrcbPad5[18];
++++#endif
        LONG TickOffset;
----    struct _KDPC* CallDpc;
++++    KDPC CallDpc;
++++#if (NTDDI_VERSION >= NTDDI_LONGHORN)
++++    LONG ClockKeepAlive;
++++    UCHAR ClockCheckSlot;
++++    UCHAR ClockPollCycle;
++++    UCHAR PrcbPad6[2];
++++    LONG DpcWatchdogPeriod;
++++    LONG DpcWatchDogCount;
++++    LONG ThreadWatchdogPeriod;
++++    LONG ThreadWatchDogCount;
++++    ULONG PrcbPad70[2];
++++#else
        ULONG PrcbPad7[8];
++++#endif
        LIST_ENTRY WaitListHead;
        ULONG ReadySummary;
----    ULONG SelectNextLast;
++++    ULONG QueueIndex;
++++#if (NTDDI_VERSION >= NTDDI_LONGHORN)
++++    SINGLE_LIST_ENTRY DeferredReadyListHead;
++++    ULONGLONG StartCycles;
++++    ULONGLONG CycleTime;
++++    ULONGLONG PrcbPad71[3];
++++    LIST_ENTRY DispatcherReadyListHead[32];
++++#else
        LIST_ENTRY DispatcherReadyListHead[32];
        SINGLE_LIST_ENTRY DeferredReadyListHead;
        ULONG PrcbPad72[11];
++++#endif
        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;
++++    volatile LONG MmPageFaultCount;
++++    volatile LONG MmCopyOnWriteCount;
++++    volatile LONG MmTransitionCount;
++++    volatile LONG MmCacheTransitionCount;
++++    volatile LONG MmDemandZeroCount;
++++    volatile LONG MmPageReadCount;
++++    volatile LONG MmPageReadIoCount;
++++    volatile LONG MmCacheReadCount;
++++    volatile LONG MmCacheIoCount;
++++    volatile LONG MmDirtyPagesWriteCount;
++++    volatile LONG MmDirtyWriteIoCount;
++++    volatile LONG MmMappedPagesWriteCount;
++++    volatile LONG MmMappedWriteIoCount;
++++#if (NTDDI_VERSION >= NTDDI_LONGHORN)
++++    ULONG CachedCommit;
++++    ULONG CachedResidentAvailable;
++++    PVOID HyperPte;
++++    UCHAR CpuVendor;
++++    UCHAR PrcbPad9[3];
++++#else
        ULONG SpareFields0[1];
++++#endif
        CHAR VendorString[13];
        UCHAR InitialApicId;
        UCHAR LogicalProcessorsPerPhysicalProcessor;
        ULONG MHz;
        ULONG FeatureBits;
        LARGE_INTEGER UpdateSignature;
----    LARGE_INTEGER IsrTime;
++++    volatile LARGE_INTEGER IsrTime;
        LARGE_INTEGER SpareField1;
        FX_SAVE_AREA NpxSaveArea;
        PROCESSOR_POWER_STATE PowerState;
++++#if (NTDDI_VERSION >= NTDDI_LONGHORN)
++++    KDPC DpcWatchdogDoc;
++++    KTIMER DpcWatchdogTimer;
++++    PVOID WheaInfo;
++++    PVOID EtwSupport;
++++    SLIST_HEADER InterruptObjectPool;
++++    LARGE_INTEGER HyperCallPagePhysical;
++++    LARGE_INTEGER HyperCallPageVirtual;
++++    PVOID RateControl;
++++    CACHE_DESCRIPTOR Cache[5];
++++    ULONG CacheCount;
++++    ULONG CacheProcessorMask[5];
++++    UCHAR LogicalProcessorsPerCore;
++++    UCHAR PrcbPad8[3];
++++    ULONG PackageProcessorSet;
++++    ULONG CoreProcessorSet;
++++#endif
    } KPRCB, *PKPRCB;
    
    //
    //
    typedef struct _KIPCR
    {
----    USHORT MinorVersion;\r
----    USHORT MajorVersion;\r
----    PKINTERRUPT_ROUTINE InterruptRoutine[MAXIMUM_VECTOR];\r
----    ULONG PcrPage2;\r
----    ULONG Kseg0Top;\r
++++    USHORT MinorVersion;
++++    USHORT MajorVersion;
++++    PKINTERRUPT_ROUTINE InterruptRoutine[MAXIMUM_VECTOR];
++++    ULONG PcrPage2;
++++    ULONG Kseg0Top;
        ULONG Spare7[30];
----    ULONG FirstLevelDcacheSize;\r
----    ULONG FirstLevelDcacheFillSize;\r
----    ULONG FirstLevelIcacheSize;\r
----    ULONG FirstLevelIcacheFillSize;\r
----    ULONG SecondLevelDcacheSize;\r
----    ULONG SecondLevelDcacheFillSize;\r
----    ULONG SecondLevelIcacheSize;\r
++++    ULONG FirstLevelDcacheSize;
++++    ULONG FirstLevelDcacheFillSize;
++++    ULONG FirstLevelIcacheSize;
++++    ULONG FirstLevelIcacheFillSize;
++++    ULONG SecondLevelDcacheSize;
++++    ULONG SecondLevelDcacheFillSize;
++++    ULONG SecondLevelIcacheSize;
        ULONG SecondLevelIcacheFillSize;
        struct _KPRCB *Prcb;
        PVOID Teb;
----    ULONG DcacheAlignment;\r
++++    ULONG DcacheAlignment;
        ULONG DcacheFillSize;
----    ULONG IcacheAlignment;\r
++++    ULONG IcacheAlignment;
        ULONG IcacheFillSize;
----    ULONG ProcessorVersion;\r
++++    ULONG ProcessorVersion;
        ULONG ProcessorRevision;
----    ULONG ProfileInterval;\r
----    ULONG ProfileCount;\r
----    ULONG StallExecutionCount;\r
++++    ULONG ProfileInterval;
++++    ULONG ProfileCount;
++++    ULONG StallExecutionCount;
        ULONG StallScaleFactor;
        ULONG Spare;
----    union\r
----    {\r
----        ULONG CachePolicy;\r
----        struct\r
----        {\r
----            UCHAR IcacheMode;\r
----            UCHAR DcacheMode;\r
----            USHORT ModeSpare;\r
----        };\r
----    };\r
----    UCHAR IrqlMask[32];\r
++++    union
++++    {
++++        ULONG CachePolicy;
++++        struct
++++        {
++++            UCHAR IcacheMode;
++++            UCHAR DcacheMode;
++++            USHORT ModeSpare;
++++        };
++++    };
++++    UCHAR IrqlMask[32];
        UCHAR IrqlTable[9];
----    UCHAR CurrentIrql;\r
----    CCHAR Number;\r
----    KAFFINITY SetMember;\r
----    ULONG ReservedVectors;\r
----    struct _KTHREAD *CurrentThread;\r
----    ULONG AlignedCachePolicy;\r
----    union\r
----    {\r
----        ULONG SoftwareInterrupt;\r
----        struct\r
----        {\r
----            UCHAR ApcInterrupt;\r
----            UCHAR DispatchInterrupt;\r
----            UCHAR Spare4;\r
----            UCHAR Spare5;\r
----        };\r
----    };\r
----    KAFFINITY NotMember;\r
----    ULONG SystemReserved[16];\r
----    ULONG HalReserved[16];\r
----    ULONG FirstLevelActive;\r
----    ULONG SystemServiceDispatchStart;\r
----    ULONG SystemServiceDispatchEnd;\r
----    ULONG InterruptStack;\r
----    ULONG QuantumEnd;\r
----    PVOID InitialStack;\r
----    PVOID PanicStack;\r
----    ULONG BadVaddr;\r
----    PVOID StackLimit;\r
----    PVOID SavedStackLimit;\r
----    ULONG SavedV0;\r
----    ULONG SavedV1;\r
----    UCHAR DebugActive;\r
----    UCHAR Spare6[3];\r
----    ULONG GprSave[6];\r
----    ULONG SiR0;\r
----    ULONG SiR2;\r
----    ULONG SiR3;\r
----    ULONG SiR4;\r
----    ULONG SiR5;\r
----    ULONG Spare0;\r
----    ULONG Spare8;\r
----    ULONG PgDirRa;\r
----    ULONG OnInterruptStack;\r
++++    UCHAR CurrentIrql;
++++    CCHAR Number;
++++    KAFFINITY SetMember;
++++    ULONG ReservedVectors;
++++    struct _KTHREAD *CurrentThread;
++++    ULONG AlignedCachePolicy;
++++    union
++++    {
++++        ULONG SoftwareInterrupt;
++++        struct
++++        {
++++            UCHAR ApcInterrupt;
++++            UCHAR DispatchInterrupt;
++++            UCHAR Spare4;
++++            UCHAR Spare5;
++++        };
++++    };
++++    KAFFINITY NotMember;
++++    ULONG SystemReserved[16];
++++    ULONG HalReserved[16];
++++    ULONG FirstLevelActive;
++++    ULONG SystemServiceDispatchStart;
++++    ULONG SystemServiceDispatchEnd;
++++    ULONG InterruptStack;
++++    ULONG QuantumEnd;
++++    PVOID InitialStack;
++++    PVOID PanicStack;
++++    ULONG BadVaddr;
++++    PVOID StackLimit;
++++    PVOID SavedStackLimit;
++++    ULONG SavedV0;
++++    ULONG SavedV1;
++++    UCHAR DebugActive;
++++    UCHAR Spare6[3];
++++    ULONG GprSave[6];
++++    ULONG SiR0;
++++    ULONG SiR2;
++++    ULONG SiR3;
++++    ULONG SiR4;
++++    ULONG SiR5;
++++    ULONG Spare0;
++++    ULONG Spare8;
++++    ULONG PgDirRa;
++++    ULONG OnInterruptStack;
        ULONG SavedInitialStack;
    } KIPCR, *PKIPCR;
    #pragma pack(pop)
@@@@@ -450,43 -410,43 -410,43 -410,43 +606,43 @@@@@ typedef struct _KTSS 
    //
    typedef struct _KEXCEPTION_FRAME
    {
----    ULONG Fill1;\r
----    ULONG Gpr13;\r
----    ULONG Gpr14;\r
----    ULONG Gpr15;\r
----    ULONG Gpr16;\r
----    ULONG Gpr17;\r
----    ULONG Gpr18;\r
----    ULONG Gpr19;\r
----    ULONG Gpr20;\r
----    ULONG Gpr21;\r
----    ULONG Gpr22;\r
----    ULONG Gpr23;\r
----    ULONG Gpr24;\r
----    ULONG Gpr25;\r
----    ULONG Gpr26;\r
----    ULONG Gpr27;\r
----    ULONG Gpr28;\r
----    ULONG Gpr29;\r
----    ULONG Gpr30;\r
----    ULONG Gpr31;\r
----    DOUBLE Fpr14;\r
----    DOUBLE Fpr15;\r
----    DOUBLE Fpr16;\r
----    DOUBLE Fpr17;\r
----    DOUBLE Fpr18;\r
----    DOUBLE Fpr19;\r
----    DOUBLE Fpr20;\r
----    DOUBLE Fpr21;\r
----    DOUBLE Fpr22;\r
----    DOUBLE Fpr23;\r
----    DOUBLE Fpr24;\r
----    DOUBLE Fpr25;\r
----    DOUBLE Fpr26;\r
----    DOUBLE Fpr27;\r
----    DOUBLE Fpr28;\r
----    DOUBLE Fpr29;\r
----    DOUBLE Fpr30;\r
++++    ULONG Fill1;
++++    ULONG Gpr13;
++++    ULONG Gpr14;
++++    ULONG Gpr15;
++++    ULONG Gpr16;
++++    ULONG Gpr17;
++++    ULONG Gpr18;
++++    ULONG Gpr19;
++++    ULONG Gpr20;
++++    ULONG Gpr21;
++++    ULONG Gpr22;
++++    ULONG Gpr23;
++++    ULONG Gpr24;
++++    ULONG Gpr25;
++++    ULONG Gpr26;
++++    ULONG Gpr27;
++++    ULONG Gpr28;
++++    ULONG Gpr29;
++++    ULONG Gpr30;
++++    ULONG Gpr31;
++++    DOUBLE Fpr14;
++++    DOUBLE Fpr15;
++++    DOUBLE Fpr16;
++++    DOUBLE Fpr17;
++++    DOUBLE Fpr18;
++++    DOUBLE Fpr19;
++++    DOUBLE Fpr20;
++++    DOUBLE Fpr21;
++++    DOUBLE Fpr22;
++++    DOUBLE Fpr23;
++++    DOUBLE Fpr24;
++++    DOUBLE Fpr25;
++++    DOUBLE Fpr26;
++++    DOUBLE Fpr27;
++++    DOUBLE Fpr28;
++++    DOUBLE Fpr29;
++++    DOUBLE Fpr30;
        DOUBLE Fpr31;
    } KEXCEPTION_FRAME, *PKEXCEPTION_FRAME;
    
Simple merge
@@@@@ -81,7 -81,7 -81,7 -81,7 +81,7 @@@@@ extern "C" 
    #ifndef VOID
    #define VOID void
    #endif
----typedef char CHAR;
++++typedef signed char CHAR;
    typedef short SHORT;
    #ifndef LONG_DEFINED
    #define LONG_DEFINED
@@@@@ -3716,19 -3774,15 -3774,15 -3774,15 +3774,17 @@@@@ static __inline__ PVOID GetCurrentFiber
    
    static __inline__ struct _TEB * NtCurrentTeb(void)
    {
-   #ifdef _X86_
        struct _TEB *ret;
    
++++#ifndef _M_PPC
        __asm__ __volatile__ (
            "movl %%fs:0x18, %0\n"
            : "=r" (ret)
            : /* no inputs */
        );
++++#endif
    
        return ret;
-   #elif defined(_PPC_)
-       return NULL;
-   #endif
    }
    
    #elif defined(__WATCOMC__)
@@@@@ -3789,14 -3843,13 -3843,13 -3843,13 +3845,38 @@@@@ InterlockedBitTestAndSet(IN LONG volati
                             IN LONG Bit)
    {
        LONG OldBit;
+   
 +++#ifdef _M_IX86
        __asm__ __volatile__("lock "
                             "btsl %2,%1\n\t"
                             "sbbl %0,%0\n\t"
                             :"=r" (OldBit),"=m" (*Base)
                             :"Ir" (Bit)
                             : "memory");
++++#elif defined(_M_PPC)
++++    LONG scratch;
++++
++++    Bit = 1 << Bit;
++++    /* %0 - OldBit
++++     * %1 - Bit
++++     * %2 - scratch
++++     * %3 - Base
++++     */
++++    __asm__ __volatile__(
++++        "sync\n"
++++        "0:\n\t"
++++        "lwarx %2,0,%3\n\t"
++++            "mr %0,%2\n\t"
++++        "or %2,%1,%2\n\t"
++++        "stwcx. %2,0,%3\n\t"
++++        "bne- 0b\n\t" : 
++++        "=r" (OldBit) :
++++        "r" (Bit),
++++        "r" (scratch),
++++        "r" (Base)
++++        );
 +++#endif
++++
        return OldBit;
    }
    
@@@@@ -3805,24 -3858,32 -3858,32 -3858,32 +3885,74 @@@@@ InterlockedBitTestAndReset(IN LONG vola
                              IN LONG Bit)
    {
        LONG OldBit;
+   
 +++#ifdef _M_IX86
        __asm__ __volatile__("lock "
                             "btrl %2,%1\n\t"
                             "sbbl %0,%0\n\t"
                             :"=r" (OldBit),"=m" (*Base)
                             :"Ir" (Bit)
                             : "memory");
++++#elif defined(_M_PPC)
++++    LONG scratch;
++++
++++    Bit = ~(1 << Bit);
++++    /* %0 - OldBit
++++     * %1 - Bit
++++     * %2 - scratch
++++     * %3 - Base
++++     */
++++    __asm__ __volatile__(
++++        "sync\n"
++++        "0:\n\t"
++++        "lwarx %2,0,%3\n\t"
++++            "mr %0,%2\n\t"
++++        "and %2,%1,%2\n\t"
++++        "stwcx. %2,0,%3\n\t"
++++        "bne- 0b\n\t" : 
++++        "=r" (OldBit) :
++++        "r" (Bit),
++++        "r" (scratch),
++++        "r" (Base)
++++        );
 +++#endif
++++
        return OldBit;
    }
    
+   static __inline__ BOOLEAN
+   BitScanReverse(OUT ULONG *Index,
+                  IN ULONG Mask)
+   {
++++#ifdef _M_IX86
+       BOOLEAN BitPosition = 0;
++++
+       __asm__ __volatile__("bsrl %2,%0\n\t"
+                            "setnz %1\n\t"
+                            :"=&r" (*Index), "=r" (BitPosition)
+                                :"rm" (Mask)
+                                    :"memory");
++++
+       return BitPosition;
++++#else
++++    /* Slow implementation for now */
++++    for( *Index = 31; *Index; *Index-- ) {
++++            if( (1<<*Index) & Mask ) {
++++                    return TRUE;
++++            }
++++    }
++++
++++    return FALSE;
++++#endif
+   }
+   
    #endif
    
 +++#ifdef _M_IX86
    #define YieldProcessor() __asm__ __volatile__("pause");
-   #define YieldProcessor() __asm__("ori 0,0,0");
 +++#elif defined(_M_PPC)
++++#define YieldProcessor() __asm__ __volatile__("nop");
 +++#endif
    
    #if defined(_AMD64_)
    #if defined(_M_AMD64)
Simple merge
    # define _SEHSetJmp setjmp
    # define _SEHJmpBuf_t jmp_buf
    #endif
-   unsigned long DbgPrint(char * Format,...);
 ---unsigned long DbgPrint(const char * Format,...);
    typedef struct __SEHFrame
    {
     _SEHPortableFrame_t SEH_Header;
Simple merge
@@@@@ -110,8 -110,92 -110,92 -110,92 +110,96 @@@@@ RtlRaiseStatus(NTSTATUS Status
    }
    
    /*
-   * @unimplemented
-   */
+    * @implemented
+    */
+   ULONG
+   NTAPI
+   RtlWalkFrameChain(OUT PVOID *Callers,
+                     IN ULONG Count,
+                     IN ULONG Flags)
+   {
+       PULONG Stack, NewStack;
+       ULONG Eip;
+       ULONG_PTR StackBegin, StackEnd;
+       BOOLEAN Result, StopSearch = FALSE;
+       ULONG i = 0;
+   
+       /* Get current EBP */
++++#ifdef _M_IX86
+   #if defined __GNUC__
+       __asm__("mov %%ebp, %0" : "=r" (Stack) : );
+   #elif defined(_MSC_VER)
+       __asm mov Stack, ebp
+   #endif
++++#elif defined(_M_PPC)
++++    __asm__("mr %0, %%r1" : "=r" (Stack) : );
++++#endif
+   
+       /* Set it as the stack begin limit as well */
+       StackBegin = (ULONG_PTR)Stack;
+   
+       /* Check if we're called for non-logging mode */
+       if (!Flags)
+       {
+           /* Get the actual safe limits */
+           Result = RtlpCaptureStackLimits((ULONG_PTR)Stack,
+                                           &StackBegin,
+                                           &StackEnd);
+           if (!Result) return 0;
+       }
+   
+       /* Loop the frames */
+       for (i = 0; i < Count; i++)
+       {
+           /* Check if we're past the stack */
+           if ((ULONG_PTR)Stack >= StackEnd) break;
+   
+           /* Check if this is the first entry */
+   #if 0
+           if (!i)
+           {
+               if ((ULONG_PTR)Stack != StackBegin) break;
+           }
+           else
+           {
+               if ((ULONG_PTR)Stack == StackBegin) break;
+           }
+   #endif
+   
+           /* Make sure there's enough frames */
+           if ((StackEnd - (ULONG_PTR)Stack) < (2 * sizeof(ULONG_PTR))) break;
+   
+           /* Get new stack and EIP */
+           NewStack = (PULONG)Stack[0];
+           Eip = Stack[1];
+   
+           /* Check if the new pointer is above the oldone and past the end */
+           if (!((Stack < NewStack) && ((ULONG_PTR)NewStack < StackEnd)))
+           {
+               /* Stop searching after this entry */
+               StopSearch = TRUE;
+           }
+   
+           /* Also make sure that the EIP isn't a stack address */
+           if ((StackBegin < Eip) && (Eip < StackEnd)) break;
+   
+           /* Save this frame */
+           Callers[i] = (PVOID)Eip;
+   
+           /* Check if we should continue */
+           if (StopSearch) break;
+   
+           /* Move to the next stack */
+           Stack = NewStack;
+       }
+   
+       /* Return frames parsed */
+       return i;
+   }
+   
+   /*
+    * @implemented
+    */
    USHORT
    NTAPI
    RtlCaptureStackBackTrace(IN ULONG FramesToSkip,
@@@@@ -846,147 -907,94 -907,94 -907,94 +907,158 @@@@@ static BOOL HEAP_ValidateFreeArena( SUB
    /***********************************************************************
     *           HEAP_ValidateInUseArena
     */
-   static BOOLEAN HEAP_ValidateInUseArena( SUBHEAP *subheap, ARENA_INUSE *pArena, BOOLEAN quiet )
+   static BOOL HEAP_ValidateInUseArena( const SUBHEAP *subheap, const ARENA_INUSE *pArena, BOOL quiet )
    {
-      char *heapEnd = (char *)subheap + subheap->size;
-   
-      /* Check magic number */
-      if (pArena->magic != ARENA_INUSE_MAGIC)
-      {
-         if (quiet == NOISY)
-         {
-            DPRINT("Heap %p: invalid in-use arena magic for %p\n",
-                   subheap->heap, pArena);
-            if (TRACE_ON(heap))
-               HEAP_Dump( subheap->heap );
-         }
-         else if (WARN_ON(heap))
-         {
-            DPRINT("Heap %p: invalid in-use arena magic for %p\n",
-                   subheap->heap, pArena);
-            if (TRACE_ON(heap))
-               HEAP_Dump( subheap->heap );
-         }
-         return FALSE;
-      }
-      /* Check size flags */
-      if (pArena->size & ARENA_FLAG_FREE)
-      {
-         DPRINT("Heap %p: bad flags %lx for in-use arena %p\n",
-                subheap->heap, pArena->size & ~ARENA_SIZE_MASK, pArena);
-         return FALSE;
-      }
-      /* Check arena size */
-      if ((char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK) > heapEnd)
-      {
-         DPRINT("Heap %p: bad size %08lx for in-use arena %p\n",
-                subheap->heap, (ULONG)pArena->size & ARENA_SIZE_MASK, pArena);
-         return FALSE;
-      }
-      /* Check next arena PREV_FREE flag */
-      if (((char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK) < heapEnd) &&
-            (*(PULONG)((char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK)) & ARENA_FLAG_PREV_FREE))
-      {
-         DPRINT("Heap %p: in-use arena %p next block has PREV_FREE flag\n",
-                subheap->heap, pArena);
-         return FALSE;
-      }
-      /* Check prev free arena */
-      if (pArena->size & ARENA_FLAG_PREV_FREE)
-      {
-         ARENA_FREE *pPrev = *((ARENA_FREE **)pArena - 1);
-         /* Check prev pointer */
-         if (!HEAP_IsValidArenaPtr( subheap->heap, pPrev ))
-         {
-            DPRINT("Heap %p: bad back ptr %p for arena %p\n",
+       const char *heapEnd = (const char *)subheap + subheap->size;
+   
+       /* Check for unaligned pointers */
+       if ( (ULONG_PTR)pArena % ALIGNMENT != 0 )
+       {
+           if ( quiet == NOISY )
+           {
+               ERR( "Heap %p: unaligned arena pointer %p\n", subheap->heap, pArena );
+               if ( TRACE_ON(heap) )
+                   HEAP_Dump( subheap->heap );
+           }
+           else if ( WARN_ON(heap) )
+           {
+               WARN( "Heap %p: unaligned arena pointer %p\n", subheap->heap, pArena );
+               if ( TRACE_ON(heap) )
+                   HEAP_Dump( subheap->heap );
+           }
+           return FALSE;
+       }
+   
+       /* Check magic number */
+       if (pArena->magic != ARENA_INUSE_MAGIC)
+       {
+           if (quiet == NOISY) {
+               ERR("Heap %p: invalid in-use arena magic for %p\n", subheap->heap, pArena );
+               if (TRACE_ON(heap))
+                  HEAP_Dump( subheap->heap );
+           }  else if (WARN_ON(heap)) {
+               WARN("Heap %p: invalid in-use arena magic for %p\n", subheap->heap, pArena );
+               if (TRACE_ON(heap))
+                  HEAP_Dump( subheap->heap );
+           }
+           return FALSE;
+       }
+       /* Check size flags */
+       if (pArena->size & ARENA_FLAG_FREE)
+       {
+           ERR("Heap %p: bad flags %08lx for in-use arena %p\n",
+               subheap->heap, pArena->size & ~ARENA_SIZE_MASK, pArena );
+           return FALSE;
+       }
+       /* Check arena size */
+       if ((const char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK) > heapEnd)
+       {
+           ERR("Heap %p: bad size %08lx for in-use arena %p\n",
+               subheap->heap, pArena->size & ARENA_SIZE_MASK, pArena );
+           return FALSE;
+       }
+       /* Check next arena PREV_FREE flag */
+       if (((const char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK) < heapEnd) &&
+           (*(const DWORD *)((const char *)(pArena + 1) + (pArena->size & ARENA_SIZE_MASK)) & ARENA_FLAG_PREV_FREE))
+       {
+           ERR("Heap %p: in-use arena %p next block has PREV_FREE flag\n",
+               subheap->heap, pArena );
+           return FALSE;
+       }
+       /* Check prev free arena */
+       if (pArena->size & ARENA_FLAG_PREV_FREE)
+       {
+           const ARENA_FREE *pPrev = *((const ARENA_FREE * const*)pArena - 1);
+           /* Check prev pointer */
+           if (!HEAP_IsValidArenaPtr( subheap->heap, pPrev ))
+           {
+               ERR("Heap %p: bad back ptr %p for arena %p\n",
                    subheap->heap, pPrev, pArena );
-            return FALSE;
-         }
-         /* Check that prev arena is free */
-         if (!(pPrev->size & ARENA_FLAG_FREE) ||
+               return FALSE;
+           }
+           /* Check that prev arena is free */
+           if (!(pPrev->size & ARENA_FLAG_FREE) ||
                (pPrev->magic != ARENA_FREE_MAGIC))
-         {
-            DPRINT("Heap %p: prev arena %p invalid for in-use %p\n",
-                   subheap->heap, pPrev, pArena);
-            return FALSE;
-         }
-         /* Check that prev arena is really the previous block */
-         if ((char *)(pPrev + 1) + (pPrev->size & ARENA_SIZE_MASK) != (char *)pArena)
-         {
-            DPRINT("Heap %p: prev arena %p is not prev for in-use %p\n",
+           {
+               ERR("Heap %p: prev arena %p invalid for in-use %p\n",
                    subheap->heap, pPrev, pArena );
-            return FALSE;
-         }
-      }
-      return TRUE;
+               return FALSE;
+           }
+           /* Check that prev arena is really the previous block */
+           if ((const char *)(pPrev + 1) + (pPrev->size & ARENA_SIZE_MASK) != (const char *)pArena)
+           {
+               ERR("Heap %p: prev arena %p is not prev for in-use %p\n",
+                   subheap->heap, pPrev, pArena );
+               return FALSE;
+           }
+       }
+       return TRUE;
    }
    
-   
 +++/***********************************************************************
 +++ *           HEAP_IsInsideHeap
 +++ * Checks whether the pointer points to a block inside a given heap.
 +++ *
 +++ * NOTES
 +++ * Should this return BOOL32?
 +++ *
 +++ * RETURNS
 +++ * !0: Success
 +++ * 0: Failure
 +++ */
 +++int HEAP_IsInsideHeap(
 +++   HANDLE heap, /* [in] Heap */
 +++   ULONG flags,   /* [in] Flags */
 +++   PVOID ptr    /* [in] Pointer */
 +++)
 +++{
 +++   HEAP *heapPtr = HEAP_GetPtr( heap );
 +++   SUBHEAP *subheap;
 +++   int ret;
 +++
 +++   /* Validate the parameters */
 +++
 +++   if (!heapPtr)
 +++      return 0;
 +++   flags |= heapPtr->flags;
 +++   if (!(flags & HEAP_NO_SERIALIZE))
 +++      RtlEnterHeapLock( &heapPtr->critSection );
 +++   ret = (((subheap = HEAP_FindSubHeap( heapPtr, ptr )) != NULL) &&
 +++          (((char *)ptr >= (char *)subheap + subheap->headerSize
 +++            + sizeof(ARENA_INUSE))));
 +++   if (!(flags & HEAP_NO_SERIALIZE))
 +++      RtlLeaveHeapLock( &heapPtr->critSection );
 +++   return ret;
 +++}
 +++
 +++
 +++void DumpStackFrames ( PULONG Frame, ULONG FrameCount )
 +++{
 +++#ifdef _M_IX86
 +++    ULONG i=0;
 +++
 +++    DbgPrint("Frames: ");
 +++    if ( !Frame )
 +++    {
 +++#if defined __GNUC__
 +++            __asm__("mov %%ebp, %0" : "=r" (Frame) : );
 +++#elif defined(_MSC_VER)
 +++            __asm mov [Frame], ebp
 +++#endif
 +++            Frame = (PULONG)Frame[0]; // step out of DumpStackFrames
 +++    }
 +++    while ( Frame != 0 && (ULONG)Frame != 0xDEADBEEF && (ULONG)Frame != 0xcdcdcdcd && (ULONG)Frame != 0xcccccccc && i++ < FrameCount )
 +++    {
 +++            DbgPrint("<%p>", (PVOID)Frame[1]);
 +++            if (Frame[1] == 0xdeadbeef)
 +++                break;
 +++            Frame = (PULONG)Frame[0];
 +++            DbgPrint(" ");
 +++    }
 +++    DbgPrint("\n");
 +++#endif
 +++}
 +++
    /***********************************************************************
     *           HEAP_IsRealArena  [Internal]
     * Validates a block is a valid arena.
Simple merge
    #include <windows.h>
    #include <ndk/ntndk.h>
    
++++#ifdef _M_PPC /* Hmm why is this needed? */
++++#define DBG_PRINTEXCEPTION_C             ((NTSTATUS)0x40010006)
++++#endif
++++
    /* Internal RTL header */
    #include <reactos/helper.h>
    #include "rtlp.h"
@@@@@ -83,6 -83,6 -83,6 -83,6 +83,8 @@@@@ _itoa(int value, char *string, int radi
      return _ltoa(value, string, radix);\r
    }\r
    \r
++++extern void ofw_print_string( const char *str );\r
++++extern void ofw_print_number( int x );\r
    \r
    /*\r
     * @implemented\r
    /* helper function for *scanf.  Returns the value of character c in the
     * given base, or -1 if the given character is not a digit of the base.
     */
++++#if 0
    static int char2digit(char c, int base) {
        if ((c>='0') && (c<='9') && (c<='0'+base-1)) return (c-'0');
        if (base<=10) return -1;
        if ((c>='a') && (c<='z') && (c<='a'+base-11)) return (c-'a'+10);
        return -1;
    }
++++#endif
    
    /* vsscanf */
    #undef WIDE_SCANF
    #undef CONSOLE
    #define STRING 1
----#include "scanf.h"
++++//#include "scanf.h"
    
    int sscanf(const char *str, const char *format, ...)
    {
----    va_list valist;
        int res;
++++#if 0
++++    va_list valist;
    
        va_start(valist, format);
        res = vsscanf(str, format, valist);
        va_end(valist);
++++#endif
++++
        return res;
    }
    
@@@@@ -7,7 -7,7 -7,7 -7,7 +7,9 @@@@@
    
        <!--    __MINGW_IMPORT needs to be defined differently because it's defined
                as dllimport by default, which is invalid from GCC 4.1.0 on!    -->
----    <define name="__MINGW_IMPORT">"extern __attribute__ ((dllexport))"</define>
++++    <if property="ARCH" value="i386">
++++            <define name="__MINGW_IMPORT">"extern __attribute__ ((dllexport))"</define>
++++    </if>
    
        <if property="ARCH" value="i386">
                <directory name="i386">
Simple merge
Simple merge
Simple merge
@@@@@ -44,6 -76,59 -76,51 -76,59 +76,59 @@@@@ extern ULONG_PTR KERNEL_BASE
    extern ULONG KeI386NpxPresent;
    extern ULONG KeI386XMMIPresent;
    extern ULONG KeI386FxsrPresent;
  - extern ULONG trap_stack_top;
+   extern ULONG KeI386CpuType;
+   extern ULONG KeI386CpuStep;
+   extern ULONG KeProcessorArchitecture;
+   extern ULONG KeProcessorLevel;
+   extern ULONG KeProcessorRevision;
+   extern ULONG KeFeatureBits;
+ + extern ULONG Ke386GlobalPagesEnabled;
+ + extern KNODE KiNode0;
+   extern PKNODE KeNodeBlock[1];
+   extern UCHAR KeNumberNodes;
+   extern UCHAR KeProcessNodeSeed;
+ + extern ETHREAD KiInitialThread;
+ + extern EPROCESS KiInitialProcess;
+   extern ULONG KiInterruptTemplate[KINTERRUPT_DISPATCH_CODES];
+   extern PULONG KiInterruptTemplateObject;
+   extern PULONG KiInterruptTemplateDispatch;
+   extern PULONG KiInterruptTemplate2ndDispatch;
+   extern ULONG KiUnexpectedEntrySize;
+   extern PVOID Ki386IopmSaveArea;
+   extern ULONG KeI386EFlagsAndMaskV86;
+   extern ULONG KeI386EFlagsOrMaskV86;
+   extern BOOLEAN KeI386VirtualIntExtensions;
+   extern KIDTENTRY KiIdt[];
+   extern KGDTENTRY KiBootGdt[];
+ + extern KDESCRIPTOR KiGdtDescriptor;
+ + extern KDESCRIPTOR KiIdtDescriptor;
+   extern KTSS KiBootTss;
+ + extern UCHAR P0BootStack[];
+ + extern UCHAR KiDoubleFaultStack[];
+   extern FAST_MUTEX KernelAddressSpaceLock;
+   extern ULONG KiMaximumDpcQueueDepth;
+   extern ULONG KiMinimumDpcRate;
+   extern ULONG KiAdjustDpcThreshold;
+   extern ULONG KiIdealDpcRate;
+   extern LARGE_INTEGER KiTimeIncrementReciprocal;
+   extern UCHAR KiTimeIncrementShiftCount;
+   extern LIST_ENTRY BugcheckCallbackListHead, BugcheckReasonCallbackListHead;
+   extern KSPIN_LOCK BugCheckCallbackLock;
+   extern KDPC KiExpireTimerDpc;
+   extern KTIMER_TABLE_ENTRY KiTimerTableListHead[TIMER_TABLE_SIZE];
+   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;
+   extern PKPRCB KiProcessorBlock[];
+   extern ULONG KiMask32Array[MAXIMUM_PRIORITY];
+   extern ULONG IdleProcessorMask;
+   extern VOID KiTrap8(VOID);
+ + extern VOID KiTrap2(VOID);
    
    /* MACROS *************************************************************************/
    
@@@@@ -708,4 -757,74 -749,54 -757,74 +757,84 @@@@@ KeV86Exception
        ULONG address
    );
    
+   VOID
+   NTAPI
+   KiStartUnexpectedRange(
+       VOID
+   );
+   
+   VOID
+   NTAPI
+   KiEndUnexpectedRange(
+       VOID
+   );
+   
+   VOID
+   NTAPI
+   KiInterruptDispatch(
+       VOID
+   );
+   
+   VOID
+   NTAPI
+   KiChainedDispatch(
+       VOID
+   );
+   
+   VOID
+   NTAPI
+   Ki386AdjustEsp0(
+       IN PKTRAP_FRAME TrapFrame
+   );
+   
+   VOID
+   NTAPI
+   Ki386SetupAndExitToV86Mode(
+       OUT PTEB VdmTeb
+   );
+   
+   VOID
+   NTAPI
+   KeI386VdmInitialize(
+       VOID
+   );
+   
+   VOID
+   NTAPI
+   KiFlushNPXState(
+       IN FLOATING_SAVE_AREA *SaveArea
+   );
+   
+ + VOID
+ + NTAPI
+ + KiInitSpinLocks(
+ +     IN PKPRCB Prcb,
+ +     IN CCHAR Number
+ + );
+ + 
+ + LARGE_INTEGER
+ + NTAPI
+ + KiComputeReciprocal(
+ +     IN LONG Divisor,
+ +     OUT PUCHAR Shift
+ + );
+ + 
+ + VOID
+ + NTAPI
+ + KiInitSystem(
+ +     VOID
+ + );
+ + 
++++#ifdef _M_IX86
++++#define KeHaltProcessor Ke386HaltProcessor
++++#define KeEnableInterrupts Ke386EnableInterrupts
++++#define KeDisableInterrupts Ke386DisableInterrupts
++++#elif defined(_M_PPC)
++++#define KeHaltProcessor KePPCHaltProcessor
++++#define KeEnableInterrupts KePPCEnableInterrupts
++++#define KeDisableInterrupts KePPCDisableInterrupts
++++#endif
++++
+   #include "ke_x.h"
+   
    #endif /* __NTOSKRNL_INCLUDE_INTERNAL_KE_H */
    #include "i386/mm.h"
    #include "i386/fpu.h"
    #include "i386/v86m.h"
 +++#elif defined(_M_PPC)
 +++#include "powerpc/mm.h"
 +++#else
 +++#error "Unknown CPU"
 +++#endif
    #include "ob.h"
    #include "mm.h"
+   #include "ex.h"
    #include "ps.h"
    #include "cc.h"
    #include "io.h"
@@@@@ -120,7 -120,7 -120,7 -120,7 +120,7 @@@@@ __asm__ __volatile__("mfmsr 0\n\t" 
    
    #define KePPCEnableInterrupts() \
     __asm__ __volatile__("mfmsr 0\n\t" \
----                      "li    8,0x8000\n\t" \
++++                      "lis    8,0x8000@ha\n\t" \
                          "or    0,8,0\n\t" \
                          "mtmsr 0\n\t")
    
    #define KeArchEraseFlags()
    #define KeArchDisableInterrupts() KePPCDisableInterrupts()
    
 +++static __inline struct _KPRCB * KeGetCurrentPrcb(
 +++  VOID)
 +++{
 +++  ULONG Value = 0;
 +++  return (struct _KPRCB *) Value;
 +++}
 +++
 +++static __inline KIRQL KeGetCurrentIrql(
 +++    VOID)
 +++{
 +++    return PASSIVE_LEVEL;
 +++}
 +++
 +++VOID
 +++STDCALL
 +++KePPCInitThreadWithContext(
 +++    PKTHREAD Thread,
 +++    PKSYSTEM_ROUTINE SystemRoutine,
 +++    PKSTART_ROUTINE StartRoutine,
 +++    PVOID StartContext,
 +++    PCONTEXT Context);
 +++
 +++VOID
 +++STDCALL
 +++KeApplicationProcessorInitDispatcher(
 +++  VOID);
 +++
 +++VOID
 +++STDCALL
 +++KeCreateApplicationProcessorIdleThread(
 +++  ULONG Id);
 +++
++++VOID KePPCHaltProcessor();
++++
 +++#ifdef _NTOSKRNL_ /* FIXME: Move flags above to NDK instead of here */
 +++VOID
 +++STDCALL
 +++KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
 +++                PKSTART_ROUTINE StartRoutine,
 +++                PVOID StartContext,
 +++                BOOLEAN UserThread,
 +++                KTRAP_FRAME TrapFrame);
 +++#endif
 +++
 +++#endif /* __ASM__ */
 +++
    #endif /* __NTOSKRNL_INCLUDE_INTERNAL_POWERPC_KE_H */
    
    /* EOF */
Simple merge
@@@@@ -292,133 -250,617 -250,617 -250,617 +250,629 @@@@@ KiDoBugCheckCallbacks(VOID
    }
    
    VOID
-   STDCALL
-   KeBugCheckWithTf(ULONG BugCheckCode,
-                    ULONG BugCheckParameter1,
-                    ULONG BugCheckParameter2,
-                    ULONG BugCheckParameter3,
-                    ULONG BugCheckParameter4,
-                    PKTRAP_FRAME Tf)
+   NTAPI
+   KiBugCheckDebugBreak(IN ULONG StatusCode)
+   {
+       /* If KDBG isn't connected, freeze the CPU, otherwise, break */
 ---    if (KdDebuggerNotPresent) for (;;) Ke386HaltProcessor();
++++    if (KdDebuggerNotPresent) for (;;) KeHaltProcessor();
+       DbgBreakPointWithStatus(StatusCode);
+   }
+   
+   PVOID
+   NTAPI
+   KiPcToFileHeader(IN PVOID Eip,
+                    OUT PLDR_DATA_TABLE_ENTRY *LdrEntry,
+                    IN BOOLEAN DriversOnly,
+                    OUT PBOOLEAN InKernel)
    {
-       KIRQL OldIrql;
-       BOOLEAN GotExtendedCrashInfo = FALSE;
-       PVOID Address = 0;
-       PLDR_DATA_TABLE_ENTRY CurrentModule = NULL;
 +++#ifdef _M_IX86
+       ULONG i = 0;
+       PVOID ImageBase, EipBase = NULL;
+       PLDR_DATA_TABLE_ENTRY Entry;
+       PLIST_ENTRY ListHead, NextEntry;
        extern LIST_ENTRY ModuleListHead;
-   #if 0
-       CHAR PrintString[100];
-   #endif
-       /* Make sure we're switching back to the blue screen and print messages on it */
-       HalReleaseDisplayOwnership();
-       if (!KdpDebugMode.Screen)
-       {
-          /* Enable screen debug mode */
-          KdpDebugMode.Screen = TRUE;
-          InitRoutines[0](&DispatchTable[0], 0);
-       }
    
-       /* Try to find out who did this. For this, we need a Trap Frame.
-        * Note: Some special BSODs pass the Frame/EIP as a Param. MSDN has the
-        * info so it eventually needs to be supported.
-        */
-       if (Tf) 
-       {
-           /* For now, get Address from EIP */
-           Address = (PVOID)Tf->Eip;
+       /* Assume no */
+       *InKernel = FALSE;
    
-           /* Try to get information on the module */
-           LIST_FOR_EACH(CurrentModule, &ModuleListHead, LDR_DATA_TABLE_ENTRY, InLoadOrderLinks)
+       /* Set list pointers and make sure it's valid */
+       ListHead = &ModuleListHead;
+       NextEntry = ListHead->Flink;
+       if (NextEntry)
+       {
+           /* Start loop */
+           while (NextEntry != ListHead)
            {
+               /* Increase entry */
+               i++;
+   
+               /* Check if this is a kernel entry and we only want drivers */
+               if ((i <= 2) && (DriversOnly == TRUE))
+               {
+                   /* Skip it */
+                   NextEntry = NextEntry->Flink;
+                   continue;
+               }
+   
+               /* Get the loader entry */
+               Entry = CONTAINING_RECORD(NextEntry,
+                                         LDR_DATA_TABLE_ENTRY,
+                                         InLoadOrderLinks);
+   
+               /* Move to the next entry */
+               NextEntry = NextEntry->Flink;
+               ImageBase = Entry->DllBase;
+   
                /* Check if this is the right one */
-               if ((Address != NULL && (Address >= (PVOID)CurrentModule->DllBase &&
-                    Address < (PVOID)((ULONG_PTR)CurrentModule->DllBase + CurrentModule->SizeOfImage)))) 
+               if (((ULONG_PTR)Eip >= (ULONG_PTR)Entry->DllBase) &&
+                   ((ULONG_PTR)Eip < ((ULONG_PTR)Entry->DllBase + Entry->SizeOfImage)))
                {
-                   /* We got it */
-                   GotExtendedCrashInfo = TRUE;
+                   /* Return this entry */
+                   *LdrEntry = Entry;
+                   EipBase = ImageBase;
+   
+                   /* Check if this was a kernel or HAL entry */
+                   if (i <= 2) *InKernel = TRUE;
                    break;
                }
            }
        }
    
-       /* Raise IRQL to HIGH_LEVEL */
-       Ke386DisableInterrupts();
-       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+       /* Return the base address */
+       return EipBase;
++++#else
++++    return 0;
++++#endif
+   }
    
-       /* Unload the Kernel Adress Space if we own it */
-       if (KernelAddressSpaceLock.Owner == KeGetCurrentThread())
-           MmUnlockAddressSpace(MmGetKernelAddressSpace());
+   PCHAR
+   NTAPI
+   KeBugCheckUnicodeToAnsi(IN PUNICODE_STRING Unicode,
+                           OUT PCHAR Ansi,
+                           IN ULONG Length)
+   {
+       PCHAR p;
+       PWCHAR pw;
+       ULONG i;
+   
+       /* Set length and normalize it */
+       i = Unicode->Length / sizeof(WCHAR);
+       i = min(i, Length - 1);
+   
+       /* Set source and destination, and copy */
+       pw = Unicode->Buffer;
+       p = Ansi;
+       while (i--) *p++ = (CHAR)*pw++;
+   
+       /* Null terminate and return */
+       *p = ANSI_NULL;
+       return Ansi;
+   }
+   
+   VOID
+   NTAPI
+   KiDumpParameterImages(IN PCHAR Message,
+                         IN PULONG_PTR Parameters,
+                         IN ULONG ParameterCount,
+                         IN PKE_BUGCHECK_UNICODE_TO_ANSI ConversionRoutine)
+   {
+       ULONG i;
+       BOOLEAN InSystem;
+       PLDR_DATA_TABLE_ENTRY LdrEntry;
+       PVOID ImageBase;
+       PUNICODE_STRING DriverName;
+       CHAR AnsiName[32];
+       PIMAGE_NT_HEADERS NtHeader;
+       ULONG TimeStamp;
+       BOOLEAN FirstRun = TRUE;
+   
+       /* Loop parameters */
+       for (i = 0; i < ParameterCount; i++)
+       {
+           /* Get the base for this parameter */
+           ImageBase = KiPcToFileHeader((PVOID)Parameters[i],
+                                        &LdrEntry,
+                                        FALSE,
+                                        &InSystem);
+           if (!ImageBase)
+           {
+               /* Driver wasn't found, check for unloaded driver */
+               DriverName = NULL; // FIXME: ROS can't
+               if (!DriverName) continue;
+   
+               /* Convert the driver name */
+               ImageBase = (PVOID)Parameters[i];
+               ConversionRoutine(DriverName, AnsiName, sizeof(AnsiName));
+           }
+           else
+           {
+               /* Get the NT Headers and Timestamp */
+               NtHeader = RtlImageNtHeader(LdrEntry->DllBase);
+               TimeStamp = NtHeader->FileHeader.TimeDateStamp;
+   
+               /* Convert the driver name */
+               DriverName = &LdrEntry->BaseDllName;
+               ConversionRoutine(&LdrEntry->BaseDllName,
+                                 AnsiName,
+                                 sizeof(AnsiName));
+           }
+   
+           /* Format driver name */
+           sprintf(Message,
+                   "%s**  %12s - Address %p base at %p, DateStamp %08lx\n",
+                   FirstRun ? "\r\n*":"*",
+                   AnsiName,
+                   (PVOID)Parameters[i],
+                   ImageBase,
+                   TimeStamp);
+   
+           /* Check if we only had one parameter */
+           if (ParameterCount <= 1)
+           {
+               /* Then just save the name */
+               KiBugCheckDriver = DriverName;
+           }
+           else
+           {
+               /* Otherwise, display the message */
+               InbvDisplayString(Message);
+           }
+   
+           /* Loop again */
+           FirstRun = FALSE;
+       }
+   }
+   
+   VOID
+   NTAPI
+   KiDisplayBlueScreen(IN ULONG MessageId,
+                       IN BOOLEAN IsHardError,
+                       IN PCHAR HardErrCaption OPTIONAL,
+                       IN PCHAR HardErrMessage OPTIONAL,
+                       IN PCHAR Message)
+   {
+       CHAR AnsiName[75];
    
        /* FIXMEs: Use inbv to clear, fill and write to screen. */
    
-       /* Show the STOP Message */
-   #if 0
-       InbvDisplayString("A problem has been detected and ReactOS has been shut down to prevent "
-                         "damage to your computer.\n\n");
-   #else
-       DbgPrint("A problem has been detected and ReactOS has been shut down to prevent "
-                "damage to your computer.\n\n");
-   #endif
-       /* Show the module name of who caused this */
-       if (GotExtendedCrashInfo) 
+       /* Check if this is a hard error */
+       if (IsHardError)
        {
-   #if 0
-           sprintf(PrintString, 
-                   "The problem seems to be caused by the following file: %wZ\n\n",
-                   &CurrentModule->BaseDllName);
-           InbvDisplayString(PrintString);
-   #else
-           DbgPrint("The problem seems to be caused by the following file: %wZ\n\n",
-                    &CurrentModule->BaseDllName);
-   #endif
+           /* Display caption and message */
+           if (HardErrCaption) InbvDisplayString(HardErrCaption);
+           if (HardErrMessage) InbvDisplayString(HardErrMessage);
+           return;
        }
    
-       /* Find the Bug Code String */
-       KeGetBugMessageText(BugCheckCode, NULL);
+       /* Begin the display */
+       InbvDisplayString("\r\n");
+   
+       /* Print out initial message */
+       KeGetBugMessageText(BUGCHECK_MESSAGE_INTRO, NULL);
+       InbvDisplayString("\r\n\r\n");
+   
+       /* Check if we have a driver */
+       if (KiBugCheckDriver)
+       {
+           /* Print out into to driver name */
+           KeGetBugMessageText(BUGCODE_ID_DRIVER, NULL);
+   
+           /* Convert and print out driver name */
+           KeBugCheckUnicodeToAnsi(KiBugCheckDriver, AnsiName, sizeof(AnsiName));
+           InbvDisplayString(" ");
+           InbvDisplayString(AnsiName);
+           InbvDisplayString("\r\n\r\n");
+       }
+   
+       /* Check if this is the generic message */
+       if (MessageId == BUGCODE_PSS_MESSAGE)
+       {
+           /* It is, so get the bug code string as well */
+           KeGetBugMessageText(KiBugCheckData[0], NULL);
+           InbvDisplayString("\r\n\r\n");
+       }
+   
+       /* Print second introduction message */
+       KeGetBugMessageText(PSS_MESSAGE_INTRO, NULL);
+       InbvDisplayString("\r\n\r\n");
+   
+       /* Get the bug code string */
+       KeGetBugMessageText(MessageId, NULL);
+       InbvDisplayString("\r\n\r\n");
+   
+       /* Print message for technical information */
+       KeGetBugMessageText(BUGCHECK_TECH_INFO, NULL);
    
        /* Show the techincal Data */
-   #if 0
-       sprintf(PrintString,
-               "Technical information:\n\n*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)\n\n",
-               BugCheckCode,
-               (PVOID)BugCheckParameter1,
-               (PVOID)BugCheckParameter2,
-               (PVOID)BugCheckParameter3,
-               (PVOID)BugCheckParameter4);
-       InbvDisplayString(PrintString);
-   #else
-       DbgPrint("Technical information:\n\n*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)\n\n",
-                BugCheckCode,
-               (PVOID)BugCheckParameter1,
-               (PVOID)BugCheckParameter2,
-               (PVOID)BugCheckParameter3,
-               (PVOID)BugCheckParameter4);
-   #endif
-       /* Show the module name and more data of who caused this */
-       if (GotExtendedCrashInfo) 
+       sprintf(AnsiName,
+               "\r\n\r\n*** STOP: 0x%08lX (0x%p,0x%p,0x%p,0x%p)\r\n\r\n",
+               KiBugCheckData[0],
+               (PVOID)KiBugCheckData[1],
+               (PVOID)KiBugCheckData[2],
+               (PVOID)KiBugCheckData[3],
+               (PVOID)KiBugCheckData[4]);
+       InbvDisplayString(AnsiName);
+   
+       /* Check if we have a driver*/
+       if (KiBugCheckDriver)
        {
-   #if 0
-           sprintf(PrintString,
-                   "***    %wZ - Address 0x%p base at 0x%p, DateStamp 0x%x\n\n",
-                   &CurrentModule->BaseDllName,
-                   Address,
-                   (PVOID)CurrentModule->DllBase,
-                   0);
-           InbvDisplayString(PrintString);
-   #else
-           DbgPrint("***    %wZ - Address 0x%p base at 0x%p, DateStamp 0x%x\n\n",
-                    &CurrentModule->BaseDllName,
-                    Address,
-                    (PVOID)CurrentModule->DllBase,
-                    0);
+           /* Display technical driver data */
+           InbvDisplayString(Message);
+       }
+       else
+       {
+           /* Dump parameter information */
+           KiDumpParameterImages(Message,
+                                 (PVOID)&KiBugCheckData[1],
+                                 4,
+                                 KeBugCheckUnicodeToAnsi);
+       }
+   }
+   
+   VOID
+   NTAPI
+   KeBugCheckWithTf(IN ULONG BugCheckCode,
+                    IN ULONG_PTR BugCheckParameter1,
+                    IN ULONG_PTR BugCheckParameter2,
+                    IN ULONG_PTR BugCheckParameter3,
+                    IN ULONG_PTR BugCheckParameter4,
+                    IN PKTRAP_FRAME TrapFrame)
+   {
+       PKPRCB Prcb = KeGetCurrentPrcb();
+       CONTEXT Context;
+       ULONG MessageId;
+       CHAR AnsiName[128];
+       BOOLEAN IsSystem, IsHardError = FALSE;
+       PCHAR HardErrCaption = NULL, HardErrMessage = NULL;
+       PVOID Eip = NULL, Memory;
+       PVOID DriverBase;
+       PLDR_DATA_TABLE_ENTRY LdrEntry;
+       PULONG_PTR HardErrorParameters;
+       KIRQL OldIrql;
+   
+       /* Set active bugcheck */
+       KeBugCheckActive = TRUE;
+       KiBugCheckDriver = NULL;
+   
+       /* Check if this is power failure simulation */
+       if (BugCheckCode == POWER_FAILURE_SIMULATE)
+       {
+           /* Call the Callbacks and reboot */;
+           KiDoBugCheckCallbacks();
+           HalReturnToFirmware(HalRebootRoutine);
+       }
+   
+       /* Save the IRQL and set hardware trigger */
+       Prcb->DebuggerSavedIRQL = KeGetCurrentIrql();
+       InterlockedIncrement((PLONG)&KiHardwareTrigger);
+   
+       /* Capture the CPU Context */
 ---    RtlCaptureContext(&Prcb->ProcessorState.ContextFrame);
++++    RtlCaptureContext((PVOID)&Prcb->ProcessorState.ContextFrame);
+       Context = Prcb->ProcessorState.ContextFrame;
+   
+       /* FIXME: Call the Watchdog if it's regsitered */
+   
+       /* Check which bugcode this is */
+       switch (BugCheckCode)
+       {
+           /* These bug checks already have detailed messages, keep them */
+           case UNEXPECTED_KERNEL_MODE_TRAP:
+           case DRIVER_CORRUPTED_EXPOOL:
+           case ACPI_BIOS_ERROR:
+           case ACPI_BIOS_FATAL_ERROR:
+           case THREAD_STUCK_IN_DEVICE_DRIVER:
+           case DATA_BUS_ERROR:
+           case FAT_FILE_SYSTEM:
+           case NO_MORE_SYSTEM_PTES:
+           case INACCESSIBLE_BOOT_DEVICE:
+           case KMODE_EXCEPTION_NOT_HANDLED:
+   
+               /* Keep the same code */
+               MessageId = BugCheckCode;
+               break;
+   
+           /* Check if this is a kernel-mode exception */
+           case KERNEL_MODE_EXCEPTION_NOT_HANDLED:
+   
+               /* Use the generic text message */
+               MessageId = KMODE_EXCEPTION_NOT_HANDLED;
+   
+           /* File-system errors */
+           case NTFS_FILE_SYSTEM:
+   
+               /* Use the generic message for FAT */
+               MessageId = FAT_FILE_SYSTEM;
+   
+           /* Check if this is a coruption of the Mm's Pool */
+           case DRIVER_CORRUPTED_MMPOOL:
+   
+               /* Use generic corruption message */
+               MessageId = DRIVER_CORRUPTED_EXPOOL;
+   
+           /* Check if this is a signature check failure */
+           case STATUS_SYSTEM_IMAGE_BAD_SIGNATURE:
+   
+               /* Use the generic corruption message */
+               MessageId = BUGCODE_PSS_MESSAGE_SIGNATURE;
+   
+           /* All other codes */
+           default:
+   
+               /* Use the default bugcheck message */
+               MessageId = BUGCODE_PSS_MESSAGE;
+       }
+   
+       /* Save bugcheck data */
+       KiBugCheckData[0] = BugCheckCode;
+       KiBugCheckData[1] = BugCheckParameter1;
+       KiBugCheckData[2] = BugCheckParameter2;
+       KiBugCheckData[3] = BugCheckParameter3;
+       KiBugCheckData[4] = BugCheckParameter4;
+   
+       /* Now check what bugcheck this is */
+       switch (BugCheckCode)
+       {
+           /* Invalid access to R/O memory or Unhandled KM Exception */
+           case KERNEL_MODE_EXCEPTION_NOT_HANDLED:
+           case ATTEMPTED_WRITE_TO_READONLY_MEMORY:
+           case ATTEMPTED_EXECUTE_OF_NOEXECUTE_MEMORY:
+   
+               /* Check if we have a trap frame */
+               if (!TrapFrame)
+               {
+                   /* Use parameter 3 as a trap frame, if it exists */
+                   if (BugCheckParameter3) TrapFrame = (PVOID)BugCheckParameter3;
+               }
+   
+               /* Check if we got one now and if we need to get EIP */
+               if ((TrapFrame) &&
+                   (BugCheckCode != KERNEL_MODE_EXCEPTION_NOT_HANDLED))
+               {
++++#ifdef _M_IX86
+                   /* Get EIP */
+                   Eip = (PVOID)TrapFrame->Eip;
++++#elif defined(_M_PPC)
++++            Eip = (PVOID)TrapFrame->Iar;
++++#endif
+               }
+               break;
+   
+           /* Wrong IRQL */
+           case IRQL_NOT_LESS_OR_EQUAL:
+   
+               /*
+                * The NT kernel has 3 special sections:
+                * MISYSPTE, POOLMI and POOLCODE. The bug check code can
+                * determine in which of these sections this bugcode happened
+                * and provide a more detailed analysis. For now, we don't.
+                */
+   
+               /* Eip is in parameter 4 */
+               Eip = (PVOID)BugCheckParameter4;
+   
+               /* Get the driver base */
+               DriverBase = KiPcToFileHeader(Eip, &LdrEntry, FALSE, &IsSystem);
+               if (IsSystem)
+               {
+                   /*
+                    * The error happened inside the kernel or HAL.
+                    * Get the memory address that was being referenced.
+                    */
+                   Memory = (PVOID)BugCheckParameter1;
+   
+                   /* Find to which driver it belongs */
+                   DriverBase = KiPcToFileHeader(Memory,
+                                                 &LdrEntry,
+                                                 TRUE,
+                                                 &IsSystem);
+                   if (DriverBase)
+                   {
+                       /* Get the driver name and update the bug code */
+                       KiBugCheckDriver = &LdrEntry->BaseDllName;
+                       KiBugCheckData[0] = DRIVER_PORTION_MUST_BE_NONPAGED;
+                   }
+                   else
+                   {
+                       /* Find the driver that unloaded at this address */
+                       KiBugCheckDriver = NULL; // FIXME: ROS can't locate
+   
+                       /* Check if the cause was an unloaded driver */
+                       if (KiBugCheckDriver)
+                       {
+                           /* Update bug check code */
+                           KiBugCheckData[0] =
+                               SYSTEM_SCAN_AT_RAISED_IRQL_CAUGHT_IMPROPER_DRIVER_UNLOAD;
+                       }
+                   }
+               }
+               else
+               {
+                   /* Update the bug check code */
+                   KiBugCheckData[0] = DRIVER_IRQL_NOT_LESS_OR_EQUAL;
+               }
+   
+               /* Clear EIP so we don't look it up later */
+               Eip = NULL;
+               break;
+   
+           /* Hard error */
+           case FATAL_UNHANDLED_HARD_ERROR:
+   
+               /* Copy bug check data from hard error */
+               HardErrorParameters = (PULONG_PTR)BugCheckParameter2;
+               KiBugCheckData[0] = BugCheckParameter1;
+               KiBugCheckData[1] = HardErrorParameters[0];
+               KiBugCheckData[2] = HardErrorParameters[1];
+               KiBugCheckData[3] = HardErrorParameters[2];
+               KiBugCheckData[4] = HardErrorParameters[3];
+   
+               /* Remember that this is hard error and set the caption/message */
+               IsHardError = TRUE;
+               HardErrCaption = (PCHAR)BugCheckParameter3;
+               HardErrMessage = (PCHAR)BugCheckParameter4;
+               break;
+   
+           /* Page fault */
+           case PAGE_FAULT_IN_NONPAGED_AREA:
+   
+               /* Assume no driver */
+               DriverBase = NULL;
+   
+               /* Check if we have a trap frame */
+               if (!TrapFrame)
+               {
+                   /* We don't, use parameter 3 if possible */
+                   if (BugCheckParameter3) TrapFrame = (PVOID)BugCheckParameter3;
+               }
+   
+               /* Check if we have a frame now */
+               if (TrapFrame)
+               {
++++#ifdef _M_IX86
+                   /* Get EIP */
+                   Eip = (PVOID)TrapFrame->Eip;
++++#elif defined(_M_PPC)
++++            Eip = (PVOID)TrapFrame->Iar;
 +++#endif
+   
+                   /* Find out if was in the kernel or drivers */
+                   DriverBase = KiPcToFileHeader(Eip, &LdrEntry, FALSE, &IsSystem);
+               }
+   
+               /*
+                * Now we should check if this happened in:
+                * 1) Special Pool 2) Free Special Pool 3) Session Pool
+                * and update the bugcheck code appropriately.
+                */
+   
+               /* Check if we had a driver base */
+               if (DriverBase)
+               {
+                   /* Find the driver that unloaded at this address */
+                   KiBugCheckDriver = NULL; // FIXME: ROS can't locate
+   
+                   /* Check if the cause was an unloaded driver */
+                   if (KiBugCheckDriver)
+                   {
+                       KiBugCheckData[0] =
+                           DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS;
+                   }
+               }
+               break;
+   
+           /* Check if the driver forgot to unlock pages */
+           case DRIVER_LEFT_LOCKED_PAGES_IN_PROCESS:
+   
+               /* EIP is in parameter 1 */
+               Eip = (PVOID)BugCheckParameter1;
+               break;
+   
+           /* Check if the driver consumed too many PTEs */
+           case DRIVER_USED_EXCESSIVE_PTES:
+   
+               /* Driver base is in parameter 1 */
+               DriverBase = (PVOID)BugCheckParameter1;
+               /* FIXME: LdrEntry is uninitialized for god's sake!!!
+                  KiBugCheckDriver = &LdrEntry->BaseDllName; */
+               break;
+   
+           /* Check if the driver has a stuck thread */
+           case THREAD_STUCK_IN_DEVICE_DRIVER:
+   
+               /* The name is in Parameter 3 */
+               KiBugCheckDriver = (PVOID)BugCheckParameter3;
+               break;
+   
+           /* Anything else */
+           default:
+               break;
+       }
+   
+       /* Do we have a driver name? */
+       if (KiBugCheckDriver)
+       {
+           /* Convert it to ANSI */
+           KeBugCheckUnicodeToAnsi(KiBugCheckDriver, AnsiName, sizeof(AnsiName));
+       }
+       else
+       {
+           /* Do we have an EIP? */
+           if (Eip)
+           {
+               /* Dump image name */
+               KiDumpParameterImages(AnsiName,
+                                     (PULONG_PTR)&Eip,
+                                     1,
+                                     KeBugCheckUnicodeToAnsi);
+           }
+       }
+   
+       /* FIXME: Check if we need to save the context for KD */
+   
+       /* Check if a debugger is connected */
+       if ((BugCheckCode != MANUALLY_INITIATED_CRASH) && (KdDebuggerEnabled))
+       {
+           /* Crash on the debugger console */
+           DbgPrint("\n*** Fatal System Error: 0x%08lx\n"
+                    "                       (0x%p,0x%p,0x%p,0x%p)\n\n",
+                    KiBugCheckData[0],
+                    KiBugCheckData[1],
+                    KiBugCheckData[2],
+                    KiBugCheckData[3],
+                    KiBugCheckData[4]);
+   
+           /* Check if the debugger isn't currently connected */
+           if (!KdDebuggerNotPresent)
+           {
+               /* Check if we have a driver to blame */
+               if (KiBugCheckDriver)
+               {
+                   /* Dump it */
+                   DbgPrint("Driver at fault: %s.\n", AnsiName);
+               }
+   
+               /* Check if this was a hard error */
+               if (IsHardError)
+               {
+                   /* Print caption and message */
+                   if (HardErrCaption) DbgPrint(HardErrCaption);
+                   if (HardErrMessage) DbgPrint(HardErrMessage);
+               }
+   
+               /* Break in the debugger */
+               KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_FIRST);
+           }
+           else
+           {
+               /*
+                * ROS HACK.
+                * Ok, so debugging is enabled, but KDBG isn't there.
+                * We'll manually dump the stack for the user.
+                */
+               KeRosDumpStackFrames(NULL, 0);
+           }
+       }
+   
+       /* Switching back to the blue screen so we print messages on it */
+       HalReleaseDisplayOwnership();
+   
+       /* Raise IRQL to HIGH_LEVEL */
 ---    Ke386DisableInterrupts();
++++    KeDisableInterrupts();
+       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+   
+       /* Unlock the Kernel Adress Space if we own it */
+       if (KernelAddressSpaceLock.Owner == KeGetCurrentThread())
+       {
+           MmUnlockAddressSpace(MmGetKernelAddressSpace());
        }
    
-       /* There can only be one Bugcheck per Bootup */
-       if (!InterlockedDecrement((PLONG)&KeBugCheckCount)) 
+       /* Avoid recursion */
+       if (!InterlockedDecrement((PLONG)&KeBugCheckCount))
        {
+           /* Set CPU that is bug checking now */
+           KeBugCheckOwner = Prcb->Number;
+   
    #ifdef CONFIG_SMP
-           LONG i;
            /* Freeze the other CPUs */
            for (i = 0; i < KeNumberProcessors; i++) 
            {
                }
            }
    #endif
-           /* Check if we got a Trap Frame */
-           if (Tf) 
-           {
-               /* Dump it */
-               KiDumpTrapFrame(Tf, BugCheckParameter1, BugCheckParameter2);
-           } 
-           else 
-           {
-               /* We can only dump the frames */
-   #if defined(__GNUC__)
-               KeDumpStackFrames((PULONG)__builtin_frame_address(0));
-   #elif defined(_MSC_VER)
-               __asm push ebp
-               __asm call KeDumpStackFrames
-               __asm add esp, 4
-   #else
-   #error Unknown compiler for inline assembler
-   #endif
-           }
    
-           /* Call the Callbacks */;
-           KiDoBugCheckCallbacks();
+           /* Display the BSOD */
+           KiDisplayBlueScreen(MessageId,
+                               IsHardError,
+                               HardErrCaption,
+                               HardErrMessage,
+                               AnsiName);
    
-           /* Dump the BSOD to the Paging File */
-           MmDumpToPagingFile(BugCheckCode,
-                              BugCheckParameter1,
-                              BugCheckParameter2,
-                              BugCheckParameter3,
-                              BugCheckParameter4,
-                              Tf);
+           /* FIXME: Enable debugger if it was pending */
    
-           /* Wake up the Debugger */
-           if (KdDebuggerEnabled) 
-           {
-               Ke386EnableInterrupts();
-               DbgBreakPointWithStatus(DBG_STATUS_BUGCHECK_SECOND);
-               Ke386DisableInterrupts();
-           }
+           /* Print the last line */
+           InbvDisplayString("\r\n");
+   
+           /* Save the context */
+           Prcb->ProcessorState.ContextFrame = Context;
+   
+           /* FIXME: Support Triage Dump */
+   
+           /* Write the crash dump */
+           MmDumpToPagingFile(KiBugCheckData[4],
+                              KiBugCheckData[0],
+                              KiBugCheckData[1],
+                              KiBugCheckData[2],
+                              KiBugCheckData[3],
+                              TrapFrame);
        }
    
-       /* Halt this CPU now */
-       for (;;) Ke386HaltProcessor();
-   #elif defined(_M_PPC)
-       for (;;);
-   #endif
+       /* Increase recursioun count */
+       KeBugCheckOwnerRecursionCount++;
+       if (KeBugCheckOwnerRecursionCount == 2)
+       {
+           /* Break in the debugger */
+           KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_SECOND);
+       }
+       else if (KeBugCheckOwnerRecursionCount > 2)
+       {
+           /* Halt the CPU */
 ---        for (;;) Ke386HaltProcessor();
++++        for (;;) KeHaltProcessor();
+       }
+   
+       /* Call the Callbacks */
+       KiDoBugCheckCallbacks();
+   
+       /* FIXME: Call Watchdog if enabled */
+   
+       /* Attempt to break in the debugger (otherwise halt CPU) */
+       KiBugCheckDebugBreak(DBG_STATUS_BUGCHECK_SECOND);
+   }
+   
+   /* PUBLIC FUNCTIONS **********************************************************/
+   
+   /*
+    * @implemented
+    */
+   BOOLEAN
+   NTAPI
+   KeDeregisterBugCheckCallback(IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord)
+   {
+       KIRQL OldIrql;
+       BOOLEAN Status = FALSE;
+   
+       /* Raise IRQL to High */
+       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+   
+       /* Check the Current State */
+       if (CallbackRecord->State == BufferInserted)
+       {
+           /* Reset state and remove from list */
+           CallbackRecord->State = BufferEmpty;
+           RemoveEntryList(&CallbackRecord->Entry);
+           Status = TRUE;
+       }
+   
+       /* Lower IRQL and return */
+       KeLowerIrql(OldIrql);
+       return Status;
+   }
+   
+   /*
+    * @implemented
+    */
+   BOOLEAN
+   NTAPI
+   KeDeregisterBugCheckReasonCallback(
+       IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord)
+   {
+       KIRQL OldIrql;
+       BOOLEAN Status = FALSE;
+   
+       /* Raise IRQL to High */
+       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+   
+       /* Check the Current State */
+       if (CallbackRecord->State == BufferInserted)
+       {
+           /* Reset state and remove from list */
+           CallbackRecord->State = BufferEmpty;
+           RemoveEntryList(&CallbackRecord->Entry);
+           Status = TRUE;
+       }
+   
+       /* Lower IRQL and return */
+       KeLowerIrql(OldIrql);
+       return Status;
+   }
+   
+   /*
+    * @implemented
+    */
+   BOOLEAN
+   NTAPI
+   KeRegisterBugCheckCallback(IN PKBUGCHECK_CALLBACK_RECORD CallbackRecord,
+                              IN PKBUGCHECK_CALLBACK_ROUTINE CallbackRoutine,
+                              IN PVOID Buffer,
+                              IN ULONG Length,
+                              IN PUCHAR Component)
+   {
+       KIRQL OldIrql;
+       BOOLEAN Status = FALSE;
+   
+       /* Raise IRQL to High */
+       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+   
+       /* Check the Current State first so we don't double-register */
+       if (CallbackRecord->State == BufferEmpty)
+       {
+           /* Set the Callback Settings and insert into the list */
+           CallbackRecord->Length = Length;
+           CallbackRecord->Buffer = Buffer;
+           CallbackRecord->Component = Component;
+           CallbackRecord->CallbackRoutine = CallbackRoutine;
+           CallbackRecord->State = BufferInserted;
+           InsertTailList(&BugcheckCallbackListHead, &CallbackRecord->Entry);
+           Status = TRUE;
+       }
+   
+       /* Lower IRQL and return */
+       KeLowerIrql(OldIrql);
+       return Status;
+   }
+   
+   /*
+    * @implemented
+    */
+   BOOLEAN
+   NTAPI
+   KeRegisterBugCheckReasonCallback(
+       IN PKBUGCHECK_REASON_CALLBACK_RECORD CallbackRecord,
+       IN PKBUGCHECK_REASON_CALLBACK_ROUTINE CallbackRoutine,
+       IN KBUGCHECK_CALLBACK_REASON Reason,
+       IN PUCHAR Component)
+   {
+       KIRQL OldIrql;
+       BOOLEAN Status = FALSE;
+   
+       /* Raise IRQL to High */
+       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
+   
+       /* Check the Current State first so we don't double-register */
+       if (CallbackRecord->State == BufferEmpty)
+       {
+           /* Set the Callback Settings and insert into the list */
+           CallbackRecord->Component = Component;
+           CallbackRecord->CallbackRoutine = CallbackRoutine;
+           CallbackRecord->State = BufferInserted;
+           CallbackRecord->Reason = Reason;
+           InsertTailList(&BugcheckReasonCallbackListHead,
+                          &CallbackRecord->Entry);
+           Status = TRUE;
+       }
+   
+       /* Lower IRQL and return */
+       KeLowerIrql(OldIrql);
+       return Status;
    }
    
    /*
    
    #include <ntoskrnl.h>
    #define NDEBUG
-   #include <internal/debug.h>
+   #include <debug.h>
    
-   #if defined (ALLOC_PRAGMA)
-   #pragma alloc_text(INIT, KeInitDpc)
-   #endif
+   /* GLOBALS *******************************************************************/
    
+   ULONG KiMaximumDpcQueueDepth = 4;
+   ULONG KiMinimumDpcRate = 3;
+   ULONG KiAdjustDpcThreshold = 20;
+   ULONG KiIdealDpcRate = 20;
+   KMUTEX KiGenericCallDpcMutex;
    
-   /* TYPES *******************************************************************/
+   /* PRIVATE FUNCTIONS *********************************************************/
    
-   #define MAX_QUANTUM 0x7F
+   VOID
+   NTAPI
+   KiQuantumEnd(VOID)
+   {
+       PKPRCB Prcb = KeGetCurrentPrcb();
+       PKTHREAD CurrentThread = KeGetCurrentThread();
+       KIRQL OldIrql;
+       PKPROCESS Process;
+       KPRIORITY OldPriority;
+       KPRIORITY NewPriority;
    
-   /* FUNCTIONS ****************************************************************/
+       /* Check if a DPC Event was requested to be signaled */
+       if (InterlockedExchange(&Prcb->DpcSetEventRequest, 0))
+       {
+           /* Signal it */
 ---        KeSetEvent(&Prcb->DpcEvent, 0, 0);
++++        KeSetEvent((PVOID)&Prcb->DpcEvent, 0, 0);
+       }
+   
+       /* Lock dispatcher */
+       OldIrql = KeRaiseIrqlToSynchLevel();
+       ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL);
+   
+       /* Get the Thread's Process */
+       Process = CurrentThread->ApcState.Process;
+   
+       /* Check if Quantum expired */
+       if (CurrentThread->Quantum <= 0)
+       {
+           /* Reset the new Quantum */
+           CurrentThread->Quantum = CurrentThread->QuantumReset;
+   
+           /* Calculate new priority */
+           OldPriority = CurrentThread->Priority;
+           if (OldPriority < LOW_REALTIME_PRIORITY)
+           {
+               /* Set the New Priority and add the Priority Decrement */
+               NewPriority = OldPriority - CurrentThread->PriorityDecrement - 1;
+   
+               /* Don't go out of bounds */
+               if (NewPriority < CurrentThread->BasePriority)
+               {
+                   NewPriority = CurrentThread->BasePriority;
+               }
+   
+               /* Reset the priority decrement */
+               CurrentThread->PriorityDecrement = 0;
+   
+               /* Set a new priority if needed */
+               if (OldPriority != NewPriority)
+               {
+                   /* Set new Priority */
+                   BOOLEAN Dummy; /* <- This is a hack anyways... */
+                   KiSetPriorityThread(CurrentThread, NewPriority, &Dummy);
+               }
+               else
+               {
+                   /* Queue new thread if none is already */
+                   if (!Prcb->NextThread)
+                   {
+                       /* FIXME: Schedule a New Thread, when ROS will have NT Scheduler */
+                   }
+                   else
+                   {
+                       /* Make the current thread non-premeptive if a new thread is queued */
+                       CurrentThread->Preempted = FALSE;
+                   }
+               }
+           }
+           else
+           {
+               /* Set the Quantum back to Maximum */
+               //if (CurrentThread->DisableQuantum) {
+               //    CurrentThread->Quantum = MAX_QUANTUM;
+               //}
+           }
+       }
+   
+       /* Dispatch the Thread */
+       KeLowerIrql(DISPATCH_LEVEL);
+       KiDispatchThread(Ready);
+   }
    
-   /*
-    * FUNCTION: Initialize DPC handling
-    */
    VOID
-   INIT_FUNCTION
-   NTAPI
-   KeInitDpc(PKPRCB Prcb)
+   FASTCALL
+   KiRetireDpcList(IN PKPRCB Prcb)
    {
-      InitializeListHead(&Prcb->DpcData[0].DpcListHead);
-   #if 0
-      /*
-       * FIXME:
-       *   Prcb->DpcEvent is a NULL pointer.
-       */
-      KeInitializeEvent(Prcb->DpcEvent, 0, 0);
-   #endif
-      KeInitializeSpinLock(&Prcb->DpcData[0].DpcLock);
-      Prcb->MaximumDpcQueueDepth = 4;
-      Prcb->MinimumDpcRate = 3;
-      Prcb->DpcData[0].DpcQueueDepth = 0;
+       PKDPC_DATA DpcData = Prcb->DpcData;
+       PLIST_ENTRY DpcEntry;
+       PKDPC Dpc;
+       PKDEFERRED_ROUTINE DeferredRoutine;
+       PVOID DeferredContext, SystemArgument1, SystemArgument2;
+   
+       /* Main outer loop */
+       do
+       {
+           /* Set us as active */
+           Prcb->DpcRoutineActive = TRUE;
+   
+           /* Check if this is a timer expiration request */
+           if (Prcb->TimerRequest)
+           {
+               /* FIXME: Not yet implemented */
+               ASSERT(FALSE);
+           }
+   
+           /* Loop while we have entries in the queue */
+           while (DpcData->DpcQueueDepth)
+           {
+               /* Lock the DPC data */
+               KefAcquireSpinLockAtDpcLevel(&DpcData->DpcLock);
+   
+               /* Make sure we have an entry */
+               if (!IsListEmpty(&DpcData->DpcListHead))
+               {
+                   /* Remove the DPC from the list */
+                   DpcEntry = RemoveHeadList(&DpcData->DpcListHead);
+                   Dpc = CONTAINING_RECORD(DpcEntry, KDPC, DpcListEntry);
+   
+                   /* Clear its DPC data and save its parameters */
+                   Dpc->DpcData = NULL;
+                   DeferredRoutine = Dpc->DeferredRoutine;
+                   DeferredContext = Dpc->DeferredContext;
+                   SystemArgument1 = Dpc->SystemArgument1;
+                   SystemArgument2 = Dpc->SystemArgument2;
+   
+                   /* Decrease the queue depth */
+                   DpcData->DpcQueueDepth--;
+   
+                   /* Clear DPC Time */
+                   Prcb->DebugDpcTime = 0;
+   
+                   /* Release the lock */
+                   KefReleaseSpinLockFromDpcLevel(&DpcData->DpcLock);
+   
+                   /* Re-enable interrupts */
 ---                Ke386EnableInterrupts();
++++                KeEnableInterrupts();
+   
+                   /* Call the DPC */
+                   DeferredRoutine(Dpc,
+                                   DeferredContext,
+                                   SystemArgument1,
+                                   SystemArgument2);
+                   ASSERT_IRQL(DISPATCH_LEVEL);
+   
+                   /* Disable interrupts and keep looping */
 ---                Ke386DisableInterrupts();
++++                KeDisableInterrupts();
+               }
+               else
+               {
+                   /* The queue should be flushed now */
+                   ASSERT(DpcData->DpcQueueDepth == 0);
+   
+                   /* Release DPC Lock */
+                   KefReleaseSpinLockFromDpcLevel(&DpcData->DpcLock);
+                   break;
+               }
+           }
+   
+           /* Clear DPC Flags */
+           Prcb->DpcRoutineActive = FALSE;
+           Prcb->DpcInterruptRequested = FALSE;
+   
+           /* Check if we have deferred threads */
+           if (Prcb->DeferredReadyListHead.Next)
+           {
+               /* FIXME: 2K3-style scheduling not implemeted */
+               ASSERT(FALSE);
+           }
+       } while (DpcData->DpcQueueDepth);
    }
    
-   /*
-    * @implemented
-    */
    VOID
-   STDCALL
-   KeInitializeThreadedDpc(PKDPC Dpc,
-                           PKDEFERRED_ROUTINE DeferredRoutine,
-                           PVOID DeferredContext)
-   /*
-    * FUNCTION:
-    *          Initalizes a Threaded DPC and registers the DeferredRoutine for it.
-    * ARGUMENTS:
-    *          Dpc = Pointer to a caller supplied DPC to be initialized. The caller must allocate this memory.
-    *          DeferredRoutine = Pointer to associated DPC callback routine.
-    *          DeferredContext = Parameter to be passed to the callback routine.
-    * NOTE: Callers can be running at any IRQL.
-    */
+   NTAPI
+   KiInitializeDpc(IN PKDPC Dpc,
+                   IN PKDEFERRED_ROUTINE DeferredRoutine,
+                   IN PVOID DeferredContext,
+                   IN KOBJECTS Type)
    {
-       DPRINT("Threaded DPC Initializing: %x with Routine: %x\n", Dpc, DeferredRoutine);
-       Dpc->Type = ThreadedDpcObject;
+       /* Setup the DPC Object */
+       Dpc->Type = Type;
        Dpc->Number= 0;
        Dpc->Importance= MediumImportance;
        Dpc->DeferredRoutine = DeferredRoutine;
@@@@@ -109,231 -243,193 -243,193 -243,193 +243,197 @@@@@ KeInitializeDpc(IN PKDPC Dpc
    
    /*
     * @implemented
-    *
-    * FUNCTION:
-    *          Queues a DPC for execution when the IRQL of a processor
-    *          drops below DISPATCH_LEVEL
-    * ARGUMENTS:
-    *          Dpc = Pointed to a DPC Object Initalized by KeInitializeDpc.
-    *          SystemArgument1 = Driver Determined context data
-    *          SystemArgument2 = Driver Determined context data
-    * RETURNS:
-    *          TRUE if the DPC object wasn't already in the queue
-    *          FALSE otherwise
-    * NOTES:
-    *          If there is currently a DPC active on the target processor, or a DPC
-    * interrupt has already been requested on the target processor when a
-    * DPC is queued, then no further action is necessary. The DPC will be
-    * executed on the target processor when its queue entry is processed.
-    *
-    *          If there is not a DPC active on the target processor and a DPC interrupt
-    * has not been requested on the target processor, then the exact treatment
-    * of the DPC is dependent on whether the host system is a UP system or an
-    * MP system.
-    *
-    * UP system.
-    * ----------
-    *          If the DPC is of medium or high importance, the current DPC queue depth
-    * is greater than the maximum target depth, or current DPC request rate is
-    * less the minimum target rate, then a DPC interrupt is requested on the
-    * host processor and the DPC will be processed when the interrupt occurs.
-    * Otherwise, no DPC interupt is requested and the DPC execution will be
-    * delayed until the DPC queue depth is greater that the target depth or the
-    * minimum DPC rate is less than the target rate.
-    *
-    * MP system.
-    * ----------
-    *          If the DPC is being queued to another processor and the depth of the DPC
-    * queue on the target processor is greater than the maximum target depth or
-    * the DPC is of high importance, then a DPC interrupt is requested on the
-    * target processor and the DPC will be processed when the interrupt occurs.
-    * Otherwise, the DPC execution will be delayed on the target processor until
-    * the DPC queue depth on the target processor is greater that the maximum
-    * target depth or the minimum DPC rate on the target processor is less than
-    * the target mimimum rate.
-    *
-    *          If the DPC is being queued to the current processor and the DPC is not of
-    * low importance, the current DPC queue depth is greater than the maximum
-    * target depth, or the minimum DPC rate is less than the minimum target rate,
-    * then a DPC interrupt is request on the current processor and the DPV will
-    * be processed whne the interrupt occurs. Otherwise, no DPC interupt is
-    * requested and the DPC execution will be delayed until the DPC queue depth
-    * is greater that the target depth or the minimum DPC rate is less than the
-    * target rate.
     */
    BOOLEAN
-   STDCALL
-   KeInsertQueueDpc(PKDPC Dpc,
-                    PVOID SystemArgument1,
-                    PVOID SystemArgument2)
+   NTAPI
+   KeInsertQueueDpc(IN PKDPC Dpc,
+                    IN PVOID SystemArgument1,
+                    IN PVOID SystemArgument2)
    {
        KIRQL OldIrql;
-       PKPRCB Prcb;
-   
-       DPRINT("KeInsertQueueDpc(DPC %x, SystemArgument1 %x, SystemArgument2 %x)\n",
-           Dpc, SystemArgument1, SystemArgument2);
+       PKPRCB Prcb, CurrentPrcb = KeGetCurrentPrcb();
+       ULONG Cpu;
+       PKDPC_DATA DpcData;
+       BOOLEAN DpcConfigured = FALSE, DpcInserted = FALSE;
+       ASSERT_DPC(Dpc);
    
        /* Check IRQL and Raise it to HIGH_LEVEL */
-       ASSERT(KeGetCurrentIrql()>=DISPATCH_LEVEL);
        KeRaiseIrql(HIGH_LEVEL, &OldIrql);
    
-       /* Check if this is a Thread DPC, which we don't support (yet) */
-       if (Dpc->Type == ThreadedDpcObject) {
-           KeLowerIrql(OldIrql);
-           return FALSE;
-       }
-   
-   #ifdef CONFIG_SMP
-       /* Get the right PCR for this CPU */
-       if (Dpc->Number >= MAXIMUM_PROCESSORS) {
-   
-           ASSERT (Dpc->Number - MAXIMUM_PROCESSORS < KeNumberProcessors);
-           Prcb = ((PKPCR)((ULONG_PTR)KPCR_BASE + ((Dpc->Number - MAXIMUM_PROCESSORS) * PAGE_SIZE)))->Prcb;
-   
-       } else {
-   
-           ASSERT (Dpc->Number < KeNumberProcessors);
-           Prcb = KeGetCurrentPrcb();
-           Dpc->Number = KeGetCurrentProcessorNumber();
+       /* Check if the DPC has more then the maximum number of CPUs */
+       if (Dpc->Number >= MAXIMUM_PROCESSORS)
+       {
+           /* Then substract the maximum and get that PRCB. */
+           Cpu = Dpc->Number - MAXIMUM_PROCESSORS;
+           Prcb = KiProcessorBlock[Cpu];
        }
-   
-       KiAcquireSpinLock(&Prcb->DpcData[0].DpcLock);
-   #else
-       Prcb = ((PKPCR)KPCR_BASE)->Prcb;
-   #endif
-   
-       /* Get the DPC Data */
-       if (InterlockedCompareExchangeUL(&Dpc->DpcData, &Prcb->DpcData[0].DpcLock, 0)) {
-   
-           DPRINT("DPC Already Inserted\n");
-   #ifdef CONFIG_SMP
-           KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
-   #endif
-           KeLowerIrql(OldIrql);
-           return(FALSE);
+       else
+       {
+           /* Use the current one */
+           Prcb = CurrentPrcb;
+           Cpu = Prcb->Number;
        }
    
-       /* Make sure the lists are free if the Queue is 0 */
-       if (Prcb->DpcData[0].DpcQueueDepth == 0) {
-   
-           ASSERT(IsListEmpty(&Prcb->DpcData[0].DpcListHead));
-       } else {
-   
-           ASSERT(!IsListEmpty(&Prcb->DpcData[0].DpcListHead));
+       /* Check if this is a threaded DPC and threaded DPCs are enabled */
+       if ((Dpc->Type = ThreadedDpcObject) && (Prcb->ThreadDpcEnable))
+       {
+           /* Then use the threaded data */
+           DpcData = &Prcb->DpcData[DPC_THREADED];
        }
-   
-       /* Now we can play with the DPC safely */
-       Dpc->SystemArgument1=SystemArgument1;
-       Dpc->SystemArgument2=SystemArgument2;
-       Prcb->DpcData[0].DpcQueueDepth++;
-       Prcb->DpcData[0].DpcCount++;
-   
-       /* Insert the DPC into the list. HighImportance DPCs go at the beginning  */
-       if (Dpc->Importance == HighImportance) {
-   
-           InsertHeadList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry);
-       } else {
-   
-           InsertTailList(&Prcb->DpcData[0].DpcListHead, &Dpc->DpcListEntry);
+       else
+       {
+           /* Otherwise, use the regular data */
+           DpcData = &Prcb->DpcData[DPC_NORMAL];
        }
-       DPRINT("New DPC Added. Dpc->DpcListEntry.Flink %x\n", Dpc->DpcListEntry.Flink);
-   
-       /* Make sure a DPC isn't executing already and respect rules outlined above. */
-       if ((!Prcb->DpcRoutineActive) && (!Prcb->DpcInterruptRequested)) {
-   
-   #ifdef CONFIG_SMP
-           /* Check if this is the same CPU */
-           if (Prcb != KeGetCurrentPrcb()) {
-   
-               /* Send IPI if High Importance */
-               if ((Dpc->Importance == HighImportance) ||
-                   (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth)) {
    
-                   if (Dpc->Number >= MAXIMUM_PROCESSORS) {
+       /* Acquire the DPC lock */
+       KiAcquireSpinLock(&DpcData->DpcLock);
    
-                       KiIpiSendRequest(1 << (Dpc->Number - MAXIMUM_PROCESSORS), IPI_DPC);
-                   } else {
-   
-                       KiIpiSendRequest(1 << Dpc->Number, IPI_DPC);
-                   }
+       /* Get the DPC Data */
+       if (!InterlockedCompareExchangePointer(&Dpc->DpcData, DpcData, NULL))
+       {
+           /* Now we can play with the DPC safely */
+           Dpc->SystemArgument1 = SystemArgument1;
+           Dpc->SystemArgument2 = SystemArgument2;
+           DpcData->DpcQueueDepth++;
+           DpcData->DpcCount++;
+           DpcConfigured = TRUE;
+   
+           /* Check if this is a high importance DPC */
+           if (Dpc->Importance == HighImportance)
+           {
+               /* Pre-empty other DPCs */
+               InsertHeadList(&DpcData->DpcListHead, &Dpc->DpcListEntry);
+           }
+           else
+           {
+               /* Add it at the end */
+               InsertTailList(&DpcData->DpcListHead, &Dpc->DpcListEntry);
+           }
    
+           /* Check if this is the DPC on the threaded list */
+           if (&Prcb->DpcData[DPC_THREADED].DpcListHead == &DpcData->DpcListHead)
+           {
+               /* Make sure a threaded DPC isn't already active */
+               if (!(Prcb->DpcThreadActive) && (!Prcb->DpcThreadRequested))
+               {
+                   /* FIXME: Setup Threaded DPC */
+                   ASSERT(FALSE);
                }
-           } else {
-   
-               /* Request an Interrupt only if the DPC isn't low priority */
-               if ((Dpc->Importance != LowImportance) ||
-                    (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) ||
-                   (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) {
-   
-                   /* Request Interrupt */
-                   HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
-                   Prcb->DpcInterruptRequested = TRUE;
+           }
+           else
+           {
+               /* Make sure a DPC isn't executing already */
+               if ((!Prcb->DpcRoutineActive) && (!Prcb->DpcInterruptRequested))
+               {
+                   /* Check if this is the same CPU */
+                   if (Prcb != CurrentPrcb)
+                   {
+                       /*
+                        * Check if the DPC is of high importance or above the
+                        * maximum depth. If it is, then make sure that the CPU
+                        * isn't idle, or that it's sleeping.
+                        */
+                       if (((Dpc->Importance == HighImportance) ||
+                           (DpcData->DpcQueueDepth >=
 ---                         Prcb->MaximumDpcQueueDepth)) &&
++++                         Prcb->MaximumDpcQueueDepth))
++++#ifndef _M_PPC
++++                                &&
+                           (!(AFFINITY_MASK(Cpu) & IdleProcessorMask) ||
 ---                         (Prcb->Sleeping)))
++++                         (Prcb->Sleeping))
++++#endif
++++                   )
+                       {
+                           /* Set interrupt requested */
+                           Prcb->DpcInterruptRequested = TRUE;
+   
+                           /* Set DPC inserted */
+                           DpcInserted = TRUE;
+                       }
+                   }
+                   else
+                   {
+                       /* Check if the DPC is of anything but low importance */
+                       if ((Dpc->Importance != LowImportance) ||
+                           (DpcData->DpcQueueDepth >=
+                            Prcb->MaximumDpcQueueDepth) ||
+                           (Prcb->DpcRequestRate < Prcb->MinimumDpcRate))
+                       {
+                           /* Set interrupt requested */
+                           Prcb->DpcInterruptRequested = TRUE;
+   
+                           /* Set DPC inserted */
+                           DpcInserted = TRUE;
+                       }
+                   }
                }
            }
-   #else
-           DPRINT("Requesting Interrupt. Importance: %x. QueueDepth: %x. MaxQueue: %x . RequestRate: %x. MinRate:%x \n", Dpc->Importance, Prcb->DpcData[0].DpcQueueDepth, Prcb->MaximumDpcQueueDepth, Prcb->DpcRequestRate, Prcb->MinimumDpcRate);
+       }
    
-           /* Request an Interrupt only if the DPC isn't low priority */
-           if ((Dpc->Importance != LowImportance) ||
-               (Prcb->DpcData[0].DpcQueueDepth >= Prcb->MaximumDpcQueueDepth) ||
-               (Prcb->DpcRequestRate < Prcb->MinimumDpcRate)) {
+       /* Release the lock */
+       KiReleaseSpinLock(&DpcData->DpcLock);
    
-               /* Request Interrupt */
-               DPRINT("Requesting Interrupt\n");
+       /* Check if the DPC was inserted */
+       if (DpcInserted)
+       {
+           /* Check if this was SMP */
+           if (Prcb != CurrentPrcb)
+           {
+               /* It was, request and IPI */
+               KiIpiSendRequest(AFFINITY_MASK(Cpu), IPI_DPC);
+           }
+           else
+           {
+               /* It wasn't, request an interrupt from HAL */
                HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
-               Prcb->DpcInterruptRequested = TRUE;
            }
-   #endif
        }
-   #ifdef CONFIG_SMP
-       KiReleaseSpinLock(&Prcb->DpcData[0].DpcLock);
-   #endif
+   
        /* Lower IRQL */
        KeLowerIrql(OldIrql);
-       return(TRUE);
+       return DpcConfigured;
    }
    
    /*
     * @implemented
-    *
-    * FUNCTION:
-    *          Removes DPC object from the system dpc queue
-    * ARGUMENTS:
-    *          Dpc = Pointer to DPC to remove from the queue.
-    * RETURNS:
-    *          TRUE if the DPC was in the queue
-    *          FALSE otherwise
     */
    BOOLEAN
-   STDCALL
-   KeRemoveQueueDpc(PKDPC Dpc)
+   NTAPI
+   KeRemoveQueueDpc(IN PKDPC Dpc)
    {
-       BOOLEAN WasInQueue;
-       KIRQL OldIrql;
-   
-       /* Raise IRQL */
-       DPRINT("Removing DPC: %x\n", Dpc);
-       KeRaiseIrql(HIGH_LEVEL, &OldIrql);
-   #ifdef CONFIG_SMP
-       KiAcquireSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock);
-   #endif
+       PKDPC_DATA DpcData;
+       UCHAR DpcType;
+       ASSERT_DPC(Dpc);
    
-       /* First make sure the DPC lock isn't being held */
-       WasInQueue = Dpc->DpcData ? TRUE : FALSE;
-       if (Dpc->DpcData) {
+       /* Disable interrupts */
 ---    Ke386DisableInterrupts();
++++    KeDisableInterrupts();
    
-           /* Remove the DPC */
-           ((PKDPC_DATA)Dpc->DpcData)->DpcQueueDepth--;
-           RemoveEntryList(&Dpc->DpcListEntry);
+       /* Get DPC data and type */
+       DpcType = Dpc->Type;
+       DpcData = Dpc->DpcData;
+       if (DpcData)
+       {
+           /* Acquire the DPC lock */
+           KiAcquireSpinLock(&DpcData->DpcLock);
+   
+           /* Make sure that the data didn't change */
+           if (DpcData == Dpc->DpcData)
+           {
+               /* Remove the DPC */
+               DpcData->DpcQueueDepth--;
+               RemoveEntryList(&Dpc->DpcListEntry);
+               Dpc->DpcData = NULL;
+           }
    
+           /* Release the lock */
+           KiReleaseSpinLock(&DpcData->DpcLock);
        }
-   #ifdef CONFIG_SMP
-           KiReleaseSpinLock(&((PKDPC_DATA)Dpc->DpcData)->DpcLock);
-   #endif
+   
+       /* Re-enable interrupts */
 ---    Ke386EnableInterrupts();
++++    KeEnableInterrupts();
    
        /* Return if the DPC was in the queue or not */
-       KeLowerIrql(OldIrql);
-       return WasInQueue;
+       return DpcData ? TRUE : FALSE;
    }
    
    /*
    
    /* GLOBALS *******************************************************************/
    
- - #define BUILD_OSCSDVERSION(major, minor) (((major & 0xFF) << 8) | (minor & 0xFF))
  - 
- - 
- - ULONG NtMajorVersion = 5;
- - ULONG NtMinorVersion = 0;
- - ULONG NtOSCSDVersion = BUILD_OSCSDVERSION(4, 0);
- - ULONG NtBuildNumber = KERNEL_VERSION_BUILD;
- - ULONG NtGlobalFlag = 0;
-   CHAR  KeNumberProcessors;
  - CHAR KeNumberProcessors;
- - KAFFINITY KeActiveProcessors = 1;
- - ROS_LOADER_PARAMETER_BLOCK KeLoaderBlock;
- - ULONG KeDcacheFlushCount = 0;
- - ULONG KeIcacheFlushCount = 0;
- - ULONG KiDmaIoCoherency = 0; /* RISC Architectures only */
- - ULONG InitSafeBootMode = 0; /* KB83764 */
- - 
+ + /* FreeLDR Module Data */
    LOADER_MODULE KeLoaderModules[64];
    static CHAR KeLoaderModuleStrings[64][256];
- - static CHAR KeLoaderCommandLine[256];
+ + PLOADER_MODULE CachedModules[MaximumCachedModuleType];
+ + 
+ + /* FreeLDR Memory Data */
    ADDRESS_RANGE KeMemoryMap[64];
    ULONG KeMemoryMapRangeCount;
    ULONG_PTR FirstKrnlPhysAddr;
    ULONG_PTR LastKrnlPhysAddr;
    ULONG_PTR LastKernelAddress;
    
- - PVOID KeUserApcDispatcher = NULL;
- - PVOID KeUserCallbackDispatcher = NULL;
- - PVOID KeUserExceptionDispatcher = NULL;
- - PVOID KeRaiseUserExceptionDispatcher = NULL;
- - 
- - ULONG KeLargestCacheLine = 0x40; /* FIXME: Arch-specific */
- - 
- - /* the initial stacks are declared in main_asm.S */
- - extern ULONG kernel_stack;
- - extern ULONG kernel_stack_top;
- - extern ULONG kernel_trap_stack;
- - extern ULONG kernel_trap_stack_top;
- - 
- - /* These point to the aligned 3 pages */
- - ULONG init_stack = (ULONG)&kernel_stack;
- - ULONG init_stack_top = (ULONG)&kernel_stack_top;
- - ULONG trap_stack = (ULONG)&kernel_trap_stack;
- - ULONG trap_stack_top = (ULONG)&kernel_trap_stack_top;
- - 
- - /* Cached modules from the loader block */
- - PLOADER_MODULE CachedModules[MaximumCachedModuleType];
+ + /* FreeLDR Loader Data */
+ + ROS_LOADER_PARAMETER_BLOCK KeLoaderBlock;
+ + static CHAR KeLoaderCommandLine[256];
    
+ + /* FreeLDR PE Hack Data */
    extern unsigned int _image_base__;
    ULONG_PTR KERNEL_BASE = (ULONG_PTR)&_image_base__;
  - 
  - #if defined (ALLOC_PRAGMA)
  - #pragma alloc_text(INIT, _main)
  - #endif
  - 
+   extern LDR_DATA_TABLE_ENTRY HalModuleObject;
    
-   VOID INIT_FUNCTION _main(ULONG MultiBootMagic, PROS_LOADER_PARAMETER_BLOCK _LoaderBlock);
-   
-   #if defined (ALLOC_PRAGMA)
-   #pragma alloc_text(INIT, _main)
-   #endif
-   
- - /* FUNCTIONS ****************************************************************/
- - 
- - /*
- -  * @implemented
- -  */
- - ULONG
- - STDCALL
- - KeGetRecommendedSharedDataAlignment(VOID)
- - {
- -     return KeLargestCacheLine;
- - }
-   
-   VOID
-   #ifdef __GNUC__
-   __attribute((noinline))
-   #endif
-   KiSystemStartup(BOOLEAN BootProcessor)
-   {
-       DPRINT("KiSystemStartup(%d)\n", BootProcessor);
-   
-       /* Initialize the Application Processor */
-       if (!BootProcessor) KeApplicationProcessorInit();
-   
-       /* Initialize the Processor with HAL */
-       HalInitializeProcessor(KeNumberProcessors, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
-   
-       /* Load the Kernel if this is the Boot CPU, else inialize the App CPU only */
-       if (BootProcessor) {
-   
-           /* Initialize the Kernel Executive */
-           ExpInitializeExecutive();
-   
-           /* Free Initial Memory */
-           MiFreeInitMemory();
-   
-           /* Never returns */
-   #if 0
-       /* FIXME:
-            *   The initial thread isn't a real ETHREAD object, we cannot call PspExitThread.
-        */
-       PspExitThread(STATUS_SUCCESS);
-   #else
-       while (1) {
-          LARGE_INTEGER Timeout;
-          Timeout.QuadPart = 0x7fffffffffffffffLL;
-          KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
-       }
-   #endif
-       } else {
-   
-           /* Do application processor initialization */
-           KeApplicationProcessorInitDispatcher();
+ + /* FUNCTIONS *****************************************************************/
    
-           /* Lower IRQL and go to Idle Thread */
-           KeLowerIrql(PASSIVE_LEVEL);
-           PsIdleThreadMain(NULL);
-       }
-   
-       /* Bug Check and loop forever if anything failed */
-       KEBUGCHECK(0);
-       for(;;);
-   }
-   
-   /*
-    * FUNCTION: Called by the boot loader to start the kernel
-    * ARGUMENTS:
-    *          LoaderBlock = Pointer to boot parameters initialized by the boot
-    *                        loader
-    * NOTE: The boot parameters are stored in low memory which will become
-    * invalid after the memory managment is initialized so we make a local copy.
-    */
    VOID
-   INIT_FUNCTION
-   _main(ULONG MultiBootMagic,
-         PROS_LOADER_PARAMETER_BLOCK _LoaderBlock)
+   NTAPI
+   KiRosPrepareForSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
    {
++++#ifdef _M_IX86
        ULONG i;
        ULONG size;
        ULONG HalBase;
        PIMAGE_OPTIONAL_HEADER OptHead;
        CHAR* s;
    
+ +     /* Load the GDT and IDT */
+ +     Ke386SetGlobalDescriptorTable(KiGdtDescriptor);
+ +     Ke386SetInterruptDescriptorTable(KiIdtDescriptor);
+ + 
        /* Copy the Loader Block Data locally since Low-Memory will be wiped */
-       memcpy(&KeLoaderBlock, _LoaderBlock, sizeof(LOADER_PARAMETER_BLOCK));
+       memcpy(&KeLoaderBlock, LoaderBlock, sizeof(ROS_LOADER_PARAMETER_BLOCK));
        memcpy(&KeLoaderModules[1],
               (PVOID)KeLoaderBlock.ModsAddr,
               sizeof(LOADER_MODULE) * KeLoaderBlock.ModsCount);
        KeLoaderBlock.ModsCount++;
        KeLoaderBlock.ModsAddr = (ULONG)&KeLoaderModules;
    
  -         KeLoaderBlock.MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
+       /* Check for BIOS memory map */
+       KeMemoryMapRangeCount = 0;
+       if (KeLoaderBlock.Flags & MB_FLAGS_MMAP_INFO)
+       {
+           /* We have a memory map from the nice BIOS */
+           size = *((PULONG)(KeLoaderBlock.MmapAddr - sizeof(ULONG)));
+           i = 0;
+   
+           /* Map it until we run out of size */
+           while (i < KeLoaderBlock.MmapLength)
+           {
+               /* Copy into the Kernel Memory Map */
+               memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
+                       (PVOID)(KeLoaderBlock.MmapAddr + i),
+                       sizeof(ADDRESS_RANGE));
+   
+               /* Increase Memory Map Count */
+               KeMemoryMapRangeCount++;
+   
+               /* Increase Size */
+               i += size;
+           }
+   
+           /* Save data */
+ +         KeLoaderBlock.MmapLength = KeMemoryMapRangeCount *
+ +                                    sizeof(ADDRESS_RANGE);
+           KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
+       }
+       else
+       {
+           /* Nothing from BIOS */
+           KeLoaderBlock.MmapLength = 0;
+           KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
+       }
+   
        /* Save the Base Address */
        MmSystemRangeStart = (PVOID)KeLoaderBlock.KernelBase;
    
        OptHead = &NtHeader->OptionalHeader;
    
        /* Set Kernel Ending */
- -     KeLoaderModules[0].ModEnd = KeLoaderModules[0].ModStart + PAGE_ROUND_UP((ULONG)OptHead->SizeOfImage);
+ +     KeLoaderModules[0].ModEnd = KeLoaderModules[0].ModStart +
+ +                                 PAGE_ROUND_UP((ULONG)OptHead->SizeOfImage);
    
        /* Create a block for each module */
-       for (i = 1; i < KeLoaderBlock.ModsCount; i++) {
-   
+       for (i = 1; i < KeLoaderBlock.ModsCount; i++)
+       {
            /* Check if we have to copy the path or not */
-           if ((s = strrchr((PCHAR)KeLoaderModules[i].String, '/')) != 0) {
-   
+           if ((s = strrchr((PCHAR)KeLoaderModules[i].String, '/')) != 0)
+           {
                strcpy(KeLoaderModuleStrings[i], s + 1);
-   
-           } else {
-   
+           }
+           else
+           {
                strcpy(KeLoaderModuleStrings[i], (PCHAR)KeLoaderModules[i].String);
            }
    
        }
    
        /* Choose last module address as the final kernel address */
- -     LastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.ModsCount - 1].ModEnd);
-   
-       /* Low level architecture specific initialization */
-       KeInit1((PCHAR)KeLoaderBlock.CommandLine, &LastKernelAddress);
+ +     LastKernelAddress = PAGE_ROUND_UP(KeLoaderModules[KeLoaderBlock.
+ +                                                       ModsCount - 1].ModEnd);
    
        /* Select the HAL Base */
        HalBase = KeLoaderModules[1].ModStart;
                                (PVOID)KERNEL_BASE,
                                &DriverSize);
    
  -     HalModuleObject.SizeOfImage =  RtlImageNtHeader((PVOID)HalModuleObject.DllBase)->OptionalHeader.SizeOfImage;
+       //
+       //
+       // HACK HACK HACK WHEN WILL YOU PEOPLE FIX FREELDR?!?!?!
+       // FREELDR SENDS US AN ***INVALID*** HAL PE HEADER!!!
+       // WE READ IT IN LdrInitModuleManagement ABOVE!!!
+       // WE SET .SizeOfImage TO A *GARBAGE* VALUE!!!
+       //
+       // This dirty hack fixes it, and should make symbol lookup work too.
+       //
+ +     HalModuleObject.SizeOfImage =  RtlImageNtHeader((PVOID)HalModuleObject.
+ +                                                     DllBase)->
+ +                                                     OptionalHeader.SizeOfImage;
+   
        /* Increase the last kernel address with the size of HAL */
        LastKernelAddress += PAGE_ROUND_UP(DriverSize);
    
        FirstKrnlPhysAddr = KeLoaderModules[0].ModStart - KERNEL_BASE + 0x200000;
        LastKrnlPhysAddr = LastKernelAddress - KERNEL_BASE + 0x200000;
    
-       KeMemoryMapRangeCount = 0;
-       if (KeLoaderBlock.Flags & MB_FLAGS_MMAP_INFO) {
-   
-           /* We have a memory map from the nice BIOS */
-           size = *((PULONG)(KeLoaderBlock.MmapAddr - sizeof(ULONG)));
-           i = 0;
-   
-           /* Map it until we run out of size */
-           while (i < KeLoaderBlock.MmapLength) {
-   
-               /* Copy into the Kernel Memory Map */
-               memcpy (&KeMemoryMap[KeMemoryMapRangeCount],
-                       (PVOID)(KeLoaderBlock.MmapAddr + i),
-                       sizeof(ADDRESS_RANGE));
-   
-               /* Increase Memory Map Count */
-               KeMemoryMapRangeCount++;
-   
-               /* Increase Size */
-               i += size;
-           }
-   
-           /* Save data */
-           KeLoaderBlock.MmapLength = KeMemoryMapRangeCount * sizeof(ADDRESS_RANGE);
-           KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
-   
-       } else {
-   
-           /* Nothing from BIOS */
-           KeLoaderBlock.MmapLength = 0;
-           KeLoaderBlock.MmapAddr = (ULONG)KeMemoryMap;
-       }
-   
-       /* Initialize the Debugger */
-       KdInitSystem (0, &KeLoaderBlock);
+       /* Setup the IDT */
+       KeInitExceptions(); // ONCE HACK BELOW IS GONE, MOVE TO KISYSTEMSTARTUP!
+       KeInitInterrupts(); // ROS HACK DEPRECATED SOON BY NEW HAL
++++#elif defined(_M_PPC)
++++    ULONG DriverBase = 0;
++++    ULONG DriverSize = 0;
++++    
++++    memset( KeLoaderModules, 0, sizeof(KeLoaderModules) );
++++    memset( KeLoaderCommandLine, 0, sizeof(KeLoaderCommandLine) );
++++    memset( KeLoaderModuleStrings, 0, sizeof(KeLoaderModuleStrings) );
++++
++++    /* Stop here for now -- we'll write this part later */
++++    char *foo = 0;
++++    *foo = 1;
++++#endif
    
-       /* Initialize HAL */
-       HalInitSystem (0, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
+       /* Load the Kernel with the PE Loader */
+       LdrSafePEProcessModule((PVOID)KERNEL_BASE,
+                              (PVOID)KERNEL_BASE,
+                              (PVOID)DriverBase,
+                              &DriverSize);
    
        /* Do general System Startup */
-       KiSystemStartup(1);
+       KiSystemStartup(LoaderBlock);
    }
    
    /* EOF */
@@@@@ -100,23 -45,29 -45,29 -45,29 +45,29 @@@@@ KiAcquireGuardedMutexContented(IN OUT P
            /* Check if the Guarded Mutex is locked */
            if (OldValue & GM_LOCK_BIT)
            {
+               /* Sanity check */
+               ASSERT((BitsToRemove == GM_LOCK_BIT) ||
+                      ((OldValue & GM_LOCK_WAITER_WOKEN) != 0));
+   
                /* Unlock it by removing the Lock Bit */
-               if (InterlockedCompareExchange(&GuardedMutex->Count,
-                                              OldValue &~ BitsToRemove,
-                                              OldValue) == OldValue)
-               {
-                   /* The Guarded Mutex is now unlocked */
-                   break;
-               }
 ---            NewValue = InterlockedCompareExchange(&GuardedMutex->Count,
++++            NewValue = InterlockedCompareExchange((PLONG)&GuardedMutex->Count,
+                                                     OldValue ^ BitsToRemove,
+                                                     OldValue);
+               if (NewValue == OldValue) break;
+   
+               /* Value got changed behind our backs, start over */
+               OldValue = NewValue;
            }
            else
            {
                /* The Guarded Mutex isn't locked, so simply set the bits */
-               if (InterlockedCompareExchange(&GuardedMutex->Count,
-                                              OldValue | BitsToAdd,
-                                              OldValue) != OldValue)
 ---            NewValue = InterlockedCompareExchange(&GuardedMutex->Count,
++++            NewValue = InterlockedCompareExchange((PLONG)&GuardedMutex->Count,
+                                                     OldValue + BitsToAdd,
+                                                     OldValue);
+               if (NewValue != OldValue)
                {
-                   /* The Guarded Mutex value changed behind our back, start over */
+                   /* Value got changed behind our backs, start over */
+                   OldValue = NewValue;
                    continue;
                }
    
@@@@@ -155,17 -109,18 -109,18 -109,18 +109,18 @@@@@ KiReleaseGuardedMutex(IN OUT PKGUARDED_
        GuardedMutex->Owner = NULL;
    
        /* Add the Lock Bit */
----    OldValue = InterlockedExchangeAdd(&GuardedMutex->Count, 1);
++++    OldValue = InterlockedExchangeAdd((PLONG)&GuardedMutex->Count, 1);
+       ASSERT((OldValue & GM_LOCK_BIT) == 0);
    
        /* Check if it was already locked, but not woken */
-       if (OldValue && !(OldValue & GM_LOCK_WAITER_WOKEN))
+       if ((OldValue) && !(OldValue & GM_LOCK_WAITER_WOKEN))
        {
            /* Update the Oldvalue to what it should be now */
            OldValue |= GM_LOCK_BIT;
    
            /* Remove the Woken bit */
----        if (InterlockedCompareExchange(&GuardedMutex->Count,
-                                          OldValue &~ GM_LOCK_WAITER_WOKEN,
++++        if (InterlockedCompareExchange((PLONG)&GuardedMutex->Count,
+                                          OldValue - GM_LOCK_WAITER_WOKEN,
                                           OldValue) == OldValue)
            {
                /* Signal the Gate */
@@@@@ -33,9 -33,7 -33,7 -33,7 +33,7 @@@@@ KiIpiSendRequest(KAFFINITY TargetSet, U
          if (TargetSet & Current)
          {
             Pcr = (PKPCR)(KPCR_BASE + i * PAGE_SIZE);
-   #ifdef _M_IX86
-        Ke386TestAndSetBit(IpiRequest, &Pcr->Prcb->IpiFrozen);
-   #endif
 ---     Ke386TestAndSetBit(IpiRequest, (PLONG)&Pcr->Prcb->IpiFrozen);
++++     InterlockedBitTestAndSet((PLONG)&Pcr->Prcb->IpiFrozen, IpiRequest);
         HalRequestIpi(i);
          }
       }
@@@@@ -63,19 -59,18 -59,18 -59,18 +59,18 @@@@@ KiIpiServiceRoutine(IN PKTRAP_FRAME Tra
    
       Prcb = KeGetCurrentPrcb();
    
-   #ifdef _M_IX86
-      if (Ke386TestAndClearBit(IPI_APC, &Prcb->IpiFrozen))
 ---   if (Ke386TestAndClearBit(IPI_APC, (PLONG)&Prcb->IpiFrozen))
++++   if (InterlockedBitTestAndReset((PLONG)&Prcb->IpiFrozen, IPI_APC))
       {
          HalRequestSoftwareInterrupt(APC_LEVEL);
       }
    
-      if (Ke386TestAndClearBit(IPI_DPC, &Prcb->IpiFrozen))
 ---   if (Ke386TestAndClearBit(IPI_DPC, (PLONG)&Prcb->IpiFrozen))
++++   if (InterlockedBitTestAndReset((PLONG)&Prcb->IpiFrozen, IPI_DPC))
       {
          Prcb->DpcInterruptRequested = TRUE;
          HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
       }
    
-      if (Ke386TestAndClearBit(IPI_SYNCH_REQUEST, &Prcb->IpiFrozen))
 ---   if (Ke386TestAndClearBit(IPI_SYNCH_REQUEST, (PLONG)&Prcb->IpiFrozen))
++++   if (InterlockedBitTestAndReset((PLONG)&Prcb->IpiFrozen, IPI_SYNCH_REQUEST))
       {
          (void)InterlockedDecrementUL(&Prcb->SignalDone->CurrentPacket[1]);
          if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
             }
          }
          ((VOID (STDCALL*)(PVOID))(Prcb->SignalDone->WorkerRoutine))(Prcb->SignalDone->CurrentPacket[0]);
-         Ke386TestAndClearBit(KeGetCurrentProcessorNumber(), &Prcb->SignalDone->TargetSet);
 ---      Ke386TestAndClearBit(KeGetCurrentProcessorNumber(), (PLONG)&Prcb->SignalDone->TargetSet);
++++      InterlockedBitTestAndReset((PLONG)&Prcb->SignalDone->TargetSet, KeGetCurrentProcessorNumber());
          if (InterlockedCompareExchangeUL(&Prcb->SignalDone->CurrentPacket[2], 0, 0))
          {
    #ifdef DBG
@@@@@ -146,8 -140,7 -140,7 -140,7 +140,7 @@@@@ KiIpiSendPacket(KAFFINITY TargetSet, VO
           {
          Prcb = ((PKPCR)(KPCR_BASE + i * PAGE_SIZE))->Prcb;
          while(0 != InterlockedCompareExchangeUL(&Prcb->SignalDone, (LONG)CurrentPrcb, 0));
-   #ifdef _M_IX86
-         Ke386TestAndSetBit(IPI_SYNCH_REQUEST, &Prcb->IpiFrozen);
 ---      Ke386TestAndSetBit(IPI_SYNCH_REQUEST, (PLONG)&Prcb->IpiFrozen);
++++      InterlockedBitTestAndReset((PLONG)&Prcb->IpiFrozen, IPI_SYNCH_REQUEST);
          if (Processor != CurrentPrcb->SetMember)
          {
             HalRequestIpi(i);
index 0000000,734d1ee,dd820c8,734d1ee..e766864
mode 000000,100644,100644,100644..100644
--- /dev/null
@@@@@ -1,0 -1,330 -1,602 -1,330 +1,332 @@@@@
  - /* $Id$
  -  *
  -  * COPYRIGHT:       See COPYING in the top level directory
  -  * PROJECT:         ReactOS kernel
  -  * FILE:            ntoskrnl/ke/i386/kernel.c
  -  * PURPOSE:         Initializes the kernel
  -  *
  -  * PROGRAMMERS:     David Welch (welch@mcmail.com)
  -  */
  - 
  - /* INCLUDES *****************************************************************/
  - 
  - #include <ntoskrnl.h>
  - #define NDEBUG
  - #include <internal/debug.h>
  - #include <internal/napi.h>
  - 
  - /* GLOBALS *******************************************************************/
  - 
  - PKPRCB KiProcessorBlock[MAXIMUM_PROCESSORS];
  - KNODE KiNode0;
  - PKNODE KeNodeBlock[1];
  - UCHAR KeNumberNodes = 1;
  - UCHAR KeProcessNodeSeed;
  - ETHREAD KiInitialThread;
  - EPROCESS KiInitialProcess;
  - 
  - extern ULONG Ke386GlobalPagesEnabled;
  - extern PVOID trap_stack, init_stack;
  - 
  - /* System-defined Spinlocks */
  - KSPIN_LOCK KiDispatcherLock;
  - KSPIN_LOCK MmPfnLock;
  - KSPIN_LOCK MmSystemSpaceLock;
  - KSPIN_LOCK CcBcbSpinLock;
  - KSPIN_LOCK CcMasterSpinLock;
  - KSPIN_LOCK CcVacbSpinLock;
  - KSPIN_LOCK CcWorkQueueSpinLock;
  - KSPIN_LOCK NonPagedPoolLock;
  - KSPIN_LOCK MmNonPagedPoolLock;
  - KSPIN_LOCK IopCancelSpinLock;
  - KSPIN_LOCK IopVpbSpinLock;
  - KSPIN_LOCK IopDatabaseLock;
  - KSPIN_LOCK IopCompletionLock;
  - KSPIN_LOCK NtfsStructLock;
  - KSPIN_LOCK AfdWorkQueueSpinLock;
  - KSPIN_LOCK KiTimerTableLock[16];
  - KSPIN_LOCK KiReverseStallIpiLock;
  - 
  - KSPIN_LOCK KiFreezeExecutionLock;
  - KSPIN_LOCK Ki486CompatibilityLock;
  - 
  - #if defined (ALLOC_PRAGMA)
  - #pragma alloc_text(INIT, KeInit1)
  - #pragma alloc_text(INIT, KeInit2)
  - #endif
  - 
  - /* FUNCTIONS *****************************************************************/
  - 
  - VOID
  - NTAPI
  - KiInitSystem(VOID)
  - {
  -     ULONG i;
  - 
  -     /* Initialize Bugcheck Callback data */
  -     InitializeListHead(&BugcheckCallbackListHead);
  -     InitializeListHead(&BugcheckReasonCallbackListHead);
  -     KeInitializeSpinLock(&BugCheckCallbackLock);
  - 
  -     /* Initialize the Timer Expiration DPC */
  -     KeInitializeDpc(&KiExpireTimerDpc, KiExpireTimers, NULL);
  -     KeSetTargetProcessorDpc(&KiExpireTimerDpc, 0);
  - 
  -     /* Initialize Profiling data */
  -     KeInitializeSpinLock(&KiProfileLock);
  -     InitializeListHead(&KiProfileListHead);
  -     InitializeListHead(&KiProfileSourceListHead);
  - 
  -     /* Loop the timer table */
  -     for (i = 0; i < TIMER_TABLE_SIZE; i++)
  -     {
  -         /* Initialize the list and entries */
  -         InitializeListHead(&KiTimerTableListHead[i].Entry);
  -         KiTimerTableListHead[i].Time.HighPart = 0xFFFFFFFF;
  -         KiTimerTableListHead[i].Time.LowPart = 0;
  -     }
  - 
  -     /* Initialize old-style list */
  -     InitializeListHead(&KiTimerListHead);
  - 
  -     /* Initialize the Swap event and all swap lists */
  -     KeInitializeEvent(&KiSwapEvent, SynchronizationEvent, FALSE);
  -     InitializeListHead(&KiProcessInSwapListHead);
  -     InitializeListHead(&KiProcessOutSwapListHead);
  -     InitializeListHead(&KiStackInSwapListHead);
  - 
  -     /* Initialize the mutex for generic DPC calls */
  -     KeInitializeMutex(&KiGenericCallDpcMutex, 0);
  - 
  -     /* Initialize the syscall table */
  -     KeServiceDescriptorTable[0].Base = MainSSDT;
  -     KeServiceDescriptorTable[0].Count = NULL;
  -     KeServiceDescriptorTable[0].Limit = NUMBER_OF_SYSCALLS;
  -     KeServiceDescriptorTable[1].Limit = 0;
  -     KeServiceDescriptorTable[0].Number = MainSSPT;
  - 
  -     /* Copy the the current table into the shadow table for win32k */
  -     RtlCopyMemory(KeServiceDescriptorTableShadow,
  -                   KeServiceDescriptorTable,
  -                   sizeof(KeServiceDescriptorTable));
  - }
  - 
  - LARGE_INTEGER
  - NTAPI
  - KiComputeReciprocal(IN LONG Divisor,
  -                     OUT PUCHAR Shift)
  - {
  -     LARGE_INTEGER Reciprocal = {{0}};
  -     LONG BitCount = 0, Remainder = 1;
  - 
  -     /* Start by calculating the remainder */
  -     while (Reciprocal.HighPart >= 0)
  -     {
  -         /* Increase the loop (bit) count */
  -         BitCount++;
  - 
  -         /* Calculate the current fraction */
  -         Reciprocal.HighPart = (Reciprocal.HighPart << 1) |
  -                               (Reciprocal.LowPart >> 31);
  -         Reciprocal.LowPart <<= 1;
  - 
  -         /* Double the remainder and see if we went past the divisor */
  -         Remainder <<= 1;
  -         if (Remainder >= Divisor)
  -         {
  -             /* Set the low-bit and calculate the new remainder */
  -             Remainder -= Divisor;
  -             Reciprocal.LowPart |= 1;
  -         }
  -     }
  - 
  -     /* Check if we have a remainder */
  -     if (Remainder)
  -     {
  -         /* Check if the current fraction value is too large */
  -         if ((Reciprocal.LowPart == 0xFFFFFFFF) &&
  -             (Reciprocal.HighPart == 0xFFFFFFFF))
  -         {
  -             /* Set the high bit and reduce the bit count */
  -             Reciprocal.LowPart = 0;
  -             Reciprocal.HighPart = 0x80000000;
  -             BitCount--;
  -         }
  -         else
  -         {
  -             /* Check if only the lowest bits got too large */
  -             if (Reciprocal.LowPart == 0xFFFFFFFF)
  -             {
  -                 /* Reset them and increase the high bits instead */
  -                 Reciprocal.LowPart = 0;
  -                 Reciprocal.HighPart++;
  -             }
  -             else
  -             {
  -                 /* All is well, increase the low bits */
  -                 Reciprocal.LowPart++;
  -             }
  -         }
  -     }
  - 
  -     /* Now calculate the actual shift and return the reciprocal */
  -     *Shift = (UCHAR)BitCount - 64;
  -     return Reciprocal;
  - }
  - 
  - VOID
  - NTAPI
  - KiInitSpinLocks(IN PKPRCB Prcb,
  -                 IN CCHAR Number)
  - {
  -     ULONG i;
  - 
  -     /* Initialize Dispatcher Fields */
  -     Prcb->QueueIndex = 1;
  -     Prcb->ReadySummary = 0;
  -     Prcb->DeferredReadyListHead.Next = NULL;
  -     for (i = 0; i < 32; i++)
  -     {
  -         /* Initialize the ready list */
  -         InitializeListHead(&Prcb->DispatcherReadyListHead[i]);
  -     }
  - 
  -     /* Initialize DPC Fields */
  -     InitializeListHead(&Prcb->DpcData[DPC_NORMAL].DpcListHead);
  -     KeInitializeSpinLock(&Prcb->DpcData[DPC_NORMAL].DpcLock);
  -     Prcb->DpcData[DPC_NORMAL].DpcQueueDepth = 0;
  -     Prcb->DpcData[DPC_NORMAL].DpcCount = 0;
  -     Prcb->DpcRoutineActive = FALSE;
  -     Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
  -     Prcb->MinimumDpcRate = KiMinimumDpcRate;
  -     Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
  -     KeInitializeDpc(&Prcb->CallDpc, NULL, NULL);
  -     KeSetTargetProcessorDpc(&Prcb->CallDpc, Number);
  -     KeSetImportanceDpc(&Prcb->CallDpc, HighImportance);
  - 
  -     /* Initialize the Wait List Head */
  -     InitializeListHead(&Prcb->WaitListHead);
  - 
  -     /* Initialize Queued Spinlocks */
  -     Prcb->LockQueue[LockQueueDispatcherLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueDispatcherLock].Lock = &KiDispatcherLock;
  -     Prcb->LockQueue[LockQueueExpansionLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueExpansionLock].Lock = NULL;
  -     Prcb->LockQueue[LockQueuePfnLock].Next = NULL;
  -     Prcb->LockQueue[LockQueuePfnLock].Lock = &MmPfnLock;
  -     Prcb->LockQueue[LockQueueSystemSpaceLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueSystemSpaceLock].Lock = &MmSystemSpaceLock;
  -     Prcb->LockQueue[LockQueueBcbLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueBcbLock].Lock = &CcBcbSpinLock;
  -     Prcb->LockQueue[LockQueueMasterLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueMasterLock].Lock = &CcMasterSpinLock;
  -     Prcb->LockQueue[LockQueueVacbLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueVacbLock].Lock = &CcVacbSpinLock;
  -     Prcb->LockQueue[LockQueueWorkQueueLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueWorkQueueLock].Lock = &CcWorkQueueSpinLock;
  -     Prcb->LockQueue[LockQueueNonPagedPoolLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueNonPagedPoolLock].Lock = &NonPagedPoolLock;
  -     Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Lock = &MmNonPagedPoolLock;
  -     Prcb->LockQueue[LockQueueIoCancelLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueIoCancelLock].Lock = &IopCancelSpinLock;
  -     Prcb->LockQueue[LockQueueIoVpbLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueIoVpbLock].Lock = &IopVpbSpinLock;
  -     Prcb->LockQueue[LockQueueIoDatabaseLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueIoDatabaseLock].Lock = &IopDatabaseLock;
  -     Prcb->LockQueue[LockQueueIoCompletionLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueIoCompletionLock].Lock = &IopCompletionLock;
  -     Prcb->LockQueue[LockQueueNtfsStructLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueNtfsStructLock].Lock = &NtfsStructLock;
  -     Prcb->LockQueue[LockQueueAfdWorkQueueLock].Next = NULL;
  -     Prcb->LockQueue[LockQueueAfdWorkQueueLock].Lock = &AfdWorkQueueSpinLock;
  -     Prcb->LockQueue[LockQueueUnusedSpare16].Next = NULL;
  -     Prcb->LockQueue[LockQueueUnusedSpare16].Lock = NULL;
  - 
  -     /* Loop timer locks */
  -     for (i = 0; i < LOCK_QUEUE_TIMER_TABLE_LOCKS; i++)
  -     {
  -         /* Initialize the lock and setup the Queued Spinlock */
  -         KeInitializeSpinLock(&KiTimerTableLock[i]);
  -         Prcb->LockQueue[i].Next = NULL;
  -         Prcb->LockQueue[i].Lock = &KiTimerTableLock[i];
  -     }
  - 
  -     /* Check if this is the boot CPU */
  -     if (!Number)
  -     {
  -         /* Initialize the lock themselves */
  -         KeInitializeSpinLock(&KiDispatcherLock);
  -         KeInitializeSpinLock(&KiReverseStallIpiLock);
  -         KeInitializeSpinLock(&MmPfnLock);
  -         KeInitializeSpinLock(&MmSystemSpaceLock);
  -         KeInitializeSpinLock(&CcBcbSpinLock);
  -         KeInitializeSpinLock(&CcMasterSpinLock);
  -         KeInitializeSpinLock(&CcVacbSpinLock);
  -         KeInitializeSpinLock(&CcWorkQueueSpinLock);
  -         KeInitializeSpinLock(&IopCancelSpinLock);
  -         KeInitializeSpinLock(&IopCompletionLock);
  -         KeInitializeSpinLock(&IopDatabaseLock);
  -         KeInitializeSpinLock(&IopVpbSpinLock);
  -         KeInitializeSpinLock(&NonPagedPoolLock);
  -         KeInitializeSpinLock(&MmNonPagedPoolLock);
  -         KeInitializeSpinLock(&NtfsStructLock);
  -         KeInitializeSpinLock(&AfdWorkQueueSpinLock);
  -         KeInitializeDispatcher(); // ROS OLD DISPATCHER
  -     }
  - }
  - 
  - VOID
  - NTAPI
  - KiInitializePcr(IN ULONG ProcessorNumber,
  -                 IN PKIPCR Pcr,
  -                 IN PKIDTENTRY Idt,
  -                 IN PKGDTENTRY Gdt,
  -                 IN PKTSS Tss,
  -                 IN PKTHREAD IdleThread,
  -                 IN PVOID DpcStack)
  - {
  -     /* Setup the TIB */
  -     Pcr->NtTib.ExceptionList = EXCEPTION_CHAIN_END;
  -     Pcr->NtTib.StackBase = 0;
  -     Pcr->NtTib.StackLimit = 0;
  -     Pcr->NtTib.Self = 0;
  - 
  -     /* Set the Current Thread */
  -     //Pcr->PrcbData.CurrentThread = IdleThread;
  - 
  -     /* Set pointers to ourselves */
  -     Pcr->Self = (PKPCR)Pcr;
  -     Pcr->Prcb = &Pcr->PrcbData;
  - 
  -     /* Set the PCR Version */
  -     Pcr->MajorVersion = PCR_MAJOR_VERSION;
  -     Pcr->MinorVersion = PCR_MINOR_VERSION;
  - 
  -     /* Set the PCRB Version */
  -     Pcr->PrcbData.MajorVersion = 1;
  -     Pcr->PrcbData.MinorVersion = 1;
  - 
  -     /* Set the Build Type */
  -     Pcr->PrcbData.BuildType = 0;
  - 
  -     /* Set the Processor Number and current Processor Mask */
  -     Pcr->PrcbData.Number = (UCHAR)ProcessorNumber;
  -     Pcr->PrcbData.SetMember = 1 << ProcessorNumber;
  - 
  -     /* Set the PRCB for this Processor */
  -     KiProcessorBlock[ProcessorNumber] = Pcr->Prcb;
  - 
  -     /* Start us out at PASSIVE_LEVEL */
  -     Pcr->Irql = PASSIVE_LEVEL;
  - 
  -     /* Set the GDI, IDT, TSS and DPC Stack */
  -     Pcr->GDT = (PVOID)Gdt;
  -     Pcr->IDT = Idt;
  -     Pcr->TSS = Tss;
  -     Pcr->PrcbData.DpcStack = DpcStack;
  - }
  - 
  - VOID
  - NTAPI
  - KiInitializeKernel(IN PKPROCESS InitProcess,
  -                    IN PKTHREAD InitThread,
  -                    IN PVOID IdleStack,
  -                    IN PKPRCB Prcb,
  -                    IN CCHAR Number,
  -                    IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
  - {
  -     BOOLEAN NpxPresent;
  -     ULONG FeatureBits;
  -     LARGE_INTEGER PageDirectory;
  -     PVOID DpcStack;
  - 
  -     /* Detect and set the CPU Type */
  -     KiSetProcessorType();
  - 
  -     /* Set CR0 features based on detected CPU */
  -     KiSetCR0Bits();
  - 
  -     /* Check if an FPU is present */
  -     NpxPresent = KiIsNpxPresent();
  - 
  -     /* Initialize the Power Management Support for this PRCB */
  -     PoInitializePrcb(Prcb);
  - 
  -     /* Bugcheck if this is a 386 CPU */
  -     if (Prcb->CpuType == 3) KeBugCheckEx(0x5D, 0x386, 0, 0, 0);
  - 
  -     /* Get the processor features for the CPU */
  -     FeatureBits = KiGetFeatureBits();
  - 
  -     /* Save feature bits */
  -     Prcb->FeatureBits = FeatureBits;
  - 
  -     /* Get cache line information for this CPU */
  -     KiGetCacheInformation();
  - 
  -     /* Initialize spinlocks and DPC data */
  -     KiInitSpinLocks(Prcb, Number);
  - 
  -     /* Check if this is the Boot CPU */
  -     if (!Number)
  -     {
  -         /* Set Node Data */
  -         KeNodeBlock[0] = &KiNode0;
  -         Prcb->ParentNode = KeNodeBlock[0];
  -         KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
  - 
  -         /* Set boot-level flags */
  -         KeI386NpxPresent = NpxPresent;
  -         KeI386CpuType = Prcb->CpuType;
  -         KeI386CpuStep = Prcb->CpuStep;
  -         KeProcessorArchitecture = 0;
  -         KeProcessorLevel = (USHORT)Prcb->CpuType;
  -         if (Prcb->CpuID) KeProcessorRevision = Prcb->CpuStep;
  -         KeFeatureBits = FeatureBits;
  -         KeI386FxsrPresent = (KeFeatureBits & KF_FXSR) ? TRUE : FALSE;
  -         KeI386XMMIPresent = (KeFeatureBits & KF_XMMI) ? TRUE : FALSE;
  - 
  -         /* Set the current MP Master KPRCB to the Boot PRCB */
  -         Prcb->MultiThreadSetMaster = Prcb;
  - 
  -         /* Initialize some spinlocks */
  -         KeInitializeSpinLock(&KiFreezeExecutionLock);
  -         KeInitializeSpinLock(&Ki486CompatibilityLock);
  - 
  -         /* Initialize portable parts of the OS */
  -         KiInitSystem();
  - 
  -         /* Initialize the Idle Process and the Process Listhead */
  -         InitializeListHead(&KiProcessListHead);
  -         PageDirectory.QuadPart = 0;
  -         KeInitializeProcess(InitProcess,
  -                             0,
  -                             0xFFFFFFFF,
  -                             PageDirectory);
  -         InitProcess->QuantumReset = MAXCHAR;
  -     }
  -     else
  -     {
  -         /* FIXME */
  -         DPRINT1("SMP Boot support not yet present\n");
  -     }
  - 
  - #if 0
  -     /* Setup the Idle Thread */
  -     KeInitializeThread(InitProcess,
  -                        InitThread,
  -                        NULL,
  -                        NULL,
  -                        NULL,
  -                        NULL,
  -                        NULL,
  -                        IdleStack);
  - #endif
  -     InitThread->NextProcessor = Number;
  -     InitThread->Priority = HIGH_PRIORITY;
  -     InitThread->State = Running;
  -     InitThread->Affinity = 1 << Number;
  -     InitThread->WaitIrql = DISPATCH_LEVEL;
  -     InitProcess->ActiveProcessors = 1 << Number;
  - 
  -     /* Set up the thread-related fields in the PRCB */
  -     //Prcb->CurrentThread = InitThread;
  -     Prcb->NextThread = NULL;
  -     //Prcb->IdleThread = InitThread;
  - 
  -     /* Initialize the Debugger */
  -     KdInitSystem (0, &KeLoaderBlock);
  - 
  -     /* Initialize the Kernel Executive */
  -     ExpInitializeExecutive();
  - 
  -     /* Only do this on the boot CPU */
  -     if (!Number)
  -     {
  -         /* Calculate the time reciprocal */
  -         KiTimeIncrementReciprocal =
  -             KiComputeReciprocal(KeMaximumIncrement,
  -                                 &KiTimeIncrementShiftCount);
  - 
  -         /* Update DPC Values in case they got updated by the executive */
  -         Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
  -         Prcb->MinimumDpcRate = KiMinimumDpcRate;
  -         Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
  - 
  -         /* Allocate the DPC Stack */
  -         DpcStack = MmCreateKernelStack(FALSE);
  -         if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
  -         Prcb->DpcStack = DpcStack;
  - 
  -         /* Allocate the IOPM save area. */
  -         Ki386IopmSaveArea = ExAllocatePoolWithTag(PagedPool,
  -                                                   PAGE_SIZE * 2,
  -                                                   TAG('K', 'e', ' ', ' '));
  -         if (!Ki386IopmSaveArea)
  -         {
  -             /* Bugcheck. We need this for V86/VDM support. */
  -             KeBugCheckEx(NO_PAGES_AVAILABLE, 2, PAGE_SIZE * 2, 0, 0);
  -         }
  -     }
  - 
  -     /* Free Initial Memory */
  -     MiFreeInitMemory();
  - 
  -     while (1)
  -     {
  -         LARGE_INTEGER Timeout;
  -         Timeout.QuadPart = 0x7fffffffffffffffLL;
  -         KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
  -     }
  - 
  -     /* Bug Check and loop forever if anything failed */
  -     KEBUGCHECK(0);
  -     for(;;);
  - }
  - 
  - VOID
  - NTAPI
  - KiSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
  - {
  -     /* Currently hacked for CPU 0 only */
  -     ULONG Cpu = 0;
  -     PKIPCR Pcr = (PKIPCR)KPCR_BASE;
  -     PKPRCB Prcb;
  - 
  -     /* Initialize the PCR */
  -     RtlZeroMemory(Pcr, PAGE_SIZE);
  -     KiInitializePcr(Cpu,
  -                     Pcr,
  -                     KiIdt,
  -                     KiBootGdt,
  -                     &KiBootTss,
  -                     &KiInitialThread.Tcb,
  -                     trap_stack);
  -     Prcb = Pcr->Prcb;
  - 
  -     /* Set us as the current process */
  -     KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb;
  - 
  -     /* Clear DR6/7 to cleanup bootloader debugging */
  -     Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr6 = 0;
  -     Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr7 = 0;
  - 
  -     /* Setup the boot (Freeldr should've done), double fault and NMI TSS */
  -     Ki386InitializeTss();
  - 
  -     /* Setup CPU-related fields */
  -     Pcr->Number = Cpu;
  -     Pcr->SetMember = 1 << Cpu;
  -     Pcr->SetMemberCopy = 1 << Cpu;
  -     Prcb->SetMember = 1 << Cpu;
  - 
  -     /* Initialize the Processor with HAL */
  -     HalInitializeProcessor(Cpu, (PLOADER_PARAMETER_BLOCK)&KeLoaderBlock);
  - 
  -     /* Set active processors */
  -     KeActiveProcessors |= Pcr->SetMember;
  -     KeNumberProcessors++;
  - 
  -     /* Raise to HIGH_LEVEL */
  -     KfRaiseIrql(HIGH_LEVEL);
  - 
  -     /* Call main kernel intialization */
  -     KiInitializeKernel(&KiInitialProcess.Pcb,
  -                        &KiInitialThread.Tcb,
  -                        init_stack,
  -                        Prcb,
  -                        Cpu,
  -                        LoaderBlock);
  - }
  - 
  - VOID
  - INIT_FUNCTION
  - NTAPI
  - KeInit2(VOID)
  - {
  -     ULONG Protect;
  - 
  -     /* Check if Fxsr was found */
  -     if (KeI386FxsrPresent)
  -     {
  -         /* Enable it. FIXME: Send an IPI */
  -         Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSFXSR);
  - 
  -         /* Check if XMM was found too */
  -         if (KeI386XMMIPresent)
  -         {
  -             /* Enable it: FIXME: Send an IPI. */
  -             Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSXMMEXCPT);
  - 
  -             /* FIXME: Implement and enable XMM Page Zeroing for Mm */
  -         }
  -     }
  - 
  -     if (KeFeatureBits & KF_GLOBAL_PAGE)
  -     {
  -         ULONG Flags;
  -         /* Enable global pages */
  -         Ke386GlobalPagesEnabled = TRUE;
  -         Ke386SaveFlags(Flags);
  -         Ke386DisableInterrupts();
  -         Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);
  -         Ke386RestoreFlags(Flags);
  -     }
  - 
  -     if (KeFeatureBits & KF_FAST_SYSCALL)
  -     {
  -         extern void KiFastCallEntry(void);
  - 
  -         /* CS Selector of the target segment. */
  -         Ke386Wrmsr(0x174, KGDT_R0_CODE, 0);
  -         /* Target ESP. */
  -         Ke386Wrmsr(0x175, 0, 0);
  -         /* Target EIP. */
  -         Ke386Wrmsr(0x176, (ULONG_PTR)KiFastCallEntry, 0);
  -     }
  - 
  -     /* Does the CPU Support 'prefetchnta' (SSE)  */
  -     if(KeFeatureBits & KF_XMMI)
  -     {
  -         Protect = MmGetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal);
  -         MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect | PAGE_IS_WRITABLE);
  -         /* Replace the ret by a nop */
  -         *(PCHAR)RtlPrefetchMemoryNonTemporal = 0x90;
  -         MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect);
  -     }
  - 
  -     /* Set IDT to writable */
  -     Protect = MmGetPageProtect(NULL, (PVOID)KiIdt);
  -     MmSetPageProtect(NULL, (PVOID)KiIdt, Protect | PAGE_IS_WRITABLE);
  - }
+ + /*\r
+ +  * PROJECT:         ReactOS Kernel\r
+ +  * LICENSE:         GPL - See COPYING in the top level directory\r
+ +  * FILE:            ntoskrnl/ke/krnlinit.c\r
+ +  * PURPOSE:         Portable part of kernel initialization\r
+ +  * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)\r
+ +  */\r
+ + \r
+ + /* INCLUDES *****************************************************************/\r
+ + \r
+ + #include <ntoskrnl.h>\r
+ + #define NDEBUG\r
+ + #include <debug.h>\r
+ + #include <internal/napi.h>\r
+ + \r
+ + /* GLOBALS *******************************************************************/\r
+ + \r
+ + /* PRCB Array */\r
+ + PKPRCB KiProcessorBlock[MAXIMUM_PROCESSORS];\r
+ + \r
+ + /* NUMA Node Support */\r
+ + KNODE KiNode0;\r
+ + PKNODE KeNodeBlock[1];\r
+ + UCHAR KeNumberNodes = 1;\r
+ + UCHAR KeProcessNodeSeed;\r
+ + \r
+ + /* Initial Process and Thread */\r
+ + ETHREAD KiInitialThread;\r
+ + EPROCESS KiInitialProcess;\r
+ + \r
+ + /* System-defined Spinlocks */\r
+ + KSPIN_LOCK KiDispatcherLock;\r
+ + KSPIN_LOCK MmPfnLock;\r
+ + KSPIN_LOCK MmSystemSpaceLock;\r
+ + KSPIN_LOCK CcBcbSpinLock;\r
+ + KSPIN_LOCK CcMasterSpinLock;\r
+ + KSPIN_LOCK CcVacbSpinLock;\r
+ + KSPIN_LOCK CcWorkQueueSpinLock;\r
+ + KSPIN_LOCK NonPagedPoolLock;\r
+ + KSPIN_LOCK MmNonPagedPoolLock;\r
+ + KSPIN_LOCK IopCancelSpinLock;\r
+ + KSPIN_LOCK IopVpbSpinLock;\r
+ + KSPIN_LOCK IopDatabaseLock;\r
+ + KSPIN_LOCK IopCompletionLock;\r
+ + KSPIN_LOCK NtfsStructLock;\r
+ + KSPIN_LOCK AfdWorkQueueSpinLock;\r
+ + KSPIN_LOCK KiTimerTableLock[16];\r
+ + KSPIN_LOCK KiReverseStallIpiLock;\r
+ + \r
+ + /* FUNCTIONS *****************************************************************/\r
+ + \r
+ + VOID\r
+ + NTAPI\r
+ + KiInitSystem(VOID)\r
+ + {\r
+ +     ULONG i;\r
+ + \r
+ +     /* Initialize Bugcheck Callback data */\r
+ +     InitializeListHead(&BugcheckCallbackListHead);\r
+ +     InitializeListHead(&BugcheckReasonCallbackListHead);\r
+ +     KeInitializeSpinLock(&BugCheckCallbackLock);\r
+ + \r
+ +     /* Initialize the Timer Expiration DPC */\r
+ +     KeInitializeDpc(&KiExpireTimerDpc, KiExpireTimers, NULL);\r
+ +     KeSetTargetProcessorDpc(&KiExpireTimerDpc, 0);\r
+ + \r
+ +     /* Initialize Profiling data */\r
+ +     KeInitializeSpinLock(&KiProfileLock);\r
+ +     InitializeListHead(&KiProfileListHead);\r
+ +     InitializeListHead(&KiProfileSourceListHead);\r
+ + \r
+ +     /* Loop the timer table */\r
+ +     for (i = 0; i < TIMER_TABLE_SIZE; i++)\r
+ +     {\r
+ +         /* Initialize the list and entries */\r
+ +         InitializeListHead(&KiTimerTableListHead[i].Entry);\r
+ +         KiTimerTableListHead[i].Time.HighPart = 0xFFFFFFFF;\r
+ +         KiTimerTableListHead[i].Time.LowPart = 0;\r
+ +     }\r
+ + \r
+ +     /* Initialize old-style list */\r
+ +     InitializeListHead(&KiTimerListHead);\r
+ + \r
+ +     /* Initialize the Swap event and all swap lists */\r
+ +     KeInitializeEvent(&KiSwapEvent, SynchronizationEvent, FALSE);\r
+ +     InitializeListHead(&KiProcessInSwapListHead);\r
+ +     InitializeListHead(&KiProcessOutSwapListHead);\r
+ +     InitializeListHead(&KiStackInSwapListHead);\r
+ + \r
+ +     /* Initialize the mutex for generic DPC calls */\r
+ +     KeInitializeMutex(&KiGenericCallDpcMutex, 0);\r
+ + \r
+ +     /* Initialize the syscall table */\r
+ +     KeServiceDescriptorTable[0].Base = MainSSDT;\r
+ +     KeServiceDescriptorTable[0].Count = NULL;\r
+ +     KeServiceDescriptorTable[0].Limit = NUMBER_OF_SYSCALLS;\r
+ +     KeServiceDescriptorTable[1].Limit = 0;\r
+ +     KeServiceDescriptorTable[0].Number = MainSSPT;\r
+ + \r
+ +     /* Copy the the current table into the shadow table for win32k */\r
+ +     RtlCopyMemory(KeServiceDescriptorTableShadow,\r
+ +                   KeServiceDescriptorTable,\r
+ +                   sizeof(KeServiceDescriptorTable));\r
+ + }\r
+ + \r
+ + LARGE_INTEGER\r
+ + NTAPI\r
+ + KiComputeReciprocal(IN LONG Divisor,\r
+ +                     OUT PUCHAR Shift)\r
+ + {\r
+ +     LARGE_INTEGER Reciprocal = {{0}};\r
+ +     LONG BitCount = 0, Remainder = 1;\r
+ + \r
+ +     /* Start by calculating the remainder */\r
+ +     while (Reciprocal.HighPart >= 0)\r
+ +     {\r
+ +         /* Increase the loop (bit) count */\r
+ +         BitCount++;\r
+ + \r
+ +         /* Calculate the current fraction */\r
+ +         Reciprocal.HighPart = (Reciprocal.HighPart << 1) |\r
+ +                               (Reciprocal.LowPart >> 31);\r
+ +         Reciprocal.LowPart <<= 1;\r
+ + \r
+ +         /* Double the remainder and see if we went past the divisor */\r
+ +         Remainder <<= 1;\r
+ +         if (Remainder >= Divisor)\r
+ +         {\r
+ +             /* Set the low-bit and calculate the new remainder */\r
+ +             Remainder -= Divisor;\r
+ +             Reciprocal.LowPart |= 1;\r
+ +         }\r
+ +     }\r
+ + \r
+ +     /* Check if we have a remainder */\r
+ +     if (Remainder)\r
+ +     {\r
+ +         /* Check if the current fraction value is too large */\r
+ +         if ((Reciprocal.LowPart == 0xFFFFFFFF) &&\r
+ +             (Reciprocal.HighPart == 0xFFFFFFFF))\r
+ +         {\r
+ +             /* Set the high bit and reduce the bit count */\r
+ +             Reciprocal.LowPart = 0;\r
+ +             Reciprocal.HighPart = 0x80000000;\r
+ +             BitCount--;\r
+ +         }\r
+ +         else\r
+ +         {\r
+ +             /* Check if only the lowest bits got too large */\r
+ +             if (Reciprocal.LowPart == 0xFFFFFFFF)\r
+ +             {\r
+ +                 /* Reset them and increase the high bits instead */\r
+ +                 Reciprocal.LowPart = 0;\r
+ +                 Reciprocal.HighPart++;\r
+ +             }\r
+ +             else\r
+ +             {\r
+ +                 /* All is well, increase the low bits */\r
+ +                 Reciprocal.LowPart++;\r
+ +             }\r
+ +         }\r
+ +     }\r
+ + \r
+ +     /* Now calculate the actual shift and return the reciprocal */\r
+ +     *Shift = (UCHAR)BitCount - 64;\r
+ +     return Reciprocal;\r
+ + }\r
+ + \r
+ + VOID\r
+ + NTAPI\r
+ + KiInitSpinLocks(IN PKPRCB Prcb,\r
+ +                 IN CCHAR Number)\r
+ + {\r
+ +     ULONG i;\r
+ + \r
+ +     /* Initialize Dispatcher Fields */\r
+ +     Prcb->QueueIndex = 1;\r
+ +     Prcb->ReadySummary = 0;\r
+ +     Prcb->DeferredReadyListHead.Next = NULL;\r
+ +     for (i = 0; i < 32; i++)\r
+ +     {\r
+ +         /* Initialize the ready list */\r
+ +         InitializeListHead(&Prcb->DispatcherReadyListHead[i]);\r
+ +     }\r
+ + \r
+ +     /* Initialize DPC Fields */\r
+ +     InitializeListHead(&Prcb->DpcData[DPC_NORMAL].DpcListHead);\r
+ +     KeInitializeSpinLock(&Prcb->DpcData[DPC_NORMAL].DpcLock);\r
+ +     Prcb->DpcData[DPC_NORMAL].DpcQueueDepth = 0;\r
+ +     Prcb->DpcData[DPC_NORMAL].DpcCount = 0;\r
+ +     Prcb->DpcRoutineActive = FALSE;\r
+ +     Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;\r
+ +     Prcb->MinimumDpcRate = KiMinimumDpcRate;\r
+ +     Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;\r
+ +     KeInitializeDpc(&Prcb->CallDpc, NULL, NULL);\r
+ +     KeSetTargetProcessorDpc(&Prcb->CallDpc, Number);\r
+ +     KeSetImportanceDpc(&Prcb->CallDpc, HighImportance);\r
+ + \r
+ +     /* Initialize the Wait List Head */\r
+ +     InitializeListHead(&Prcb->WaitListHead);\r
+ + \r
+ +     /* Initialize Queued Spinlocks */\r
+ +     Prcb->LockQueue[LockQueueDispatcherLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueDispatcherLock].Lock = &KiDispatcherLock;\r
+ +     Prcb->LockQueue[LockQueueExpansionLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueExpansionLock].Lock = NULL;\r
+ +     Prcb->LockQueue[LockQueuePfnLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueuePfnLock].Lock = &MmPfnLock;\r
+ +     Prcb->LockQueue[LockQueueSystemSpaceLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueSystemSpaceLock].Lock = &MmSystemSpaceLock;\r
+ +     Prcb->LockQueue[LockQueueBcbLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueBcbLock].Lock = &CcBcbSpinLock;\r
+ +     Prcb->LockQueue[LockQueueMasterLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueMasterLock].Lock = &CcMasterSpinLock;\r
+ +     Prcb->LockQueue[LockQueueVacbLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueVacbLock].Lock = &CcVacbSpinLock;\r
+ +     Prcb->LockQueue[LockQueueWorkQueueLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueWorkQueueLock].Lock = &CcWorkQueueSpinLock;\r
+ +     Prcb->LockQueue[LockQueueNonPagedPoolLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueNonPagedPoolLock].Lock = &NonPagedPoolLock;\r
+ +     Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueMmNonPagedPoolLock].Lock = &MmNonPagedPoolLock;\r
+ +     Prcb->LockQueue[LockQueueIoCancelLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueIoCancelLock].Lock = &IopCancelSpinLock;\r
+ +     Prcb->LockQueue[LockQueueIoVpbLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueIoVpbLock].Lock = &IopVpbSpinLock;\r
+ +     Prcb->LockQueue[LockQueueIoDatabaseLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueIoDatabaseLock].Lock = &IopDatabaseLock;\r
+ +     Prcb->LockQueue[LockQueueIoCompletionLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueIoCompletionLock].Lock = &IopCompletionLock;\r
+ +     Prcb->LockQueue[LockQueueNtfsStructLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueNtfsStructLock].Lock = &NtfsStructLock;\r
+ +     Prcb->LockQueue[LockQueueAfdWorkQueueLock].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueAfdWorkQueueLock].Lock = &AfdWorkQueueSpinLock;\r
+ +     Prcb->LockQueue[LockQueueUnusedSpare16].Next = NULL;\r
+ +     Prcb->LockQueue[LockQueueUnusedSpare16].Lock = NULL;\r
+ + \r
+ +     /* Loop timer locks */\r
+ +     for (i = 0; i < LOCK_QUEUE_TIMER_TABLE_LOCKS; i++)\r
+ +     {\r
+ +         /* Initialize the lock and setup the Queued Spinlock */\r
+ +         KeInitializeSpinLock(&KiTimerTableLock[i]);\r
+ +         Prcb->LockQueue[i].Next = NULL;\r
+ +         Prcb->LockQueue[i].Lock = &KiTimerTableLock[i];\r
+ +     }\r
+ + \r
+ +     /* Check if this is the boot CPU */\r
+ +     if (!Number)\r
+ +     {\r
+ +         /* Initialize the lock themselves */\r
+ +         KeInitializeSpinLock(&KiDispatcherLock);\r
+ +         KeInitializeSpinLock(&KiReverseStallIpiLock);\r
+ +         KeInitializeSpinLock(&MmPfnLock);\r
+ +         KeInitializeSpinLock(&MmSystemSpaceLock);\r
+ +         KeInitializeSpinLock(&CcBcbSpinLock);\r
+ +         KeInitializeSpinLock(&CcMasterSpinLock);\r
+ +         KeInitializeSpinLock(&CcVacbSpinLock);\r
+ +         KeInitializeSpinLock(&CcWorkQueueSpinLock);\r
+ +         KeInitializeSpinLock(&IopCancelSpinLock);\r
+ +         KeInitializeSpinLock(&IopCompletionLock);\r
+ +         KeInitializeSpinLock(&IopDatabaseLock);\r
+ +         KeInitializeSpinLock(&IopVpbSpinLock);\r
+ +         KeInitializeSpinLock(&NonPagedPoolLock);\r
+ +         KeInitializeSpinLock(&MmNonPagedPoolLock);\r
+ +         KeInitializeSpinLock(&NtfsStructLock);\r
+ +         KeInitializeSpinLock(&AfdWorkQueueSpinLock);\r
+ +         KeInitializeDispatcher(); // ROS OLD DISPATCHER\r
+ +     }\r
+ + }\r
+ + \r
+ + /* FIXME: Rename and make portable */\r
+ + VOID\r
+ + NTAPI\r
+ + KeInit2(VOID)\r
+ + {\r
+ +     ULONG Protect;\r
+ + \r
++++#ifdef _M_IX86\r
+ +     /* Check if Fxsr was found */\r
+ +     if (KeI386FxsrPresent)\r
+ +     {\r
+ +         /* Enable it. FIXME: Send an IPI */\r
+ +         Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSFXSR);\r
+ + \r
+ +         /* Check if XMM was found too */\r
+ +         if (KeI386XMMIPresent)\r
+ +         {\r
+ +             /* Enable it: FIXME: Send an IPI. */\r
+ +             Ke386SetCr4(Ke386GetCr4() | X86_CR4_OSXMMEXCPT);\r
+ + \r
+ +             /* FIXME: Implement and enable XMM Page Zeroing for Mm */\r
+ +         }\r
+ +     }\r
+ + \r
+ +     if (KeFeatureBits & KF_GLOBAL_PAGE)\r
+ +     {\r
+ +         ULONG Flags;\r
+ +         /* Enable global pages */\r
+ +         Ke386GlobalPagesEnabled = TRUE;\r
+ +         Ke386SaveFlags(Flags);\r
+ +         Ke386DisableInterrupts();\r
+ +         Ke386SetCr4(Ke386GetCr4() | X86_CR4_PGE);\r
+ +         Ke386RestoreFlags(Flags);\r
+ +     }\r
+ + \r
+ +     if (KeFeatureBits & KF_FAST_SYSCALL)\r
+ +     {\r
+ +         extern void KiFastCallEntry(void);\r
+ + \r
+ +         /* CS Selector of the target segment. */\r
+ +         Ke386Wrmsr(0x174, KGDT_R0_CODE, 0);\r
+ +         /* Target ESP. */\r
+ +         Ke386Wrmsr(0x175, 0, 0);\r
+ +         /* Target EIP. */\r
+ +         Ke386Wrmsr(0x176, (ULONG_PTR)KiFastCallEntry, 0);\r
+ +     }\r
++++#endif\r
+ + \r
+ +     /* Does the CPU Support 'prefetchnta' (SSE)  */\r
+ +     if(KeFeatureBits & KF_XMMI)\r
+ +     {\r
+ +         Protect = MmGetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal);\r
+ +         MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect | PAGE_IS_WRITABLE);\r
+ +         /* Replace the ret by a nop */\r
+ +         *(PCHAR)RtlPrefetchMemoryNonTemporal = 0x90;\r
+ +         MmSetPageProtect(NULL, (PVOID)RtlPrefetchMemoryNonTemporal, Protect);\r
+ +     }\r
+ + \r
+ +     /* Set IDT to writable */\r
+ +     Protect = MmGetPageProtect(NULL, (PVOID)KiIdt);\r
+ +     MmSetPageProtect(NULL, (PVOID)KiIdt, Protect | PAGE_IS_WRITABLE);\r
+ + }\r
@@@@@ -858,49 -852,130 -852,130 -852,130 +852,134 @@@@@ KeInitThread(IN OUT PKTHREAD Thread
        Thread->StackLimit = (ULONG_PTR)KernelStack - KERNEL_STACK_SIZE;
        Thread->KernelStackResident = TRUE;
    
-       /*
-        * Establish the pde's for the new stack and the thread structure within the
-        * address space of the new process. They are accessed while taskswitching or
-        * while handling page faults. At this point it isn't possible to call the
-        * page fault handler for the missing pde's.
-        */
-       MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread->StackLimit, KERNEL_STACK_SIZE);
+       /* ROS Mm HACK */
+       MmUpdatePageDir((PEPROCESS)Process,
+                       (PVOID)Thread->StackLimit,
+                       KERNEL_STACK_SIZE);
        MmUpdatePageDir((PEPROCESS)Process, (PVOID)Thread, sizeof(ETHREAD));
    
-       /* Initalize the Thread Context */
-       DPRINT("Initializing the Context for the thread: %x\n", Thread);
-       KiArchInitThreadWithContext(Thread,
-                                   SystemRoutine,
-                                   StartRoutine,
-                                   StartContext,
-                                   Context);
+       /* Enter SEH to avoid crashes due to user mode */
+       Status = STATUS_SUCCESS;
+       _SEH_TRY
+       {
++++#ifdef _M_IX86
+           /* Initalize the Thread Context */
+           Ke386InitThreadWithContext(Thread,
+                                      SystemRoutine,
+                                      StartRoutine,
+                                      StartContext,
+                                      Context);
++++#endif
+       }
+       _SEH_HANDLE
+       {
+           /* Set failure status */
+           Status = STATUS_UNSUCCESSFUL;
    
-       /* Setup scheduler Fields based on Parent */
-       DPRINT("Thread context created, setting Scheduler Data\n");
-       Thread->BasePriority = Process->BasePriority;
+           /* Check if a stack was allocated */
+           if (AllocatedStack)
+           {
+               /* Delete the stack */
+               MmDeleteKernelStack(Thread->StackBase, FALSE);
+               Thread->InitialStack = NULL;
+           }
+       }
+       _SEH_END;
+   
+       /* Set the Thread to initalized */
+       Thread->State = Initialized;
+       return Status;
+   }
+   
+   VOID
+   NTAPI
+   KeStartThread(IN OUT PKTHREAD Thread)
+   {
+       KIRQL OldIrql;
+       PKPROCESS Process = Thread->ApcState.Process;
+       PKNODE Node;
+       PKPRCB NodePrcb;
+       ULONG Set, Mask;
+       UCHAR IdealProcessor;
+   
+       /* Setup static fields from parent */
++++#ifdef _M_IX86
+       Thread->Iopl = Process->Iopl;
++++#endif
        Thread->Quantum = Process->QuantumReset;
        Thread->QuantumReset = Process->QuantumReset;
-       Thread->Affinity = Process->Affinity;
+       Thread->SystemAffinityActive = FALSE;
+   
+       /* Lock the process */
+       KeAcquireSpinLock(&Process->ProcessLock, &OldIrql);
+   
+       /* Setup volatile data */
        Thread->Priority = Process->BasePriority;
+       Thread->BasePriority = Process->BasePriority;
+       Thread->Affinity = Process->Affinity;
        Thread->UserAffinity = Process->Affinity;
-       Thread->DisableBoost = Process->DisableBoost;
-       Thread->AutoAlignment = Process->AutoAlignment;
-   #ifdef _M_IX86
-       Thread->Iopl = Process->Iopl;
-   #endif
    
-       /* Set the Thread to initalized */
-       Thread->State = Initialized;
+       /* Get the KNODE and its PRCB */
+       Node = KeNodeBlock[Process->IdealNode];
+       NodePrcb = (PKPRCB)(KPCR_BASE + (Process->ThreadSeed * PAGE_SIZE));
+   
+       /* Calculate affinity mask */
+       Set = ~NodePrcb->MultiThreadProcessorSet;
+       Mask = (ULONG)(Node->ProcessorMask & Process->Affinity);
+       Set &= Mask;
+       if (Set) Mask = Set;
+   
+       /* Get the new thread seed */
+       IdealProcessor = KeFindNextRightSetAffinity(Process->ThreadSeed, Mask);
+       Process->ThreadSeed = IdealProcessor;
+   
+       /* Sanity check */
+       ASSERT((Thread->UserAffinity & AFFINITY_MASK(IdealProcessor)));
    
-       /*
-        * Insert the Thread into the Process's Thread List
-        * Note, this is the KTHREAD Thread List. It is removed in
-        * ke/kthread.c!KeTerminateThread.
-        */
+       /* Set the Ideal Processor */
+       Thread->IdealProcessor = IdealProcessor;
+       Thread->UserIdealProcessor = IdealProcessor;
+   
+       /* Lock the Dispatcher Database */
+       KeAcquireDispatcherDatabaseLockAtDpcLevel();
+   
+       /* Insert the thread into the process list */
        InsertTailList(&Process->ThreadListHead, &Thread->ThreadListEntry);
-       DPRINT("Thread initalized\n");
+   
+       /* Increase the stack count */
+       ASSERT(Process->StackCount != MAXULONG_PTR);
+       Process->StackCount++;
+   
+       /* Release locks and return */
+       KeReleaseDispatcherDatabaseLockFromDpcLevel();
+       KeReleaseSpinLock(&Process->ProcessLock, OldIrql);
    }
    
+   VOID
+   NTAPI
+   KeInitializeThread(IN PKPROCESS Process,
+                      IN OUT PKTHREAD Thread,
+                      IN PKSYSTEM_ROUTINE SystemRoutine,
+                      IN PKSTART_ROUTINE StartRoutine,
+                      IN PVOID StartContext,
+                      IN PCONTEXT Context,
+                      IN PVOID Teb,
+                      IN PVOID KernelStack)
+   {
+       /* Initailize and start the thread on success */
+       if (NT_SUCCESS(KeInitThread(Thread,
+                                   KernelStack,
+                                   SystemRoutine,
+                                   StartRoutine,
+                                   StartContext,
+                                   Context,
+                                   Teb,
+                                   Process)))
+       {
+           /* Start it */
+           KeStartThread(Thread);
+       }
+   }
    
    /*
     * @implemented
     *                  Gregor Anich
     */
    
- - /* INCLUDES *****************************************************************/
+ + /* INCLUDES ********(*********************************************************/
    
    #include <ntoskrnl.h>
-   #include <internal/napi.h>
    #define NDEBUG
    #include <internal/debug.h>
    
- - /* GLOBALS   *****************************************************************/
+ + /* GLOBALS *******************************************************************/
    
-   KSERVICE_TABLE_DESCRIPTOR
-   __declspec(dllexport)
-   KeServiceDescriptorTable[SSDT_MAX_ENTRIES] =
-   {
-       { MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
-       { NULL,     NULL,   0,   NULL   },
-   };
+   LIST_ENTRY KiProcessListHead;
+   LIST_ENTRY KiProcessInSwapListHead, KiProcessOutSwapListHead;
+   LIST_ENTRY KiStackInSwapListHead;
+   KEVENT KiSwapEvent;
    
-   KSERVICE_TABLE_DESCRIPTOR
-   KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES] =
-   {
-       { MainSSDT, NULL, NUMBER_OF_SYSCALLS, MainSSPT },
-       { NULL,     NULL,   0,   NULL   },
-   };
+   KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable[SSDT_MAX_ENTRIES];
+   KSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTableShadow[SSDT_MAX_ENTRIES];
+   
+ + PVOID KeUserApcDispatcher;
+ + PVOID KeUserCallbackDispatcher;
+ + PVOID KeUserExceptionDispatcher;
+ + PVOID KeRaiseUserExceptionDispatcher;
  + 
    /* FUNCTIONS *****************************************************************/
    
    PKPROCESS
@@@@@ -133,15 -131,52 -126,52 -131,52 +131,54 @@@@@ KeInitializeProcess(IN OUT PKPROCESS Pr
        Process->QuantumReset = 6;
        Process->DirectoryTableBase = DirectoryTableBase;
        Process->AutoAlignment = TRUE;
 +++#ifdef _M_IX86
        Process->IopmOffset = 0xFFFF;
-       Process->State = ProcessInMemory;
 +++#endif
    
-       /* Initialize the Thread List */
+       /* Initialize the lists */
        InitializeListHead(&Process->ThreadListHead);
-       KeInitializeSpinLock(&Process->ProcessLock);
-       DPRINT("The Process has now been initalized with the Kernel\n");
+       InitializeListHead(&Process->ProfileListHead);
+       InitializeListHead(&Process->ReadyListHead);
+   
+       /* Initialize the current State */
+       Process->State = ProcessInMemory;
+   
+       /* Check how many Nodes there are on the system */
+       if (KeNumberNodes > 1)
+       {
+           /* Set the new seed */
+           KeProcessNodeSeed = (KeProcessNodeSeed + 1) / KeNumberNodes;
+           IdealNode = KeProcessNodeSeed;
+   
+           /* Loop every node */
+           do
+           {
+               /* Check if the affinity matches */
+               if (KeNodeBlock[IdealNode]->ProcessorMask != Affinity) break;
+   
+               /* No match, try next Ideal Node and increase node loop index */
+               IdealNode++;
+               i++;
+   
+               /* Check if the Ideal Node is beyond the total number of nodes */
+               if (IdealNode >= KeNumberNodes)
+               {
+                   /* Normalize the Ideal Node */
+                   IdealNode -= KeNumberNodes;
+               }
+           } while (i < KeNumberNodes);
+       }
+   
+       /* Set the ideal node and get the ideal node block */
+       Process->IdealNode = IdealNode;
+       Node = KeNodeBlock[IdealNode];
+       ASSERT(Node->ProcessorMask & Affinity);
+   
+       /* Find the matching affinity set to calculate the thread seed */
+       Affinity &= Node->ProcessorMask;
+       Process->ThreadSeed = KeFindNextRightSetAffinity(Node->Seed,
+                                                        (ULONG)Affinity);
+       Node->Seed = Process->ThreadSeed;
    }
    
    ULONG
    KiSwapProcess(PKPROCESS NewProcess,
                  PKPROCESS OldProcess)
    {
 +++#ifdef _M_IX86
        DPRINT("Switching CR3 to: %x\n", NewProcess->DirectoryTableBase.u.LowPart);
        Ke386SetPageTableDirectory(NewProcess->DirectoryTableBase.u.LowPart);
 +++#endif
    }
    
+   VOID
+   NTAPI
+   KeSetQuantumProcess(IN PKPROCESS Process,
+                       IN UCHAR Quantum)
+   {
+       KIRQL OldIrql;
+       PLIST_ENTRY NextEntry, ListHead;
+       PKTHREAD Thread;
+       ASSERT_PROCESS(Process);
+       ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+   
+       /* Lock Dispatcher */
+       OldIrql = KeAcquireDispatcherDatabaseLock();
+   
+       /* Set new quantum */
+       Process->QuantumReset = Quantum;
+   
+       /* Loop all child threads */
+       ListHead = &Process->ThreadListHead;
+       NextEntry = ListHead->Flink;
+       while (ListHead != NextEntry)
+       {
+           /* Get the thread */
+           Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
+   
+           /* Set quantum */
+           Thread->QuantumReset = Quantum;
+   
+           /* Go to the next one */
+           NextEntry = NextEntry->Flink;
+       }
+   
+       /* Release Dispatcher Database */
+       KeReleaseDispatcherDatabaseLock(OldIrql);
+   }
+   
+   KPRIORITY
+   NTAPI
+   KeSetPriorityAndQuantumProcess(IN PKPROCESS Process,
+                                  IN KPRIORITY Priority,
+                                  IN UCHAR Quantum OPTIONAL)
+   {
+       KPRIORITY Delta;
+       PLIST_ENTRY NextEntry, ListHead;
+       KPRIORITY NewPriority, OldPriority;
+       KIRQL OldIrql;
+       PKTHREAD Thread;
+       BOOLEAN Released;
+       ASSERT_PROCESS(Process);
+       ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
+   
+       /* Check if the process already has this priority */
+       if (Process->BasePriority == Priority)
+       {
+           /* Don't change anything */
+           return Process->BasePriority;
+       }
+   
+       /* If the caller gave priority 0, normalize to 1 */
+       if (!Priority) Priority = 1;
+   
+       /* Lock Dispatcher */
+       OldIrql = KeAcquireDispatcherDatabaseLock();
+   
+       /* Check if we are modifying the quantum too */
+       if (Quantum) Process->QuantumReset = Quantum;
+   
+       /* Save the current base priority and update it */
+       OldPriority = Process->BasePriority;
+       Process->BasePriority = Priority;
+   
+       /* Calculate the priority delta */
+       Delta = Priority - OldPriority;
+   
+       /* Set the list head and list entry */
+       ListHead = &Process->ThreadListHead;
+       NextEntry = ListHead->Flink;
+   
+       /* Check if this is a real-time priority */
+       if (Priority >= LOW_REALTIME_PRIORITY)
+       {
+           /* Loop the thread list */
+           while (NextEntry != ListHead)
+           {
+               /* Get the thread */
+               Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
+   
+               /* Update the quantum if we had one */
+               if (Quantum) Thread->QuantumReset = Quantum;
+   
+               /* Calculate the new priority */
+               NewPriority = Thread->BasePriority + Delta;
+               if (NewPriority < LOW_REALTIME_PRIORITY)
+               {
+                   /* We're in real-time range, don't let it go below */
+                   NewPriority = LOW_REALTIME_PRIORITY;
+               }
+               else if (NewPriority > HIGH_PRIORITY)
+               {
+                   /* We're going beyond the maximum priority, normalize */
+                   NewPriority = HIGH_PRIORITY;
+               }
+   
+               /*
+                * If priority saturation occured or the old priority was still in
+                * the real-time range, don't do anything.
+                */
+               if (!(Thread->Saturation) || (OldPriority < LOW_REALTIME_PRIORITY))
+               {
+                   /* Check if we had priority saturation */
+                   if (Thread->Saturation > 0)
+                   {
+                       /* Boost priority to maximum */
+                       NewPriority = HIGH_PRIORITY;
+                   }
+                   else if (Thread->Saturation < 0)
+                   {
+                       /* If we had negative saturation, set minimum priority */
+                       NewPriority = LOW_REALTIME_PRIORITY;
+                   }
+   
+                   /* Update priority and quantum */
+                   Thread->BasePriority = NewPriority;
+                   Thread->Quantum = Thread->QuantumReset;
+   
+                   /* Disable decrements and update priority */
+                   Thread->PriorityDecrement = 0;
+                   KiSetPriorityThread(Thread, NewPriority, &Released);
+               }
+   
+               /* Go to the next thread */
+               NextEntry = NextEntry->Flink;
+           }
+       }
+       else
+       {
+           /* Loop the thread list */
+           while (NextEntry != ListHead)
+           {
+               /* Get the thread */
+               Thread = CONTAINING_RECORD(NextEntry, KTHREAD, ThreadListEntry);
+   
+               /* Update the quantum if we had one */
+               if (Quantum) Thread->QuantumReset = Quantum;
+   
+               /* Calculate the new priority */
+               NewPriority = Thread->BasePriority + Delta;
+               if (NewPriority >= LOW_REALTIME_PRIORITY)
+               {
+                   /* We're not real-time range, don't let it enter RT range */
+                   NewPriority = LOW_REALTIME_PRIORITY - 1;
+               }
+               else if (NewPriority <= LOW_PRIORITY)
+               {
+                   /* We're going below the minimum priority, normalize */
+                   NewPriority = 1;
+               }
+   
+               /*
+                * If priority saturation occured or the old priority was still in
+                * the real-time range, don't do anything.
+                */
+               if (!(Thread->Saturation) ||
+                   (OldPriority >= LOW_REALTIME_PRIORITY))
+               {
+                   /* Check if we had priority saturation */
+                   if (Thread->Saturation > 0)
+                   {
+                       /* Boost priority to maximum */
+                       NewPriority = LOW_REALTIME_PRIORITY - 1;
+                   }
+                   else if (Thread->Saturation < 0)
+                   {
+                       /* If we had negative saturation, set minimum priority */
+                       NewPriority = 1;
+                   }
+   
+                   /* Update priority and quantum */
+                   Thread->BasePriority = NewPriority;
+                   Thread->Quantum = Thread->QuantumReset;
+   
+                   /* Disable decrements and update priority */
+                   Thread->PriorityDecrement = 0;
+                   KiSetPriorityThread(Thread, NewPriority, &Released);
+               }
+   
+               /* Go to the next thread */
+               NextEntry = NextEntry->Flink;
+           }
+       }
+   
+       /* Release Dispatcher Database */
+       if (!Released) KeReleaseDispatcherDatabaseLock(OldIrql);
+   
+       /* Return previous priority */
+       return OldPriority;
+   }
+   
    /*
     * @implemented
     */
Simple merge
        <directory name="ke">
                <if property="ARCH" value="i386">
                        <directory name="i386">
- -                             <file first="true">main_asm.S</file>
-                               <file>bios.c</file>
-                               <file>cpu.S</file>
+ +                             <file first="true">boot.S</file>
+                               <file>abios.c</file>
+                               <file>cpu.c</file>
                                <file>ctxswitch.S</file>
+                   <file>clock.S</file>
                                <file>exp.c</file>
-                               <file>fpu.c</file>
-                               <file>gdt.c</file>
-                               <file>irq.c</file>
-                               <file>irqhand.s</file>
-                               <file>kernel.c</file>
+                   <!-- <file>irq.c</file> -->
  -                             <file>kernel.c</file>
+ +                             <file>kiinit.c</file>
                                <file>ldt.c</file>
                                <file>thread.c</file>
                                <file>trap.s</file>
-                               <file>tss.c</file>
                                <file>usercall_asm.S</file>
-                               <file>usertrap.c</file>
-                               <file>v86m.c</file>
+                               <file>v86vdm.c</file>
                                <file>v86m_sup.S</file>
-                               <file>vdm.c</file>
                        </directory>
 +++            </if>
 +++            <if property="ARCH" value="powerpc">
 +++                    <directory name="powerpc">
 +++                            <file first="true">main_asm.S</file>
++++                            <file>ppc_irq.c</file>
 +++                    </directory>
                </if>
                        <file>apc.c</file>
                        <file>bug.c</file>
                        <file>usercall.c</file>
                        <file>wait.c</file>
        </directory>
 ---    <directory name="deprecated">
 ---        <file>irqhand.S</file>
 ---        <file>irq.c</file>
 ---    </directory>
++++        <if property="ARCH" value="i386">
++++            <directory name="deprecated">
++++                <file>irqhand.S</file>
++++                <file>irq.c</file>
++++            </directory>
++++        </if>
++++    <if property="ARCH" value="powerpc">
++++        <directory name="powerpc">
++++            <file>ppc_irq.c</file>
++++        </directory>
++++    </if>
        <directory name="cc">
                        <file>cacheman.c</file>
                        <file>copy.c</file>
@@@@@ -44,38 -112,41 -112,41 -112,41 +112,46 @@@@@ PspGetOrSetContextKernelRoutine(IN PKAP
        PGET_SET_CTX_CONTEXT GetSetContext;
        PKEVENT Event;
        PCONTEXT Context;
+       PKTHREAD Thread;
        KPROCESSOR_MODE Mode;
++++#ifdef _M_IX86
        PKTRAP_FRAME TrapFrame;
-   
-       TrapFrame = (PKTRAP_FRAME)((ULONG_PTR)KeGetCurrentThread()->InitialStack -
-                                             sizeof (FX_SAVE_AREA) - sizeof (KTRAP_FRAME));
++++#endif
+       PAGED_CODE();
    
        /* Get the Context Structure */
        GetSetContext = CONTAINING_RECORD(Apc, GET_SET_CTX_CONTEXT, Apc);
        Context = &GetSetContext->Context;
        Event = &GetSetContext->Event;
        Mode = GetSetContext->Mode;
+       Thread = Apc->SystemArgument2;
    
 +++#ifdef _M_IX86
 +++    if (TrapFrame->SegCs == KGDT_R0_CODE && Mode != KernelMode)
+       /* Get the trap frame */
+       TrapFrame = (PKTRAP_FRAME)((ULONG_PTR)KeGetCurrentThread()->InitialStack -
+                                  sizeof (FX_SAVE_AREA) - sizeof (KTRAP_FRAME));
+   
+       /* Sanity check */
+       ASSERT(((TrapFrame->SegCs & MODE_MASK) != KernelMode) ||
+           (TrapFrame->EFlags & EFLAGS_V86_MASK));
+   
+       /* Check if it's a set or get */
+       if (SystemArgument1)
        {
-           GetSetContext->Status = STATUS_ACCESS_DENIED;
+           /* Get the Context */
+           KeTrapFrameToContext(TrapFrame, NULL, Context);
        }
        else
        {
-   #endif
-           /* Check if it's a set or get */
-           if (*SystemArgument1) {
-               /* Get the Context */
-               KeTrapFrameToContext(TrapFrame, NULL, Context);
-           } else {
-               /* Set the Context */
-               KeContextToTrapFrame(Context, NULL, TrapFrame, Context->ContextFlags, Mode);
-           }
-           GetSetContext->Status = STATUS_SUCCESS;
-   #ifdef _M_IX86
+           /* Set the Context */
+           KeContextToTrapFrame(Context,
+                                NULL,
+                                TrapFrame,
+                                Context->ContextFlags,
+                                Mode);
        }
 +++#endif
    
        /* Notify the Native API that we are done */
        KeSetEvent(Event, IO_NO_INCREMENT, FALSE);
Simple merge
Simple merge
index 63af41d,0000000,0000000,0000000..3133822
mode 100755,000000,000000,000000..100755
--- /dev/null
--- /dev/null
--- /dev/null
@@@@@ -1,9 -1,0 -1,0 -1,0 +1,9 @@@@@
-   ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mmu.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a
 +++#!/bin/sh -v
 +++
 +++export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin
++++ld -EL -g -nostartfiles -nostdlib -N -Ttext=0x8000 -o freeldr.elf obj-ppc/boot/freeldr/freeldr/arch/powerpc/boot.o obj-ppc/boot/freeldr/freeldr/cache/blocklist.o obj-ppc/boot/freeldr/freeldr/cache/cache.o obj-ppc/boot/freeldr/freeldr/comm/rs232.o obj-ppc/boot/freeldr/freeldr/disk/disk.o obj-ppc/boot/freeldr/freeldr/disk/partition.o obj-ppc/boot/freeldr/freeldr/fs/ext2.o obj-ppc/boot/freeldr/freeldr/fs/fat.o obj-ppc/boot/freeldr/freeldr/fs/fs.o obj-ppc/boot/freeldr/freeldr/fs/fsrec.o obj-ppc/boot/freeldr/freeldr/fs/iso.o obj-ppc/boot/freeldr/freeldr/fs/ntfs.o obj-ppc/boot/freeldr/freeldr/inifile/ini_init.o obj-ppc/boot/freeldr/freeldr/inifile/inifile.o obj-ppc/boot/freeldr/freeldr/inifile/parse.o obj-ppc/boot/freeldr/freeldr/math/libgcc2.o obj-ppc/boot/freeldr/freeldr/mm/meminit.o obj-ppc/boot/freeldr/freeldr/mm/mm.o obj-ppc/boot/freeldr/freeldr/reactos/registry.o obj-ppc/boot/freeldr/freeldr/reactos/binhive.o obj-ppc/boot/freeldr/freeldr/reactos/arcname.o obj-ppc/boot/freeldr/freeldr/reactos/reactos.o obj-ppc/boot/freeldr/freeldr/rtl/list.o obj-ppc/boot/freeldr/freeldr/ui/gui.o obj-ppc/boot/freeldr/freeldr/ui/tui.o obj-ppc/boot/freeldr/freeldr/ui/tuimenu.o obj-ppc/boot/freeldr/freeldr/ui/ui.o obj-ppc/boot/freeldr/freeldr/video/bank.o obj-ppc/boot/freeldr/freeldr/video/fade.o obj-ppc/boot/freeldr/freeldr/video/palette.o obj-ppc/boot/freeldr/freeldr/video/pixel.o obj-ppc/boot/freeldr/freeldr/video/video.o obj-ppc/boot/freeldr/freeldr/freeldr.o obj-ppc/boot/freeldr/freeldr/debug.o obj-ppc/boot/freeldr/freeldr/version.o obj-ppc/boot/freeldr/freeldr/cmdline.o obj-ppc/boot/freeldr/freeldr/machine.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mach.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/ofw.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mmu.o obj-ppc/boot/freeldr/freeldr/arch/powerpc/mboot.o obj-ppc/boot/freeldr/freeldr/bootmgr.o obj-ppc/boot/freeldr/freeldr/drivemap.o obj-ppc/boot/freeldr/freeldr/miscboot.o obj-ppc/boot/freeldr/freeldr/options.o obj-ppc/boot/freeldr/freeldr/linuxboot.o obj-ppc/boot/freeldr/freeldr/oslist.o obj-ppc/boot/freeldr/freeldr/custom.o obj-ppc/lib/rossym/rossym.a obj-ppc/lib/cmlib/cmlib.a obj-ppc/lib/string/string.a obj-ppc/lib/rtl/rtl.a /usr/local/pkg/reactos-powerpc/lib/libgcc.a
 +++objcopy -O binary freeldr.elf freeldr.tmp.le
 +++output-ppc/tools/ppc-le2be freeldr.tmp.le freeldr.tmp
 +++objcopy -I binary -B powerpc:common -O elf32-powerpc freeldr.tmp ofwldr.payload
 +++reactos-powerpc-as -mbig -o ofwboot.o boot/freeldr/bootsect/ofwboot.s boot/freeldr/bootsect/ofw_util.s boot/freeldr/bootsect/ofw.s
 +++ld -EB -Ttext 0xe00000 -Tdata 0xe17000 -e _begin -o ofwldr ofwboot.o ofwldr.payload
Simple merge
Simple merge