2 * PROJECT: ReactOS Kernel
3 * LICENSE: BSD - See COPYING.ARM in the top level directory
4 * FILE: ntoskrnl/mm/ARM3/mmsup.c
5 * PURPOSE: ARM Memory Manager Support Routines
6 * PROGRAMMERS: ReactOS Portable Systems Group
9 /* INCLUDES *******************************************************************/
15 #define MODULE_INVOLVED_IN_ARM3
16 #include <mm/ARM3/miarm.h>
18 /* GLOBALS ********************************************************************/
20 SIZE_T MmMinimumWorkingSetSize
;
21 SIZE_T MmMaximumWorkingSetSize
;
22 SIZE_T MmPagesAboveWsMinimum
;
24 /* PUBLIC FUNCTIONS ***********************************************************/
31 MmMapUserAddressesToPage(IN PVOID BaseAddress
,
32 IN SIZE_T NumberOfBytes
,
36 return STATUS_NOT_IMPLEMENTED
;
44 MmAdjustWorkingSetSize(IN SIZE_T WorkingSetMinimumInBytes
,
45 IN SIZE_T WorkingSetMaximumInBytes
,
47 IN BOOLEAN IncreaseOkay
)
49 SIZE_T MinimumWorkingSetSize
, MaximumWorkingSetSize
;
54 /* Check for special case: empty the working set */
55 if ((WorkingSetMinimumInBytes
== -1) &&
56 (WorkingSetMaximumInBytes
== -1))
59 return STATUS_NOT_IMPLEMENTED
;
63 Status
= STATUS_SUCCESS
;
65 /* Get the working set and lock it */
66 Ws
= &PsGetCurrentProcess()->Vm
;
67 MiLockWorkingSet(PsGetCurrentThread(), Ws
);
69 /* Calculate the actual minimum and maximum working set size to set */
70 MinimumWorkingSetSize
= (WorkingSetMinimumInBytes
!= 0) ?
71 (WorkingSetMinimumInBytes
/ PAGE_SIZE
) : Ws
->MinimumWorkingSetSize
;
72 MaximumWorkingSetSize
= (WorkingSetMaximumInBytes
!= 0) ?
73 (WorkingSetMaximumInBytes
/ PAGE_SIZE
) : Ws
->MaximumWorkingSetSize
;
75 /* Check if the new maximum exceeds the global maximum */
76 if (MaximumWorkingSetSize
> MmMaximumWorkingSetSize
)
78 MaximumWorkingSetSize
= MmMaximumWorkingSetSize
;
79 Status
= STATUS_WORKING_SET_LIMIT_RANGE
;
82 /* Check if the new minimum is below the global minimum */
83 if (MinimumWorkingSetSize
< MmMinimumWorkingSetSize
)
85 MinimumWorkingSetSize
= MmMinimumWorkingSetSize
;
86 Status
= STATUS_WORKING_SET_LIMIT_RANGE
;
89 /* Check if the new minimum exceeds the new maximum */
90 if (MinimumWorkingSetSize
> MaximumWorkingSetSize
)
92 DPRINT1("MinimumWorkingSetSize (%lu) > MaximumWorkingSetSize (%lu)\n",
93 MinimumWorkingSetSize
, MaximumWorkingSetSize
);
94 Status
= STATUS_BAD_WORKING_SET_LIMIT
;
98 /* Calculate the minimum WS size adjustment and check if we increase */
99 Delta
= MinimumWorkingSetSize
- Ws
->MinimumWorkingSetSize
;
102 /* Is increasing ok? */
105 DPRINT1("Privilege for WS size increase not held\n");
106 Status
= STATUS_PRIVILEGE_NOT_HELD
;
110 /* Check if the number of available pages is large enough */
111 if (((SIZE_T
)Delta
/ 1024) > (MmAvailablePages
- 128))
113 DPRINT1("Not enough available pages\n");
114 Status
= STATUS_INSUFFICIENT_RESOURCES
;
118 /* Check if there are enough resident available pages */
120 (MmResidentAvailablePages
- MmSystemLockPagesCount
- 256))
122 DPRINT1("Not enough resident pages\n");
123 Status
= STATUS_INSUFFICIENT_RESOURCES
;
128 /* Update resident available pages */
131 InterlockedExchangeAddSizeT(&MmResidentAvailablePages
, -Delta
);
134 /* Calculate new pages above minimum WS size */
135 Delta
+= max((SSIZE_T
)Ws
->WorkingSetSize
- MinimumWorkingSetSize
, 0);
137 /* Subtract old pages above minimum WS size */
138 Delta
-= max((SSIZE_T
)Ws
->WorkingSetSize
- Ws
->MinimumWorkingSetSize
, 0);
140 /* If it changed, add it to the global variable */
143 InterlockedExchangeAddSizeT(&MmPagesAboveWsMinimum
, Delta
);
146 /* Set the new working set size */
147 Ws
->MinimumWorkingSetSize
= MinimumWorkingSetSize
;
148 Ws
->MaximumWorkingSetSize
= MaximumWorkingSetSize
;
152 /* Unlock the working set and return the status */
153 MiUnlockWorkingSet(PsGetCurrentThread(), Ws
);
162 MmSetAddressRangeModified(IN PVOID Address
,
174 MmIsAddressValid(IN PVOID VirtualAddress
)
176 #if _MI_PAGING_LEVELS >= 4
177 /* Check if the PXE is valid */
178 if (MiAddressToPxe(VirtualAddress
)->u
.Hard
.Valid
== 0) return FALSE
;
181 #if _MI_PAGING_LEVELS >= 3
182 /* Check if the PPE is valid */
183 if (MiAddressToPpe(VirtualAddress
)->u
.Hard
.Valid
== 0) return FALSE
;
186 #if _MI_PAGING_LEVELS >= 2
187 /* Check if the PDE is valid */
188 if (MiAddressToPde(VirtualAddress
)->u
.Hard
.Valid
== 0) return FALSE
;
191 /* Check if the PTE is valid */
192 if (MiAddressToPte(VirtualAddress
)->u
.Hard
.Valid
== 0) return FALSE
;
194 /* This address is valid now, but it will only stay so if the caller holds
204 MmIsNonPagedSystemAddressValid(IN PVOID VirtualAddress
)
206 DPRINT1("WARNING: %s returns bogus result\n", __FUNCTION__
);
207 return MmIsAddressValid(VirtualAddress
);
215 MmSetBankedSection(IN HANDLE ProcessHandle
,
216 IN PVOID VirtualAddress
,
218 IN BOOLEAN ReadWriteBank
,
219 IN PVOID BankRoutine
,
223 return STATUS_NOT_IMPLEMENTED
;
231 MmIsRecursiveIoFault(VOID
)
233 PETHREAD Thread
= PsGetCurrentThread();
236 // If any of these is true, this is a recursive fault
238 return ((Thread
->DisablePageFaultClustering
) | (Thread
->ForwardClusterOnly
));
246 MmIsThisAnNtAsSystem(VOID
)
248 /* Return if this is a server system */
249 return MmProductType
& 0xFF;
257 MmQuerySystemSize(VOID
)
259 /* Return the low, medium or high memory system type */