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
9 /* INCLUDES *******************************************************************/
15 #line 15 "ARMĀ³::HYPERMAP"
16 #define MODULE_INVOLVED_IN_ARM3
17 #include "../ARM3/miarm.h"
19 /* GLOBALS ********************************************************************/
21 PMMPTE MmFirstReservedMappingPte
, MmLastReservedMappingPte
;
22 PMMPTE MiFirstReservedZeroingPte
;
23 MMPTE HyperTemplatePte
;
24 PEPROCESS HyperProcess
;
27 /* PRIVATE FUNCTIONS **********************************************************/
31 MiMapPageInHyperSpace(IN PEPROCESS Process
,
40 // Never accept page 0 or non-physical pages
43 ASSERT(MiGetPfnEntry(Page
) != NULL
);
48 TempPte
= ValidKernelPte
;
49 TempPte
.u
.Hard
.PageFrameNumber
= Page
;
50 MI_MAKE_LOCAL_PAGE(&TempPte
); // Hyperspace is local!
53 // Pick the first hyperspace PTE
55 PointerPte
= MmFirstReservedMappingPte
;
58 // Acquire the hyperlock
60 ASSERT(Process
== PsGetCurrentProcess());
61 KeAcquireSpinLock(&Process
->HyperSpaceLock
, OldIrql
);
64 // Now get the first free PTE
66 Offset
= PFN_FROM_PTE(PointerPte
);
72 Offset
= MI_HYPERSPACE_PTES
;
77 // Prepare the next PTE
79 PointerPte
->u
.Hard
.PageFrameNumber
= Offset
- 1;
82 // Write the current PTE
85 ASSERT(PointerPte
->u
.Hard
.Valid
== 0);
86 ASSERT(TempPte
.u
.Hard
.Valid
== 1);
87 *PointerPte
= TempPte
;
92 return MiPteToAddress(PointerPte
);
97 MiUnmapPageInHyperSpace(IN PEPROCESS Process
,
101 ASSERT(Process
== PsGetCurrentProcess());
104 // Blow away the mapping
106 MiAddressToPte(Address
)->u
.Long
= 0;
109 // Release the hyperlock
111 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
112 KeReleaseSpinLock(&Process
->HyperSpaceLock
, OldIrql
);
117 MiMapPagesToZeroInHyperSpace(IN PFN_NUMBER
*Pages
,
118 IN PFN_NUMBER NumberOfPages
)
122 PFN_NUMBER Offset
, PageFrameIndex
;
127 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
128 ASSERT(NumberOfPages
!= 0);
129 ASSERT(NumberOfPages
<= (MI_ZERO_PTES
- 1));
132 // Pick the first zeroing PTE
134 PointerPte
= MiFirstReservedZeroingPte
;
137 // Now get the first free PTE
139 Offset
= PFN_FROM_PTE(PointerPte
);
140 if (NumberOfPages
> Offset
)
145 Offset
= MI_ZERO_PTES
- 1;
146 PointerPte
->u
.Hard
.PageFrameNumber
= Offset
;
151 // Prepare the next PTE
153 PointerPte
->u
.Hard
.PageFrameNumber
= Offset
- NumberOfPages
;
156 // Write the current PTE
158 PointerPte
+= (Offset
+ 1);
159 TempPte
= ValidKernelPte
;
160 MI_MAKE_LOCAL_PAGE(&TempPte
); // Hyperspace is local!
164 // Get the first page entry and its PFN
166 PageFrameIndex
= *Pages
++;
171 TempPte
.u
.Hard
.PageFrameNumber
= PageFrameIndex
;
174 // Set the correct PTE to write to, and set its new value
177 ASSERT(PointerPte
->u
.Hard
.Valid
== 0);
178 ASSERT(TempPte
.u
.Hard
.Valid
== 1);
179 *PointerPte
= TempPte
;
180 } while (--NumberOfPages
);
183 // Return the address
185 return MiPteToAddress(PointerPte
);
190 MiUnmapPagesInZeroSpace(IN PVOID VirtualAddress
,
191 IN PFN_NUMBER NumberOfPages
)
198 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
199 ASSERT (NumberOfPages
!= 0);
200 ASSERT (NumberOfPages
<= (MI_ZERO_PTES
- 1));
203 // Get the first PTE for the mapped zero VA
205 PointerPte
= MiAddressToPte(VirtualAddress
);
208 // Blow away the mapped zero PTEs
210 RtlZeroMemory(PointerPte
, NumberOfPages
* sizeof(MMPTE
));