- Fix KTSS definition.

- Add GetSegment inlines (ie: GetSs, GetDs, etc)
- Fix up definition of KiBootGdt to use KGDTENTRY instead of USHORT. Also define KiGdtDescriptor using KDESCRIPTOR.
- Remove GDT initialization code completely. The GDT is already initialized on boot.
- Remove tss.c and add KiInitializeTss(2) to setup a TSS and proper IOPM/Interrupt Direction map settings for V86/VDM.
- Copy the TSS code over but prettyify it to use NT/NDK structures instead of ugly USHORT typecasts.

svn path=/trunk/; revision=23894
This commit is contained in:
Alex Ionescu 2006-09-03 06:51:03 +00:00
parent 00f50dd922
commit 6b42f391e0
8 changed files with 162 additions and 249 deletions

View file

@ -647,7 +647,6 @@ typedef struct _KiIoAccessMap
UCHAR IoMap[8196];
} KIIO_ACCESS_MAP;
#include <pshpack1.h>
typedef struct _KTSS
{
USHORT Backlink;
@ -658,7 +657,15 @@ typedef struct _KTSS
ULONG NotUsed1[4];
ULONG CR3;
ULONG Eip;
ULONG NotUsed2[9];
ULONG EFlags;
ULONG Eax;
ULONG Ecx;
ULONG Edx;
ULONG Ebx;
ULONG Esp;
ULONG Ebp;
ULONG Esi;
ULONG Edi;
USHORT Es;
USHORT Reserved2;
USHORT Cs;
@ -678,7 +685,6 @@ typedef struct _KTSS
KIIO_ACCESS_MAP IoMaps[1];
UCHAR IntDirectionMap[32];
} KTSS, *PKTSS;
#include <poppack.h>
//
// i386 CPUs don't have exception frames

View file

