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=2…
==============================================================================
--- 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=…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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=…
==============================================================================
--- 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?…
==============================================================================
--- 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();
}
-