- Add Ke386SetFs, Ds, Es (using Ke386SetSeg) and Ke386SetTr new inlined commands.

- Also setup an NMI Task gate after the double fault task gate. Will be useful when we hand to handle NMIs later.
- Setup FS in KiSystemStartup and initialize the TSS before the PCR. Also add a bit more support for SMP systems (To skip boot-cpu-only initialization).
- Also setup DS/ES directly in KiSystemStartup.
- Initialize KD at phase 0 in KiSystemStartup, not in KiInitializeKernel, and also check for debug break at this time.

svn path=/trunk/; revision=23898
This commit is contained in:
Alex Ionescu 2006-09-03 17:18:08 +00:00
parent 25090facc3
commit c6f105da0b
6 changed files with 71 additions and 22 deletions

View file

@ -164,6 +164,9 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
__d; \
})
#define _Ke386SetCr(N,X) __asm__ __volatile__("movl %0,%%cr" #N : :"r" (X));
#define Ke386SetTr(X) __asm__ __volatile__("ltr %%ax" : :"a" (X));
#define _Ke386SetSeg(N,X) __asm__ __volatile__("movl %0,%%" #N : :"r" (X));
#define Ke386GetCr0() _Ke386GetCr(0)
#define Ke386SetCr0(X) _Ke386SetCr(0,X)
@ -172,6 +175,9 @@ KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
#define Ke386GetCr4() _Ke386GetCr(4)
#define Ke386SetCr4(X) _Ke386SetCr(4,X)
#define Ke386GetSs() _Ke386GetSeg(ss)
#define Ke386SetFs(X) _Ke386SetSeg(fs, X)
#define Ke386SetDs(X) _Ke386SetSeg(ds, X)
#define Ke386SetEs(X) _Ke386SetSeg(es, X)
static inline LONG Ke386TestAndClearBit(ULONG BitPos, volatile PULONG Addr)
{

View file

@ -121,6 +121,7 @@ extern ULONG KiMask32Array[MAXIMUM_PRIORITY];
extern ULONG IdleProcessorMask;
extern ULONG trap_stack_top;
extern VOID KiTrap8(VOID);
extern VOID KiTrap2(VOID);
/* MACROS *************************************************************************/

View file

@ -26,6 +26,9 @@ KTSS KiBootTss;
/* The TSS to use for Double Fault Traps (INT 0x9) */
UCHAR KiDoubleFaultTSS[KTSS_IO_MAPS];
/* The TSS to use for NMI Fault Traps (INT 0x2) */
UCHAR KiNMITSS[KTSS_IO_MAPS];
/* The Boot GDT (FIXME: should have more entries */
KGDTENTRY KiBootGdt[12] =
{
@ -563,7 +566,7 @@ Ki386InitializeTss(VOID)
TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
/* Load the task register */
__asm__("ltr %%ax":: "a" (KGDT_TSS));
Ke386SetTr(KGDT_TSS);
/* Setup the Task Gate for Double Fault Traps */
TaskGateEntry = &KiIdt[8];
@ -596,6 +599,37 @@ Ki386InitializeTss(VOID)
TssEntry->HighWord.Bytes.BaseMid = (UCHAR)((ULONG_PTR)Tss >> 16);
TssEntry->HighWord.Bytes.BaseHi = (UCHAR)((ULONG_PTR)Tss >> 24);
TssEntry->LimitLow = KTSS_IO_MAPS;
/* Now setup the NMI Task Gate */
TaskGateEntry = &KiIdt[2];
TaskGateAccess = (PKIDT_ACCESS)&TaskGateEntry->Access;
#if 0
TaskGateAccess->SegmentType = I386_TASK_GATE;
TaskGateAccess->Present = 1;
TaskGateEntry->Selector = KGDT_NMI_TSS;
#endif
/* Initialize the actual TSS */
Tss = (PKTSS)KiNMITSS;
KiInitializeTSS(Tss);
Tss->CR3 = _Ke386GetCr(3);
Tss->Esp0 = trap_stack_top;
Tss->Eip = PtrToUlong(KiTrap2);
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;
/* And its associated TSS Entry */
TssEntry = &KiBootGdt[KGDT_NMI_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;
}
/* This is a rather naive implementation of Ke(Save/Restore)FloatingPointState

View file

@ -435,9 +435,6 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
Prcb->NextThread = NULL;
//Prcb->IdleThread = InitThread;
/* Initialize the Debugger */
KdInitSystem (0, &KeLoaderBlock);
/* Initialize the Kernel Executive */
ExpInitializeExecutive();
@ -489,11 +486,26 @@ VOID
NTAPI
KiSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
{
/* Currently hacked for CPU 0 only */
ULONG Cpu = 0;
ULONG Cpu;
PKIPCR Pcr = (PKIPCR)KPCR_BASE;
PKPRCB Prcb;
/* Save the loader block and get the current CPU */
//KeLoaderBlock = LoaderBlock;
Cpu = KeNumberProcessors;
if (!Cpu)
{
/* If this is the boot CPU, set FS and the CPU Number*/
Ke386SetFs(KGDT_R0_PCR);
KeGetPcr()->Number = Cpu;
}
/* Skip initial setup if this isn't the Boot CPU */
if (Cpu) goto AppCpuInit;
/* Setup the boot (Freeldr should've done), double fault and NMI TSS */
Ki386InitializeTss();
/* Initialize the PCR */
RtlZeroMemory(Pcr, PAGE_SIZE);
KiInitializePcr(Cpu,
@ -503,7 +515,6 @@ KiSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
&KiBootTss,
&KiInitialThread.Tcb,
trap_stack);
Prcb = Pcr->Prcb;
/* Set us as the current process */
KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb;
@ -512,10 +523,13 @@ KiSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr6 = 0;
Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr7 = 0;
/* Setup the boot (Freeldr should've done), double fault and NMI TSS */
Ki386InitializeTss();
/* Load Ring 3 selectors for DS/ES */
Ke386SetDs(KGDT_R3_DATA | RPL_MASK);
Ke386SetEs(KGDT_R3_DATA | RPL_MASK);
/* Setup CPU-related fields */
AppCpuInit:
Prcb = Pcr->Prcb;
Pcr->Number = Cpu;
Pcr->SetMember = 1 << Cpu;
Pcr->SetMemberCopy = 1 << Cpu;
@ -528,6 +542,12 @@ KiSystemStartup(IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
KeActiveProcessors |= Pcr->SetMember;
KeNumberProcessors++;
/* Initialize the Debugger for the Boot CPU */
if (!Cpu) KdInitSystem (0, &KeLoaderBlock);
/* Check for break-in */
if (KdPollBreakIn()) DbgBreakPointWithStatus(1);
/* Raise to HIGH_LEVEL */
KfRaiseIrql(HIGH_LEVEL);

View file

@ -36,19 +36,6 @@ _NtProcessStartup:
lgdt _KiGdtDescriptor
lidt _KiIdtDescriptor
/* Load the PCR selector */
movl $KGDT_R0_PCR, %eax
movl %eax, %fs
/* Load DS/ES (with override) */
.intel_syntax noprefix
mov eax, KGDT_R3_DATA + RPL_MASK
.byte 0x66
mov ds, ax
.byte 0x66
mov es, ax
.att_syntax
/* Load the initial kernel stack */
lea _kernel_stack_top, %eax
sub $(SIZEOF_FX_SAVE_AREA), %eax

View file

@ -826,6 +826,7 @@ V86Int1:
int 3
.endfunc
.globl _KiTrap2
.func KiTrap2
_KiTrap2: