Author: tkreuzer Date: Sat Nov 14 00:30:44 2009 New Revision: 44144
URL: http://svn.reactos.org/svn/reactos?rev=44144&view=rev Log: - Share some more inline functions between the kernel and freeldr - Use __ltr instead of Ke386SetTr - refactor KiInitializeTss - Update some Mm conatnts - Halfplement KeFlushEntireTb - Clean the mapping of page 0 in KiSystemStartup, as long as we don't clean mappings in freeldr - Fix a serious bug in KiPageFault, where ebp was used instead of rbp, resulting in recursive page faults as soon as usermode mappings were cleared - Refactor MmArmInitSystem and related. Pahse 0 initialisation completes here now. we fail later in freelist setup code, which is not 64 bit safe.
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/windows/amd64/wlmemory.c branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/intrin_i.h branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/ke.h branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/mm.h branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/cpu.c branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/kiinit.c branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/trap.S branches/ros-amd64-bringup/reactos/ntoskrnl/mm/amd64/init.c
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/f... ============================================================================== --- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/include/arch/amd64/amd64.h [iso-8859-1] Sat Nov 14 00:30:44 2009 @@ -58,28 +58,6 @@ HARDWARE_PTE Pde[512]; } PAGE_DIRECTORY_AMD64, *PPAGE_DIRECTORY_AMD64;
-PKGDTENTRY64 -FORCEINLINE -KiGetGdtEntry(PVOID pGdt, USHORT Index) -{ - return (PKGDTENTRY64)((ULONG64)pGdt + (Index & ~RPL_MASK)); -} - -VOID -FORCEINLINE -KiInitGdtEntry(PKGDTENTRY64 Entry, ULONG64 Base, ULONG Limit, UCHAR Type, UCHAR Dpl) -{ - Entry->Bits.Type = Type; - Entry->Bits.Present = 1; - Entry->Bits.Dpl = Dpl; - Entry->BaseLow = (USHORT)(Base & 0xFFFF); - Entry->Bytes.BaseMiddle = (UCHAR)(Base >> 16); - Entry->Bytes.BaseHigh = (UCHAR)(Base >> 24); - Entry->BaseUpper = (ULONG)(Base >> 32); - Entry->LimitLow = (USHORT)(Limit & 0xFFFF); - Entry->Bits.LimitHigh = (ULONG)((Limit >> 16) & 0xf); - Entry->MustBeZero = 0; -}
VOID FrLdrSetupGdtIdt();
Modified: branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/windows/amd64/wlmemory.c URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/boot/f... ============================================================================== --- branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/windows/amd64/wlmemory.c [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/boot/freeldr/freeldr/windows/amd64/wlmemory.c [iso-8859-1] Sat Nov 14 00:30:44 2009 @@ -354,8 +354,8 @@ Ke386SetGs(KGDT_64_DATA | RPL_MASK); // 0x2b Ke386SetSs(KGDT_64_R0_SS); // 0x18
- // Load TSR - Ke386SetTr(KGDT_TSS); + /* Load TSR */ + __ltr(KGDT_TSS);
DPRINTM(DPRINT_WINDOWS, "leave WinLdrSetProcessorContext\n"); }
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/intrin_i.h URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskr... ============================================================================== --- branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/intrin_i.h [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/intrin_i.h [iso-8859-1] Sat Nov 14 00:30:44 2009 @@ -9,6 +9,57 @@
#define KeSetCurrentIrql(x) __writecr8(x)
+PKGDTENTRY64 +FORCEINLINE +KiGetGdtEntry(PVOID pGdt, USHORT Selector) +{ + return (PKGDTENTRY64)((ULONG64)pGdt + (Selector & ~RPL_MASK)); +} + +PVOID +FORCEINLINE +KiGetGdtDescriptorBase(PKGDTENTRY Entry) +{ + return (PVOID)((ULONG64)Entry->BaseLow | + (ULONG64)Entry->Bytes.BaseMiddle << 16 | + (ULONG64)Entry->Bytes.BaseHigh << 24 | + (ULONG64)Entry->BaseUpper << 32); +} + +VOID +FORCEINLINE +KiSetGdtDescriptorBase(PKGDTENTRY Entry, ULONG64 Base) +{ + Entry->BaseLow = Base & 0xffff; + Entry->Bits.BaseMiddle = (Base >> 16) & 0xff; + Entry->Bits.BaseHigh = (Base >> 24) & 0xff; + Entry->BaseUpper = Base >> 32; +} + +PVOID +FORCEINLINE +KiSetGdtDescriptorLimit(PKGDTENTRY Entry, ULONG Limit) +{ + Entry->LimitLow = Limit & 0xffff; + Entry->Bits.LimitHigh = Limit >> 16; +} + +VOID +FORCEINLINE +KiInitGdtEntry(PKGDTENTRY64 Entry, ULONG64 Base, ULONG Size, UCHAR Type, UCHAR Dpl) +{ + KiSetGdtDescriptorBase(Entry, Base); + KiSetGdtDescriptorLimit(Entry, Size - 1); + Entry->Bits.Type = Type; + Entry->Bits.Dpl = Dpl; + Entry->Bits.Present = 1; + Entry->Bits.System = 0; + Entry->Bits.LongMode = 0; + Entry->Bits.DefaultBig = 0; + Entry->Bits.Granularity = 0; + Entry->MustBeZero = 0; +} + #if defined(__GNUC__)
static __inline__ __attribute__((always_inline)) void __lgdt(void *Source) @@ -41,9 +92,9 @@ __asm__ __volatile__("stmxcsr %0" : : "m"(*Destination) : "memory"); }
-static __inline__ __attribute__((always_inline)) void __ltr(unsigned short *Source) -{ - __asm__ __volatile__("ltr %0" : : "m"(*Source)); +static __inline__ __attribute__((always_inline)) void __ltr(unsigned short Source) +{ + __asm__ __volatile__("ltr %0" : : "rm"(Source)); }
static __inline__ __attribute__((always_inline)) void __str(unsigned short *Destination) @@ -51,25 +102,6 @@ __asm__ __volatile__("str %0" : : "m"(*Destination) : "memory"); }
-#define Ke386GetLocalDescriptorTable(X) \ - __asm__("sldt %0\n\t" \ - : /* no outputs */ \ - : "m" (X)); - -#define Ke386SetLocalDescriptorTable(X) \ - __asm__("lldt %w0\n\t" \ - : /* no outputs */ \ - : "q" (X)); - -#define Ke386SetTr(X) __asm__ __volatile__("ltr %%ax" : :"a" (X)); - -#define Ke386GetTr(X) \ - __asm__("str %0\n\t" \ - : /* no outputs */ \ - : "m" (X)); - -#define Ke386SaveFlags(x) __asm__ __volatile__("pushfq ; popq %0":"=rm" (x): /* no input */) -#define Ke386RestoreFlags(x) __asm__ __volatile__("pushq %0 ; popfq": /* no output */ :"irm" (x):"memory")
#define _Ke386GetSeg(N) ({ \ unsigned int __d; \
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/ke.h URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskr... ============================================================================== --- branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/ke.h [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/ke.h [iso-8859-1] Sat Nov 14 00:30:44 2009 @@ -46,6 +46,8 @@ #define X86_MSR_CSTAR 0xC0000083 #define X86_MSR_SFMASK 0xC0000084
+#define AMD64_TSS 9 + #ifndef __ASM__
#include "intrin_i.h" @@ -118,21 +120,10 @@ }
struct _KPCR; -VOID -KiInitializeGdt(struct _KPCR* Pcr); -VOID -Ki386ApplicationProcessorInitializeTSS(VOID); - -// Hack -VOID KiRosPrepareForSystemStartup(ULONG, PROS_LOADER_PARAMETER_BLOCK);
VOID FASTCALL -Ki386InitializeTss( - IN PKTSS Tss, - IN PVOID GdtBase, - IN UINT64 Stack -); +KiInitializeTss(IN PKTSS Tss, IN UINT64 Stack);
VOID KiDivideErrorFault(); VOID KiDebugTrapOrFault();
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/mm.h URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskr... ============================================================================== --- branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/mm.h [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/ntoskrnl/include/internal/amd64/mm.h [iso-8859-1] Sat Nov 14 00:30:44 2009 @@ -5,11 +5,24 @@ #ifndef __NTOSKRNL_INCLUDE_INTERNAL_AMD64_MM_H #define __NTOSKRNL_INCLUDE_INTERNAL_AMD64_MM_H
+/* Helper macros */ #define PAGE_MASK(x) ((x)&(~0xfff)) #define PAE_PAGE_MASK(x) ((x)&(~0xfffLL))
-#define HYPER_SPACE 0xFFFFF70000000000ULL -#define HYPER_SPACE_END 0xFFFFF77FFFFFFFFFULL +/* Memory layout base addresses */ +#define HYPER_SPACE 0xFFFFF70000000000ULL +#define HYPER_SPACE_END 0xFFFFF77FFFFFFFFFULL +#define MI_SESSION_VIEW_END (PVOID)0xFFFFF97FFF000000ULL +#define MI_SESSION_SPACE_END (PVOID)0xFFFFF98000000000ULL + +#define MI_PAGED_POOL_START (PVOID)0xFFFFFA8000000000ULL + +#define MI_NON_PAGED_SYSTEM_START_MIN 0xFFFFFAA000000000ULL +#define MI_NONPAGED_POOL_END (PVOID)0xFFFFFAE000000000ULL + +#define MI_DEBUG_MAPPING (PVOID)0xFFFFFFFF80000000ULL // FIXME + +
PULONG64 FORCEINLINE @@ -87,8 +100,8 @@ #define MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING ((255*1024*1024) >> PAGE_SHIFT) #define MI_MIN_PAGES_FOR_SYSPTE_TUNING ((19*1024*1024) >> PAGE_SHIFT) #define MI_MIN_PAGES_FOR_SYSPTE_BOOST ((32*1024*1024) >> PAGE_SHIFT) -#define MI_MAX_INIT_NONPAGED_POOL_SIZE (128 * 1024 * 1024) -#define MI_MAX_NONPAGED_POOL_SIZE (128 * 1024 * 1024) +#define MI_MAX_INIT_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024) +#define MI_MAX_NONPAGED_POOL_SIZE (128ULL * 1024 * 1024 * 1024) #define MI_MAX_FREE_PAGE_LISTS 4
#define MI_MIN_INIT_PAGED_POOLSIZE (32 * 1024 * 1024) @@ -104,9 +117,6 @@
#define MI_SYSTEM_VIEW_SIZE (16 * 1024 * 1024)
-#define MI_PAGED_POOL_START (PVOID)0xFFFFFA8000000000ULL -#define MI_NONPAGED_POOL_END (PVOID)0xFFFFFAE000000000ULL -#define MI_DEBUG_MAPPING (PVOID)0xFFFFFFFF80000000ULL // FIXME
#define MM_HIGHEST_VAD_ADDRESS \ (PVOID)((ULONG_PTR)MM_HIGHEST_USER_ADDRESS - (16 * PAGE_SIZE))
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/cpu.c URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskr... ============================================================================== --- branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/cpu.c [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/cpu.c [iso-8859-1] Sat Nov 14 00:30:44 2009 @@ -46,6 +46,9 @@ KIRQL KiOldIrql; ULONG KiFreezeFlag;
+/* Flush data */ +volatile LONG KiTbFlushTimeStamp; + /* CPU Signatures */ static const CHAR CmpIntelID[] = "GenuineIntel"; static const CHAR CmpAmdID[] = "AuthenticAMD"; @@ -90,7 +93,7 @@ KeGetCurrentPrcb()->CpuID = 0;
/* Save EFlags */ - Ke386SaveFlags(EFlags); + EFlags = __readeflags();
/* Do CPUID 1 now */ __cpuid(Reg, 1); @@ -115,7 +118,7 @@ KeGetCurrentPrcb()->CpuStep = (USHORT)Stepping;
/* Restore EFLAGS */ - Ke386RestoreFlags(EFlags); + __writeeflags(EFlags); }
ULONG @@ -389,35 +392,19 @@
VOID FASTCALL -Ki386InitializeTss(IN PKTSS64 Tss, - IN PVOID GdtBase, - IN UINT64 Stack) +KiInitializeTss(IN PKTSS64 Tss, + IN UINT64 Stack) { PKGDTENTRY64 TssEntry;
- /* Initialize the TSS descriptor entry */ - TssEntry = (PVOID)((ULONG64)GdtBase + KGDT_TSS); - TssEntry->Bits.Type = 9;//AMD64_TSS; - TssEntry->Bits.Dpl = 0; - TssEntry->Bits.Present = 1; - TssEntry->Bits.System = 0; - TssEntry->Bits.LongMode = 0; - TssEntry->Bits.DefaultBig = 0; - TssEntry->Bits.Granularity = 0; - TssEntry->MustBeZero = 0; - - /* Descriptor base is the TSS address */ - TssEntry->BaseLow = (ULONG64)Tss & 0xffff; - TssEntry->Bits.BaseMiddle = ((ULONG64)Tss >> 16) & 0xff; - TssEntry->Bits.BaseHigh = ((ULONG64)Tss >> 24) & 0xff; - TssEntry->BaseUpper = (ULONG64)Tss >> 32; - - /* Set the limit */ - TssEntry->LimitLow = sizeof(KTSS64) -1; - TssEntry->Bits.LimitHigh = 0; + /* Get pointer to the GDT entry */ + TssEntry = KiGetGdtEntry(KeGetPcr()->GdtBase, KGDT_TSS); + + /* Initialize the GDT entry */ + KiInitGdtEntry(TssEntry, (ULONG64)Tss, sizeof(KTSS64), AMD64_TSS, 0);
/* Zero out the TSS */ - RtlZeroMemory(Tss, sizeof(KTSS)); + RtlZeroMemory(Tss, sizeof(KTSS64));
/* FIXME: I/O Map? */ Tss->IoMapBase = 0x68; @@ -435,8 +422,7 @@ Tss->Ist[3] = (ULONG64)KiDoubleFaultStack;
/* Load the task register */ - Ke386SetTr(KGDT_TSS); - + __ltr(KGDT_TSS); }
VOID @@ -535,7 +521,19 @@ KeFlushEntireTb(IN BOOLEAN Invalid, IN BOOLEAN AllProcessors) { - UNIMPLEMENTED; + KIRQL OldIrql; + + // FIXME: halfplemented + /* Raise the IRQL for the TB Flush */ + OldIrql = KeRaiseIrqlToSynchLevel(); + + /* Flush the TB for the Current CPU, and update the flush stamp */ + KeFlushCurrentTb(); + + /* Update the flush stamp and return to original IRQL */ + InterlockedExchangeAdd(&KiTbFlushTimeStamp, 1); + KeLowerIrql(OldIrql); + }
KAFFINITY
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/kiinit.c URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskr... ============================================================================== --- branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/kiinit.c [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/kiinit.c [iso-8859-1] Sat Nov 14 00:30:44 2009 @@ -337,7 +337,7 @@ IN PVOID DpcStack) { KDESCRIPTOR GdtDescriptor = {{0},0,0}, IdtDescriptor = {{0},0,0}; - KGDTENTRY64 TssSelector; + PKGDTENTRY64 TssEntry; USHORT Tr = 0;
/* Zero out the PCR */ @@ -375,19 +375,16 @@ Pcr->IdtBase = (PKIDTENTRY)IdtDescriptor.Base;
/* Get TSS Selector */ - Ke386GetTr(Tr); // <- FIXME: this is ugly! - if (Tr != KGDT_TSS) Tr = KGDT_TSS; // FIXME: HACKHACK - - /* Get TSS Selector, mask it and get its GDT Entry */ - TssSelector = *(PKGDTENTRY)((ULONG_PTR)Pcr->GdtBase + (Tr & ~RPL_MASK)); + __str(&Tr); + ASSERT(Tr == KGDT_TSS); + + /* Get TSS Entry */ + TssEntry = KiGetGdtEntry(Pcr->GdtBase, Tr);
/* Get the KTSS itself */ - Pcr->TssBase = (PKTSS)(ULONG_PTR)(TssSelector.BaseLow | - TssSelector.Bytes.BaseMiddle << 16 | - TssSelector.Bytes.BaseHigh << 24 | - (ULONG64)TssSelector.BaseUpper << 32); - - Pcr->Prcb.RspBase = Pcr->TssBase->Rsp0; + Pcr->TssBase = KiGetGdtDescriptorBase(TssEntry); + + Pcr->Prcb.RspBase = Pcr->TssBase->Rsp0; // FIXME
/* Set DPC Stack */ Pcr->Prcb.DpcStack = DpcStack; @@ -403,7 +400,7 @@ Pcr->Prcb.CurrentThread = IdleThread;
/* Start us out at PASSIVE_LEVEL */ -// Pcr->Irql = PASSIVE_LEVEL; + Pcr->Irql = PASSIVE_LEVEL; KeSetCurrentIrql(PASSIVE_LEVEL);
} @@ -627,6 +624,9 @@ FrLdrDbgPrint = ((PLOADER_PARAMETER_BLOCK)Dummy)->u.I386.CommonDataArea; FrLdrDbgPrint("Hello from KiSystemStartup!!!\n");
+ /* HACK, because freeldr maps page 0 */ + MiAddressToPte((PVOID)0)->u.Hard.Valid = 0; + KiSystemStartupReal((PLOADER_PARAMETER_BLOCK)Dummy);
// KiRosPrepareForSystemStartup(Dummy, LoaderBlock); @@ -699,7 +699,7 @@ if (Cpu == 0) { /* Setup the TSS descriptors and entries */ - Ki386InitializeTss(Pcr->TssBase, Pcr->GdtBase, InitialStack); + KiInitializeTss(Pcr->TssBase, InitialStack);
/* Setup the IDT */ KeInitExceptions(); @@ -711,7 +711,7 @@ KdInitSystem(0, KeLoaderBlock);
/* Check for break-in */ -// if (KdPollBreakIn()) DbgBreakPointWithStatus(1); + if (KdPollBreakIn()) DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
/* Hack! Wait for the debugger! */ while (!KdPollBreakIn()); @@ -728,7 +728,7 @@
// DPRINT1("Gdt = %p, Idt = %p, Pcr = %p, Tss = %p\n", Gdt, Idt, Pcr, Tss);
- DbgBreakPointWithStatus(0); + DbgBreakPointWithStatus(DBG_STATUS_CONTROL_C);
/* Initialize the Processor with HAL */ HalInitializeProcessor(Cpu, KeLoaderBlock);
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/trap.S URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskr... ============================================================================== --- branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/trap.S [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/ntoskrnl/ke/amd64/trap.S [iso-8859-1] Sat Nov 14 00:30:44 2009 @@ -19,7 +19,7 @@ .asciz "WARNING: %s at %s:%d is UNIMPLEMENTED!\n"
_MsgPageFault: -.ascii "Page fault 0x%x at %p!\n\0" +.ascii "Page fault! Code = 0x%x, RIP = %p, FaultingAddress = %p\n\0"
_MsgGeneralProtFault: .ascii "General protection fault at %p!\n\0" @@ -333,9 +333,9 @@
ENTER_TRAP_FRAME (0x28), TRAPFLAG_ALL
- lea rcx, _MsgBreakpointTrap[rip] - mov rdx, rbp - call _FrLdrDbgPrint[rip] +// lea rcx, _MsgBreakpointTrap[rip] +// mov rdx, rsp +// call _FrLdrDbgPrint[rip]
/* Dispatch the exception */ mov ecx, STATUS_BREAKPOINT @@ -495,23 +495,25 @@ .pushframe 1 /* We have an error code */
-// lea rcx, _MsgPageFault[rip] -// mov rdx, [rsp] -// mov r8, [rsp+8] -// mov r9, rsp -// call _FrLdrDbgPrint[rip] - ENTER_TRAP_FRAME (0x28), TRAPFLAG_ALL + +#if 0 + lea rcx, _MsgPageFault[rip] + mov rdx, [rbp + KTRAP_FRAME_ErrorCode] + mov r8, [rbp + KTRAP_FRAME_Rip] + mov r9, [rbp + KTRAP_FRAME_FaultAddress] + call _FrLdrDbgPrint[rip] +#endif
/* Save page fault address */ mov rdx, cr2 mov [rbp + KTRAP_FRAME_FaultAddress], rdx
/* Call page fault handler */ - mov ecx, [ebp + KTRAP_FRAME_ErrorCode] // StoreInstruction + mov ecx, [rbp + KTRAP_FRAME_ErrorCode] // StoreInstruction and ecx, 1 // rdx == Address - mov r8b, [ebp + KTRAP_FRAME_SegCs] // Mode + mov r8b, [rbp + KTRAP_FRAME_SegCs] // Mode and r8b, 1 mov r9, rbp // TrapInformation // call _MmAccessFault @@ -524,7 +526,7 @@ jge PageFaultReturn
/* Set parameter 1 to error code */ - mov r9d, [ebp + KTRAP_FRAME_ErrorCode] + mov r9d, [rbp + KTRAP_FRAME_ErrorCode]
/* Set parameter2 to faulting address */ mov r10, cr2 // Param2 = faulting address
Modified: branches/ros-amd64-bringup/reactos/ntoskrnl/mm/amd64/init.c URL: http://svn.reactos.org/svn/reactos/branches/ros-amd64-bringup/reactos/ntoskr... ============================================================================== --- branches/ros-amd64-bringup/reactos/ntoskrnl/mm/amd64/init.c [iso-8859-1] (original) +++ branches/ros-amd64-bringup/reactos/ntoskrnl/mm/amd64/init.c [iso-8859-1] Sat Nov 14 00:30:44 2009 @@ -15,9 +15,7 @@
#include "../ARM3/miarm.h"
-#define MI_SESSION_SPACE_END (PVOID)0xFFFFF98000000000ULL -#define MI_SESSION_VIEW_END 0xFFFFF97FFF000000ULL -#define MI_NON_PAGED_SYSTEM_START_MIN 0x0FFFFFAA000000000ULL +extern PMMPTE MmDebugPte;
/* GLOBALS *****************************************************************/
@@ -65,10 +63,11 @@ ULONG64 MmBootImageSize; PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock; RTL_BITMAP MiPfnBitMap; -ULONG MmNumberOfPhysicalPages, MmHighestPhysicalPage, MmLowestPhysicalPage = -1; +ULONG MmNumberOfPhysicalPages, MmHighestPhysicalPage, MmLowestPhysicalPage = -1; // FIXME: ULONG64 ULONG64 MmNumberOfSystemPtes; PMMPTE MmSystemPagePtes; ULONG64 MxPfnAllocation; +ULONG64 MxPfnSizeInBytes;
PVOID MmSystemCacheStart; PVOID MmSystemCacheEnd; @@ -83,24 +82,59 @@ PFN_NUMBER MxFreePageBase; ULONG64 MxFreePageCount = 0;
-VOID -NTAPI -MxSetupFreePageList(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +ULONG +NoDbgPrint(const char *Format, ...) +{ + return 0; +} + +VOID +NTAPI +MiEvaluateMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock) { PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; PLIST_ENTRY ListEntry; + PFN_NUMBER LastPage;
/* Loop the memory descriptors */ for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink; ListEntry != &LoaderBlock->MemoryDescriptorListHead; ListEntry = ListEntry->Flink) { - /* Get the memory block */ + /* Get the memory descriptor */ MdBlock = CONTAINING_RECORD(ListEntry, MEMORY_ALLOCATION_DESCRIPTOR, ListEntry);
- /* Check if this is free memory */ + /* Skip pages that are not part of the PFN database */ + if ((MdBlock->MemoryType == LoaderFirmwarePermanent) || + (MdBlock->MemoryType == LoaderBBTMemory) || + (MdBlock->MemoryType == LoaderHALCachedMemory) || + (MdBlock->MemoryType == LoaderSpecialMemory) || + (MdBlock->MemoryType == LoaderBad)) + { + continue; + } + + /* Add this to the total of pages */ + MmNumberOfPhysicalPages += MdBlock->PageCount; + + /* Check if this is the new lowest page */ + if (MdBlock->BasePage < MmLowestPhysicalPage) + { + /* Update the lowest page */ + MmLowestPhysicalPage = MdBlock->BasePage; + } + + /* Check if this is the new highest page */ + LastPage = MdBlock->BasePage + MdBlock->PageCount - 1; + if (LastPage > MmHighestPhysicalPage) + { + /* Update the highest page */ + MmHighestPhysicalPage = LastPage; + } + + /* Check if this is currently free memory */ if ((MdBlock->MemoryType == LoaderFree) || (MdBlock->MemoryType == LoaderLoadedProgram) || (MdBlock->MemoryType == LoaderFirmwareTemporary) || @@ -142,14 +176,17 @@ return Pfn; }
-VOID -MxMapPage(PVOID Address) +PMMPTE +NTAPI +MxGetPte(PVOID Address) { PMMPTE Pte; MMPTE TmpPte;
+ /* Setup template pte */ TmpPte.u.Long = 0; - TmpPte.u.Hard.Valid = 1; + TmpPte.u.Flush.Valid = 1; + TmpPte.u.Flush.Write = 1;
/* Get a pointer to the PXE */ Pte = MiAddressToPxe(Address); @@ -180,163 +217,41 @@
/* Get a pointer to the PTE */ Pte = MiAddressToPte(Address); - if (!Pte->u.Hard.Valid) - { - /* It's not valid, map it! */ + return Pte; +} + +VOID +MxMapPageRange(PVOID Address, ULONG64 PageCount) +{ + MMPTE TmpPte, *Pte; + + /* Setup template pte */ + TmpPte.u.Long = 0; + TmpPte.u.Flush.Valid = 1; + TmpPte.u.Flush.Write = 1; + + while (PageCount--) + { + /* Get the PTE for that page */ + Pte = MxGetPte(Address); + ASSERT(Pte->u.Hard.Valid == 0); + + /* Map a physical page */ TmpPte.u.Hard.PageFrameNumber = MxGetNextPage(1); *Pte = TmpPte; - } -} - -VOID -MxMapPageRange(PVOID Address, ULONG64 PageCount) -{ - ULONG64 i; - - for (i = 0; i < PageCount; i++) - { - MxMapPage(Address); + + /* Goto next page */ Address = (PVOID)((ULONG64)Address + PAGE_SIZE); } }
- -VOID -NTAPI -MiArmIninializeMemoryLayout(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +VOID +NTAPI +MiArmConfigureMemorySizes(IN PLOADER_PARAMETER_BLOCK LoaderBloc) { /* Get the size of the boot loader's image allocations */ - MmBootImageSize = KeLoaderBlock->Extension->LoaderPagesSpanned; - MmBootImageSize *= PAGE_SIZE; - MmBootImageSize = (MmBootImageSize + (4 * 1024 * 1024) - 1) & ~((4 * 1024 * 1024) - 1); - ASSERT((MmBootImageSize % (4 * 1024 * 1024)) == 0); - - MiSessionSpaceEnd = (PVOID)MI_SESSION_SPACE_END; - - /* This is where we will load Win32k.sys and the video driver */ - MiSessionImageEnd = MiSessionSpaceEnd; - MiSessionImageStart = (PVOID)((ULONG_PTR)MiSessionImageEnd - - MmSessionImageSize); - - /* The view starts right below the session working set (itself below - * the image area) */ - MiSessionViewEnd = (PVOID)MI_SESSION_VIEW_END; - MiSessionViewStart = (PVOID)((ULONG_PTR)MiSessionViewStart - - MmSessionViewSize); - - /* Session pool follows */ - MiSessionPoolEnd = MiSessionViewStart; - MiSessionPoolStart = (PVOID)((ULONG_PTR)MiSessionPoolEnd - - MmSessionPoolSize); - - /* And it all begins here */ - MmSessionBase = MiSessionPoolStart; - - // Sanity check that our math is correct - //ASSERT((ULONG_PTR)MmSessionBase + MmSessionSize == PTE_BASE); - - /* System view space ends at session space, so now that we know where - * this is, we can compute the base address of system view space itself. */ - MiSystemViewStart = (PVOID)((ULONG_PTR)MmSessionBase - - MmSystemViewSize); - - /* Use the default */ - MmNumberOfSystemPtes = 22000; - - /* FIXME: should start below paged pool */ - MmPfnDatabase = (PVOID)0xFFFFFD5FC0000000ULL; - -} - -VOID -MiArmInitializePageTable() -{ - ULONG64 PageFrameOffset; - PMMPTE StartPte, EndPte; - - /* Set CR3 for the system process */ - PageFrameOffset = ((PMMPTE)PXE_BASE)->u.Hard.PageFrameNumber << PAGE_SHIFT; - PsGetCurrentProcess()->Pcb.DirectoryTableBase[0] = PageFrameOffset; - - /* Clear user mode mappings in PML4 */ - StartPte = MiAddressToPxe(0); - EndPte = MiAddressToPxe(MmSystemRangeStart); - RtlZeroMemory(StartPte, (EndPte - StartPte) * sizeof(MMPTE)); -} - - -VOID -NTAPI -MiArmEvaluateMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock) -{ - PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; - PLIST_ENTRY ListEntry; - PFN_NUMBER BasePage, LastPage, PageCount; - - /* Loop the memory descriptors */ - for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink; - ListEntry != &LoaderBlock->MemoryDescriptorListHead; - ListEntry = ListEntry->Flink) - { - /* Get the descriptor */ - MdBlock = CONTAINING_RECORD(ListEntry, - MEMORY_ALLOCATION_DESCRIPTOR, - ListEntry); - - /* Skip pages that are not part of the PFN database */ - if ((MdBlock->MemoryType == LoaderFirmwarePermanent) || - (MdBlock->MemoryType == LoaderBBTMemory) || - (MdBlock->MemoryType == LoaderHALCachedMemory) || // ??? - (MdBlock->MemoryType == LoaderSpecialMemory)) - { - continue; - } - - /* Check if BURNMEM was used */ - if (MdBlock->MemoryType != LoaderBad) - { - /* Count this in the total of pages */ - MmNumberOfPhysicalPages += MdBlock->PageCount; - } - - BasePage = MdBlock->BasePage; - LastPage = MdBlock->BasePage + MdBlock->PageCount - 1; - - /* Check if this is the new lowest page */ - if (BasePage < MmLowestPhysicalPage) - { - /* Update the lowest page */ - MmLowestPhysicalPage = BasePage; - } - - /* Check if this is the new highest page */ - if (LastPage > MmHighestPhysicalPage) - { - /* Update the highest page */ - MmHighestPhysicalPage = LastPage; - } -DPRINT1("BasePage = %ld, LastPage = %ld\n", BasePage, LastPage); -__debugbreak(); - /* Map pages for the PFN database */ - PageCount = PAGE_ROUND_UP(MdBlock->PageCount * sizeof(MMPFN)) / PAGE_SIZE; - MxMapPageRange(&MmPfnDatabase[BasePage], PageCount); - - /* Zero out the pages */ - RtlZeroMemory(&MmPfnDatabase[BasePage], PageCount * PAGE_SIZE); - } - - /* Calculate the number of bytes, and then convert to pages */ - MxPfnAllocation = (MmHighestPhysicalPage + 1) * sizeof(MMPFN); - MxPfnAllocation >>= PAGE_SHIFT; - MxPfnAllocation++; - -} - -VOID -NTAPI -MiArmPrepareNonPagedPool() -{ - PFN_NUMBER PageCount; + MmBootImageSize = KeLoaderBlock->Extension->LoaderPagesSpanned * PAGE_SIZE; + MmBootImageSize = ROUND_UP(MmBootImageSize, 4 * 1024 * 1024);
/* Check if this is a machine with less than 256MB of RAM, and no overide */ if ((MmNumberOfPhysicalPages <= MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING) && @@ -396,14 +311,173 @@ MmMaximumNonPagedPoolInBytes = MI_MAX_NONPAGED_POOL_SIZE; }
+ // MmSessionImageSize +} + +VOID +NTAPI +MiArmInitializeMemoryLayout(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + /* Set up session space */ + MiSessionSpaceEnd = (PVOID)MI_SESSION_SPACE_END; + + /* This is where we will load Win32k.sys and the video driver */ + MiSessionImageEnd = MiSessionSpaceEnd; + MiSessionImageStart = (PVOID)((ULONG_PTR)MiSessionImageEnd - + MmSessionImageSize); + + /* The view starts right below the session working set (itself below + * the image area) */ + MiSessionViewEnd = MI_SESSION_VIEW_END; + MiSessionViewStart = (PVOID)((ULONG_PTR)MiSessionViewStart - + MmSessionViewSize); + + /* Session pool follows */ + MiSessionPoolEnd = MiSessionViewStart; + MiSessionPoolStart = (PVOID)((ULONG_PTR)MiSessionPoolEnd - + MmSessionPoolSize); + + /* And it all begins here */ + MmSessionBase = MiSessionPoolStart; + + /* System view space ends at session space, so now that we know where + * this is, we can compute the base address of system view space itself. */ + MiSystemViewStart = (PVOID)((ULONG_PTR)MmSessionBase - + MmSystemViewSize); + + /* Use the default */ + MmNumberOfSystemPtes = 22000; + + ASSERT(MiSessionViewEnd <= MiSessionImageStart); + ASSERT(MmSessionBase <= MiSessionPoolStart); +} + +VOID +MiArmInitializePageTable() +{ + ULONG64 PageFrameOffset; + PMMPTE Pte, StartPte, EndPte; + + /* Get current directory base */ + PageFrameOffset = ((PMMPTE)PXE_SELFMAP)->u.Hard.PageFrameNumber << PAGE_SHIFT; + ASSERT(PageFrameOffset == __readcr3()); + + /* Set directory base for the system process */ + PsGetCurrentProcess()->Pcb.DirectoryTableBase[0] = PageFrameOffset; + + /* HACK: don't use freeldr debug pront anymore */ + FrLdrDbgPrint = NoDbgPrint; + +#if 1 + /* Clear user mode mappings in PML4 */ + StartPte = MiAddressToPxe(0); + EndPte = MiAddressToPxe(MmHighestUserAddress); + + for (Pte = StartPte; Pte <= EndPte; Pte++) + { + /* Zero the pte */ + Pte->u.Long = 0; + } +#else + /* Clear user mode mappings in PML4 */ + StartPte = MiAddressToPte(0); + EndPte = MiAddressToPte((PVOID)0xa00000); + + for (Pte = StartPte; Pte < EndPte; Pte++) + { + /* Zero the pte */ + //Pte->u.Long = 0; + } + + /* Flush the TLB */ + KeFlushCurrentTb(); + +// MiAddressToPde(0)->u.Long = 0; +// MiAddressToPde((PVOID)0x200000)->u.Long = 0; +// MiAddressToPde((PVOID)0x400000)->u.Long = 0; +// MiAddressToPde((PVOID)0x600000)->u.Long = 0; +// MiAddressToPde((PVOID)0x800000)->u.Long = 0; + + // MiAddressToPpe->u.Long = 0; + +#endif + + /* Flush the TLB */ + KeFlushCurrentTb(); + + /* Setup debug mapping pte */ + MmDebugPte = MxGetPte(MI_DEBUG_MAPPING); +} + + +VOID +NTAPI +MiArmPreparePfnDatabse(IN PLOADER_PARAMETER_BLOCK LoaderBlock) +{ + PMEMORY_ALLOCATION_DESCRIPTOR MdBlock; + PLIST_ENTRY ListEntry; + PFN_COUNT PageCount; + PVOID PageBase; + + /* The PFN database is at the start of the non paged region */ + MmPfnDatabase = (PVOID)((ULONG64)MmNonPagedPoolEnd - MmMaximumNonPagedPoolInBytes); + + /* Loop the memory descriptors */ + for (ListEntry = LoaderBlock->MemoryDescriptorListHead.Flink; + ListEntry != &LoaderBlock->MemoryDescriptorListHead; + ListEntry = ListEntry->Flink) + { + /* Get the memory descriptor */ + MdBlock = CONTAINING_RECORD(ListEntry, + MEMORY_ALLOCATION_DESCRIPTOR, + ListEntry); + + /* Skip pages that are not part of the PFN database */ + if ((MdBlock->MemoryType == LoaderFirmwarePermanent) || + (MdBlock->MemoryType == LoaderBBTMemory) || + (MdBlock->MemoryType == LoaderHALCachedMemory) || + (MdBlock->MemoryType == LoaderSpecialMemory) || + (MdBlock->MemoryType != LoaderBad)) + { + continue; + } + + /* Map pages for the PFN database */ + PageCount = ROUND_TO_PAGES(MdBlock->PageCount * sizeof(MMPFN)) / PAGE_SIZE; + PageBase = PAGE_ALIGN(&MmPfnDatabase[MdBlock->BasePage]); + MxMapPageRange(PageBase, PageCount); + + /* Zero out the pages */ + RtlZeroMemory(PageBase, PageCount * PAGE_SIZE); + } + + /* Calculate the number of bytes, and then convert to pages */ + MxPfnSizeInBytes = ROUND_TO_PAGES(MmHighestPhysicalPage + 1) * sizeof(MMPFN); + MxPfnAllocation = MxPfnSizeInBytes >> PAGE_SHIFT; + + /* Reduce maximum pool size */ + MmMaximumNonPagedPoolInBytes -= MxPfnSizeInBytes; +} + + +VOID +NTAPI +MiArmPrepareNonPagedPool() +{ + PFN_NUMBER PageCount; + PVOID Address; + + /* Non paged pool comes after the PFN database */ + MmNonPagedPoolStart = (PVOID)((ULONG64)MmPfnDatabase + + MxPfnSizeInBytes); + ASSERT((ULONG64)MmNonPagedPoolEnd == (ULONG64)MmNonPagedPoolStart + + MmMaximumNonPagedPoolInBytes); + /* Calculate the nonpaged pool expansion start region */ MmNonPagedPoolExpansionStart = (PVOID)((ULONG_PTR)MmNonPagedPoolEnd - MmMaximumNonPagedPoolInBytes + MmSizeOfNonPagedPoolInBytes); MmNonPagedPoolExpansionStart = (PVOID)PAGE_ALIGN(MmNonPagedPoolExpansionStart); - - DPRINT("NP Pool has been tuned to: %d bytes and %d bytes\n", - MmSizeOfNonPagedPoolInBytes, MmMaximumNonPagedPoolInBytes);
/* Now calculate the nonpaged system VA region, which includes the * nonpaged pool expansion (above) and the system PTEs. Note that it is @@ -427,15 +501,21 @@ ASSERT(MmNumberOfSystemPtes > 1000); }
- /* Non paged pool comes after the PFN database */ - MmNonPagedPoolStart = (PVOID)((ULONG_PTR)MmPfnDatabase + - (MxPfnAllocation << PAGE_SHIFT)); - /* Map the nonpaged pool */ PageCount = (MmSizeOfNonPagedPoolInBytes + PAGE_SIZE - 1) / PAGE_SIZE; MxMapPageRange(MmNonPagedPoolStart, PageCount);
- /* Sanity check: make sure we have properly defined the system PTE space */ + /* Create PTEs for the paged pool extension */ + for (Address = MmNonPagedPoolExpansionStart; + Address < MmNonPagedPoolEnd; + Address = (PVOID)((ULONG64)Address + PAGE_SIZE)) + { + /* Create PXE, PPE, PDE and set PTE to 0*/ + MxGetPte(Address)->u.Long = 0; + } + +//DPRINT1("MmNonPagedPoolStart = %p, Pte=%p \n", MmNonPagedPoolStart, MiAddressToPte(MmNonPagedPoolStart)); + /* Sanity check */ ASSERT(MiAddressToPte(MmNonPagedSystemStart) < MiAddressToPte(MmNonPagedPoolExpansionStart));
@@ -448,18 +528,22 @@ { if (Phase == 0) { - /* Get a continuous range of physical pages */ - MxSetupFreePageList(LoaderBlock); + /* Parse memory descriptors */ + MiEvaluateMemoryDescriptors(LoaderBlock); + + /* Configure the memory sizes */ + MiArmConfigureMemorySizes(LoaderBlock);
/* Initialize the memory layout */ - MiArmIninializeMemoryLayout(LoaderBlock); - - /* Loop descriptors and prepare PFN database */ - MiArmEvaluateMemoryDescriptors(LoaderBlock); - + MiArmInitializeMemoryLayout(LoaderBlock); + + /* Prepare PFN database mappings */ + MiArmPreparePfnDatabse(LoaderBlock); + + /* Initialize some mappings */ MiArmInitializePageTable();
- /* Configure size of the non paged pool */ + /* Prepare paged pool mappings */ MiArmPrepareNonPagedPool();
/* Initialize the ARM3 nonpaged pool */ @@ -476,6 +560,7 @@ /* The PFN database was created, restore the free descriptor */ *MxFreeDescriptor = MxOldFreeDescriptor;
+ ASSERT(FALSE);
}