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
);
27 DBG_DEFAULT_CHANNEL(MEMORY
);
29 PFN_NUMBER LoaderPagesSpanned
= 0;
31 PVOID
MmAllocateMemoryWithType(SIZE_T MemorySize
, TYPE_OF_MEMORY MemoryType
)
33 PFN_NUMBER PagesNeeded
;
34 PFN_NUMBER FirstFreePageFromEnd
;
39 WARN("MmAllocateMemory() called for 0 bytes. Returning NULL.\n");
40 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemory() called for 0 bytes.");
44 MemorySize
= ROUND_UP(MemorySize
, 4);
46 // Find out how many blocks it will take to
47 // satisfy this allocation
48 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
50 // If we don't have enough available mem
52 if (FreePagesInLookupTable
< PagesNeeded
)
54 ERR("Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
55 UiMessageBoxCritical("Memory allocation failed: out of memory.");
59 FirstFreePageFromEnd
= MmFindAvailablePages(PageLookupTableAddress
, TotalPagesInLookupTable
, PagesNeeded
, FALSE
);
61 if (FirstFreePageFromEnd
== 0)
63 ERR("Memory allocation failed in MmAllocateMemory(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
64 UiMessageBoxCritical("Memory allocation failed: out of memory.");
68 MmAllocatePagesInLookupTable(PageLookupTableAddress
, FirstFreePageFromEnd
, PagesNeeded
, MemoryType
);
70 FreePagesInLookupTable
-= PagesNeeded
;
71 MemPointer
= (PVOID
)((ULONG_PTR
)FirstFreePageFromEnd
* MM_PAGE_SIZE
);
73 TRACE("Allocated %d bytes (%d pages) of memory (type %ld) starting at page 0x%lx.\n",
74 MemorySize
, PagesNeeded
, MemoryType
, FirstFreePageFromEnd
);
75 TRACE("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
MmAllocateMemoryAtAddress(SIZE_T MemorySize
, PVOID DesiredAddress
, TYPE_OF_MEMORY MemoryType
)
87 PFN_NUMBER PagesNeeded
;
88 PFN_NUMBER StartPageNumber
;
93 WARN("MmAllocateMemoryAtAddress() called for 0 bytes. Returning NULL.\n");
94 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemoryAtAddress() called for 0 bytes.");
98 // Find out how many blocks it will take to
99 // satisfy this allocation
100 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
102 // Get the starting page number
103 StartPageNumber
= MmGetPageNumberFromAddress(DesiredAddress
);
105 // If we don't have enough available mem
107 if (FreePagesInLookupTable
< PagesNeeded
)
109 ERR("Memory allocation failed in MmAllocateMemoryAtAddress(). "
110 "Not enough free memory to allocate %d bytes (requesting %d pages but have only %d). "
111 "\n", MemorySize
, PagesNeeded
, FreePagesInLookupTable
);
112 UiMessageBoxCritical("Memory allocation failed: out of memory.");
116 if (MmAreMemoryPagesAvailable(PageLookupTableAddress
, TotalPagesInLookupTable
, DesiredAddress
, PagesNeeded
) == FALSE
)
118 WARN("Memory allocation failed in MmAllocateMemoryAtAddress(). "
119 "Not enough free memory to allocate %d bytes at address %p.\n",
120 MemorySize
, DesiredAddress
);
122 // Don't tell this to user since caller should try to alloc this memory
123 // at a different address
124 //UiMessageBoxCritical("Memory allocation failed: out of memory.");
128 MmAllocatePagesInLookupTable(PageLookupTableAddress
, StartPageNumber
, PagesNeeded
, MemoryType
);
130 FreePagesInLookupTable
-= PagesNeeded
;
131 MemPointer
= (PVOID
)((ULONG_PTR
)StartPageNumber
* MM_PAGE_SIZE
);
133 TRACE("Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, StartPageNumber
);
134 TRACE("Memory allocation pointer: 0x%x\n", MemPointer
);
136 // Update LoaderPagesSpanned count
137 if ((((ULONG_PTR
)MemPointer
+ MemorySize
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
) > LoaderPagesSpanned
)
138 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
+ PAGE_SIZE
- 1) >> PAGE_SHIFT
);
140 // Now return the pointer
144 VOID
MmSetMemoryType(PVOID MemoryAddress
, SIZE_T MemorySize
, TYPE_OF_MEMORY NewType
)
146 PFN_NUMBER PagesNeeded
;
147 PFN_NUMBER StartPageNumber
;
149 // Find out how many blocks it will take to
150 // satisfy this allocation
151 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
153 // Get the starting page number
154 StartPageNumber
= MmGetPageNumberFromAddress(MemoryAddress
);
156 // Set new type for these pages
157 MmAllocatePagesInLookupTable(PageLookupTableAddress
, StartPageNumber
, PagesNeeded
, NewType
);
160 PVOID
MmAllocateHighestMemoryBelowAddress(SIZE_T MemorySize
, PVOID DesiredAddress
, TYPE_OF_MEMORY MemoryType
)
162 PFN_NUMBER PagesNeeded
;
163 PFN_NUMBER FirstFreePageFromEnd
;
164 PFN_NUMBER DesiredAddressPageNumber
;
169 WARN("MmAllocateHighestMemoryBelowAddress() called for 0 bytes. Returning NULL.\n");
170 UiMessageBoxCritical("Memory allocation failed: MmAllocateHighestMemoryBelowAddress() called for 0 bytes.");
174 // Find out how many blocks it will take to
175 // satisfy this allocation
176 PagesNeeded
= ROUND_UP(MemorySize
, MM_PAGE_SIZE
) / MM_PAGE_SIZE
;
178 // Get the page number for their desired address
179 DesiredAddressPageNumber
= (ULONG_PTR
)DesiredAddress
/ MM_PAGE_SIZE
;
181 // If we don't have enough available mem
183 if (FreePagesInLookupTable
< PagesNeeded
)
185 ERR("Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
186 UiMessageBoxCritical("Memory allocation failed: out of memory.");
190 FirstFreePageFromEnd
= MmFindAvailablePagesBeforePage(PageLookupTableAddress
, TotalPagesInLookupTable
, PagesNeeded
, DesiredAddressPageNumber
);
192 if (FirstFreePageFromEnd
== 0)
194 ERR("Memory allocation failed in MmAllocateHighestMemoryBelowAddress(). Not enough free memory to allocate %d bytes.\n", MemorySize
);
195 UiMessageBoxCritical("Memory allocation failed: out of memory.");
199 MmAllocatePagesInLookupTable(PageLookupTableAddress
, FirstFreePageFromEnd
, PagesNeeded
, MemoryType
);
201 FreePagesInLookupTable
-= PagesNeeded
;
202 MemPointer
= (PVOID
)((ULONG_PTR
)FirstFreePageFromEnd
* MM_PAGE_SIZE
);
204 TRACE("Allocated %d bytes (%d pages) of memory starting at page %d.\n", MemorySize
, PagesNeeded
, FirstFreePageFromEnd
);
205 TRACE("Memory allocation pointer: 0x%x\n", MemPointer
);
207 // Update LoaderPagesSpanned count
208 if ((((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
) > LoaderPagesSpanned
)
209 LoaderPagesSpanned
= (((ULONG_PTR
)MemPointer
+ MemorySize
) >> PAGE_SHIFT
);
211 // Now return the pointer
215 VOID
MmFreeMemory(PVOID MemoryPointer
)
221 VOID
DumpMemoryAllocMap(VOID
)
224 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable
= (PPAGE_LOOKUP_TABLE_ITEM
)PageLookupTableAddress
;
226 DbgPrint("----------- Memory Allocation Bitmap -----------\n");
228 for (Idx
=0; Idx
<TotalPagesInLookupTable
; Idx
++)
233 DbgPrint("%08x:\t", (Idx
* MM_PAGE_SIZE
));
235 else if ((Idx
% 4) == 0)
240 switch (RealPageLookupTable
[Idx
].PageAllocated
)
248 case LoaderLoadedProgram
:
251 case LoaderFirmwareTemporary
:
254 case LoaderFirmwarePermanent
:
257 case LoaderOsloaderHeap
:
260 case LoaderOsloaderStack
:
263 case LoaderSystemCode
:
269 case LoaderBootDriver
:
272 case LoaderStartupPcrPage
:
275 case LoaderRegistryData
:
278 case LoaderMemoryData
:
284 case LoaderSpecialMemory
:
297 PPAGE_LOOKUP_TABLE_ITEM
MmGetMemoryMap(PFN_NUMBER
*NoEntries
)
299 PPAGE_LOOKUP_TABLE_ITEM RealPageLookupTable
= (PPAGE_LOOKUP_TABLE_ITEM
)PageLookupTableAddress
;
301 *NoEntries
= TotalPagesInLookupTable
;
303 return RealPageLookupTable
;