3 * Copyright (C) 2006-2008 Aleksey Bragin <aleksey@reactos.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 VOID
DumpMemoryAllocMap(VOID
);
25 VOID
MemAllocTest(VOID
);
28 ULONG LoaderPagesSpanned
= 0;
30 PVOID
MmAllocateMemoryWithType(ULONG MemorySize
, TYPE_OF_MEMORY MemoryType
)
33 ULONG FirstFreePageFromEnd
;
38 DPRINTM(DPRINT_MEMORY
, "MmAllocateMemory() called for 0 bytes. Returning NULL.\n");
39 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemory() called for 0 bytes.");
43 MemorySize
= ROUND_UP(MemorySize
, 4);
45 // Find out how many blocks it will take to
46 // satisfy this allocation
47 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
49 // If we don't have enough available mem
51 if (FreePagesInLookupTable
< PagesNeeded
)
53 DPRINTM(DPRINT_MEMORY
, "Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
54 UiMessageBoxCritical("Memory allocation failed: out of memory.");
58 FirstFreePageFromEnd
= MmFindAvailablePages(PageLookupTableAddress
, TotalPagesInLookupTable
, PagesNeeded
, FALSE
);
60 if (FirstFreePageFromEnd
== 0)
62 DPRINTM(DPRINT_MEMORY
, "Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
63 UiMessageBoxCritical("Memory allocation failed: out of memory.");
67 MmAllocatePagesInLookupTable(PageLookupTableAddress
, FirstFreePageFromEnd
, PagesNeeded
, MemoryType
);
69 FreePagesInLookupTable
-= PagesNeeded
;
70 MemPointer
= (PVOID
)((ULONG_PTR
)FirstFreePageFromEnd
* MM_PAGE_SIZE
);
73 DPRINTM(DPRINT_MEMORY
, "Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, FirstFreePageFromEnd
);
74 DPRINTM(DPRINT_MEMORY
, "Memory allocation pointer: 0x%x\n", MemPointer
);
77 // Update LoaderPagesSpanned count
78 if ((((ULONG_PTR
)MemPointer
+ MemorySize
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
) > LoaderPagesSpanned
)
79 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
);
81 // Now return the pointer
85 PVOID
MmHeapAlloc(ULONG MemorySize
)
89 if (MemorySize
> MM_PAGE_SIZE
)
91 DPRINTM(DPRINT_MEMORY
, "Consider using other functions to allocate %d bytes of memory!\n", MemorySize
);
94 // Get the buffer from BGET pool
95 Result
= bget(MemorySize
);
99 DPRINTM(DPRINT_MEMORY
, "Heap allocation for %d bytes failed\n", MemorySize
);
103 LONG CurAlloc
, TotalFree
, MaxFree
, NumberOfGets
, NumberOfRels
;
106 bstats(&CurAlloc
, &TotalFree
, &MaxFree
, &NumberOfGets
, &NumberOfRels
);
108 DPRINTM(DPRINT_MEMORY
, "Current alloced %d bytes, free %d bytes, allocs %d, frees %d\n",
109 CurAlloc
, TotalFree
, NumberOfGets
, NumberOfRels
);
115 VOID
MmHeapFree(PVOID MemoryPointer
)
117 // Release the buffer to the pool
121 PVOID
MmAllocateMemory(ULONG MemorySize
)
123 // Temporary forwarder...
124 return MmAllocateMemoryWithType(MemorySize
, LoaderOsloaderHeap
);
127 PVOID
MmAllocateMemoryAtAddress(ULONG MemorySize
, PVOID DesiredAddress
, TYPE_OF_MEMORY MemoryType
)
130 ULONG StartPageNumber
;
135 DPRINTM(DPRINT_MEMORY
, "MmAllocateMemoryAtAddress() called for 0 bytes. Returning NULL.\n");
136 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemoryAtAddress() called for 0 bytes.");
140 // Find out how many blocks it will take to
141 // satisfy this allocation
142 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
144 // Get the starting page number
145 StartPageNumber
= MmGetPageNumberFromAddress(DesiredAddress
);
147 // If we don't have enough available mem
149 if (FreePagesInLookupTable
< PagesNeeded
)
151 DPRINTM(DPRINT_MEMORY
, "Memory allocation failed in MmAllocateMemoryAtAddress(). "
152 "Not enough free memory to allocate %d bytes (requesting %d pages but have only %d). "
153 "\n", MemorySize
, PagesNeeded
, FreePagesInLookupTable
);
154 UiMessageBoxCritical("Memory allocation failed: out of memory.");
158 if (MmAreMemoryPagesAvailable(PageLookupTableAddress
, TotalPagesInLookupTable
, DesiredAddress
, PagesNeeded
) == FALSE
)
160 DPRINTM(DPRINT_MEMORY
, "Memory allocation failed in MmAllocateMemoryAtAddress(). "
161 "Not enough free memory to allocate %d bytes at address %p.\n",
162 MemorySize
, DesiredAddress
);
164 // Don't tell this to user since caller should try to alloc this memory
165 // at a different address
166 //UiMessageBoxCritical("Memory allocation failed: out of memory.");
170 MmAllocatePagesInLookupTable(PageLookupTableAddress
, StartPageNumber
, PagesNeeded
, MemoryType
);
172 FreePagesInLookupTable
-= PagesNeeded
;
173 MemPointer
= (PVOID
)((ULONG_PTR
)StartPageNumber
* MM_PAGE_SIZE
);
176 DPRINTM(DPRINT_MEMORY
, "Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, StartPageNumber
);
177 DPRINTM(DPRINT_MEMORY
, "Memory allocation pointer: 0x%x\n", MemPointer
);
180 // Update LoaderPagesSpanned count
181 if ((((ULONG_PTR
)MemPointer
+ MemorySize
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
) > LoaderPagesSpanned
)
182 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
);
184 // Now return the pointer
188 VOID
MmSetMemoryType(PVOID MemoryAddress
, ULONG MemorySize
, TYPE_OF_MEMORY NewType
)
191 ULONG StartPageNumber
;
193 // Find out how many blocks it will take to
194 // satisfy this allocation
195 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
197 // Get the starting page number
198 StartPageNumber
= MmGetPageNumberFromAddress(MemoryAddress
);
200 // Set new type for these pages
201 MmAllocatePagesInLookupTable(PageLookupTableAddress
, StartPageNumber
, PagesNeeded
, NewType
);
204 PVOID
MmAllocateHighestMemoryBelowAddress(ULONG MemorySize
, PVOID DesiredAddress
, TYPE_OF_MEMORY MemoryType
)
207 ULONG FirstFreePageFromEnd
;
208 ULONG DesiredAddressPageNumber
;
213 DPRINTM(DPRINT_MEMORY
, "MmAllocateHighestMemoryBelowAddress() called for 0 bytes. Returning NULL.\n");
214 UiMessageBoxCritical("Memory allocation failed: MmAllocateHighestMemoryBelowAddress() called for 0 bytes.");
218 // Find out how many blocks it will take to
219 // satisfy this allocation
220 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
222 // Get the page number for their desired address
223 DesiredAddressPageNumber
= (ULONG_PTR
)DesiredAddress
/ MM_PAGE_SIZE
;
225 // If we don't have enough available mem
227 if (FreePagesInLookupTable
< PagesNeeded
)
229 DPRINTM(DPRINT_MEMORY
, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
230 UiMessageBoxCritical("Memory allocation failed: out of memory.");
234 FirstFreePageFromEnd
= MmFindAvailablePagesBeforePage(PageLookupTableAddress
, TotalPagesInLookupTable
, PagesNeeded
, DesiredAddressPageNumber
);
236 if (FirstFreePageFromEnd
== 0)
238 DPRINTM(DPRINT_MEMORY
, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
239 UiMessageBoxCritical("Memory allocation failed: out of memory.");
243 MmAllocatePagesInLookupTable(PageLookupTableAddress
, FirstFreePageFromEnd
, PagesNeeded
, MemoryType
);
245 FreePagesInLookupTable
-= PagesNeeded
;
246 MemPointer
= (PVOID
)((ULONG_PTR
)FirstFreePageFromEnd
* MM_PAGE_SIZE
);
249 DPRINTM(DPRINT_MEMORY
, "Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, FirstFreePageFromEnd
);
250 DPRINTM(DPRINT_MEMORY
, "Memory allocation pointer: 0x%x\n", MemPointer
);
253 // Update LoaderPagesSpanned count
254 if ((((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
) > LoaderPagesSpanned
)
255 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
);
257 // Now return the pointer
261 VOID
MmFreeMemory(PVOID MemoryPointer
)
267 VOID
DumpMemoryAllocMap(VOID
)
270 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable
= (PPAGE_LOOKUP_TABLE_ITEM
)PageLookupTableAddress
;
272 DPRINTM(DPRINT_MEMORY
, "----------- Memory Allocation Bitmap -----------\n");
274 for (Idx
=0; Idx
<TotalPagesInLookupTable
; Idx
++)
278 DPRINTM(DPRINT_MEMORY
, "\n");
279 DPRINTM(DPRINT_MEMORY
, "%08x:\t", (Idx
* MM_PAGE_SIZE
));
281 else if ((Idx
% 4) == 0)
283 DPRINTM(DPRINT_MEMORY
, " ");
286 switch (RealPageLookupTable
[Idx
].PageAllocated
)
289 DPRINTM(DPRINT_MEMORY
, "*");
292 DPRINTM(DPRINT_MEMORY
, "-");
294 case LoaderLoadedProgram
:
295 DPRINTM(DPRINT_MEMORY
, "O");
297 case LoaderFirmwareTemporary
:
298 DPRINTM(DPRINT_MEMORY
, "T");
300 case LoaderFirmwarePermanent
:
301 DPRINTM(DPRINT_MEMORY
, "P");
303 case LoaderOsloaderHeap
:
304 DPRINTM(DPRINT_MEMORY
, "H");
306 case LoaderOsloaderStack
:
307 DPRINTM(DPRINT_MEMORY
, "S");
309 case LoaderSystemCode
:
310 DPRINTM(DPRINT_MEMORY
, "K");
313 DPRINTM(DPRINT_MEMORY
, "L");
315 case LoaderBootDriver
:
316 DPRINTM(DPRINT_MEMORY
, "B");
318 case LoaderStartupPcrPage
:
319 DPRINTM(DPRINT_MEMORY
, "G");
321 case LoaderRegistryData
:
322 DPRINTM(DPRINT_MEMORY
, "R");
324 case LoaderMemoryData
:
325 DPRINTM(DPRINT_MEMORY
, "M");
328 DPRINTM(DPRINT_MEMORY
, "N");
330 case LoaderSpecialMemory
:
331 DPRINTM(DPRINT_MEMORY
, "C");
334 DPRINTM(DPRINT_MEMORY
, "?");
339 DPRINTM(DPRINT_MEMORY
, "\n");
343 PPAGE_LOOKUP_TABLE_ITEM
MmGetMemoryMap(ULONG
*NoEntries
)
345 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable
= (PPAGE_LOOKUP_TABLE_ITEM
)PageLookupTableAddress
;
347 *NoEntries
= TotalPagesInLookupTable
;
349 return RealPageLookupTable
;
352 #undef ExAllocatePoolWithTag
356 ExAllocatePoolWithTag(
357 IN POOL_TYPE PoolType
,
358 IN SIZE_T NumberOfBytes
,
361 return MmHeapAlloc(NumberOfBytes
);
374 #undef ExFreePoolWithTag
394 ptr
= MmHeapAlloc(Size
);
395 if (ptr
&& (Flags
& HEAP_ZERO_MEMORY
))
397 RtlZeroMemory(ptr
, Size
);
410 MmHeapFree(HeapBase
);