@ -57,7 +57,8 @@ KiInitializeGdt(struct _KPCR* Pcr);
VOID
Ki386ApplicationProcessorInitializeTSS(VOID);
VOID
Ki386BootInitializeTSS(VOID);
NTAPI
Ki386InitializeTss(VOID);
VOID
KiGdtPrepareForApplicationProcessorInit(ULONG Id);
VOID
@ -151,6 +152,12 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
#define Ke386SaveFlags(x) __asm__ __volatile__("pushfl ; popl %0":"=g" (x): /* no input */)
#define Ke386RestoreFlags(x) __asm__ __volatile__("pushl %0 ; popfl": /* no output */ :"g" (x):"memory")
#define _Ke386GetSeg(N) ({ \
unsigned int __d; \
__asm__("movl %%" #N ",%0\n\t" :"=r" (__d)); \
__d; \
})
#define _Ke386GetCr(N) ({ \
unsigned int __d; \
__asm__("movl %%cr" #N ",%0\n\t" :"=r" (__d)); \
@ -164,6 +171,7 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
#define Ke386SetCr2(X) _Ke386SetCr(2,X)
#define Ke386GetCr4() _Ke386GetCr(4)
#define Ke386SetCr4(X) _Ke386SetCr(4,X)
#define Ke386GetSs() _Ke386GetSeg(ss)
static inline LONG Ke386TestAndClearBit(ULONG BitPos, volatile PULONG Addr)
{

View file

@ -95,6 +95,7 @@ extern ULONG KeI386EFlagsAndMaskV86;
extern ULONG KeI386EFlagsOrMaskV86;
extern BOOLEAN KeI386VirtualIntExtensions;
extern KIDTENTRY KiIdt[];
extern KGDTENTRY KiBootGdt[];
extern FAST_MUTEX KernelAddressSpaceLock;
extern ULONG KiMaximumDpcQueueDepth;
extern ULONG KiMinimumDpcRate;
@ -116,6 +117,8 @@ extern KEVENT KiSwapEvent;
extern PKPRCB KiProcessorBlock[];
extern ULONG KiMask32Array[MAXIMUM_PRIORITY];
extern ULONG IdleProcessorMask;
extern ULONG trap_stack_top;
extern VOID KiTrap8(VOID);
/* MACROS *************************************************************************/
@ -184,7 +187,13 @@ extern KSPIN_LOCK DispatcherDatabaseLock;
/* One of the Reserved Wait Blocks, this one is for the Thread's Timer */
#define TIMER_WAIT_BLOCK 0x3L
/* IOPM Definitions */
#define IO_ACCESS_MAP_NONE 0
#define IOPM_OFFSET FIELD_OFFSET(KTSS, IoMaps[0].IoMap)
#define KiComputeIopmOffset(MapNumber) \
(MapNumber == IO_ACCESS_MAP_NONE) ? \
(USHORT)(sizeof(KTSS)) : \
(USHORT)(FIELD_OFFSET(KTSS, IoMaps[MapNumber-1].IoMap))
#define SIZE_OF_FX_REGISTERS 32

View file

@ -20,6 +20,12 @@
/* GLOBALS *******************************************************************/
/* The Boot TSS */
KTSS KiBootTss;
/* The TSS to use for Double Fault Traps (INT 0x9) */
UCHAR KiDoubleFaultTSS[KTSS_IO_MAPS];
ULONG KeI386CpuType;
ULONG KeI386CpuStep;
ULONG KeProcessorArchitecture;
@ -459,6 +465,117 @@ KiSetCR0Bits(VOID)
Ke386SetCr0(Cr0);
}
VOID
NTAPI
KiInitializeTSS2(IN PKTSS Tss,
IN PKGDTENTRY TssEntry OPTIONAL)
{
PUCHAR p;
/* Make sure the GDT Entry is valid */
if (TssEntry)
{
/* Set the Limit */
TssEntry->LimitLow = sizeof(KTSS) - 1;
TssEntry->HighWord.Bits.LimitHi &= 0xF0;
}
/* Now clear the I/O Map */
RtlFillMemory(Tss->IoMaps[0].IoMap, 8096, -1);
/* Initialize Interrupt Direction Maps */
p = (PUCHAR)(Tss->IoMaps[0].DirectionMap);
RtlZeroMemory(p, 32);
/* Add DPMI support for interrupts */
p[0] = 4;
p[3] = 0x18;
p[4] = 0x18;
/* Initialize the default Interrupt Direction Map */
p = Tss->IntDirectionMap;
RtlZeroMemory(Tss->IntDirectionMap, 32);
/* Add DPMI support */
p[0] = 4;
p[3] = 0x18;
p[4] = 0x18;
}
VOID
NTAPI
KiInitializeTSS(IN PKTSS Tss)
{
/* Set an invalid map base */
Tss->IoMapBase = KiComputeIopmOffset(IO_ACCESS_MAP_NONE);
/* Disable traps during Task Switches */
Tss->Flags = 0;
/* Set LDT and Ring 0 SS */
Tss->LDT = 0;
Tss->Ss0 = KGDT_R0_DATA;
}
VOID
NTAPI
Ki386InitializeTss(VOID)
{
PKTSS Tss;
PKGDTENTRY TssEntry;
PKIDTENTRY TaskGateEntry;
PKIDT_ACCESS TaskGateAccess;
/* Initialize the boot TSS. */
Tss = &KiBootTss;
TssEntry = &KiBootGdt[KGDT_TSS / sizeof(KGDTENTRY)];
KiInitializeTSS2(Tss, TssEntry);
KiInitializeTSS(Tss);
/* Initialize a descriptor for the TSS */
TssEntry->HighWord.Bits.Type = I386_TSS;
TssEntry->HighWord.Bits.Pres = 1;
TssEntry->HighWord.Bits.Dpl = 0;
TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
/* Load the task register */
__asm__("ltr %%ax":: "a" (KGDT_TSS));
/* Setup the Task Gate for Double Fault Traps */
TaskGateEntry = &KiIdt[8];
TaskGateAccess = (PKIDT_ACCESS)&TaskGateEntry->Access;
#if 0
TaskGateAccess->SegmentType = I386_TASK_GATE;
TaskGateAccess->Present = 1;
TaskGateAccess->Dpl = 0;
TaskGateEntry->Selector = KGDT_DF_TSS;
#endif
/* Initialize the TSS used for handling double faults. */
Tss = (PKTSS)KiDoubleFaultTSS;
KiInitializeTSS(Tss);
Tss->CR3 = _Ke386GetCr(3);
Tss->Esp0 = trap_stack_top;
Tss->Eip = PtrToUlong(KiTrap8);
Tss->Cs = KGDT_R0_CODE;
Tss->Fs = KGDT_R0_PCR;
Tss->Ss = Ke386GetSs();
Tss->Es = KGDT_R3_DATA | RPL_MASK;
Tss->Ds = KGDT_R3_DATA | RPL_MASK;
/* Setup the Double Trap TSS entry in the GDT */
TssEntry = &KiBootGdt[KGDT_DF_TSS / sizeof(KGDTENTRY)];
TssEntry->HighWord.Bits.Type = I386_TSS;
TssEntry->HighWord.Bits.Pres = 1;
TssEntry->HighWord.Bits.Dpl = 0;
TssEntry->BaseLow = (USHORT)((ULONG_PTR)Tss & 0xFFFF);
TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
TssEntry->LimitLow = KTSS_IO_MAPS;
}
VOID INIT_FUNCTION
Ki386SetProcessorFeatures(VOID)
{

View file

@ -12,135 +12,31 @@
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
#include <debug.h>
/* GLOBALS *******************************************************************/
PUSHORT KiGdtArray[MAXIMUM_PROCESSORS];
USHORT KiBootGdt[11 * 4] =
KGDTENTRY KiBootGdt[11] =
{
0x0, 0x0, 0x0, 0x0, /* Null */
0xffff, 0x0, 0x9a00, 0xcf, /* Kernel CS */
0xffff, 0x0, 0x9200, 0xcf, /* Kernel DS */
0xffff, 0x0, 0xfa00, 0xcf, /* User CS */
0xffff, 0x0, 0xf200, 0xcf, /* User DS */
0x0, 0x0, 0x0, 0x0, /* TSS */
0x0fff, 0x0000, 0x9200, 0xff00, /* PCR */
0x0fff, 0x0, 0xf200, 0x0, /* TEB */
0x0, 0x0, 0x0, 0x0, /* Reserved */
0x0, 0x0, 0x0, 0x0, /* LDT */
0x0, 0x0, 0x0, 0x0 /* Trap TSS */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* Null */
{0xffff, 0x0000, {{0x00, 0x9a, 0xcf, 0x00}}}, /* Kernel CS */
{0xffff, 0x0000, {{0x00, 0x92, 0xcf, 0x00}}}, /* Kernel DS */
{0xffff, 0x0000, {{0x00, 0xfa, 0xcf, 0x00}}}, /* User CS */
{0xffff, 0x0000, {{0x00, 0xf2, 0xcf, 0x00}}}, /* User DS */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* TSS */
{0x0fff, 0x0000, {{0x00, 0x92, 0x00, 0xff}}}, /* PCR */
{0x0fff, 0x0000, {{0x00, 0xf2, 0x00, 0x00}}}, /* TEB */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* Reserved */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}}, /* LDT */
{0x0000, 0x0000, {{0x00, 0x00, 0x00, 0x00}}} /* Trap TSS */
};
#include <pshpack1.h>
struct LocalGdtDescriptor_t
{
USHORT Length;
ULONG Base;
} KiGdtDescriptor = { 11 * 8, (ULONG)KiBootGdt };
#include <poppack.h>
KDESCRIPTOR KiGdtDescriptor = {sizeof(KiBootGdt), (ULONG)KiBootGdt};
static KSPIN_LOCK GdtLock;
/* FUNCTIONS *****************************************************************/
VOID
KiInitializeGdt(PKPCR Pcr)
{
PUSHORT Gdt;
struct LocalGdtDescriptor_t Descriptor;
ULONG Entry;
ULONG Base;
if (Pcr == NULL)
{
KiGdtArray[0] = KiBootGdt;
return;
}
/*
* Allocate a GDT
*/
Gdt = KiGdtArray[Pcr->Number];
if (Gdt == NULL)
{
DbgPrint("No GDT (%d)\n", Pcr->Number);
KEBUGCHECK(0);
}
/*
* Copy the boot processor's GDT onto this processor's GDT. Note that
* the only entries that can change are the PCR, TEB and LDT descriptors.
* We will be initializing these later so their current values are
* irrelevant.
*/
memcpy(Gdt, KiBootGdt, sizeof(USHORT) * 4 * 11);
Pcr->GDT = Gdt;
/*
* Set the base address of the PCR
*/
Base = (ULONG)Pcr;
Entry = KGDT_R0_PCR / 2;
Gdt[Entry + 1] = (USHORT)(((ULONG)Base) & 0xffff);
Gdt[Entry + 2] = Gdt[Entry + 2] & ~(0xff);
Gdt[Entry + 2] = (USHORT)(Gdt[Entry + 2] | ((((ULONG)Base) & 0xff0000) >> 16));
Gdt[Entry + 3] = Gdt[Entry + 3] & ~(0xff00);
Gdt[Entry + 3] = (USHORT)(Gdt[Entry + 3] | ((((ULONG)Base) & 0xff000000) >> 16));
/*
* Load the GDT
*/
Descriptor.Length = 8 * 11;
Descriptor.Base = (ULONG)Gdt;
#if defined(__GNUC__)
__asm__ ("lgdt %0\n\t" : /* no output */ : "m" (Descriptor));
/*
* Reload the selectors
*/
__asm__ ("movl %0, %%ds\n\t"
"movl %0, %%es\n\t"
"movl %1, %%fs\n\t"
"xor %%ax, %%ax\n\t"
"movw %%ax, %%gs\n\t"
: /* no output */
: "a" (KGDT_R3_DATA | RPL_MASK), "d" (KGDT_R0_PCR));
__asm__ ("pushl %0\n\t"
"pushl $.l4\n\t"
"lret\n\t"
".l4:\n\t"
: /* no output */
: "a" (KGDT_R0_CODE));
#elif defined(_MSC_VER)
__asm
{
lgdt Descriptor;
mov ax, KGDT_R3_DATA | RPL_MASK;
mov dx, KGDT_R0_PCR;
mov ds, ax;
mov es, ax;
mov fs, dx;
xor ax, ax
mov gs, ax;
push KGDT_R0_CODE;
push offset l4 ;
retf
l4:
}
#else
#error Unknown compiler for inline assembler
#endif
}
/*
* @unimplemented
*/

