Partially fixed up tree after merge from HEAD. More to do.
[reactos.git] / reactos / ntoskrnl / ke / krnlinit.c
index ce4b63e..05188c4 100644 (file)
-/*\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
-#ifdef _M_IX86\r
-    Protect = MmGetPageProtect(NULL, (PVOID)KiIdt);\r
-    MmSetPageProtect(NULL, (PVOID)KiIdt, Protect | PAGE_IS_WRITABLE);\r
-#endif\r
-}\r
+/*
+ * PROJECT:         ReactOS Kernel
+ * LICENSE:         GPL - See COPYING in the top level directory
+ * FILE:            ntoskrnl/ke/krnlinit.c
+ * PURPOSE:         Portable part of kernel initialization
+ * PROGRAMMERS:     Alex Ionescu (alex.ionescu@reactos.org)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+#include <internal/napi.h>
+
+/* GLOBALS *******************************************************************/
+
+/* System call count */
+ULONG KiServiceLimit = NUMBER_OF_SYSCALLS;
+
+/* ARC Loader Block */
+PLOADER_PARAMETER_BLOCK KeLoaderBlock;
+
+/* PRCB Array */
+PKPRCB KiProcessorBlock[MAXIMUM_PROCESSORS];
+
+/* NUMA Node Support */
+KNODE KiNode0;
+PKNODE KeNodeBlock[1];
+UCHAR KeNumberNodes = 1;
+UCHAR KeProcessNodeSeed;
+
+/* Initial Process and Thread */
+ETHREAD KiInitialThread;
+EPROCESS KiInitialProcess;
+
+/* 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;
+
+/* 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 = KiServiceLimit;
+    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);
+    }
+}
+
+BOOLEAN
+NTAPI
+KeInitSystem(VOID)
+{
+    /* Check if Threaded DPCs are enabled */
+    if (KeThreadDpcEnable)
+    {
+        /* FIXME: TODO */
+        DPRINT1("Threaded DPCs not yet supported\n");
+    }
+
+    /* Initialize non-portable parts of the kernel */
+    KiInitMachineDependent();
+    return TRUE;
+}
+