2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/mm/amd64/init.c
5 * PURPOSE: Memory Manager Initialization for amd64
7 * PROGRAMMERS: Timo kreuzer (timo.kreuzer@reactos.org)
8 * ReactOS Portable Systems Group
11 /* INCLUDES ***************************************************************/
17 #include "../ARM3/miarm.h"
19 extern PMMPTE MmDebugPte
;
21 /* GLOBALS *****************************************************************/
23 ULONG64 MmUserProbeAddress
= 0x7FFFFFF0000ULL
;
24 PVOID MmHighestUserAddress
= (PVOID
)0x7FFFFFEFFFFULL
;
25 PVOID MmSystemRangeStart
= (PVOID
)0xFFFF080000000000ULL
;
27 /* Size of session view, pool, and image */
28 ULONG64 MmSessionSize
= MI_SESSION_SIZE
;
29 ULONG64 MmSessionViewSize
= MI_SESSION_VIEW_SIZE
;
30 ULONG64 MmSessionPoolSize
= MI_SESSION_POOL_SIZE
;
31 ULONG64 MmSessionImageSize
= MI_SESSION_IMAGE_SIZE
;
33 /* Session space addresses */
34 PVOID MiSessionSpaceEnd
= MI_SESSION_SPACE_END
; // FFFFF98000000000
35 PVOID MiSessionImageEnd
; // FFFFF98000000000 = MiSessionSpaceEnd
36 PVOID MiSessionImageStart
; // ?FFFFF97FFF000000 = MiSessionImageEnd - MmSessionImageSize
37 PVOID MiSessionViewEnd
; // FFFFF97FFF000000
38 PVOID MiSessionViewStart
; // = MiSessionViewEnd - MmSessionViewSize
39 PVOID MiSessionPoolEnd
; // = MiSessionViewStart
40 PVOID MiSessionPoolStart
; // FFFFF90000000000 = MiSessionPoolEnd - MmSessionPoolSize
41 PVOID MmSessionBase
; // FFFFF90000000000 = MiSessionPoolStart
44 ULONG64 MmSystemViewSize
= MI_SYSTEM_VIEW_SIZE
;
45 PVOID MiSystemViewStart
;
47 ULONG64 MmMinimumNonPagedPoolSize
= 256 * 1024;
48 ULONG64 MmSizeOfNonPagedPoolInBytes
;
49 ULONG64 MmMaximumNonPagedPoolInBytes
;
50 ULONG64 MmMaximumNonPagedPoolPercent
;
51 ULONG64 MmMinAdditionNonPagedPoolPerMb
= 32 * 1024;
52 ULONG64 MmMaxAdditionNonPagedPoolPerMb
= 400 * 1024;
53 ULONG64 MmDefaultMaximumNonPagedPool
= 1024 * 1024;
54 PVOID MmNonPagedSystemStart
;
55 PVOID MmNonPagedPoolStart
;
56 PVOID MmNonPagedPoolExpansionStart
;
57 PVOID MmNonPagedPoolEnd
= MI_NONPAGED_POOL_END
;
59 ULONG64 MmSizeOfPagedPoolInBytes
= MI_MIN_INIT_PAGED_POOLSIZE
;
60 PVOID MmPagedPoolStart
= MI_PAGED_POOL_START
;
64 ULONG64 MmBootImageSize
;
65 PPHYSICAL_MEMORY_DESCRIPTOR MmPhysicalMemoryBlock
;
66 RTL_BITMAP MiPfnBitMap
;
67 ULONG MmNumberOfPhysicalPages
, MmHighestPhysicalPage
, MmLowestPhysicalPage
= -1; // FIXME: ULONG64
68 ULONG64 MmNumberOfSystemPtes
;
69 PMMPTE MmSystemPagePtes
;
70 ULONG64 MxPfnAllocation
;
71 ULONG64 MxPfnSizeInBytes
;
73 PVOID MmSystemCacheStart
;
74 PVOID MmSystemCacheEnd
;
75 MMSUPPORT MmSystemCacheWs
;
78 ///////////////////////////////////////////////
80 PMEMORY_ALLOCATION_DESCRIPTOR MxFreeDescriptor
;
81 MEMORY_ALLOCATION_DESCRIPTOR MxOldFreeDescriptor
;
83 PFN_NUMBER MxFreePageBase
;
84 ULONG64 MxFreePageCount
= 0;
87 NoDbgPrint(const char *Format
, ...)
94 MiEvaluateMemoryDescriptors(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
96 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock
;
97 PLIST_ENTRY ListEntry
;
100 /* Loop the memory descriptors */
101 for (ListEntry
= LoaderBlock
->MemoryDescriptorListHead
.Flink
;
102 ListEntry
!= &LoaderBlock
->MemoryDescriptorListHead
;
103 ListEntry
= ListEntry
->Flink
)
105 /* Get the memory descriptor */
106 MdBlock
= CONTAINING_RECORD(ListEntry
,
107 MEMORY_ALLOCATION_DESCRIPTOR
,
110 /* Skip pages that are not part of the PFN database */
111 if ((MdBlock
->MemoryType
== LoaderFirmwarePermanent
) ||
112 (MdBlock
->MemoryType
== LoaderBBTMemory
) ||
113 (MdBlock
->MemoryType
== LoaderHALCachedMemory
) ||
114 (MdBlock
->MemoryType
== LoaderSpecialMemory
) ||
115 (MdBlock
->MemoryType
== LoaderBad
))
120 /* Add this to the total of pages */
121 MmNumberOfPhysicalPages
+= MdBlock
->PageCount
;
123 /* Check if this is the new lowest page */
124 if (MdBlock
->BasePage
< MmLowestPhysicalPage
)
126 /* Update the lowest page */
127 MmLowestPhysicalPage
= MdBlock
->BasePage
;
130 /* Check if this is the new highest page */
131 LastPage
= MdBlock
->BasePage
+ MdBlock
->PageCount
- 1;
132 if (LastPage
> MmHighestPhysicalPage
)
134 /* Update the highest page */
135 MmHighestPhysicalPage
= LastPage
;
138 /* Check if this is currently free memory */
139 if ((MdBlock
->MemoryType
== LoaderFree
) ||
140 (MdBlock
->MemoryType
== LoaderLoadedProgram
) ||
141 (MdBlock
->MemoryType
== LoaderFirmwareTemporary
) ||
142 (MdBlock
->MemoryType
== LoaderOsloaderStack
))
144 /* Check if this is the largest memory descriptor */
145 if (MdBlock
->PageCount
> MxFreePageCount
)
148 MxFreeDescriptor
= MdBlock
;
149 MxFreePageBase
= MdBlock
->BasePage
;
150 MxFreePageCount
= MdBlock
->PageCount
;
158 MxGetNextPage(IN PFN_NUMBER PageCount
)
162 /* Make sure we have enough pages */
163 if (PageCount
> MxFreePageCount
)
165 /* Crash the system */
166 KeBugCheckEx(INSTALL_MORE_MEMORY
,
167 MmNumberOfPhysicalPages
,
168 MxFreeDescriptor
->PageCount
,
169 MxOldFreeDescriptor
.PageCount
,
173 /* Use our lowest usable free pages */
174 Pfn
= MxFreePageBase
;
175 MxFreePageBase
+= PageCount
;
176 MxFreePageCount
-= PageCount
;
182 MxGetPte(PVOID Address
)
187 /* Setup template pte */
189 TmpPte
.u
.Flush
.Valid
= 1;
190 TmpPte
.u
.Flush
.Write
= 1;
192 /* Get a pointer to the PXE */
193 Pte
= MiAddressToPxe(Address
);
194 if (!Pte
->u
.Hard
.Valid
)
196 /* It's not valid, map it! */
197 TmpPte
.u
.Hard
.PageFrameNumber
= MxGetNextPage(1);
201 /* Get a pointer to the PPE */
202 Pte
= MiAddressToPpe(Address
);
203 if (!Pte
->u
.Hard
.Valid
)
205 /* It's not valid, map it! */
206 TmpPte
.u
.Hard
.PageFrameNumber
= MxGetNextPage(1);
210 /* Get a pointer to the PDE */
211 Pte
= MiAddressToPde(Address
);
212 if (!Pte
->u
.Hard
.Valid
)
214 /* It's not valid, map it! */
215 TmpPte
.u
.Hard
.PageFrameNumber
= MxGetNextPage(1);
219 /* Get a pointer to the PTE */
220 Pte
= MiAddressToPte(Address
);
225 MxMapPageRange(PVOID Address
, ULONG64 PageCount
)
229 /* Setup template pte */
231 TmpPte
.u
.Flush
.Valid
= 1;
232 TmpPte
.u
.Flush
.Write
= 1;
236 /* Get the PTE for that page */
237 Pte
= MxGetPte(Address
);
238 ASSERT(Pte
->u
.Hard
.Valid
== 0);
240 /* Map a physical page */
241 TmpPte
.u
.Hard
.PageFrameNumber
= MxGetNextPage(1);
245 Address
= (PVOID
)((ULONG64
)Address
+ PAGE_SIZE
);
251 MiArmConfigureMemorySizes(IN PLOADER_PARAMETER_BLOCK LoaderBloc
)
253 /* Get the size of the boot loader's image allocations */
254 MmBootImageSize
= KeLoaderBlock
->Extension
->LoaderPagesSpanned
* PAGE_SIZE
;
255 MmBootImageSize
= ROUND_UP(MmBootImageSize
, 4 * 1024 * 1024);
257 /* Check if this is a machine with less than 256MB of RAM, and no overide */
258 if ((MmNumberOfPhysicalPages
<= MI_MIN_PAGES_FOR_NONPAGED_POOL_TUNING
) &&
259 !(MmSizeOfNonPagedPoolInBytes
))
261 /* Force the non paged pool to be 2MB so we can reduce RAM usage */
262 MmSizeOfNonPagedPoolInBytes
= 2 * 1024 * 1024;
265 /* Check if the user gave a ridicuously large nonpaged pool RAM size */
266 if ((MmSizeOfNonPagedPoolInBytes
>> PAGE_SHIFT
) >
267 (MmNumberOfPhysicalPages
* 7 / 8))
269 /* More than 7/8ths of RAM was dedicated to nonpaged pool, ignore! */
270 MmSizeOfNonPagedPoolInBytes
= 0;
273 /* Check if no registry setting was set, or if the setting was too low */
274 if (MmSizeOfNonPagedPoolInBytes
< MmMinimumNonPagedPoolSize
)
276 /* Start with the minimum (256 KB) and add 32 KB for each MB above 4 */
277 MmSizeOfNonPagedPoolInBytes
= MmMinimumNonPagedPoolSize
;
278 MmSizeOfNonPagedPoolInBytes
+= (MmNumberOfPhysicalPages
- 1024) /
279 256 * MmMinAdditionNonPagedPoolPerMb
;
282 /* Check if the registy setting or our dynamic calculation was too high */
283 if (MmSizeOfNonPagedPoolInBytes
> MI_MAX_INIT_NONPAGED_POOL_SIZE
)
285 // Set it to the maximum */
286 MmSizeOfNonPagedPoolInBytes
= MI_MAX_INIT_NONPAGED_POOL_SIZE
;
289 /* Check if a percentage cap was set through the registry */
290 if (MmMaximumNonPagedPoolPercent
)
292 /* Don't feel like supporting this right now */
296 /* Page-align the nonpaged pool size */
297 MmSizeOfNonPagedPoolInBytes
&= ~(PAGE_SIZE
- 1);
299 /* Now, check if there was a registry size for the maximum size */
300 if (!MmMaximumNonPagedPoolInBytes
)
302 /* Start with the default (1MB) and add 400 KB for each MB above 4 */
303 MmMaximumNonPagedPoolInBytes
= MmDefaultMaximumNonPagedPool
;
304 MmMaximumNonPagedPoolInBytes
+= (MmNumberOfPhysicalPages
- 1024) /
305 256 * MmMaxAdditionNonPagedPoolPerMb
;
308 /* Don't let the maximum go too high */
309 if (MmMaximumNonPagedPoolInBytes
> MI_MAX_NONPAGED_POOL_SIZE
)
311 /* Set it to the upper limit */
312 MmMaximumNonPagedPoolInBytes
= MI_MAX_NONPAGED_POOL_SIZE
;
315 // MmSessionImageSize
320 MiArmInitializeMemoryLayout(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
322 /* Set up session space */
323 MiSessionSpaceEnd
= (PVOID
)MI_SESSION_SPACE_END
;
325 /* This is where we will load Win32k.sys and the video driver */
326 MiSessionImageEnd
= MiSessionSpaceEnd
;
327 MiSessionImageStart
= (PVOID
)((ULONG_PTR
)MiSessionImageEnd
-
330 /* The view starts right below the session working set (itself below
332 MiSessionViewEnd
= MI_SESSION_VIEW_END
;
333 MiSessionViewStart
= (PVOID
)((ULONG_PTR
)MiSessionViewStart
-
336 /* Session pool follows */
337 MiSessionPoolEnd
= MiSessionViewStart
;
338 MiSessionPoolStart
= (PVOID
)((ULONG_PTR
)MiSessionPoolEnd
-
341 /* And it all begins here */
342 MmSessionBase
= MiSessionPoolStart
;
344 /* System view space ends at session space, so now that we know where
345 * this is, we can compute the base address of system view space itself. */
346 MiSystemViewStart
= (PVOID
)((ULONG_PTR
)MmSessionBase
-
349 /* Use the default */
350 MmNumberOfSystemPtes
= MI_NUMBER_SYSTEM_PTES
;
352 ASSERT(MiSessionViewEnd
<= MiSessionImageStart
);
353 ASSERT(MmSessionBase
<= MiSessionPoolStart
);
357 MiArmInitializePageTable()
359 ULONG64 PageFrameOffset
;
360 PMMPTE Pte
, StartPte
, EndPte
;
363 /* Get current directory base */
364 PageFrameOffset
= ((PMMPTE
)PXE_SELFMAP
)->u
.Hard
.PageFrameNumber
<< PAGE_SHIFT
;
365 ASSERT(PageFrameOffset
== __readcr3());
367 /* Set directory base for the system process */
368 PsGetCurrentProcess()->Pcb
.DirectoryTableBase
[0] = PageFrameOffset
;
370 /* HACK: don't use freeldr debug print anymore */
371 // FrLdrDbgPrint = NoDbgPrint;
373 /* Clear user mode mappings in PML4 */
374 StartPte
= MiAddressToPxe(0);
375 EndPte
= MiAddressToPxe(MmHighestUserAddress
);
377 /* Loop the user mode PXEs */
378 for (Pte
= StartPte
; Pte
<= EndPte
; Pte
++)
384 /* Setup a template PTE */
386 TmpPte
.u
.Flush
.Valid
= 1;
387 TmpPte
.u
.Flush
.Write
= 1;
389 HyperTemplatePte
= TmpPte
;
391 /* Create PDPTs (1MB total) for shared system address space */
392 StartPte
= MiAddressToPxe(MmSystemRangeStart
);
393 EndPte
= MiAddressToPxe(MI_HIGHEST_SYSTEM_ADDRESS
);
395 /* Loop the system space PXEs */
396 for (Pte
= StartPte
; Pte
<= EndPte
; Pte
++)
398 /* Is the PXE already valid? */
399 if (!Pte
->u
.Hard
.Valid
)
401 /* It's not Initialize it, creating a PDPT. */
402 TmpPte
.u
.Flush
.PageFrameNumber
= MxGetNextPage(1);
405 /* Zero the page. The PXE is the PTE for the PDPT. */
406 RtlZeroMemory(MiPteToAddress(Pte
), PAGE_SIZE
);
413 /* Setup the mapping PTEs */
414 MmFirstReservedMappingPte
= MxGetPte((PVOID
)MI_MAPPING_RANGE_START
);
415 MmFirstReservedMappingPte
->u
.Hard
.PageFrameNumber
= MI_HYPERSPACE_PTES
;
416 MmLastReservedMappingPte
= MiAddressToPte((PVOID
)MI_MAPPING_RANGE_END
);
418 /* Setup debug mapping PTE */
419 MmDebugPte
= MxGetPte(MI_DEBUG_MAPPING
);
425 MiArmPreparePfnDatabse(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
427 PMEMORY_ALLOCATION_DESCRIPTOR MdBlock
;
428 PLIST_ENTRY ListEntry
;
430 PUCHAR Page
, FirstPage
;
432 /* The PFN database is at the start of the non paged region */
433 MmPfnDatabase
= (PVOID
)((ULONG64
)MmNonPagedPoolEnd
- MmMaximumNonPagedPoolInBytes
);
435 /* Loop the memory descriptors */
436 for (ListEntry
= LoaderBlock
->MemoryDescriptorListHead
.Flink
;
437 ListEntry
!= &LoaderBlock
->MemoryDescriptorListHead
;
438 ListEntry
= ListEntry
->Flink
)
440 /* Get the memory descriptor */
441 MdBlock
= CONTAINING_RECORD(ListEntry
,
442 MEMORY_ALLOCATION_DESCRIPTOR
,
445 /* Skip pages that are not part of the PFN database */
446 if ((MdBlock
->MemoryType
== LoaderFirmwarePermanent
) ||
447 (MdBlock
->MemoryType
== LoaderBBTMemory
) ||
448 (MdBlock
->MemoryType
== LoaderHALCachedMemory
) ||
449 (MdBlock
->MemoryType
== LoaderSpecialMemory
) ||
450 (MdBlock
->MemoryType
== LoaderBad
))
455 /* Get the base and size of this pfn database entry */
456 FirstPage
= PAGE_ALIGN(&MmPfnDatabase
[MdBlock
->BasePage
]);
457 Size
= ROUND_TO_PAGES(MdBlock
->PageCount
* sizeof(MMPFN
));
459 /* Loop the pages of this Pfn database entry */
460 for (Page
= FirstPage
; Page
< FirstPage
+ Size
; Page
+= PAGE_SIZE
)
462 /* Is the page already mapped? */
463 if (!MmIsAddressValid(Page
))
465 /* It's not, map it now */
466 MxMapPageRange(Page
, 1);
470 /* Zero out the pages */
471 RtlZeroMemory(FirstPage
, Size
);
474 /* Calculate the number of bytes, and then convert to pages */
475 MxPfnSizeInBytes
= ROUND_TO_PAGES(MmHighestPhysicalPage
+ 1) * sizeof(MMPFN
);
476 MxPfnAllocation
= MxPfnSizeInBytes
>> PAGE_SHIFT
;
478 /* Reduce maximum pool size */
479 MmMaximumNonPagedPoolInBytes
-= MxPfnSizeInBytes
;
485 MiArmPrepareNonPagedPool()
487 PFN_NUMBER PageCount
;
490 /* Non paged pool comes after the PFN database */
491 MmNonPagedPoolStart
= (PVOID
)((ULONG64
)MmPfnDatabase
+
493 ASSERT((ULONG64
)MmNonPagedPoolEnd
== (ULONG64
)MmNonPagedPoolStart
+
494 MmMaximumNonPagedPoolInBytes
);
496 /* Calculate the nonpaged pool expansion start region */
497 MmNonPagedPoolExpansionStart
= (PVOID
)((ULONG_PTR
)MmNonPagedPoolEnd
-
498 MmMaximumNonPagedPoolInBytes
+
499 MmSizeOfNonPagedPoolInBytes
);
500 MmNonPagedPoolExpansionStart
= (PVOID
)PAGE_ALIGN(MmNonPagedPoolExpansionStart
);
502 /* Now calculate the nonpaged system VA region, which includes the
503 * nonpaged pool expansion (above) and the system PTEs. Note that it is
504 * then aligned to a PDE boundary (4MB). */
505 MmNonPagedSystemStart
= (PVOID
)((ULONG_PTR
)MmNonPagedPoolExpansionStart
-
506 (MmNumberOfSystemPtes
+ 1) * PAGE_SIZE
);
507 MmNonPagedSystemStart
= (PVOID
)((ULONG_PTR
)MmNonPagedSystemStart
&
508 ~((4 * 1024 * 1024) - 1));
510 /* Don't let it go below the minimum */
511 if (MmNonPagedSystemStart
< (PVOID
)MI_NON_PAGED_SYSTEM_START_MIN
)
513 /* This is a hard-coded limit in the Windows NT address space */
514 MmNonPagedSystemStart
= (PVOID
)MI_NON_PAGED_SYSTEM_START_MIN
;
516 /* Reduce the amount of system PTEs to reach this point */
517 MmNumberOfSystemPtes
= ((ULONG_PTR
)MmNonPagedPoolExpansionStart
-
518 (ULONG_PTR
)MmNonPagedSystemStart
) >>
520 MmNumberOfSystemPtes
--;
521 ASSERT(MmNumberOfSystemPtes
> 1000);
524 /* Map the nonpaged pool */
525 PageCount
= (MmSizeOfNonPagedPoolInBytes
+ PAGE_SIZE
- 1) / PAGE_SIZE
;
526 MxMapPageRange(MmNonPagedPoolStart
, PageCount
);
528 /* Create PTEs for the paged pool extension */
529 for (Address
= MmNonPagedPoolExpansionStart
;
530 Address
< MmNonPagedPoolEnd
;
531 Address
= (PVOID
)((ULONG64
)Address
+ PAGE_SIZE
))
533 /* Create PXE, PPE, PDE and set PTE to 0*/
534 MxGetPte(Address
)->u
.Long
= 0;
538 ASSERT(MiAddressToPte(MmNonPagedSystemStart
) <
539 MiAddressToPte(MmNonPagedPoolExpansionStart
));
543 PPHYSICAL_MEMORY_DESCRIPTOR
545 MmInitializeMemoryLimits(IN PLOADER_PARAMETER_BLOCK LoaderBlock
,
546 IN PBOOLEAN IncludeType
)
554 MiBuildPhysicalMemoryBlock(IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
556 BOOLEAN IncludeType
[LoaderMaximum
];
557 PPHYSICAL_MEMORY_RUN Run
;
561 /* Instantiate memory that we don't consider RAM/usable */
562 for (i
= 0; i
< LoaderMaximum
; i
++) IncludeType
[i
] = TRUE
;
563 IncludeType
[LoaderBad
] = FALSE
;
564 IncludeType
[LoaderFirmwarePermanent
] = FALSE
;
565 IncludeType
[LoaderSpecialMemory
] = FALSE
;
566 IncludeType
[LoaderBBTMemory
] = FALSE
;
568 /* Build the physical memory block */
569 MmPhysicalMemoryBlock
= MmInitializeMemoryLimits(LoaderBlock
, IncludeType
);
571 /* Calculate size for the PFN bitmap */
572 Size
= (MmHighestPhysicalPage
+ sizeof(ULONG
)) / sizeof(ULONG
);
574 /* Allocate the PFN bitmap */
575 Bitmap
= ExAllocatePoolWithTag(NonPagedPool
, Size
, ' mM');
578 /* This is critical */
579 KeBugCheckEx(INSTALL_MORE_MEMORY
,
580 MmNumberOfPhysicalPages
,
581 MmLowestPhysicalPage
,
582 MmHighestPhysicalPage
,
586 /* Initialize it and clear all the bits to begin with */
587 RtlInitializeBitMap(&MiPfnBitMap
, Bitmap
, MmHighestPhysicalPage
+ 1);
588 RtlClearAllBits(&MiPfnBitMap
);
590 /* Loop physical memory runs */
591 for (i
= 0; i
< MmPhysicalMemoryBlock
->NumberOfRuns
; i
++)
594 Run
= &MmPhysicalMemoryBlock
->Run
[i
];
595 DPRINT("PHYSICAL RAM [0x%08p to 0x%08p]\n",
596 Run
->BasePage
<< PAGE_SHIFT
,
597 (Run
->BasePage
+ Run
->PageCount
) << PAGE_SHIFT
);
599 /* Make sure it has pages inside it */
602 /* Set the bits in the PFN bitmap */
603 RtlSetBits(&MiPfnBitMap
, Run
->BasePage
, Run
->PageCount
);
610 MiBuildPagedPool(VOID
)
618 MmArmInitSystem(IN ULONG Phase
,
619 IN PLOADER_PARAMETER_BLOCK LoaderBlock
)
623 /* Parse memory descriptors */
624 MiEvaluateMemoryDescriptors(LoaderBlock
);
626 /* Configure the memory sizes */
627 MiArmConfigureMemorySizes(LoaderBlock
);
629 /* Initialize the memory layout */
630 MiArmInitializeMemoryLayout(LoaderBlock
);
632 /* Initialize some mappings */
633 MiArmInitializePageTable();
635 /* Prepare PFN database mappings */
636 MiArmPreparePfnDatabse(LoaderBlock
);
638 /* Prepare paged pool mappings */
639 MiArmPrepareNonPagedPool();
641 /* Initialize the ARM3 nonpaged pool */
642 MiInitializeArmPool();
644 /* Update the memory descriptor, to make sure the pages we used
645 won't get inserted into the PFN database */
646 MxOldFreeDescriptor
= *MxFreeDescriptor
;
647 MxFreeDescriptor
->BasePage
= MxFreePageBase
;
648 MxFreeDescriptor
->PageCount
= MxFreePageCount
;
654 PPHYSICAL_MEMORY_RUN Run
;
658 /* The PFN database was created, restore the free descriptor */
659 *MxFreeDescriptor
= MxOldFreeDescriptor
;
663 /* Initialize the nonpaged pool */
664 InitializePool(NonPagedPool
, 0);
667 /* Create the system PTE space */
668 Pte
= MiAddressToPte(MI_SYSTEM_PTE_START
);
669 MiInitializeSystemPtes(Pte
, MmNumberOfSystemPtes
, SystemPteSpace
);
671 /* Reserve system PTEs for zeroing PTEs and clear them */
672 MiFirstReservedZeroingPte
= MiReserveSystemPtes(MI_ZERO_PTES
,
674 RtlZeroMemory(MiFirstReservedZeroingPte
, MI_ZERO_PTES
* sizeof(MMPTE
));
676 /* Set the counter to maximum */
677 MiFirstReservedZeroingPte
->u
.Hard
.PageFrameNumber
= MI_ZERO_PTES
- 1;
680 /* Build the physical memory block */
681 MiBuildPhysicalMemoryBlock(LoaderBlock
);
683 /* Size up paged pool and build the shadow system page directory */
687 return STATUS_SUCCESS
;