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 DBG_DEFAULT_CHANNEL(MEMORY
);
30 PFN_NUMBER LoaderPagesSpanned
= 0;
32 PVOID
MmAllocateMemoryWithType(SIZE_T MemorySize
, TYPE_OF_MEMORY MemoryType
)
34 PFN_NUMBER PagesNeeded
;
35 PFN_NUMBER FirstFreePageFromEnd
;
40 WARN("MmAllocateMemory() called for 0 bytes. Returning NULL.\n");
41 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemory() called for 0 bytes.");
45 MemorySize
= ROUND_UP(MemorySize
, 4);
47 // Find out how many blocks it will take to
48 // satisfy this allocation
49 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
51 // If we don't have enough available mem
53 if (FreePagesInLookupTable
< PagesNeeded
)
55 ERR("Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
56 UiMessageBoxCritical("Memory allocation failed: out of memory.");
60 FirstFreePageFromEnd
= MmFindAvailablePages(PageLookupTableAddress
, TotalPagesInLookupTable
, PagesNeeded
, FALSE
);
62 if (FirstFreePageFromEnd
== 0)
64 ERR("Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
65 UiMessageBoxCritical("Memory allocation failed: out of memory.");
69 MmAllocatePagesInLookupTable(PageLookupTableAddress
, FirstFreePageFromEnd
, PagesNeeded
, MemoryType
);
71 FreePagesInLookupTable
-= PagesNeeded
;
72 MemPointer
= (PVOID
)((ULONG_PTR
)FirstFreePageFromEnd
* MM_PAGE_SIZE
);
74 TRACE("Allocated %d bytes (%d pages) of memory (type %ld) starting at page 0x%lx.\n",
75 MemorySize
, PagesNeeded
, MemoryType
, FirstFreePageFromEnd
);
76 TRACE("Memory allocation pointer: 0x%x\n", MemPointer
);
78 // Update LoaderPagesSpanned count
79 if ((((ULONG_PTR
)MemPointer
+ MemorySize
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
) > LoaderPagesSpanned
)
80 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
);
82 // Now return the pointer
86 PVOID
MmAllocateMemoryAtAddress(SIZE_T MemorySize
, PVOID DesiredAddress
, TYPE_OF_MEMORY MemoryType
)
88 PFN_NUMBER PagesNeeded
;
89 PFN_NUMBER StartPageNumber
;
94 WARN("MmAllocateMemoryAtAddress() called for 0 bytes. Returning NULL.\n");
95 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemoryAtAddress() called for 0 bytes.");
99 // Find out how many blocks it will take to
100 // satisfy this allocation
101 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
103 // Get the starting page number
104 StartPageNumber
= MmGetPageNumberFromAddress(DesiredAddress
);
106 // If we don't have enough available mem
108 if (FreePagesInLookupTable
< PagesNeeded
)
110 ERR("Memory allocation failed in MmAllocateMemoryAtAddress(). "
111 "Not enough free memory to allocate %d bytes (requesting %d pages but have only %d). "
112 "\n", MemorySize
, PagesNeeded
, FreePagesInLookupTable
);
113 UiMessageBoxCritical("Memory allocation failed: out of memory.");
117 if (MmAreMemoryPagesAvailable(PageLookupTableAddress
, TotalPagesInLookupTable
, DesiredAddress
, PagesNeeded
) == FALSE
)
119 WARN("Memory allocation failed in MmAllocateMemoryAtAddress(). "
120 "Not enough free memory to allocate %d bytes at address %p.\n",
121 MemorySize
, DesiredAddress
);
123 // Don't tell this to user since caller should try to alloc this memory
124 // at a different address
125 //UiMessageBoxCritical("Memory allocation failed: out of memory.");
129 MmAllocatePagesInLookupTable(PageLookupTableAddress
, StartPageNumber
, PagesNeeded
, MemoryType
);
131 FreePagesInLookupTable
-= PagesNeeded
;
132 MemPointer
= (PVOID
)((ULONG_PTR
)StartPageNumber
* MM_PAGE_SIZE
);
134 TRACE("Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, StartPageNumber
);
135 TRACE("Memory allocation pointer: 0x%x\n", MemPointer
);
137 // Update LoaderPagesSpanned count
138 if ((((ULONG_PTR
)MemPointer
+ MemorySize
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
) > LoaderPagesSpanned
)
139 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
);
141 // Now return the pointer
145 VOID
MmSetMemoryType(PVOID MemoryAddress
, SIZE_T MemorySize
, TYPE_OF_MEMORY NewType
)
147 PFN_NUMBER PagesNeeded
;
148 PFN_NUMBER StartPageNumber
;
150 // Find out how many blocks it will take to
151 // satisfy this allocation
152 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
154 // Get the starting page number
155 StartPageNumber
= MmGetPageNumberFromAddress(MemoryAddress
);
157 // Set new type for these pages
158 MmAllocatePagesInLookupTable(PageLookupTableAddress
, StartPageNumber
, PagesNeeded
, NewType
);
161 PVOID
MmAllocateHighestMemoryBelowAddress(SIZE_T MemorySize
, PVOID DesiredAddress
, TYPE_OF_MEMORY MemoryType
)
163 PFN_NUMBER PagesNeeded
;
164 PFN_NUMBER FirstFreePageFromEnd
;
165 PFN_NUMBER DesiredAddressPageNumber
;
170 WARN("MmAllocateHighestMemoryBelowAddress() called for 0 bytes. Returning NULL.\n");
171 UiMessageBoxCritical("Memory allocation failed: MmAllocateHighestMemoryBelowAddress() called for 0 bytes.");
175 // Find out how many blocks it will take to
176 // satisfy this allocation
177 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
179 // Get the page number for their desired address
180 DesiredAddressPageNumber
= (ULONG_PTR
)DesiredAddress
/ MM_PAGE_SIZE
;
182 // If we don't have enough available mem
184 if (FreePagesInLookupTable
< PagesNeeded
)
186 ERR("Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
187 UiMessageBoxCritical("Memory allocation failed: out of memory.");
191 FirstFreePageFromEnd
= MmFindAvailablePagesBeforePage(PageLookupTableAddress
, TotalPagesInLookupTable
, PagesNeeded
, DesiredAddressPageNumber
);
193 if (FirstFreePageFromEnd
== 0)
195 ERR("Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
196 UiMessageBoxCritical("Memory allocation failed: out of memory.");
200 MmAllocatePagesInLookupTable(PageLookupTableAddress
, FirstFreePageFromEnd
, PagesNeeded
, MemoryType
);
202 FreePagesInLookupTable
-= PagesNeeded
;
203 MemPointer
= (PVOID
)((ULONG_PTR
)FirstFreePageFromEnd
* MM_PAGE_SIZE
);
205 TRACE("Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, FirstFreePageFromEnd
);
206 TRACE("Memory allocation pointer: 0x%x\n", MemPointer
);
208 // Update LoaderPagesSpanned count
209 if ((((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
) > LoaderPagesSpanned
)
210 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
);
212 // Now return the pointer
216 VOID
MmFreeMemory(PVOID MemoryPointer
)
222 VOID
DumpMemoryAllocMap(VOID
)
225 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable
= (PPAGE_LOOKUP_TABLE_ITEM
)PageLookupTableAddress
;
227 DbgPrint("----------- Memory Allocation Bitmap -----------\n");
229 for (Idx
=0; Idx
<TotalPagesInLookupTable
; Idx
++)
234 DbgPrint("%08x:\t", (Idx
* MM_PAGE_SIZE
));
236 else if ((Idx
% 4) == 0)
241 switch (RealPageLookupTable
[Idx
].PageAllocated
)
249 case LoaderLoadedProgram
:
252 case LoaderFirmwareTemporary
:
255 case LoaderFirmwarePermanent
:
258 case LoaderOsloaderHeap
:
261 case LoaderOsloaderStack
:
264 case LoaderSystemCode
:
270 case LoaderBootDriver
:
273 case LoaderStartupPcrPage
:
276 case LoaderRegistryData
:
279 case LoaderMemoryData
:
285 case LoaderSpecialMemory
:
298 PPAGE_LOOKUP_TABLE_ITEM
MmGetMemoryMap(PFN_NUMBER
*NoEntries
)
300 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable
= (PPAGE_LOOKUP_TABLE_ITEM
)PageLookupTableAddress
;
302 *NoEntries
= TotalPagesInLookupTable
;
304 return RealPageLookupTable
;