diff --git a/reactos/ntoskrnl/include/internal/i386/ke.h b/reactos/ntoskrnl/include/internal/i386/ke.h index 0dd6a866d73..7d0e521a54e 100644 --- a/reactos/ntoskrnl/include/internal/i386/ke.h +++ b/reactos/ntoskrnl/include/internal/i386/ke.h @@ -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) { diff --git a/reactos/ntoskrnl/include/internal/ke.h b/reactos/ntoskrnl/include/internal/ke.h index cab282b1c43..06d785692f4 100644 --- a/reactos/ntoskrnl/include/internal/ke.h +++ b/reactos/ntoskrnl/include/internal/ke.h @@ -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 *************************************************************************/ diff --git a/reactos/ntoskrnl/ke/i386/cpu.c b/reactos/ntoskrnl/ke/i386/cpu.c index cf14ca98a9c..daa2e252a90 100644 --- a/reactos/ntoskrnl/ke/i386/cpu.c +++ b/reactos/ntoskrnl/ke/i386/cpu.c @@ -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 diff --git a/reactos/ntoskrnl/ke/i386/kernel.c b/reactos/ntoskrnl/ke/i386/kernel.c index dd820c83369..07c69b8d4f7 100644 --- a/reactos/ntoskrnl/ke/i386/kernel.c +++ b/reactos/ntoskrnl/ke/i386/kernel.c @@ -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); diff --git a/reactos/ntoskrnl/ke/i386/main_asm.S b/reactos/ntoskrnl/ke/i386/main_asm.S index 22187d073c3..93e2834dbb5 100644 --- a/reactos/ntoskrnl/ke/i386/main_asm.S +++ b/reactos/ntoskrnl/ke/i386/main_asm.S @@ -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 diff --git a/reactos/ntoskrnl/ke/i386/trap.s b/reactos/ntoskrnl/ke/i386/trap.s index d312ed5438e..cb17cd448b4 100644 --- a/reactos/ntoskrnl/ke/i386/trap.s +++ b/reactos/ntoskrnl/ke/i386/trap.s @@ -826,6 +826,7 @@ V86Int1: int 3 .endfunc +.globl _KiTrap2 .func KiTrap2 _KiTrap2: