ReactOS  r76032
hypermap.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: ntoskrnl/mm/ARM3/hypermap.c
5  * PURPOSE: ARM Memory Manager Hyperspace Mapping Functionality
6  * PROGRAMMERS: ReactOS Portable Systems Group
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <ntoskrnl.h>
12 #define NDEBUG
13 #include <debug.h>
14 
15 #define MODULE_INVOLVED_IN_ARM3
16 #include <mm/ARM3/miarm.h>
17 
18 /* GLOBALS ********************************************************************/
19 
25 
26 /* PRIVATE FUNCTIONS **********************************************************/
27 
28 PVOID
29 NTAPI
31  IN PFN_NUMBER Page,
33 {
34  MMPTE TempPte;
35  PMMPTE PointerPte;
37 
38  //
39  // Never accept page 0 or non-physical pages
40  //
41  ASSERT(Page != 0);
42  ASSERT(MiGetPfnEntry(Page) != NULL);
43 
44  //
45  // Build the PTE
46  //
47  TempPte = ValidKernelPteLocal;
48  TempPte.u.Hard.PageFrameNumber = Page;
49 
50  //
51  // Pick the first hyperspace PTE
52  //
53  PointerPte = MmFirstReservedMappingPte;
54 
55  //
56  // Acquire the hyperlock
57  //
58  ASSERT(Process == PsGetCurrentProcess());
59  KeAcquireSpinLock(&Process->HyperSpaceLock, OldIrql);
60 
61  //
62  // Now get the first free PTE
63  //
64  Offset = PFN_FROM_PTE(PointerPte);
65  if (!Offset)
66  {
67  //
68  // Reset the PTEs
69  //
70  Offset = MI_HYPERSPACE_PTES;
72  }
73 
74  //
75  // Prepare the next PTE
76  //
77  PointerPte->u.Hard.PageFrameNumber = Offset - 1;
78 
79  //
80  // Write the current PTE
81  //
82  PointerPte += Offset;
83  MI_WRITE_VALID_PTE(PointerPte, TempPte);
84 
85  //
86  // Return the address
87  //
88  return MiPteToAddress(PointerPte);
89 }
90 
91 VOID
92 NTAPI
96 {
97  ASSERT(Process == PsGetCurrentProcess());
98 
99  //
100  // Blow away the mapping
101  //
102  MiAddressToPte(Address)->u.Long = 0;
103 
104  //
105  // Release the hyperlock
106  //
108  KeReleaseSpinLock(&Process->HyperSpaceLock, OldIrql);
109 }
110 
111 PVOID
112 NTAPI
114  IN PFN_NUMBER NumberOfPages)
115 {
116  MMPTE TempPte;
117  PMMPTE PointerPte;
118  PFN_NUMBER Offset, PageFrameIndex;
119 
120  //
121  // Sanity checks
122  //
124  ASSERT(NumberOfPages != 0);
125  ASSERT(NumberOfPages <= (MI_ZERO_PTES - 1));
126 
127  //
128  // Pick the first zeroing PTE
129  //
130  PointerPte = MiFirstReservedZeroingPte;
131 
132  //
133  // Now get the first free PTE
134  //
135  Offset = PFN_FROM_PTE(PointerPte);
136  if (NumberOfPages > Offset)
137  {
138  //
139  // Reset the PTEs
140  //
141  Offset = MI_ZERO_PTES - 1;
142  PointerPte->u.Hard.PageFrameNumber = Offset;
144  }
145 
146  //
147  // Prepare the next PTE
148  //
149  PointerPte->u.Hard.PageFrameNumber = Offset - NumberOfPages;
150 
151  /* Choose the correct PTE to use, and which template */
152  PointerPte += (Offset + 1);
153  TempPte = ValidKernelPte;
154 
155  /* Make sure the list isn't empty and loop it */
156  ASSERT(Pfn1 != (PVOID)LIST_HEAD);
157  while (Pfn1 != (PVOID)LIST_HEAD)
158  {
159  /* Get the page index for this PFN */
160  PageFrameIndex = MiGetPfnEntryIndex(Pfn1);
161 
162  //
163  // Write the PFN
164  //
165  TempPte.u.Hard.PageFrameNumber = PageFrameIndex;
166 
167  //
168  // Set the correct PTE to write to, and set its new value
169  //
170  PointerPte--;
171  MI_WRITE_VALID_PTE(PointerPte, TempPte);
172 
173  /* Move to the next PFN */
174  Pfn1 = (PMMPFN)Pfn1->u1.Flink;
175  }
176 
177  //
178  // Return the address
179  //
180  return MiPteToAddress(PointerPte);
181 }
182 
183 VOID
184 NTAPI
186  IN PFN_NUMBER NumberOfPages)
187 {
188  PMMPTE PointerPte;
189 
190  //
191  // Sanity checks
192  //
194  ASSERT (NumberOfPages != 0);
195  ASSERT (NumberOfPages <= (MI_ZERO_PTES - 1));
196 
197  //
198  // Get the first PTE for the mapped zero VA
199  //
200  PointerPte = MiAddressToPte(VirtualAddress);
201 
202  //
203  // Blow away the mapped zero PTEs
204  //
205  RtlZeroMemory(PointerPte, NumberOfPages * sizeof(MMPTE));
206 }
207 
DWORD *typedef PVOID
Definition: winlogon.h:52
PVOID NTAPI MiMapPagesInZeroSpace(IN PMMPFN Pfn1, IN PFN_NUMBER NumberOfPages)
Definition: hypermap.c:113
#define KeGetCurrentIrql()
Definition: env_spec_w32.h:706
VOID NTAPI MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress, IN PFN_NUMBER NumberOfPages)
Definition: hypermap.c:185
#define IN
Definition: typedefs.h:38
PVOID ULONG Address
Definition: oprghdlr.h:14
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel)?(CompletionRoutine!=NULL):TRUE)
PMMPTE MmLastReservedMappingPte
Definition: hypermap.c:20
KIRQL HyperIrql
Definition: hypermap.c:24
MMPTE HyperTemplatePte
Definition: hypermap.c:22
UCHAR KIRQL
Definition: env_spec_w32.h:591
#define MiAddressToPte(x)
Definition: mmx86.c:19
ULONG PFN_NUMBER
Definition: ke.h:8
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
_In_ ULONG _In_ ULONG Offset
Definition: ntddpcm.h:101
FORCEINLINE VOID MI_WRITE_VALID_PTE(IN PMMPTE PointerPte, IN MMPTE TempPte)
Definition: miarm.h:914
PMMPTE MmFirstReservedMappingPte
Definition: hypermap.c:20
#define PsGetCurrentProcess
Definition: psfuncs.h:17
#define MI_HYPERSPACE_PTES
Definition: mm.h:71
smooth NULL
Definition: ftsmooth.c:557
PVOID FORCEINLINE MiPteToAddress(PMMPTE PointerPte)
Definition: mm.h:185
VOID NTAPI MiUnmapPageInHyperSpace(IN PEPROCESS Process, IN PVOID Address, IN KIRQL OldIrql)
Definition: hypermap.c:93
PVOID NTAPI MiMapPageInHyperSpace(IN PEPROCESS Process, IN PFN_NUMBER Page, IN PKIRQL OldIrql)
Definition: hypermap.c:30
PEPROCESS HyperProcess
Definition: hypermap.c:23
MMPTE ValidKernelPteLocal
Definition: init.c:35
#define KeAcquireSpinLock(sl, irql)
Definition: env_spec_w32.h:609
HARDWARE_PTE_ARMV6 TempPte
Definition: winldr.c:75
MMPTE ValidKernelPte
Definition: init.c:31
_Requires_lock_held_ Interrupt _Releases_lock_ Interrupt _In_ _IRQL_restores_ KIRQL OldIrql
Definition: kefuncs.h:803
Definition: mm.h:301
KIRQL * PKIRQL
Definition: env_spec_w32.h:592
_In_ ULONG _In_ BOOLEAN _Must_inspect_result_ PVOID * VirtualAddress
Definition: ndis.h:3772
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
LIST_HEAD(acpi_bus_event_list)
FORCEINLINE PMMPFN MiGetPfnEntry(IN PFN_NUMBER Pfn)
Definition: mm.h:873
#define DISPATCH_LEVEL
Definition: env_spec_w32.h:696
MMPTE_HARDWARE Hard
Definition: mmtypes.h:217
struct _MMPFN * PMMPFN
#define KeReleaseSpinLock(sl, irql)
Definition: env_spec_w32.h:627
FORCEINLINE VOID KeFlushProcessTb(VOID)
Definition: ke.h:185
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
FORCEINLINE PFN_NUMBER MiGetPfnEntryIndex(IN PMMPFN Pfn1)
Definition: mm.h:893
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
ULONG64 PageFrameNumber
Definition: mmtypes.h:171
PMMPTE MiFirstReservedZeroingPte
Definition: hypermap.c:21
union _MMPTE::@2072 u
#define MI_ZERO_PTES
Definition: mm.h:72
#define PFN_FROM_PTE(v)
Definition: mm.h:82