ReactOS 0.4.15-dev-5666-gc548b97
mm.c
Go to the documentation of this file.
1/*
2 * FreeLoader
3 * Copyright (C) 2006-2008 Aleksey Bragin <aleksey@reactos.org>
4 *
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.
9 *
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.
14 *
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.
18 */
19
20#include <freeldr.h>
21#include <debug.h>
22
23#if DBG
25#endif // DBG
26
28
30
32{
33 PFN_NUMBER PagesNeeded;
34 PFN_NUMBER FirstFreePageFromEnd;
35 PVOID MemPointer;
36
37 if (MemorySize == 0)
38 {
39 WARN("MmAllocateMemory() called for 0 bytes. Returning NULL.\n");
40 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemory() called for 0 bytes.");
41 return NULL;
42 }
43
45
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;
49
50 // If we don't have enough available mem
51 // then return NULL
52 if (FreePagesInLookupTable < PagesNeeded)
53 {
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.");
56 return NULL;
57 }
58
59 FirstFreePageFromEnd = MmFindAvailablePages(PageLookupTableAddress, TotalPagesInLookupTable, PagesNeeded, FALSE);
60
61 if (FirstFreePageFromEnd == 0)
62 {
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.");
65 return NULL;
66 }
67
68 MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType);
69
70 FreePagesInLookupTable -= PagesNeeded;
71 MemPointer = (PVOID)((ULONG_PTR)FirstFreePageFromEnd * MM_PAGE_SIZE);
72
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);
76
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);
80
81 // Now return the pointer
82 return MemPointer;
83}
84
86{
87 PFN_NUMBER PagesNeeded;
88 PFN_NUMBER StartPageNumber;
89 PVOID MemPointer;
90
91 if (MemorySize == 0)
92 {
93 WARN("MmAllocateMemoryAtAddress() called for 0 bytes. Returning NULL.\n");
94 UiMessageBoxCritical("Memory allocation failed: MmAllocateMemoryAtAddress() called for 0 bytes.");
95 return NULL;
96 }
97
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;
101
102 // Get the starting page number
103 StartPageNumber = MmGetPageNumberFromAddress(DesiredAddress);
104
105 // If we don't have enough available mem
106 // then return NULL
107 if (FreePagesInLookupTable < PagesNeeded)
108 {
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.");
113 return NULL;
114 }
115
117 {
118 WARN("Memory allocation failed in MmAllocateMemoryAtAddress(). "
119 "Not enough free memory to allocate %d bytes at address %p.\n",
120 MemorySize, DesiredAddress);
121
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.");
125 return NULL;
126 }
127
128 MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded, MemoryType);
129
130 FreePagesInLookupTable -= PagesNeeded;
131 MemPointer = (PVOID)((ULONG_PTR)StartPageNumber * MM_PAGE_SIZE);
132
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);
135
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);
139
140 // Now return the pointer
141 return MemPointer;
142}
143
145{
146 PFN_NUMBER PagesNeeded;
147 PFN_NUMBER StartPageNumber;
148
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;
152
153 // Get the starting page number
154 StartPageNumber = MmGetPageNumberFromAddress(MemoryAddress);
155
156 // Set new type for these pages
157 MmAllocatePagesInLookupTable(PageLookupTableAddress, StartPageNumber, PagesNeeded, NewType);
158}
159
161{
162 PFN_NUMBER PagesNeeded;
163 PFN_NUMBER FirstFreePageFromEnd;
164 PFN_NUMBER DesiredAddressPageNumber;
165 PVOID MemPointer;
166
167 if (MemorySize == 0)
168 {
169 WARN("MmAllocateHighestMemoryBelowAddress() called for 0 bytes. Returning NULL.\n");
170 UiMessageBoxCritical("Memory allocation failed: MmAllocateHighestMemoryBelowAddress() called for 0 bytes.");
171 return NULL;
172 }
173
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;
177
178 // Get the page number for their desired address
179 DesiredAddressPageNumber = (ULONG_PTR)DesiredAddress / MM_PAGE_SIZE;
180
181 // If we don't have enough available mem
182 // then return NULL
183 if (FreePagesInLookupTable < PagesNeeded)
184 {
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.");
187 return NULL;
188 }
189
190 FirstFreePageFromEnd = MmFindAvailablePagesBeforePage(PageLookupTableAddress, TotalPagesInLookupTable, PagesNeeded, DesiredAddressPageNumber);
191
192 if (FirstFreePageFromEnd == 0)
193 {
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.");
196 return NULL;
197 }
198
199 MmAllocatePagesInLookupTable(PageLookupTableAddress, FirstFreePageFromEnd, PagesNeeded, MemoryType);
200
201 FreePagesInLookupTable -= PagesNeeded;
202 MemPointer = (PVOID)((ULONG_PTR)FirstFreePageFromEnd * MM_PAGE_SIZE);
203
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);
206
207 // Update LoaderPagesSpanned count
208 if ((((ULONG_PTR)MemPointer + MemorySize) >> PAGE_SHIFT) > LoaderPagesSpanned)
209 LoaderPagesSpanned = (((ULONG_PTR)MemPointer + MemorySize) >> PAGE_SHIFT);
210
211 // Now return the pointer
212 return MemPointer;
213}
214
215VOID MmFreeMemory(PVOID MemoryPointer)
216{
217}
218
219#if DBG
220
222{
223 PFN_NUMBER Idx;
225
226 DbgPrint("----------- Memory Allocation Bitmap -----------\n");
227
228 for (Idx=0; Idx<TotalPagesInLookupTable; Idx++)
229 {
230 if ((Idx % 32) == 0)
231 {
232 DbgPrint("\n");
233 DbgPrint("%08x:\t", (Idx * MM_PAGE_SIZE));
234 }
235 else if ((Idx % 4) == 0)
236 {
237 DbgPrint(" ");
238 }
239
240 switch (RealPageLookupTable[Idx].PageAllocated)
241 {
242 case LoaderFree:
243 DbgPrint("*");
244 break;
245 case LoaderBad:
246 DbgPrint("-");
247 break;
249 DbgPrint("O");
250 break;
252 DbgPrint("T");
253 break;
255 DbgPrint("P");
256 break;
258 DbgPrint("H");
259 break;
261 DbgPrint("S");
262 break;
263 case LoaderSystemCode:
264 DbgPrint("K");
265 break;
266 case LoaderHalCode:
267 DbgPrint("L");
268 break;
269 case LoaderBootDriver:
270 DbgPrint("B");
271 break;
273 DbgPrint("G");
274 break;
276 DbgPrint("R");
277 break;
278 case LoaderMemoryData:
279 DbgPrint("M");
280 break;
281 case LoaderNlsData:
282 DbgPrint("N");
283 break;
285 DbgPrint("C");
286 break;
287 default:
288 DbgPrint("?");
289 break;
290 }
291 }
292
293 DbgPrint("\n");
294}
295#endif // DBG
296
298{
300
301 *NoEntries = TotalPagesInLookupTable;
302
303 return RealPageLookupTable;
304}
305
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
#define DBG_DEFAULT_CHANNEL(ch)
Definition: debug.h:103
PVOID PageLookupTableAddress
Definition: meminit.c:26
struct PAGE_LOOKUP_TABLE_ITEM * PPAGE_LOOKUP_TABLE_ITEM
PFN_NUMBER TotalPagesInLookupTable
Definition: meminit.c:27
PFN_NUMBER MmGetPageNumberFromAddress(PVOID Address)
Definition: meminit.c:369
PFN_NUMBER MmFindAvailablePages(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, BOOLEAN FromEnd)
Definition: meminit.c:565
PFN_NUMBER FreePagesInLookupTable
Definition: meminit.c:28
PFN_NUMBER MmFindAvailablePagesBeforePage(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PFN_NUMBER PagesNeeded, PFN_NUMBER LastPage)
Definition: meminit.c:624
VOID MmAllocatePagesInLookupTable(PVOID PageLookupTable, PFN_NUMBER StartPage, PFN_NUMBER PageCount, TYPE_OF_MEMORY MemoryType)
Definition: meminit.c:534
BOOLEAN MmAreMemoryPagesAvailable(PVOID PageLookupTable, PFN_NUMBER TotalPageCount, PVOID PageAddress, PFN_NUMBER PageCount)
Definition: meminit.c:672
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
#define ULONG_PTR
Definition: config.h:101
#define PAGE_SIZE
Definition: env_spec_w32.h:49
#define PAGE_SHIFT
Definition: env_spec_w32.h:45
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
PVOID MmAllocateMemoryAtAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:85
VOID MmFreeMemory(PVOID MemoryPointer)
Definition: mm.c:215
VOID MmSetMemoryType(PVOID MemoryAddress, SIZE_T MemorySize, TYPE_OF_MEMORY NewType)
Definition: mm.c:144
PVOID MmAllocateMemoryWithType(SIZE_T MemorySize, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:31
PFN_NUMBER LoaderPagesSpanned
Definition: mm.c:29
PPAGE_LOOKUP_TABLE_ITEM MmGetMemoryMap(PFN_NUMBER *NoEntries)
Definition: mm.c:297
PVOID MmAllocateHighestMemoryBelowAddress(SIZE_T MemorySize, PVOID DesiredAddress, TYPE_OF_MEMORY MemoryType)
Definition: mm.c:160
#define DbgPrint
Definition: hal.h:12
void * PVOID
Definition: retypes.h:9
@ LoaderBad
Definition: arc.h:130
@ LoaderMemoryData
Definition: arc.h:147
@ LoaderBootDriver
Definition: arc.h:138
@ LoaderOsloaderHeap
Definition: arc.h:134
@ LoaderFree
Definition: arc.h:129
@ LoaderFirmwareTemporary
Definition: arc.h:132
@ LoaderLoadedProgram
Definition: arc.h:131
@ LoaderSystemCode
Definition: arc.h:136
@ LoaderNlsData
Definition: arc.h:148
@ LoaderRegistryData
Definition: arc.h:146
@ LoaderHalCode
Definition: arc.h:137
@ LoaderFirmwarePermanent
Definition: arc.h:133
@ LoaderStartupPcrPage
Definition: arc.h:144
@ LoaderOsloaderStack
Definition: arc.h:135
@ LoaderSpecialMemory
Definition: arc.h:149
enum _TYPE_OF_MEMORY TYPE_OF_MEMORY
ULONG PFN_NUMBER
Definition: ke.h:9
#define TRACE(s)
Definition: solgame.cpp:4
static CONST DWORD MemorySize[]
Definition: svga.c:32
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t ULONG_PTR
Definition: typedefs.h:65
VOID UiMessageBoxCritical(PCSTR MessageText)
Definition: ui.c:374
VOID DumpMemoryAllocMap(VOID)