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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/ntosk…
==============================================================================
--- 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/ntosk…
==============================================================================
--- 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/ntosk…
==============================================================================
--- 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/ntosk…
==============================================================================
--- 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/ntosk…
==============================================================================
--- 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/ntosk…
==============================================================================
--- 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/ntosk…
==============================================================================
--- 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);
}