Author: ion Date: Sat Sep 30 09:42:22 2006 New Revision: 24306
URL: http://svn.reactos.org/svn/reactos?rev=24306&view=rev Log: - Fix some bugs in intrin.h (missing __inline__ statments in some locations, which were causing warnings due to "static"). - Remove intrinsics in winddk.h since they're now properly done in intrin.h (thanks KJK!!!) - Make freeldr.c setup the boot KTSS like NTLDR does, so that the GDT entry for it is valid (and remove the code that was doing this from Ki386InitializeTss) - Refactor KiSystemStartup to use 100% dynamic pointers and machine data queried from the Loader Block or actual GDT/IDT/Selectors in memory, isntead of hard-coded ntoskrnl offsets. This makes it possible to be loaded by NTLDR, which sets these system structures up by itself. (we do it in freeldr.c, as hacks).
Modified: trunk/reactos/include/ddk/winddk.h trunk/reactos/include/psdk/intrin.h trunk/reactos/ntoskrnl/include/internal/i386/ke.h trunk/reactos/ntoskrnl/include/internal/ke.h trunk/reactos/ntoskrnl/ke/freeldr.c trunk/reactos/ntoskrnl/ke/i386/cpu.c trunk/reactos/ntoskrnl/ke/i386/kiinit.c
Modified: trunk/reactos/include/ddk/winddk.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/ddk/winddk.h?rev=24... ============================================================================== --- trunk/reactos/include/ddk/winddk.h (original) +++ trunk/reactos/include/ddk/winddk.h Sat Sep 30 09:42:22 2006 @@ -10568,30 +10568,6 @@
#endif
-#ifdef __GNUC__ - -/* Available as intrinsics on MSVC */ -static __inline void _disable(void) {__asm__ __volatile__("cli\n");} -static __inline void _enable(void) {__asm__ __volatile__("sti\n");} - -static __inline ULONG64 __readcr3(void) -{ - ULONG_PTR Ret; - __asm__ __volatile__("movl %%cr3, %0;\n" - :"=r"(Ret)); - return (ULONG64)Ret; -} - -static __inline ULONG64 __readcr4(void) -{ - ULONG_PTR Ret; - __asm__ __volatile__("movl %%cr4, %0; \n" - :"=r"(Ret)); - return (ULONG64)Ret; -} - -#endif - #ifdef __cplusplus } #endif
Modified: trunk/reactos/include/psdk/intrin.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/psdk/intrin.h?rev=2... ============================================================================== --- trunk/reactos/include/psdk/intrin.h (original) +++ trunk/reactos/include/psdk/intrin.h Sat Sep 30 09:42:22 2006 @@ -609,20 +609,20 @@
/*** Bit manipulation ***/ -static __attribute__((always_inline)) unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask) +static __inline__ __attribute__((always_inline)) unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask) { __asm__("bsfl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask)); return Mask ? 1 : 0; }
-static __attribute__((always_inline)) unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask) +static __inline__ __attribute__((always_inline)) unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask) { __asm__("bsrl %[Mask], %[Index]" : [Index] "=r" (*Index) : [Mask] "mr" (Mask)); return Mask ? 1 : 0; }
/* NOTE: again, the bizarre implementation follows Visual C++ */ -static __attribute__((always_inline)) unsigned char _bittest(const long * const a, const long b) +static __inline__ __attribute__((always_inline)) unsigned char _bittest(const long * const a, const long b) { unsigned char retval;
Modified: trunk/reactos/ntoskrnl/include/internal/i386/ke.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/i... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/i386/ke.h (original) +++ trunk/reactos/ntoskrnl/include/internal/i386/ke.h Sat Sep 30 09:42:22 2006 @@ -56,9 +56,14 @@ KiInitializeGdt(struct _KPCR* Pcr); VOID Ki386ApplicationProcessorInitializeTSS(VOID); -VOID -NTAPI -Ki386InitializeTss(VOID); + +VOID +FASTCALL +Ki386InitializeTss( + IN PKTSS Tss, + IN PKIDTENTRY Idt +); + VOID KiGdtPrepareForApplicationProcessorInit(ULONG Id); VOID @@ -203,6 +208,7 @@ #define Ke386GetCr4() _Ke386GetCr(4) #define Ke386SetCr4(X) _Ke386SetCr(4,X) #define Ke386GetSs() _Ke386GetSeg(ss) +#define Ke386GetFs() _Ke386GetSeg(fs) #define Ke386SetFs(X) _Ke386SetSeg(fs, X) #define Ke386SetDs(X) _Ke386SetSeg(ds, X) #define Ke386SetEs(X) _Ke386SetSeg(es, X)
Modified: trunk/reactos/ntoskrnl/include/internal/ke.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/k... ============================================================================== --- trunk/reactos/ntoskrnl/include/internal/ke.h (original) +++ trunk/reactos/ntoskrnl/include/internal/ke.h Sat Sep 30 09:42:22 2006 @@ -807,6 +807,13 @@ VOID );
+ +VOID +NTAPI +KiInitializeMachineType( + VOID +); + VOID NTAPI KiFlushNPXState(
Modified: trunk/reactos/ntoskrnl/ke/freeldr.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/freeldr.c?rev=2... ============================================================================== --- trunk/reactos/ntoskrnl/ke/freeldr.c (original) +++ trunk/reactos/ntoskrnl/ke/freeldr.c Sat Sep 30 09:42:22 2006 @@ -87,10 +87,22 @@ PIMAGE_OPTIONAL_HEADER OptHead; PLOADER_PARAMETER_BLOCK NtLoaderBlock; CHAR* s; + PKTSS Tss; + PKGDTENTRY TssEntry;
/* Load the GDT and IDT */ Ke386SetGlobalDescriptorTable(KiGdtDescriptor); Ke386SetInterruptDescriptorTable(KiIdtDescriptor); + + /* Initialize the boot TSS */ + Tss = &KiBootTss; + TssEntry = &KiBootGdt[KGDT_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);
/* Copy the Loader Block Data locally since Low-Memory will be wiped */ memcpy(&KeRosLoaderBlock, LoaderBlock, sizeof(ROS_LOADER_PARAMETER_BLOCK));
Modified: trunk/reactos/ntoskrnl/ke/i386/cpu.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/cpu.c?rev=... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/cpu.c (original) +++ trunk/reactos/ntoskrnl/ke/i386/cpu.c Sat Sep 30 09:42:22 2006 @@ -61,6 +61,7 @@ ULONG MxcsrFeatureMask = 0; ULONG KeI386XMMIPresent = 0; ULONG KeI386FxsrPresent = 0; +ULONG KeI386MachineType; ULONG Ke386Pae = FALSE; ULONG Ke386GlobalPagesEnabled = FALSE; ULONG Ke386NoExecute = FALSE; @@ -549,33 +550,24 @@ }
VOID -NTAPI -Ki386InitializeTss(VOID) -{ - PKTSS Tss; +FASTCALL +Ki386InitializeTss(IN PKTSS Tss, + IN PKIDTENTRY Idt) +{ 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 */ Ke386SetTr(KGDT_TSS);
/* Setup the Task Gate for Double Fault Traps */ - TaskGateEntry = &KiIdt[8]; + TaskGateEntry = &Idt[8]; TaskGateAccess = (PKIDT_ACCESS)&TaskGateEntry->Access; #if 0 TaskGateAccess->SegmentType = I386_TASK_GATE; @@ -607,7 +599,7 @@ TssEntry->LimitLow = KTSS_IO_MAPS;
/* Now setup the NMI Task Gate */ - TaskGateEntry = &KiIdt[2]; + TaskGateEntry = &Idt[2]; TaskGateAccess = (PKIDT_ACCESS)&TaskGateEntry->Access; #if 0 TaskGateAccess->SegmentType = I386_TASK_GATE; @@ -763,6 +755,14 @@ Ke386GetLocalDescriptorTable(ProcessorState->SpecialRegisters.Ldtr); }
+VOID +NTAPI +KiInitializeMachineType(VOID) +{ + /* Set the Machine Type we got from NTLDR */ + KeI386MachineType = KeLoaderBlock->u.I386.MachineType & 0x000FF; +} + /* PUBLIC FUNCTIONS **********************************************************/
/*
Modified: trunk/reactos/ntoskrnl/ke/i386/kiinit.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/kiinit.c?r... ============================================================================== --- trunk/reactos/ntoskrnl/ke/i386/kiinit.c (original) +++ trunk/reactos/ntoskrnl/ke/i386/kiinit.c Sat Sep 30 09:42:22 2006 @@ -11,6 +11,7 @@ #include <ntoskrnl.h> #define NDEBUG #include <debug.h> +#include <intrin.h>
/* GLOBALS *******************************************************************/
@@ -229,11 +230,56 @@
VOID NTAPI +KiGetMachineBootPointers(IN PKGDTENTRY *Gdt, + IN PKIDTENTRY *Idt, + IN PKIPCR *Pcr, + IN PKTSS *Tss) +{ + KDESCRIPTOR GdtDescriptor, IdtDescriptor; + KGDTENTRY TssSelector, PcrSelector; + ULONG Tr, Fs; + + /* Get GDT and IDT descriptors */ + Ke386GetGlobalDescriptorTable(GdtDescriptor); + Ke386GetInterruptDescriptorTable(IdtDescriptor); + + /* Save IDT and GDT */ + *Gdt = (PKGDTENTRY)GdtDescriptor.Base; + *Idt = (PKIDTENTRY)IdtDescriptor.Base; + + /* Get TSS and FS Selectors */ + Ke386GetTr(&Tr); + if (Tr != KGDT_TSS) Tr = KGDT_TSS; // FIXME: HACKHACK + Fs = Ke386GetFs(); + + /* Get PCR Selector, mask it and get its GDT Entry */ + PcrSelector = *(PKGDTENTRY)((ULONG_PTR)*Gdt + (Fs & ~RPL_MASK)); + + /* Get the KPCR itself */ + *Pcr = (PKIPCR)(ULONG_PTR)(PcrSelector.BaseLow | + PcrSelector.HighWord.Bytes.BaseMid << 16 | + PcrSelector.HighWord.Bytes.BaseHi << 24); + + /* Get TSS Selector, mask it and get its GDT Entry */ + TssSelector = *(PKGDTENTRY)((ULONG_PTR)*Gdt + (Tr & ~RPL_MASK)); + + /* Get the KTSS itself */ + *Tss = (PKTSS)(ULONG_PTR)(TssSelector.BaseLow | + TssSelector.HighWord.Bytes.BaseMid << 16 | + TssSelector.HighWord.Bytes.BaseHi << 24); +} + +VOID +NTAPI KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { ULONG Cpu; - PKIPCR Pcr = (PKIPCR)KPCR_BASE; - PKPRCB Prcb; + PKTHREAD InitialThread; + PVOID InitialStack; + PKGDTENTRY Gdt; + PKIDTENTRY Idt; + PKTSS Tss; + PKIPCR Pcr;
/* Save the loader block and get the current CPU */ KeLoaderBlock = LoaderBlock; @@ -243,30 +289,47 @@ /* If this is the boot CPU, set FS and the CPU Number*/ Ke386SetFs(KGDT_R0_PCR); KeGetPcr()->Number = Cpu; + + /* Set the initial stack and idle thread as well */ + LoaderBlock->KernelStack = (ULONG_PTR)P0BootStack; + LoaderBlock->Thread = (ULONG_PTR)&KiInitialThread; } + + /* Save the initial thread and stack */ + InitialStack = (PVOID)LoaderBlock->KernelStack; + InitialThread = (PKTHREAD)LoaderBlock->Thread; + + /* Clean the APC List Head */ + InitializeListHead(&InitialThread->ApcState.ApcListHead[KernelMode]); + + /* Initialize the machine type */ + KiInitializeMachineType();
/* 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(); + /* Get GDT, IDT, PCR and TSS pointers */ + KiGetMachineBootPointers(&Gdt, &Idt, &Pcr, &Tss); + + /* Setup the TSS descriptors and entries */ + Ki386InitializeTss(Tss, Idt);
/* Initialize the PCR */ RtlZeroMemory(Pcr, PAGE_SIZE); KiInitializePcr(Cpu, Pcr, - KiIdt, - KiBootGdt, - &KiBootTss, - &KiInitialThread.Tcb, + Idt, + Gdt, + Tss, + InitialThread, KiDoubleFaultStack);
/* Set us as the current process */ - KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb; + InitialThread->ApcState.Process = &KiInitialProcess.Pcb;
/* Clear DR6/7 to cleanup bootloader debugging */ - Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr6 = 0; - Pcr->PrcbData.ProcessorState.SpecialRegisters.KernelDr7 = 0; + __writefsdword(KPCR_DR6, 0); + __writefsdword(KPCR_DR7, 0);
/* Load Ring 3 selectors for DS/ES */ Ke386SetDs(KGDT_R3_DATA | RPL_MASK); @@ -274,11 +337,10 @@
/* Setup CPU-related fields */ AppCpuInit: - Prcb = Pcr->Prcb; - Pcr->Number = Cpu; - Pcr->SetMember = 1 << Cpu; - Pcr->SetMemberCopy = 1 << Cpu; - Prcb->SetMember = 1 << Cpu; + __writefsdword(KPCR_NUMBER, Cpu); + __writefsdword(KPCR_SET_MEMBER, 1 << Cpu); + __writefsdword(KPCR_SET_MEMBER_COPY, 1 << Cpu); + __writefsdword(KPCR_PRCB_SET_MEMBER, 1 << Cpu);
/* Initialize the Processor with HAL */ HalInitializeProcessor(Cpu, KeLoaderBlock); @@ -296,11 +358,11 @@ /* Raise to HIGH_LEVEL */ KfRaiseIrql(HIGH_LEVEL);
- /* Call main kernel intialization */ + /* Call main kernel initialization */ KiInitializeKernel(&KiInitialProcess.Pcb, - &KiInitialThread.Tcb, - P0BootStack, - Prcb, + InitialThread, + InitialStack, + &Pcr->PrcbData, //(PKPRCB)__readfsdword(KPCR_PRCB), Cpu, LoaderBlock);
@@ -314,4 +376,3 @@ KiIdleLoop(); }
-