ReactOS 0.4.15-dev-7924-g5949c20
procsup.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: GPL, See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/mm/amd64/procsup.c
5 * PURPOSE: Low level memory management manipulation
6 *
7 * PROGRAMMER: Timo Kreuzer (timo.kreuzer@reactos.org)
8 * ReactOS Portable Systems Group
9 */
10
11/* INCLUDES *******************************************************************/
12
13#include <ntoskrnl.h>
14#define NDEBUG
15#include <debug.h>
16
17#define MODULE_INVOLVED_IN_ARM3
18#include <mm/ARM3/miarm.h>
19
23 _In_ PULONG_PTR DirectoryTableBase)
24{
26 PFN_NUMBER TableBasePfn, HyperPfn, HyperPdPfn, HyperPtPfn;
27 PMMPTE SystemPte;
28 MMPTE TempPte, PdePte;
29 ULONG TableIndex;
30 PMMPTE PageTablePointer;
31 ULONG PageColor;
32
33 /* Non-arch specific code-path allocated those for us */
34 TableBasePfn = DirectoryTableBase[0] >> PAGE_SHIFT;
35 HyperPfn = DirectoryTableBase[1] >> PAGE_SHIFT;
36
37 /*
38 * Lock PFN database. Try getting zero pages.
39 * If that doesn't work, we take the slow path
40 * outside of the PFN lock.
41 */
42 OldIrql = MiAcquirePfnLock();
44 HyperPdPfn = MiRemoveZeroPageSafe(PageColor);
45 if(!HyperPdPfn)
46 {
47 HyperPdPfn = MiRemoveAnyPage(PageColor);
48 MiReleasePfnLock(OldIrql);
49 MiZeroPhysicalPage(HyperPdPfn);
50 OldIrql = MiAcquirePfnLock();
51 }
53 HyperPtPfn = MiRemoveZeroPageSafe(PageColor);
54 if(!HyperPtPfn)
55 {
56 HyperPtPfn = MiRemoveAnyPage(PageColor);
57 MiReleasePfnLock(OldIrql);
58 MiZeroPhysicalPage(HyperPtPfn);
59 }
60 else
61 {
62 MiReleasePfnLock(OldIrql);
63 }
64
65 /* Get a PTE to map the page directory */
66 SystemPte = MiReserveSystemPtes(1, SystemPteSpace);
67 if (!SystemPte)
68 return FALSE;
69
70 /* Get its address */
71 PageTablePointer = MiPteToAddress(SystemPte);
72
73 /* Build the PTE for the page directory and map it */
74 MI_MAKE_HARDWARE_PTE_KERNEL(&PdePte, SystemPte, MM_READWRITE, TableBasePfn);
75 MI_WRITE_VALID_PTE(SystemPte, PdePte);
76
77 /* Copy the kernel mappings and zero out the rest */
78 TableIndex = PXE_PER_PAGE / 2;
79 RtlZeroMemory(PageTablePointer, TableIndex * sizeof(MMPTE));
80 RtlCopyMemory(PageTablePointer + TableIndex,
81 MiAddressToPxe(0) + TableIndex,
82 PAGE_SIZE - TableIndex * sizeof(MMPTE));
83
84 /* Sanity check */
86
87 /* Setup a PTE for the page directory mappings */
89
90 /* Update the self mapping of the PML4 */
91 TableIndex = MiAddressToPxi((PVOID)PXE_SELFMAP);
92 TempPte.u.Hard.PageFrameNumber = TableBasePfn;
93 PageTablePointer[TableIndex] = TempPte;
94
95 /* Write the PML4 entry for hyperspace */
96 TableIndex = MiAddressToPxi((PVOID)HYPER_SPACE);
97 TempPte.u.Hard.PageFrameNumber = HyperPfn;
98 PageTablePointer[TableIndex] = TempPte;
99
100 /* Map the hyperspace PDPT to the system PTE */
101 PdePte.u.Hard.PageFrameNumber = HyperPfn;
102 *SystemPte = PdePte;
103 __invlpg(PageTablePointer);
104
105 /* Write the hyperspace entry for the first PD */
106 TempPte.u.Hard.PageFrameNumber = HyperPdPfn;
107 PageTablePointer[0] = TempPte;
108
109 /* Map the hyperspace PD to the system PTE */
110 PdePte.u.Hard.PageFrameNumber = HyperPdPfn;
111 *SystemPte = PdePte;
112 __invlpg(PageTablePointer);
113
114 /* Write the hyperspace entry for the first PT */
115 TempPte.u.Hard.PageFrameNumber = HyperPtPfn;
116 PageTablePointer[0] = TempPte;
117
118 /* Map the hyperspace PT to the system PTE */
119 PdePte.u.Hard.PageFrameNumber = HyperPtPfn;
120 *SystemPte = PdePte;
121 __invlpg(PageTablePointer);
122
123 /* Write the hyperspace PTE for the working set list index */
124 TempPte.u.Hard.PageFrameNumber = Process->WorkingSetPage;
125 TableIndex = MiAddressToPti(MmWorkingSetList);
126 PageTablePointer[TableIndex] = TempPte;
127
128 /* Release the system PTE */
129 MiReleaseSystemPtes(SystemPte, 1, SystemPteSpace);
130
131 return TRUE;
132}
unsigned char BOOLEAN
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:76
#define MM_READWRITE
Definition: bootanim.c:19
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
__INTRIN_INLINE void __invlpg(void *Address)
Definition: intrin_x86.h:1968
@ SystemPteSpace
Definition: miarm.h:403
PFN_NUMBER NTAPI MiRemoveAnyPage(IN ULONG Color)
Definition: pfnlist.c:477
VOID NTAPI MiReleaseSystemPtes(IN PMMPTE StartingPte, IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:264
FORCEINLINE VOID MI_MAKE_HARDWARE_PTE_KERNEL(IN PMMPTE NewPte, IN PMMPTE MappingPte, IN ULONG_PTR ProtectionMask, IN PFN_NUMBER PageFrameNumber)
Definition: miarm.h:773
PMMPTE NTAPI MiReserveSystemPtes(IN ULONG NumberOfPtes, IN MMSYSTEM_PTE_POOL_TYPE SystemPtePoolType)
Definition: syspte.c:246
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:959
#define MI_GET_NEXT_PROCESS_COLOR(x)
Definition: miarm.h:233
FORCEINLINE PFN_NUMBER MiRemoveZeroPageSafe(IN ULONG Color)
Definition: miarm.h:2415
#define ASSERT(a)
Definition: mode.c:44
#define _In_
Definition: ms_sal.h:308
PMMWSL MmWorkingSetList
Definition: wslist.cpp:19
VOID NTAPI MiZeroPhysicalPage(IN PFN_NUMBER PageFrameIndex)
Definition: pfnlist.c:122
FORCEINLINE ULONG MiAddressToPxi(PVOID Address)
Definition: mm.h:200
#define HYPER_SPACE
Definition: mm.h:14
FORCEINLINE PMMPTE MiAddressToPxe(PVOID Address)
Definition: mm.h:171
FORCEINLINE ULONG MiAddressToPti(PVOID Address)
Definition: mm.h:181
#define MiPteToAddress(_Pte)
Definition: mm.h:116
PVOID MmHyperSpaceEnd
Definition: init.c:56
MMPTE ValidKernelPte
Definition: init.c:29
BOOLEAN MiArchCreateProcessAddressSpace(_In_ PEPROCESS Process, _In_ PULONG_PTR DirectoryTableBase)
Definition: procsup.c:21
#define PXE_PER_PAGE
#define PXE_SELFMAP
ULONG PFN_NUMBER
Definition: ke.h:9
ULONG PageFrameNumber
Definition: mmtypes.h:109
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
union _MMPTE::@2330 u
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
uint32_t * PULONG_PTR
Definition: typedefs.h:65
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
uint32_t ULONG
Definition: typedefs.h:59
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:778