Windows2000/private/ntos/ke/kiinit.c
2020-09-30 17:12:32 +02:00

312 lines
5.9 KiB
C

/*++
Copyright (c) 1993 Microsoft Corporation
Module Name:
kiinit.c
Abstract:
This module implements architecture independent kernel initialization.
Author:
David N. Cutler 11-May-1993
Environment:
Kernel mode only.
Revision History:
--*/
#include "ki.h"
// Put all code for kernel initialization in the INIT section. It will be
// deallocated by memory management when phase 1 initialization is completed.
#if defined(ALLOC_PRAGMA)
#pragma alloc_text(INIT, KeInitSystem)
#pragma alloc_text(INIT, KiInitSystem)
#pragma alloc_text(INIT, KiComputeReciprocal)
#endif
BOOLEAN
KeInitSystem (
VOID
)
/*++
Routine Description:
This function initializes executive structures implemented by the
kernel.
N.B. This function is only called during phase 1 initialization.
Arguments:
None.
Return Value:
A value of TRUE is returned if initialization is successful. Otherwise,
a value of FALSE is returned.
--*/
{
BOOLEAN Initialized = TRUE;
// Initialize the executive objects.
#if 0
if ((Initialized = KiChannelInitialization()) == FALSE) {
KdPrint(("Kernel: Channel initialization failed\n"));
}
#endif
#if defined(i386)
// Perform platform dependent initialization.
Initialized = KiInitMachineDependent();
#endif
return Initialized;
}
VOID
KiInitSystem (
VOID
)
/*++
Routine Description:
This function initializes architecture independent kernel structures.
Arguments:
None.
Return Value:
None.
--*/
{
ULONG Index;
// Initialize dispatcher ready queue listheads.
for (Index = 0; Index < MAXIMUM_PRIORITY; Index += 1) {
InitializeListHead(&KiDispatcherReadyListHead[Index]);
}
// Initialize bug check callback listhead and spinlock.
InitializeListHead(&KeBugCheckCallbackListHead);
KeInitializeSpinLock(&KeBugCheckCallbackLock);
// Initialize the timer expiration DPC object.
KeInitializeDpc(&KiTimerExpireDpc,
(PKDEFERRED_ROUTINE)KiTimerExpiration, NIL);
// Initialize the profile listhead and profile locks
KeInitializeSpinLock(&KiProfileLock);
InitializeListHead(&KiProfileListHead);
// Initialize the active profile source listhead.
InitializeListHead(&KiProfileSourceListHead);
// Initialize the timer table, the timer completion listhead, and the
// timer completion DPC.
for (Index = 0; Index < TIMER_TABLE_SIZE; Index += 1) {
InitializeListHead(&KiTimerTableListHead[Index]);
}
// Initialize the swap event, the process inswap listhead, the
// process outswap listhead, the kernel stack inswap listhead,
// the wait in listhead, and the wait out listhead.
KeInitializeEvent(&KiSwapEvent,
SynchronizationEvent,
FALSE);
InitializeListHead(&KiProcessInSwapListHead);
InitializeListHead(&KiProcessOutSwapListHead);
InitializeListHead(&KiStackInSwapListHead);
InitializeListHead(&KiWaitInListHead);
InitializeListHead(&KiWaitOutListHead);
// Initialize the system service descriptor table.
KeServiceDescriptorTable[0].Base = &KiServiceTable[0];
KeServiceDescriptorTable[0].Count = NULL;
KeServiceDescriptorTable[0].Limit = KiServiceLimit;
#if defined(_IA64_)
// The global pointer associated with the table base is
// placed just before the service table.
KeServiceDescriptorTable[0].TableBaseGpOffset =
(LONG)(*(KiServiceTable-1) - (ULONG_PTR)KiServiceTable);
#endif
KeServiceDescriptorTable[0].Number = &KiArgumentTable[0];
for (Index = 1; Index < NUMBER_SERVICE_TABLES; Index += 1) {
KeServiceDescriptorTable[Index].Limit = 0;
}
// Copy the system service descriptor table to the shadow table
// which is used to record the Win32 system services.
RtlCopyMemory(KeServiceDescriptorTableShadow,
KeServiceDescriptorTable,
sizeof(KeServiceDescriptorTable));
// Initialize call performance data structures.
#if defined(_COLLECT_FLUSH_SINGLE_CALLDATA_)
ExInitializeCallData(&KiFlushSingleCallData);
#endif
#if defined(_COLLECT_SET_EVENT_CALLDATA_)
ExInitializeCallData(&KiSetEventCallData);
#endif
#if defined(_COLLECT_WAIT_SINGLE_CALLDATA_)
ExInitializeCallData(&KiWaitSingleCallData);
#endif
return;
}
LARGE_INTEGER
KiComputeReciprocal (
IN LONG Divisor,
OUT PCCHAR Shift
)
/*++
Routine Description:
This function computes the large integer reciprocal of the specified
value.
Arguments:
Divisor - Supplies the value for which the large integer reciprocal is
computed.
Shift - Supplies a pointer to a variable that receives the computed
shift count.
Return Value:
The large integer reciprocal is returned as the fucntion value.
--*/
{
LARGE_INTEGER Fraction;
LONG NumberBits;
LONG Remainder;
// Compute the large integer reciprocal of the specified value.
NumberBits = 0;
Remainder = 1;
Fraction.LowPart = 0;
Fraction.HighPart = 0;
while (Fraction.HighPart >= 0) {
NumberBits += 1;
Fraction.HighPart = (Fraction.HighPart << 1) | (Fraction.LowPart >> 31);
Fraction.LowPart <<= 1;
Remainder <<= 1;
if (Remainder >= Divisor) {
Remainder -= Divisor;
Fraction.LowPart |= 1;
}
}
if (Remainder != 0) {
if ((Fraction.LowPart == 0xffffffff) && (Fraction.HighPart == 0xffffffff)) {
Fraction.LowPart = 0;
Fraction.HighPart = 0x80000000;
NumberBits -= 1;
} else {
if (Fraction.LowPart == 0xffffffff) {
Fraction.LowPart = 0;
Fraction.HighPart += 1;
} else {
Fraction.LowPart += 1;
}
}
}
// Compute the shift count value and return the reciprocal fraction.
*Shift = (CCHAR)(NumberBits - 64);
return Fraction;
}