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 "../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 > MaximumWorkingSetSize\n");
93 Status
= STATUS_BAD_WORKING_SET_LIMIT
;
97 /* Calculate the minimum WS size adjustment and check if we increase */
98 Delta
= MinimumWorkingSetSize
- Ws
->MinimumWorkingSetSize
;
101 /* Is increasing ok? */
104 DPRINT1("Privilege for WS size increase not held\n");
105 Status
= STATUS_PRIVILEGE_NOT_HELD
;
109 /* Check if the number of available pages is large enough */
110 if (((SIZE_T
)Delta
/ 1024) > (MmAvailablePages
- 128))
112 DPRINT1("Not enough available pages\n");
113 Status
= STATUS_INSUFFICIENT_RESOURCES
;
117 /* Check if there are enough resident available pages */
119 (MmResidentAvailablePages
- MmSystemLockPagesCount
- 256))
121 DPRINT1("Not enough resident pages\n");
122 Status
= STATUS_INSUFFICIENT_RESOURCES
;
127 /* Update resident available pages */
130 InterlockedExchangeAddSizeT(&MmResidentAvailablePages
, -Delta
);
133 /* Calculate new pages above minimum WS size */
134 Delta
+= max((SSIZE_T
)Ws
->WorkingSetSize
- MinimumWorkingSetSize
, 0);
136 /* Subtract old pages above minimum WS size */
137 Delta
-= max((SSIZE_T
)Ws
->WorkingSetSize
- Ws
->MinimumWorkingSetSize
, 0);
139 /* If it changed, add it to the global variable */
142 InterlockedExchangeAddSizeT(&MmPagesAboveWsMinimum
, Delta
);
145 /* Set the new working set size */
146 Ws
->MinimumWorkingSetSize
= MinimumWorkingSetSize
;
147 Ws
->MaximumWorkingSetSize
= MaximumWorkingSetSize
;
151 /* Unlock the working set and return the status */
152 MiUnlockWorkingSet(PsGetCurrentThread(), Ws
);
161 MmSetAddressRangeModified(IN PVOID Address
,
173 MmIsAddressValid(IN PVOID VirtualAddress
)
175 #if _MI_PAGING_LEVELS >= 4
176 /* Check if the PXE is valid */
177 if (MiAddressToPxe(VirtualAddress
)->u
.Hard
.Valid
== 0) return FALSE
;
180 #if _MI_PAGING_LEVELS >= 3
181 /* Check if the PPE is valid */
182 if (MiAddressToPpe(VirtualAddress
)->u
.Hard
.Valid
== 0) return FALSE
;
185 #if _MI_PAGING_LEVELS >= 2
186 /* Check if the PDE is valid */
187 if (MiAddressToPde(VirtualAddress
)->u
.Hard
.Valid
== 0) return FALSE
;
190 /* Check if the PTE is valid */
191 if (MiAddressToPte(VirtualAddress
)->u
.Hard
.Valid
== 0) return FALSE
;
193 /* This address is valid now, but it will only stay so if the caller holds
203 MmIsNonPagedSystemAddressValid(IN PVOID VirtualAddress
)
205 DPRINT1("WARNING: %s returns bogus result\n", __FUNCTION__
);
206 return MmIsAddressValid(VirtualAddress
);
214 MmSetBankedSection(IN HANDLE ProcessHandle
,
215 IN PVOID VirtualAddress
,
217 IN BOOLEAN ReadWriteBank
,
218 IN PVOID BankRoutine
,
222 return STATUS_NOT_IMPLEMENTED
;
230 MmIsRecursiveIoFault(VOID
)
232 PETHREAD Thread
= PsGetCurrentThread();
235 // If any of these is true, this is a recursive fault
237 return ((Thread
->DisablePageFaultClustering
) | (Thread
->ForwardClusterOnly
));
245 MmIsThisAnNtAsSystem(VOID
)
247 /* Return if this is a server system */
248 return MmProductType
& 0xFF;
256 MmQuerySystemSize(VOID
)
258 /* Return the low, medium or high memory system type */