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

230 lines
5.2 KiB
C

/*++
Copyright (c) 1989 Microsoft Corporation
Module Name:
i386init.c
Abstract:
This module contains code to manipulate i386 hardware structures used
only by the kernel.
Author:
Bryan Willman 22 Feb 90
Revision History:
--*/
#include "ki.h"
VOID
KiInitializeMachineType (
VOID
);
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT,KiInitializeGDT)
#pragma alloc_text(INIT,KiInitializeGdtEntry)
#pragma alloc_text(INIT,KiInitializeMachineType)
#endif
KIRQL KiProfileIrql = PROFILE_LEVEL;
ULONG KeI386MachineType = 0;
BOOLEAN KeI386NpxPresent;
BOOLEAN KeI386FxsrPresent;
ULONG KeI386ForceNpxEmulation;
ULONG KeI386CpuType;
ULONG KeI386CpuStep;
PVOID Ki387RoundModeTable; // R3 emulators RoundingMode vector table
ULONG KiBootFeatureBits;
ULONG KiInBiosCall = FALSE;
ULONG FlagState = 0; // bios calls shouldn't automatically turn interrupts back on.
KTRAP_FRAME KiBiosFrame;
#if DBG
UCHAR MsgDpcTrashedEsp[] = "\n*** DPC routine %lx trashed ESP\n";
UCHAR MsgDpcTimeout[] = "\n*** DPC routine > 1 sec --- This is not a break in KeUpdateSystemTime\n";
UCHAR MsgISRTimeout[] = "\n*** ISR at %lx took over .5 second\n";
UCHAR MsgISROverflow[] = "\n*** ISR at %lx - %d interrupts per .5 second\n";
ULONG KiDPCTimeout = 110;
ULONG KiISRTimeout = 55;
ULONG KiISROverflow = 5500;
ULONG KiSpinlockTimeout = 55;
#endif
VOID
KiInitializeGDT (
IN OUT PKGDTENTRY Gdt,
IN USHORT GdtLimit,
IN PKPCR Pcr,
IN USHORT PcrLimit,
IN PKTSS Tss,
IN USHORT TssLimit,
IN USHORT TebLimit
)
/*++
Routine Description:
This procedure initializes a GDT. It will set standard values
for all descriptors.
It will not set PCR->GDT.
It will set the PCR address in KGDT_PCR.
KGDT_R3_TEB will be set to a base of 0, with a limit of 1 page.
Arguments:
Gdt - Supplies a pointer to an array of KGDTENTRYs.
GdtLimit - Supplies size (in bytes) of Gdt. Used to detect a
GDT which is too small (which will cause a BUGCHECK)
Pcr - FLAT address of Pcr for processor Gdt is for.
PcrLimit - Size Limit of PCR in bytes.
Tss - FLAT adderss of TSS for processor Gdt is for.
TssLimit - Size limit of TSS in bytes.
TebLimit - Size limit of Teb in bytes.
Return Value:
None.
--*/
{
if ((KGDT_NUMBER * 8) > GdtLimit)
KeBugCheck(MEMORY_MANAGEMENT);
KiInitializeGdtEntry(&Gdt[KGDT_NULL], 0, 0, 0, 0, GRAN_PAGE);
KiInitializeGdtEntry(
&Gdt[KGDT_R0_CODE], 0, (ULONG)-1, TYPE_CODE, DPL_SYSTEM, GRAN_PAGE);
KiInitializeGdtEntry(
&Gdt[KGDT_R0_DATA], 0, (ULONG)-1, TYPE_DATA, DPL_SYSTEM, GRAN_PAGE);
KiInitializeGdtEntry(&Gdt[KGDT_R3_CODE], 0,
(ULONG)-1, TYPE_CODE, DPL_USER, GRAN_PAGE);
KiInitializeGdtEntry(&Gdt[KGDT_R3_DATA], 0,
(ULONG)-1, TYPE_DATA, DPL_USER, GRAN_PAGE);
KiInitializeGdtEntry(
&Gdt[KGDT_TSS], (ULONG)Tss, TssLimit-1,
TYPE_TSS, DPL_SYSTEM, GRAN_BYTE);
KiInitializeGdtEntry(
&Gdt[KGDT_R0_PCR], (ULONG)Pcr, PcrLimit-1,
TYPE_DATA, DPL_SYSTEM, GRAN_BYTE);
KiInitializeGdtEntry(
&Gdt[KGDT_R3_TEB], 0, TebLimit-1, TYPE_DATA, DPL_USER, GRAN_BYTE);
}
VOID
KiInitializeGdtEntry (
OUT PKGDTENTRY GdtEntry,
IN ULONG Base,
IN ULONG Limit,
IN USHORT Type,
IN USHORT Dpl,
IN USHORT Granularity
)
/*++
Routine Description:
This function initializes a GDT entry. Base, Limit, Type (code,
data), and Dpl (0 or 3) are set according to parameters. All other
fields of the entry are set to match standard system values.
Arguments:
GdtEntry - GDT descriptor to be filled in.
Base - Linear address of the first byte mapped by the selector.
Limit - Size of the selector in pages. Note that 0 is 1 page
while 0xffffff is 1 megapage = 4 gigabytes.
Type - Code or Data. All code selectors are marked readable,
all data selectors are marked writeable.
Dpl - User (3) or System (0)
Granularity - 0 for byte, 1 for page
Return Value:
Pointer to the GDT entry.
--*/
{
GdtEntry->LimitLow = (USHORT)(Limit & 0xffff);
GdtEntry->BaseLow = (USHORT)(Base & 0xffff);
GdtEntry->HighWord.Bytes.BaseMid = (UCHAR)((Base & 0xff0000) >> 16);
GdtEntry->HighWord.Bits.Type = Type;
GdtEntry->HighWord.Bits.Dpl = Dpl;
GdtEntry->HighWord.Bits.Pres = 1;
GdtEntry->HighWord.Bits.LimitHi = (Limit & 0xf0000) >> 16;
GdtEntry->HighWord.Bits.Sys = 0;
GdtEntry->HighWord.Bits.Reserved_0 = 0;
GdtEntry->HighWord.Bits.Default_Big = 1;
GdtEntry->HighWord.Bits.Granularity = Granularity;
GdtEntry->HighWord.Bytes.BaseHi = (UCHAR)((Base & 0xff000000) >> 24);
}
VOID
KiInitializeMachineType (
VOID
)
/*++
Routine Description:
This function initializes machine type, i.e. MCA, ABIOS, ISA
or EISA.
N.B. This is a temporary routine. machine type:
Byte 0 - Machine Type, ISA, EISA or MCA
Byte 1 - CPU type, i386 or i486
Byte 2 - Cpu Step, A or B ... etc.
Highest bit indicates if NPX is present.
Arguments:
None.
Return Value:
None.
--*/
{
KeI386MachineType = KeLoaderBlock->u.I386.MachineType & 0x000ff;
}