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
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 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_SHIFT
) > LoaderPagesSpanned
)
79 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
);
81 // Now return the pointer
85 PVOID
MmHeapAlloc(ULONG MemorySize
)
88 LONG CurAlloc
, TotalFree
, MaxFree
, NumberOfGets
, NumberOfRels
;
90 if (MemorySize
> MM_PAGE_SIZE
)
92 DPRINTM(DPRINT_MEMORY
, "Consider using other functions to allocate %d bytes of memory!\n", MemorySize
);
95 // Get the buffer from BGET pool
96 Result
= bget(MemorySize
);
100 DPRINTM(DPRINT_MEMORY
, "Heap allocation for %d bytes failed\n", MemorySize
);
104 bstats(&CurAlloc
, &TotalFree
, &MaxFree
, &NumberOfGets
, &NumberOfRels
);
106 DPRINTM(DPRINT_MEMORY
, "Current alloced %d bytes, free %d bytes, allocs %d, frees %d\n",
107 CurAlloc
, TotalFree
, NumberOfGets
, NumberOfRels
);
112 VOID
MmHeapFree(PVOID MemoryPointer
)
114 // Release the buffer to the pool
118 PVOID
MmAllocateMemory(ULONG MemorySize
)
120 // Temporary forwarder...
121 return MmAllocateMemoryWithType(MemorySize
, LoaderOsloaderHeap
);
124 PVOID
MmAllocateMemoryAtAddress(ULONG MemorySize
, PVOID DesiredAddress
, TYPE_OF_MEMORY MemoryType
)
127 ULONG StartPageNumber
;
132 DPRINTM(DPRINT_MEMORY
, "MmAllocateMemoryAtAddress() called for 0 bytes. Returning NULL.\n");
133 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemoryAtAddress() called for 0 bytes.");
137 // Find out how many blocks it will take to
138 // satisfy this allocation
139 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
141 // Get the starting page number
142 StartPageNumber
= MmGetPageNumberFromAddress(DesiredAddress
);
144 // If we don't have enough available mem
146 if (FreePagesInLookupTable
< PagesNeeded
)
148 DPRINTM(DPRINT_MEMORY
, "Memory allocation failed in MmAllocateMemoryAtAddress(). "
149 "Not enough free memory to allocate %d bytes (requesting %d pages but have only %d). "
150 "\n", MemorySize
, PagesNeeded
, FreePagesInLookupTable
);
151 UiMessageBoxCritical("Memory allocation failed: out of memory.");
155 if (MmAreMemoryPagesAvailable(PageLookupTableAddress
, TotalPagesInLookupTable
, DesiredAddress
, PagesNeeded
) == FALSE
)
157 DPRINTM(DPRINT_MEMORY
, "Memory allocation failed in MmAllocateMemoryAtAddress(). "
158 "Not enough free memory to allocate %d bytes at address %p.\n",
159 MemorySize
, DesiredAddress
);
161 // Don't tell this to user since caller should try to alloc this memory
162 // at a different address
163 //UiMessageBoxCritical("Memory allocation failed: out of memory.");
167 MmAllocatePagesInLookupTable(PageLookupTableAddress
, StartPageNumber
, PagesNeeded
, MemoryType
);
169 FreePagesInLookupTable
-= PagesNeeded
;
170 MemPointer
= (PVOID
)((ULONG_PTR
)StartPageNumber
* MM_PAGE_SIZE
);
173 DPRINTM(DPRINT_MEMORY
, "Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, StartPageNumber
);
174 DPRINTM(DPRINT_MEMORY
, "Memory allocation pointer: 0x%x\n", MemPointer
);
177 // Update LoaderPagesSpanned count
178 if ((((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
) > LoaderPagesSpanned
)
179 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
);
181 // Now return the pointer
185 VOID
MmSetMemoryType(PVOID MemoryAddress
, ULONG MemorySize
, TYPE_OF_MEMORY NewType
)
188 ULONG StartPageNumber
;
190 // Find out how many blocks it will take to
191 // satisfy this allocation
192 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
194 // Get the starting page number
195 StartPageNumber
= MmGetPageNumberFromAddress(MemoryAddress
);
197 // Set new type for these pages
198 MmAllocatePagesInLookupTable(PageLookupTableAddress
, StartPageNumber
, PagesNeeded
, NewType
);
201 PVOID
MmAllocateHighestMemoryBelowAddress(ULONG MemorySize
, PVOID DesiredAddress
, TYPE_OF_MEMORY MemoryType
)
204 ULONG FirstFreePageFromEnd
;
205 ULONG DesiredAddressPageNumber
;
210 DPRINTM(DPRINT_MEMORY
, "MmAllocateHighestMemoryBelowAddress() called for 0 bytes. Returning NULL.\n");
211 UiMessageBoxCritical("Memory allocation failed: MmAllocateHighestMemoryBelowAddress() called for 0 bytes.");
215 // Find out how many blocks it will take to
216 // satisfy this allocation
217 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
219 // Get the page number for their desired address
220 DesiredAddressPageNumber
= (ULONG_PTR
)DesiredAddress
/ MM_PAGE_SIZE
;
222 // If we don't have enough available mem
224 if (FreePagesInLookupTable
< PagesNeeded
)
226 DPRINTM(DPRINT_MEMORY
, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
227 UiMessageBoxCritical("Memory allocation failed: out of memory.");
231 FirstFreePageFromEnd
= MmFindAvailablePagesBeforePage(PageLookupTableAddress
, TotalPagesInLookupTable
, PagesNeeded
, DesiredAddressPageNumber
);
233 if (FirstFreePageFromEnd
== 0)
235 DPRINTM(DPRINT_MEMORY
, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
236 UiMessageBoxCritical("Memory allocation failed: out of memory.");
240 MmAllocatePagesInLookupTable(PageLookupTableAddress
, FirstFreePageFromEnd
, PagesNeeded
, MemoryType
);
242 FreePagesInLookupTable
-= PagesNeeded
;
243 MemPointer
= (PVOID
)((ULONG_PTR
)FirstFreePageFromEnd
* MM_PAGE_SIZE
);
246 DPRINTM(DPRINT_MEMORY
, "Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, FirstFreePageFromEnd
);
247 DPRINTM(DPRINT_MEMORY
, "Memory allocation pointer: 0x%x\n", MemPointer
);
250 // Update LoaderPagesSpanned count
251 if ((((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
) > LoaderPagesSpanned
)
252 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
);
254 // Now return the pointer
258 VOID
MmFreeMemory(PVOID MemoryPointer
)
264 VOID
DumpMemoryAllocMap(VOID
)
267 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable
= (PPAGE_LOOKUP_TABLE_ITEM
)PageLookupTableAddress
;
269 DPRINTM(DPRINT_MEMORY
, "----------- Memory Allocation Bitmap -----------\n");
271 for (Idx
=0; Idx
<TotalPagesInLookupTable
; Idx
++)
275 DPRINTM(DPRINT_MEMORY
, "\n");
276 DPRINTM(DPRINT_MEMORY
, "%08x:\t", (Idx
* MM_PAGE_SIZE
));
278 else if ((Idx
% 4) == 0)
280 DPRINTM(DPRINT_MEMORY
, " ");
283 switch (RealPageLookupTable
[Idx
].PageAllocated
)
286 DPRINTM(DPRINT_MEMORY
, "*");
289 DPRINTM(DPRINT_MEMORY
, "-");
291 case LoaderLoadedProgram
:
292 DPRINTM(DPRINT_MEMORY
, "O");
294 case LoaderFirmwareTemporary
:
295 DPRINTM(DPRINT_MEMORY
, "T");
297 case LoaderFirmwarePermanent
:
298 DPRINTM(DPRINT_MEMORY
, "P");
300 case LoaderOsloaderHeap
:
301 DPRINTM(DPRINT_MEMORY
, "H");
303 case LoaderOsloaderStack
:
304 DPRINTM(DPRINT_MEMORY
, "S");
306 case LoaderSystemCode
:
307 DPRINTM(DPRINT_MEMORY
, "K");
310 DPRINTM(DPRINT_MEMORY
, "L");
312 case LoaderBootDriver
:
313 DPRINTM(DPRINT_MEMORY
, "B");
315 case LoaderStartupPcrPage
:
316 DPRINTM(DPRINT_MEMORY
, "G");
318 case LoaderRegistryData
:
319 DPRINTM(DPRINT_MEMORY
, "R");
321 case LoaderMemoryData
:
322 DPRINTM(DPRINT_MEMORY
, "M");
325 DPRINTM(DPRINT_MEMORY
, "N");
327 case LoaderSpecialMemory
:
328 DPRINTM(DPRINT_MEMORY
, "C");
331 DPRINTM(DPRINT_MEMORY
, "?");
336 DPRINTM(DPRINT_MEMORY
, "\n");
340 ULONG
GetSystemMemorySize(VOID
)
342 return (TotalPagesInLookupTable
* MM_PAGE_SIZE
);
345 PPAGE_LOOKUP_TABLE_ITEM
MmGetMemoryMap(ULONG
*NoEntries
)
347 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable
= (PPAGE_LOOKUP_TABLE_ITEM
)PageLookupTableAddress
;
349 *NoEntries
= TotalPagesInLookupTable
;
351 return RealPageLookupTable
;