sync to trunk head (37853) (except rbuild changes)
[reactos.git] / reactos / ntoskrnl / mm / cont.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS kernel
4 * FILE: ntoskrnl/mm/cont.c
5 * PURPOSE: Manages continuous memory
6 *
7 * PROGRAMMERS: David Welch (welch@cwcom.net)
8 */
9
10 /* INCLUDES *****************************************************************/
11
12 #include <ntoskrnl.h>
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 static VOID
19 MmFreeContinuousPage(PVOID Context, MEMORY_AREA* MemoryArea, PVOID Address,
20 PFN_TYPE Page, SWAPENTRY SwapEntry,
21 BOOLEAN Dirty)
22 {
23 ASSERT(SwapEntry == 0);
24 if (Page != 0)
25 {
26 MmReleasePageMemoryConsumer(MC_NPPOOL, Page);
27 }
28 }
29
30 /**********************************************************************
31 * NAME EXPORTED
32 * MmAllocateContiguousMemorySpecifyCache@32
33 *
34 * DESCRIPTION
35 * Allocates a range of physically contiguous memory
36 * with a cache parameter.
37 *
38 * ARGUMENTS
39 * NumberOfBytes
40 * Size of the memory block to allocate;
41 *
42 * LowestAcceptableAddress
43 * Lowest address valid for the caller.
44 *
45 * HighestAcceptableAddress
46 * Highest address valid for the caller.
47 *
48 * BoundaryAddressMultiple
49 * Address multiple not to be crossed by allocated buffer (optional).
50 *
51 * CacheType
52 * Type of caching to use.
53 *
54 * RETURN VALUE
55 * The virtual address of the memory block on success;
56 * NULL on error.
57 *
58 * REVISIONS
59 *
60 * @implemented
61 */
62 PVOID NTAPI
63 MmAllocateContiguousMemorySpecifyCache(IN SIZE_T NumberOfBytes,
64 IN PHYSICAL_ADDRESS LowestAcceptableAddress OPTIONAL,
65 IN PHYSICAL_ADDRESS HighestAcceptableAddress,
66 IN PHYSICAL_ADDRESS BoundaryAddressMultiple OPTIONAL,
67 IN MEMORY_CACHING_TYPE CacheType OPTIONAL)
68 {
69 PMEMORY_AREA MArea;
70 NTSTATUS Status;
71 PVOID BaseAddress = NULL;
72 PFN_TYPE PBase;
73 ULONG Protect;
74 ULONG i;
75
76 Protect = PAGE_EXECUTE_READWRITE | PAGE_SYSTEM;
77 if (CacheType == MmNonCached || CacheType == MmWriteCombined)
78 {
79 Protect |= PAGE_NOCACHE;
80 }
81 if (CacheType == MmWriteCombined)
82 {
83 Protect |= PAGE_WRITECOMBINE;
84 }
85
86 MmLockAddressSpace(MmGetKernelAddressSpace());
87 Status = MmCreateMemoryArea(MmGetKernelAddressSpace(),
88 MEMORY_AREA_CONTINUOUS_MEMORY,
89 &BaseAddress,
90 NumberOfBytes,
91 PAGE_READWRITE,
92 &MArea,
93 FALSE,
94 0,
95 RtlConvertLongToLargeInteger(0));
96 MmUnlockAddressSpace(MmGetKernelAddressSpace());
97
98 if (!NT_SUCCESS(Status))
99 {
100 return(NULL);
101 }
102 DPRINT( "Base = %x\n", BaseAddress );
103 PBase = MmGetContinuousPages(NumberOfBytes,
104 LowestAcceptableAddress,
105 HighestAcceptableAddress,
106 BoundaryAddressMultiple);
107 if (PBase == 0)
108 {
109 MmLockAddressSpace(MmGetKernelAddressSpace());
110 MmFreeMemoryArea(MmGetKernelAddressSpace(),
111 MArea,
112 NULL,
113 NULL);
114 MmUnlockAddressSpace(MmGetKernelAddressSpace());
115 return(NULL);
116 }
117 for (i = 0; i < (PAGE_ROUND_UP(NumberOfBytes) / PAGE_SIZE); i++, PBase++)
118 {
119 MmCreateVirtualMapping(NULL,
120 (char*)BaseAddress + (i * PAGE_SIZE),
121 Protect,
122 &PBase,
123 1);
124 }
125 return(BaseAddress);
126 }
127
128 /**********************************************************************
129 * NAME EXPORTED
130 * MmAllocateContiguousMemory@12
131 *
132 * DESCRIPTION
133 * Allocates a range of physically contiguous cache aligned
134 * memory from the non-paged pool.
135 *
136 * ARGUMENTS
137 * NumberOfBytes
138 * Size of the memory block to allocate;
139 *
140 * HighestAcceptableAddress
141 * Highest address valid for the caller.
142 *
143 * RETURN VALUE
144 * The virtual address of the memory block on success;
145 * NULL on error.
146 *
147 * NOTE
148 * Description taken from include/ddk/mmfuncs.h.
149 * Code taken from ntoskrnl/mm/special.c.
150 *
151 * REVISIONS
152 *
153 * @implemented
154 */
155 PVOID NTAPI
156 MmAllocateContiguousMemory (IN ULONG NumberOfBytes,
157 IN PHYSICAL_ADDRESS HighestAcceptableAddress)
158 {
159 return MmAllocateContiguousMemorySpecifyCache(NumberOfBytes,
160 RtlConvertLongToLargeInteger(0),
161 HighestAcceptableAddress,
162 RtlConvertLongToLargeInteger(0),
163 MmCached);
164 }
165
166
167 /**********************************************************************
168 * NAME EXPORTED
169 * MmFreeContiguousMemory@4
170 *
171 * DESCRIPTION
172 * Releases a range of physically contiguous memory allocated
173 * with MmAllocateContiguousMemory.
174 *
175 * ARGUMENTS
176 * BaseAddress
177 * Virtual address of the memory to be freed.
178 *
179 * RETURN VALUE
180 * None.
181 *
182 * NOTE
183 * Description taken from include/ddk/mmfuncs.h.
184 * Code taken from ntoskrnl/mm/special.c.
185 *
186 * REVISIONS
187 *
188 * @implemented
189 */
190 VOID NTAPI
191 MmFreeContiguousMemory(IN PVOID BaseAddress)
192 {
193 MmLockAddressSpace(MmGetKernelAddressSpace());
194 MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
195 BaseAddress,
196 MmFreeContinuousPage,
197 NULL);
198 MmUnlockAddressSpace(MmGetKernelAddressSpace());
199 }
200
201 /**********************************************************************
202 * NAME EXPORTED
203 * MmFreeContiguousMemorySpecifyCache@12
204 *
205 * DESCRIPTION
206 * Releases a range of physically contiguous memory allocated
207 * with MmAllocateContiguousMemorySpecifyCache.
208 *
209 * ARGUMENTS
210 * BaseAddress
211 * Virtual address of the memory to be freed.
212 *
213 * NumberOfBytes
214 * Size of the memory block to free.
215 *
216 * CacheType
217 * Type of caching used.
218 *
219 * RETURN VALUE
220 * None.
221 *
222 * REVISIONS
223 *
224 * @implemented
225 */
226 VOID NTAPI
227 MmFreeContiguousMemorySpecifyCache(IN PVOID BaseAddress,
228 IN SIZE_T NumberOfBytes,
229 IN MEMORY_CACHING_TYPE CacheType)
230 {
231 MmLockAddressSpace(MmGetKernelAddressSpace());
232 MmFreeMemoryAreaByPtr(MmGetKernelAddressSpace(),
233 BaseAddress,
234 MmFreeContinuousPage,
235 NULL);
236 MmUnlockAddressSpace(MmGetKernelAddressSpace());
237 }
238
239
240 /* EOF */