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 DbgPrint((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 DbgPrint((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 DbgPrint((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 DbgPrint((DPRINT_MEMORY
, "Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, FirstFreePageFromEnd
));
74 DbgPrint((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 DbgPrint((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 DbgPrint((DPRINT_MEMORY
, "Heap allocation for %d bytes failed\n", MemorySize
));
104 bstats(&CurAlloc
, &TotalFree
, &MaxFree
, &NumberOfGets
, &NumberOfRels
);
106 DbgPrint((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 DbgPrint((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 DbgPrint((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 DbgPrint((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 DbgPrint((DPRINT_MEMORY
, "Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, StartPageNumber
));
174 DbgPrint((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 PVOID
MmAllocateHighestMemoryBelowAddress(ULONG MemorySize
, PVOID DesiredAddress
, TYPE_OF_MEMORY MemoryType
)
188 ULONG FirstFreePageFromEnd
;
189 ULONG DesiredAddressPageNumber
;
194 DbgPrint((DPRINT_MEMORY
, "MmAllocateHighestMemoryBelowAddress() called for 0 bytes. Returning NULL.\n"));
195 UiMessageBoxCritical("Memory allocation failed: MmAllocateHighestMemoryBelowAddress() called for 0 bytes.");
199 // Find out how many blocks it will take to
200 // satisfy this allocation
201 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
203 // Get the page number for their desired address
204 DesiredAddressPageNumber
= (ULONG_PTR
)DesiredAddress
/ MM_PAGE_SIZE
;
206 // If we don't have enough available mem
208 if (FreePagesInLookupTable
< PagesNeeded
)
210 DbgPrint((DPRINT_MEMORY
, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize
));
211 UiMessageBoxCritical("Memory allocation failed: out of memory.");
215 FirstFreePageFromEnd
= MmFindAvailablePagesBeforePage(PageLookupTableAddress
, TotalPagesInLookupTable
, PagesNeeded
, DesiredAddressPageNumber
);
217 if (FirstFreePageFromEnd
== 0)
219 DbgPrint((DPRINT_MEMORY
, "Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize
));
220 UiMessageBoxCritical("Memory allocation failed: out of memory.");
224 MmAllocatePagesInLookupTable(PageLookupTableAddress
, FirstFreePageFromEnd
, PagesNeeded
, MemoryType
);
226 FreePagesInLookupTable
-= PagesNeeded
;
227 MemPointer
= (PVOID
)((ULONG_PTR
)FirstFreePageFromEnd
* MM_PAGE_SIZE
);
230 DbgPrint((DPRINT_MEMORY
, "Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, FirstFreePageFromEnd
));
231 DbgPrint((DPRINT_MEMORY
, "Memory allocation pointer: 0x%x\n", MemPointer
));
234 // Update LoaderPagesSpanned count
235 if ((((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
) > LoaderPagesSpanned
)
236 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
);
238 // Now return the pointer
242 VOID
MmFreeMemory(PVOID MemoryPointer
)
248 VOID
DumpMemoryAllocMap(VOID
)
251 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable
= (PPAGE_LOOKUP_TABLE_ITEM
)PageLookupTableAddress
;
253 DbgPrint((DPRINT_MEMORY
, "----------- Memory Allocation Bitmap -----------\n"));
255 for (Idx
=0; Idx
<TotalPagesInLookupTable
; Idx
++)
259 DbgPrint((DPRINT_MEMORY
, "\n"));
260 DbgPrint((DPRINT_MEMORY
, "%08x:\t", (Idx
* MM_PAGE_SIZE
)));
262 else if ((Idx
% 4) == 0)
264 DbgPrint((DPRINT_MEMORY
, " "));
267 switch (RealPageLookupTable
[Idx
].PageAllocated
)
270 DbgPrint((DPRINT_MEMORY
, "*"));
273 DbgPrint((DPRINT_MEMORY
, "-"));
275 case LoaderLoadedProgram
:
276 DbgPrint((DPRINT_MEMORY
, "O"));
278 case LoaderFirmwareTemporary
:
279 DbgPrint((DPRINT_MEMORY
, "T"));
281 case LoaderFirmwarePermanent
:
282 DbgPrint((DPRINT_MEMORY
, "P"));
284 case LoaderOsloaderHeap
:
285 DbgPrint((DPRINT_MEMORY
, "H"));
287 case LoaderOsloaderStack
:
288 DbgPrint((DPRINT_MEMORY
, "S"));
290 case LoaderSystemCode
:
291 DbgPrint((DPRINT_MEMORY
, "K"));
294 DbgPrint((DPRINT_MEMORY
, "L"));
296 case LoaderBootDriver
:
297 DbgPrint((DPRINT_MEMORY
, "B"));
299 case LoaderStartupPcrPage
:
300 DbgPrint((DPRINT_MEMORY
, "G"));
302 case LoaderRegistryData
:
303 DbgPrint((DPRINT_MEMORY
, "R"));
305 case LoaderMemoryData
:
306 DbgPrint((DPRINT_MEMORY
, "M"));
309 DbgPrint((DPRINT_MEMORY
, "N"));
311 case LoaderSpecialMemory
:
312 DbgPrint((DPRINT_MEMORY
, "C"));
315 DbgPrint((DPRINT_MEMORY
, "?"));
320 DbgPrint((DPRINT_MEMORY
, "\n"));
324 ULONG
GetSystemMemorySize(VOID
)
326 return (TotalPagesInLookupTable
* MM_PAGE_SIZE
);
329 PPAGE_LOOKUP_TABLE_ITEM
MmGetMemoryMap(ULONG
*NoEntries
)
331 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable
= (PPAGE_LOOKUP_TABLE_ITEM
)PageLookupTableAddress
;
333 *NoEntries
= TotalPagesInLookupTable
;
335 return RealPageLookupTable
;