View file

@ -515,13 +515,10 @@ KiSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr6 = 0;
Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr7 = 0;
/*
* Low-level GDT, TSS and LDT Setup, most of which Freeldr should have done
* instead, and we should only add some extra information. This would be
* required for future NTLDR compatibility.
*/
KiInitializeGdt(NULL);
Ki386BootInitializeTSS();
/* Setup the boot (Freeldr should've done), double fault and NMI TSS */
Ki386InitializeTss();
/* Setup the LDT */
Ki386InitializeLdt();
/* Setup CPU-related fields */

View file

@ -1,119 +0,0 @@
/* $Id$
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel
* FILE: ntoskrnl/ke/i386/tss.c
* PURPOSE: TSS managment
*
* PROGRAMMERS: David Welch (welch@cwcom.net)
*/
/* INCLUDES *****************************************************************/
#include <ntoskrnl.h>
#define NDEBUG
#include <internal/debug.h>
#if defined (ALLOC_PRAGMA)
#pragma alloc_text(INIT, Ki386BootInitializeTSS)
#endif
/* GLOBALS *******************************************************************/
typedef struct _KTSSNOIOPM
{
UCHAR TssData[KTSS_IO_MAPS];
} KTSSNOIOPM;
static KTSS* Ki386TssArray[MAXIMUM_PROCESSORS];
PVOID Ki386InitialStackArray[MAXIMUM_PROCESSORS];
static KTSSNOIOPM* Ki386TrapTssArray[MAXIMUM_PROCESSORS];
static PVOID Ki386TrapStackArray[MAXIMUM_PROCESSORS];
KTSS KiBootTss;
static KTSSNOIOPM KiBootTrapTss;
extern USHORT KiBootGdt[];
extern ULONG init_stack;
extern ULONG init_stack_top;
extern VOID KiTrap8(VOID);
/* FUNCTIONS *****************************************************************/
VOID INIT_FUNCTION
Ki386BootInitializeTSS(VOID)
{
ULONG cr3_;
extern unsigned int trap_stack, trap_stack_top;
unsigned int base, length;
PKTSS Tss;
Ke386GetPageTableDirectory(cr3_);
Ki386TssArray[0] = &KiBootTss;
Ki386TrapTssArray[0] = &KiBootTrapTss;
Ki386TrapStackArray[0] = (PVOID)trap_stack;
Ki386InitialStackArray[0] = (PVOID)init_stack;
/* Initialize the boot TSS. */
KiBootTss.Esp0 = (ULONG)init_stack_top - sizeof(FX_SAVE_AREA);
KiBootTss.Ss0 = KGDT_R0_DATA;
KiBootTss.IoMapBase = 0xFFFF; /* No i/o bitmap */
KiBootTss.LDT = KGDT_LDT;
/*
* Initialize a descriptor for the TSS
*/
base = (unsigned int)&KiBootTss;
length = sizeof(KiBootTss) - 1;
KiBootGdt[(KGDT_TSS / 2) + 0] = (length & 0xFFFF);
KiBootGdt[(KGDT_TSS / 2) + 1] = (base & 0xFFFF);
KiBootGdt[(KGDT_TSS / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8900;
KiBootGdt[(KGDT_TSS / 2) + 3] = ((length & 0xF0000) >> 16) |
((base & 0xFF000000) >> 16);
/* Initialize the TSS used for handling double faults. */
Tss = (PKTSS)&KiBootTrapTss;
Tss->Flags = 0;
Tss->Esp0 = (ULONG)trap_stack_top; /* FIXME: - sizeof(FX_SAVE_AREA)? */
Tss->Ss0 = KGDT_R0_DATA;
Tss->Cs = KGDT_R0_CODE;
Tss->Eip = (ULONG)KiTrap8;
Tss->Ds = KGDT_R0_DATA;
Tss->Es = KGDT_R0_DATA;
Tss->Fs = KGDT_R0_PCR;
Tss->IoMapBase = 0xFFFF; /* No i/o bitmap */
Tss->LDT = 0x0;
/*
* Initialize a descriptor for the trap TSS.
*/
base = (unsigned int)&KiBootTrapTss;
length = sizeof(KiBootTrapTss) - 1;
KiBootGdt[(KGDT_DF_TSS / 2) + 0] = (length & 0xFFFF);
KiBootGdt[(KGDT_DF_TSS / 2) + 1] = (base & 0xFFFF);
KiBootGdt[(KGDT_DF_TSS / 2) + 2] = ((base & 0xFF0000) >> 16) | 0x8900;
KiBootGdt[(KGDT_DF_TSS / 2) + 3] = ((length & 0xF0000) >> 16) |
((base & 0xFF000000) >> 16);
/*
* Load the task register
*/
#if defined(__GNUC__)
__asm__("ltr %%ax"
: /* no output */
: "a" (KGDT_TSS));
#elif defined(_MSC_VER)
__asm mov ax, KGDT_TSS
__asm ltr ax
#else
#error Unknown compiler for inline assembler
#endif
}

View file

@ -38,7 +38,6 @@
<file>ldt.c</file>
<file>thread.c</file>
<file>trap.s</file>
<file>tss.c</file>
<file>usercall_asm.S</file>
<file>v86vdm.c</file>
<file>v86m_sup.S</file>