]> git.proxmox.com Git - mirror_edk2.git/blame - EmulatorPkg/Library/GuardUefiMemoryAllocationLib/MemoryAllocationLib.c
EmulatorPkg: Replace BSD License with BSD+Patent License
[mirror_edk2.git] / EmulatorPkg / Library / GuardUefiMemoryAllocationLib / MemoryAllocationLib.c
CommitLineData
1d7ac5a6 1/** @file\r
d18d8a1d 2 Support routines for memory allocation routines based\r
1d7ac5a6 3 on boot services for Dxe phase drivers using OS malloc.\r
d18d8a1d 4\r
5 OS malloc is used so OS based malloc debugging tools can be used.\r
6 If a single driver links against this lib protocols from other\r
7 drivers, or EFI boot services can return a buffer that needs to\r
8 freed using the EFI scheme. This is why the gEmuThunk->Free ()\r
1d7ac5a6 9 can detect if the memory rang is for EFI so the right free can be\r
10 called.\r
11\r
12 Copyright (c) 2006 - 2009, Intel Corporation. All rights reserved.<BR>\r
d18d8a1d 13 Portions copyright (c) 2011, Apple Inc. All rights reserved.\r
e3ba31da 14 SPDX-License-Identifier: BSD-2-Clause-Patent\r
1d7ac5a6 15\r
16**/\r
17\r
18\r
19#include <Uefi.h>\r
20\r
21\r
22#include <Library/MemoryAllocationLib.h>\r
23#include <Library/UefiBootServicesTableLib.h>\r
24#include <Library/BaseMemoryLib.h>\r
25#include <Library/DebugLib.h>\r
26#include <Library/EmuThunkLib.h>\r
27\r
28/**\r
29 Allocates one or more 4KB pages of a certain memory type.\r
30\r
31 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated\r
32 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.\r
33 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
34\r
35 @param MemoryType The type of memory to allocate.\r
36 @param Pages The number of 4 KB pages to allocate.\r
37\r
38 @return A pointer to the allocated buffer or NULL if allocation fails.\r
39\r
40**/\r
41VOID *\r
42InternalAllocatePages (\r
d18d8a1d 43 IN EFI_MEMORY_TYPE MemoryType,\r
1d7ac5a6 44 IN UINTN Pages\r
45 )\r
46{\r
47 EFI_STATUS Status;\r
d18d8a1d 48 EFI_PHYSICAL_ADDRESS Memory;\r
1d7ac5a6 49\r
50 if (Pages == 0) {\r
51 return NULL;\r
52 }\r
53\r
54 return gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);\r
55}\r
56\r
57/**\r
58 Allocates one or more 4KB pages of type EfiBootServicesData.\r
59\r
60 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the\r
61 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
62 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
63 returned.\r
64\r
65 @param Pages The number of 4 KB pages to allocate.\r
66\r
67 @return A pointer to the allocated buffer or NULL if allocation fails.\r
68\r
69**/\r
70VOID *\r
71EFIAPI\r
72AllocatePages (\r
73 IN UINTN Pages\r
74 )\r
75{\r
76 return InternalAllocatePages (EfiBootServicesData, Pages);\r
77}\r
78\r
79/**\r
80 Allocates one or more 4KB pages of type EfiRuntimeServicesData.\r
81\r
82 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the\r
83 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
84 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
85 returned.\r
86\r
87 @param Pages The number of 4 KB pages to allocate.\r
88\r
89 @return A pointer to the allocated buffer or NULL if allocation fails.\r
90\r
91**/\r
92VOID *\r
93EFIAPI\r
94AllocateRuntimePages (\r
95 IN UINTN Pages\r
96 )\r
97{\r
98 return InternalAllocatePages (EfiRuntimeServicesData, Pages);\r
99}\r
100\r
101/**\r
102 Allocates one or more 4KB pages of type EfiReservedMemoryType.\r
103\r
104 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the\r
105 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
106 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
107 returned.\r
108\r
109 @param Pages The number of 4 KB pages to allocate.\r
110\r
111 @return A pointer to the allocated buffer or NULL if allocation fails.\r
112\r
113**/\r
114VOID *\r
115EFIAPI\r
116AllocateReservedPages (\r
117 IN UINTN Pages\r
118 )\r
119{\r
120 return InternalAllocatePages (EfiReservedMemoryType, Pages);\r
121}\r
122\r
123/**\r
124 Frees one or more 4KB pages that were previously allocated with one of the page allocation\r
125 functions in the Memory Allocation Library.\r
126\r
127 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer\r
128 must have been allocated on a previous call to the page allocation services of the Memory\r
129 Allocation Library. If it is not possible to free allocated pages, then this function will\r
130 perform no actions.\r
d18d8a1d 131\r
1d7ac5a6 132 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,\r
133 then ASSERT().\r
134 If Pages is zero, then ASSERT().\r
d18d8a1d 135\r
1d7ac5a6 136 @param Buffer The pointer to the buffer of pages to free.\r
137 @param Pages The number of 4 KB pages to free.\r
138\r
139**/\r
140VOID\r
141EFIAPI\r
142FreePages (\r
143 IN VOID *Buffer,\r
144 IN UINTN Pages\r
145 )\r
146{\r
8e4b3d32 147 EFI_STATUS Status;\r
148\r
1d7ac5a6 149 ASSERT (Pages != 0);\r
8e4b3d32 150 if (!gEmuThunk->Free (Buffer)) {\r
151 // The Free thunk will not free memory allocated in emulated EFI memory.\r
d18d8a1d 152 // The assmuption is this was allocated directly by EFI. We need this as some\r
8e4b3d32 153 // times protocols or EFI BootServices can return dynamically allocated buffers.\r
154 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
155 ASSERT_EFI_ERROR (Status);\r
156 }\r
1d7ac5a6 157}\r
158\r
159/**\r
160 Allocates one or more 4KB pages of a certain memory type at a specified alignment.\r
161\r
162 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment\r
163 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.\r
164 If there is not enough memory at the specified alignment remaining to satisfy the request, then\r
165 NULL is returned.\r
166 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
167\r
168 @param MemoryType The type of memory to allocate.\r
169 @param Pages The number of 4 KB pages to allocate.\r
170 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
171 If Alignment is zero, then byte alignment is used.\r
172\r
173 @return A pointer to the allocated buffer or NULL if allocation fails.\r
174\r
175**/\r
176VOID *\r
177InternalAllocateAlignedPages (\r
d18d8a1d 178 IN EFI_MEMORY_TYPE MemoryType,\r
1d7ac5a6 179 IN UINTN Pages,\r
180 IN UINTN Alignment\r
181 )\r
182{\r
8e4b3d32 183 EFI_STATUS Status;\r
1d7ac5a6 184 VOID *Memory;\r
185 UINTN AlignedMemory;\r
186 UINTN AlignmentMask;\r
187 UINTN UnalignedPages;\r
188 UINTN RealPages;\r
189\r
190 //\r
191 // Alignment must be a power of two or zero.\r
192 //\r
193 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
d18d8a1d 194\r
1d7ac5a6 195 if (Pages == 0) {\r
196 return NULL;\r
197 }\r
198 if (Alignment > EFI_PAGE_SIZE) {\r
199 //\r
200 // Caculate the total number of pages since alignment is larger than page size.\r
201 //\r
202 AlignmentMask = Alignment - 1;\r
203 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);\r
204 //\r
205 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.\r
206 //\r
207 ASSERT (RealPages > Pages);\r
d18d8a1d 208\r
1d7ac5a6 209 Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);\r
210 if (Memory != NULL) {\r
211 return NULL;\r
212 }\r
213 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;\r
214 UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);\r
215 if (UnalignedPages > 0) {\r
216 //\r
217 // Free first unaligned page(s).\r
218 //\r
8e4b3d32 219 FreePages (Memory, UnalignedPages);\r
1d7ac5a6 220 }\r
221 Memory = (VOID *) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));\r
222 UnalignedPages = RealPages - Pages - UnalignedPages;\r
223 if (UnalignedPages > 0) {\r
224 //\r
225 // Free last unaligned page(s).\r
226 //\r
8e4b3d32 227 FreePages (Memory, UnalignedPages);\r
1d7ac5a6 228 }\r
229 } else {\r
230 //\r
231 // Do not over-allocate pages in this case.\r
232 //\r
233 Memory = gEmuThunk->Valloc (Pages * EFI_PAGE_SIZE);\r
234 if (Memory != NULL) {\r
235 return NULL;\r
236 }\r
237 AlignedMemory = (UINTN) Memory;\r
238 }\r
239 return (VOID *) AlignedMemory;\r
240}\r
241\r
242/**\r
243 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.\r
244\r
245 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an\r
246 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
247 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
248 request, then NULL is returned.\r
d18d8a1d 249\r
1d7ac5a6 250 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
251\r
252 @param Pages The number of 4 KB pages to allocate.\r
253 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
254 If Alignment is zero, then byte alignment is used.\r
255\r
256 @return A pointer to the allocated buffer or NULL if allocation fails.\r
257\r
258**/\r
259VOID *\r
260EFIAPI\r
261AllocateAlignedPages (\r
262 IN UINTN Pages,\r
263 IN UINTN Alignment\r
264 )\r
265{\r
266 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);\r
267}\r
268\r
269/**\r
270 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.\r
271\r
272 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an\r
273 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
274 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
275 request, then NULL is returned.\r
d18d8a1d 276\r
1d7ac5a6 277 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
278\r
279 @param Pages The number of 4 KB pages to allocate.\r
280 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
281 If Alignment is zero, then byte alignment is used.\r
282\r
283 @return A pointer to the allocated buffer or NULL if allocation fails.\r
284\r
285**/\r
286VOID *\r
287EFIAPI\r
288AllocateAlignedRuntimePages (\r
289 IN UINTN Pages,\r
290 IN UINTN Alignment\r
291 )\r
292{\r
293 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);\r
294}\r
295\r
296/**\r
297 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.\r
298\r
299 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an\r
300 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
301 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
302 request, then NULL is returned.\r
d18d8a1d 303\r
1d7ac5a6 304 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
305\r
306 @param Pages The number of 4 KB pages to allocate.\r
307 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
308 If Alignment is zero, then byte alignment is used.\r
309\r
310 @return A pointer to the allocated buffer or NULL if allocation fails.\r
311\r
312**/\r
313VOID *\r
314EFIAPI\r
315AllocateAlignedReservedPages (\r
316 IN UINTN Pages,\r
317 IN UINTN Alignment\r
318 )\r
319{\r
320 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);\r
321}\r
322\r
323/**\r
324 Frees one or more 4KB pages that were previously allocated with one of the aligned page\r
325 allocation functions in the Memory Allocation Library.\r
326\r
327 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer\r
328 must have been allocated on a previous call to the aligned page allocation services of the Memory\r
d18d8a1d 329 Allocation Library. If it is not possible to free allocated pages, then this function will\r
1d7ac5a6 330 perform no actions.\r
d18d8a1d 331\r
1d7ac5a6 332 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation\r
333 Library, then ASSERT().\r
334 If Pages is zero, then ASSERT().\r
d18d8a1d 335\r
1d7ac5a6 336 @param Buffer The pointer to the buffer of pages to free.\r
337 @param Pages The number of 4 KB pages to free.\r
338\r
339**/\r
340VOID\r
341EFIAPI\r
342FreeAlignedPages (\r
343 IN VOID *Buffer,\r
344 IN UINTN Pages\r
345 )\r
346{\r
8e4b3d32 347 FreePages (Buffer, Pages);\r
1d7ac5a6 348}\r
349\r
350/**\r
351 Allocates a buffer of a certain pool type.\r
352\r
353 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a\r
354 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
355 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
356\r
357 @param MemoryType The type of memory to allocate.\r
358 @param AllocationSize The number of bytes to allocate.\r
359\r
360 @return A pointer to the allocated buffer or NULL if allocation fails.\r
361\r
362**/\r
363VOID *\r
364InternalAllocatePool (\r
d18d8a1d 365 IN EFI_MEMORY_TYPE MemoryType,\r
1d7ac5a6 366 IN UINTN AllocationSize\r
367 )\r
368{\r
369 return gEmuThunk->Malloc (AllocationSize);\r
370}\r
371\r
372/**\r
373 Allocates a buffer of type EfiBootServicesData.\r
374\r
375 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a\r
376 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
377 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
378\r
379 @param AllocationSize The number of bytes to allocate.\r
380\r
381 @return A pointer to the allocated buffer or NULL if allocation fails.\r
382\r
383**/\r
384VOID *\r
385EFIAPI\r
386AllocatePool (\r
387 IN UINTN AllocationSize\r
388 )\r
389{\r
390 return InternalAllocatePool (EfiBootServicesData, AllocationSize);\r
391}\r
392\r
393/**\r
394 Allocates a buffer of type EfiRuntimeServicesData.\r
395\r
396 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns\r
397 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
398 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
399\r
400 @param AllocationSize The number of bytes to allocate.\r
401\r
402 @return A pointer to the allocated buffer or NULL if allocation fails.\r
403\r
404**/\r
405VOID *\r
406EFIAPI\r
407AllocateRuntimePool (\r
408 IN UINTN AllocationSize\r
409 )\r
410{\r
411 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
412}\r
413\r
414/**\r
415 Allocates a buffer of type EfiReservedMemoryType.\r
416\r
417 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns\r
418 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
419 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
420\r
421 @param AllocationSize The number of bytes to allocate.\r
422\r
423 @return A pointer to the allocated buffer or NULL if allocation fails.\r
424\r
425**/\r
426VOID *\r
427EFIAPI\r
428AllocateReservedPool (\r
429 IN UINTN AllocationSize\r
430 )\r
431{\r
432 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);\r
433}\r
434\r
435/**\r
436 Allocates and zeros a buffer of a certain pool type.\r
437\r
438 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer\r
439 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid\r
440 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,\r
441 then NULL is returned.\r
442\r
443 @param PoolType The type of memory to allocate.\r
444 @param AllocationSize The number of bytes to allocate and zero.\r
445\r
446 @return A pointer to the allocated buffer or NULL if allocation fails.\r
447\r
448**/\r
449VOID *\r
450InternalAllocateZeroPool (\r
d18d8a1d 451 IN EFI_MEMORY_TYPE PoolType,\r
1d7ac5a6 452 IN UINTN AllocationSize\r
d18d8a1d 453 )\r
1d7ac5a6 454{\r
455 VOID *Memory;\r
456\r
457 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
458 if (Memory != NULL) {\r
459 Memory = ZeroMem (Memory, AllocationSize);\r
460 }\r
461 return Memory;\r
462}\r
463\r
464/**\r
465 Allocates and zeros a buffer of type EfiBootServicesData.\r
466\r
467 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the\r
468 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
469 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
470 request, then NULL is returned.\r
471\r
472 @param AllocationSize The number of bytes to allocate and zero.\r
473\r
474 @return A pointer to the allocated buffer or NULL if allocation fails.\r
475\r
476**/\r
477VOID *\r
478EFIAPI\r
479AllocateZeroPool (\r
480 IN UINTN AllocationSize\r
481 )\r
482{\r
483 return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);\r
484}\r
485\r
486/**\r
487 Allocates and zeros a buffer of type EfiRuntimeServicesData.\r
488\r
489 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the\r
490 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
491 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
492 request, then NULL is returned.\r
493\r
494 @param AllocationSize The number of bytes to allocate and zero.\r
495\r
496 @return A pointer to the allocated buffer or NULL if allocation fails.\r
497\r
498**/\r
499VOID *\r
500EFIAPI\r
501AllocateRuntimeZeroPool (\r
502 IN UINTN AllocationSize\r
503 )\r
504{\r
505 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
506}\r
507\r
508/**\r
509 Allocates and zeros a buffer of type EfiReservedMemoryType.\r
510\r
511 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the\r
512 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
513 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
514 request, then NULL is returned.\r
515\r
516 @param AllocationSize The number of bytes to allocate and zero.\r
517\r
518 @return A pointer to the allocated buffer or NULL if allocation fails.\r
519\r
520**/\r
521VOID *\r
522EFIAPI\r
523AllocateReservedZeroPool (\r
524 IN UINTN AllocationSize\r
525 )\r
526{\r
527 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);\r
528}\r
529\r
530/**\r
531 Copies a buffer to an allocated buffer of a certain pool type.\r
532\r
533 Allocates the number bytes specified by AllocationSize of a certain pool type, copies\r
534 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
535 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
536 is not enough memory remaining to satisfy the request, then NULL is returned.\r
537 If Buffer is NULL, then ASSERT().\r
d18d8a1d 538 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
1d7ac5a6 539\r
540 @param PoolType The type of pool to allocate.\r
541 @param AllocationSize The number of bytes to allocate and zero.\r
542 @param Buffer The buffer to copy to the allocated buffer.\r
543\r
544 @return A pointer to the allocated buffer or NULL if allocation fails.\r
545\r
546**/\r
547VOID *\r
548InternalAllocateCopyPool (\r
d18d8a1d 549 IN EFI_MEMORY_TYPE PoolType,\r
1d7ac5a6 550 IN UINTN AllocationSize,\r
551 IN CONST VOID *Buffer\r
d18d8a1d 552 )\r
1d7ac5a6 553{\r
554 VOID *Memory;\r
555\r
556 ASSERT (Buffer != NULL);\r
557 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
558\r
559 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
560 if (Memory != NULL) {\r
561 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
562 }\r
563 return Memory;\r
d18d8a1d 564}\r
1d7ac5a6 565\r
566/**\r
567 Copies a buffer to an allocated buffer of type EfiBootServicesData.\r
568\r
569 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies\r
570 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
571 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
572 is not enough memory remaining to satisfy the request, then NULL is returned.\r
d18d8a1d 573\r
1d7ac5a6 574 If Buffer is NULL, then ASSERT().\r
d18d8a1d 575 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
1d7ac5a6 576\r
577 @param AllocationSize The number of bytes to allocate and zero.\r
578 @param Buffer The buffer to copy to the allocated buffer.\r
579\r
580 @return A pointer to the allocated buffer or NULL if allocation fails.\r
581\r
582**/\r
583VOID *\r
584EFIAPI\r
585AllocateCopyPool (\r
586 IN UINTN AllocationSize,\r
587 IN CONST VOID *Buffer\r
588 )\r
589{\r
590 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);\r
591}\r
592\r
593/**\r
594 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.\r
595\r
596 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies\r
597 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
598 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
599 is not enough memory remaining to satisfy the request, then NULL is returned.\r
d18d8a1d 600\r
1d7ac5a6 601 If Buffer is NULL, then ASSERT().\r
d18d8a1d 602 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
1d7ac5a6 603\r
604 @param AllocationSize The number of bytes to allocate and zero.\r
605 @param Buffer The buffer to copy to the allocated buffer.\r
606\r
607 @return A pointer to the allocated buffer or NULL if allocation fails.\r
608\r
609**/\r
610VOID *\r
611EFIAPI\r
612AllocateRuntimeCopyPool (\r
613 IN UINTN AllocationSize,\r
614 IN CONST VOID *Buffer\r
615 )\r
616{\r
617 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
618}\r
619\r
620/**\r
621 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.\r
622\r
623 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies\r
624 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
625 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
626 is not enough memory remaining to satisfy the request, then NULL is returned.\r
d18d8a1d 627\r
1d7ac5a6 628 If Buffer is NULL, then ASSERT().\r
d18d8a1d 629 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT().\r
1d7ac5a6 630\r
631 @param AllocationSize The number of bytes to allocate and zero.\r
632 @param Buffer The buffer to copy to the allocated buffer.\r
633\r
634 @return A pointer to the allocated buffer or NULL if allocation fails.\r
635\r
636**/\r
637VOID *\r
638EFIAPI\r
639AllocateReservedCopyPool (\r
640 IN UINTN AllocationSize,\r
641 IN CONST VOID *Buffer\r
642 )\r
643{\r
644 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);\r
645}\r
646\r
647/**\r
648 Reallocates a buffer of a specified memory type.\r
649\r
650 Allocates and zeros the number bytes specified by NewSize from memory of the type\r
d18d8a1d 651 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and\r
652 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and\r
653 OldBuffer is freed. A pointer to the newly allocated buffer is returned.\r
654 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not\r
1d7ac5a6 655 enough memory remaining to satisfy the request, then NULL is returned.\r
d18d8a1d 656\r
1d7ac5a6 657 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
658 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
659\r
660 @param PoolType The type of pool to allocate.\r
661 @param OldSize The size, in bytes, of OldBuffer.\r
662 @param NewSize The size, in bytes, of the buffer to reallocate.\r
d18d8a1d 663 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional\r
1d7ac5a6 664 parameter that may be NULL.\r
665\r
666 @return A pointer to the allocated buffer or NULL if allocation fails.\r
667\r
668**/\r
669VOID *\r
670InternalReallocatePool (\r
d18d8a1d 671 IN EFI_MEMORY_TYPE PoolType,\r
1d7ac5a6 672 IN UINTN OldSize,\r
673 IN UINTN NewSize,\r
674 IN VOID *OldBuffer OPTIONAL\r
675 )\r
676{\r
677 VOID *NewBuffer;\r
678\r
679 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);\r
680 if (NewBuffer != NULL && OldBuffer != NULL) {\r
681 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));\r
682 FreePool (OldBuffer);\r
683 }\r
684 return NewBuffer;\r
685}\r
686\r
687/**\r
688 Reallocates a buffer of type EfiBootServicesData.\r
689\r
690 Allocates and zeros the number bytes specified by NewSize from memory of type\r
d18d8a1d 691 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and\r
692 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and\r
693 OldBuffer is freed. A pointer to the newly allocated buffer is returned.\r
694 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not\r
1d7ac5a6 695 enough memory remaining to satisfy the request, then NULL is returned.\r
d18d8a1d 696\r
1d7ac5a6 697 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
698 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
699\r
700 @param OldSize The size, in bytes, of OldBuffer.\r
701 @param NewSize The size, in bytes, of the buffer to reallocate.\r
d18d8a1d 702 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional\r
1d7ac5a6 703 parameter that may be NULL.\r
704\r
705 @return A pointer to the allocated buffer or NULL if allocation fails.\r
706\r
707**/\r
708VOID *\r
709EFIAPI\r
710ReallocatePool (\r
711 IN UINTN OldSize,\r
712 IN UINTN NewSize,\r
713 IN VOID *OldBuffer OPTIONAL\r
714 )\r
715{\r
716 return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);\r
717}\r
718\r
719/**\r
720 Reallocates a buffer of type EfiRuntimeServicesData.\r
721\r
722 Allocates and zeros the number bytes specified by NewSize from memory of type\r
d18d8a1d 723 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and\r
724 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and\r
725 OldBuffer is freed. A pointer to the newly allocated buffer is returned.\r
726 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not\r
1d7ac5a6 727 enough memory remaining to satisfy the request, then NULL is returned.\r
728\r
729 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
730 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
731\r
732 @param OldSize The size, in bytes, of OldBuffer.\r
733 @param NewSize The size, in bytes, of the buffer to reallocate.\r
d18d8a1d 734 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional\r
1d7ac5a6 735 parameter that may be NULL.\r
736\r
737 @return A pointer to the allocated buffer or NULL if allocation fails.\r
738\r
739**/\r
740VOID *\r
741EFIAPI\r
742ReallocateRuntimePool (\r
743 IN UINTN OldSize,\r
744 IN UINTN NewSize,\r
745 IN VOID *OldBuffer OPTIONAL\r
746 )\r
747{\r
748 return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);\r
749}\r
750\r
751/**\r
752 Reallocates a buffer of type EfiReservedMemoryType.\r
753\r
754 Allocates and zeros the number bytes specified by NewSize from memory of type\r
d18d8a1d 755 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and\r
756 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and\r
757 OldBuffer is freed. A pointer to the newly allocated buffer is returned.\r
758 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not\r
1d7ac5a6 759 enough memory remaining to satisfy the request, then NULL is returned.\r
760\r
761 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
762 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
763\r
764 @param OldSize The size, in bytes, of OldBuffer.\r
765 @param NewSize The size, in bytes, of the buffer to reallocate.\r
d18d8a1d 766 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional\r
1d7ac5a6 767 parameter that may be NULL.\r
768\r
769 @return A pointer to the allocated buffer or NULL if allocation fails.\r
770\r
771**/\r
772VOID *\r
773EFIAPI\r
774ReallocateReservedPool (\r
775 IN UINTN OldSize,\r
776 IN UINTN NewSize,\r
777 IN VOID *OldBuffer OPTIONAL\r
778 )\r
779{\r
780 return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);\r
781}\r
782\r
783/**\r
784 Frees a buffer that was previously allocated with one of the pool allocation functions in the\r
785 Memory Allocation Library.\r
786\r
787 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the\r
788 pool allocation services of the Memory Allocation Library. If it is not possible to free pool\r
789 resources, then this function will perform no actions.\r
d18d8a1d 790\r
1d7ac5a6 791 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,\r
792 then ASSERT().\r
793\r
794 @param Buffer The pointer to the buffer to free.\r
795\r
796**/\r
797VOID\r
798EFIAPI\r
799FreePool (\r
800 IN VOID *Buffer\r
801 )\r
802{\r
8e4b3d32 803 EFI_STATUS Status;\r
804\r
1d7ac5a6 805 if (!gEmuThunk->Free (Buffer)) {\r
806 // The Free thunk will not free memory allocated in emulated EFI memory.\r
d18d8a1d 807 // The assmuption is this was allocated directly by EFI. We need this as some\r
1d7ac5a6 808 // times protocols or EFI BootServices can return dynamically allocated buffers.\r
8e4b3d32 809 Status = gBS->FreePool (Buffer);\r
810 ASSERT_EFI_ERROR (Status);\r
1d7ac5a6 811 }\r
812}\r
813\r