302 lines
5.8 KiB
C
302 lines
5.8 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;
|
||
|
||
//
|
||
// 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;
|
||
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 = NumberBits - 64;
|
||
return Fraction;
|
||
}
|