]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/DxeCoreMemoryAllocationLib/MemoryAllocationLib.c
MdeModulePkg: Refine casting expression result to bigger size
[mirror_edk2.git] / MdeModulePkg / Library / DxeCoreMemoryAllocationLib / MemoryAllocationLib.c
CommitLineData
0ac72713 1/** @file\r
2 Support routines for memory allocation routines based \r
e2735692
SZ
3 on DxeCore Memory Allocation services for DxeCore,\r
4 with memory profile support.\r
0ac72713 5\r
16f69227 6 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
cd5ebaa0 7 This program and the accompanying materials \r
0ac72713 8 are licensed and made available under the terms and conditions of the BSD License \r
9 which accompanies this distribution. The full text of the license may be found at \r
10 http://opensource.org/licenses/bsd-license.php \r
11\r
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
14\r
15**/\r
16\r
17\r
18#include <PiDxe.h>\r
19\r
f6998888 20\r
0ac72713 21#include <Library/MemoryAllocationLib.h>\r
22#include <Library/BaseMemoryLib.h>\r
23#include <Library/DebugLib.h>\r
0ac72713 24#include "DxeCoreMemoryAllocationServices.h"\r
25\r
e2735692
SZ
26#include <Library/MemoryProfileLib.h>\r
27\r
0ac72713 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
43 IN EFI_MEMORY_TYPE MemoryType, \r
44 IN UINTN Pages\r
45 )\r
46{\r
47 EFI_STATUS Status;\r
48 EFI_PHYSICAL_ADDRESS Memory; \r
49\r
50 if (Pages == 0) {\r
51 return NULL;\r
52 }\r
53\r
54 Status = CoreAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);\r
55 if (EFI_ERROR (Status)) {\r
56 return NULL;\r
57 }\r
58 return (VOID *) (UINTN) Memory;\r
59}\r
60\r
61/**\r
62 Allocates one or more 4KB pages of type EfiBootServicesData.\r
63\r
64 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the\r
65 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
66 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
67 returned.\r
68\r
69 @param Pages The number of 4 KB pages to allocate.\r
70\r
71 @return A pointer to the allocated buffer or NULL if allocation fails.\r
72\r
73**/\r
74VOID *\r
75EFIAPI\r
76AllocatePages (\r
77 IN UINTN Pages\r
78 )\r
79{\r
e2735692
SZ
80 VOID *Buffer;\r
81\r
82 Buffer = InternalAllocatePages (EfiBootServicesData, Pages);\r
83 if (Buffer != NULL) {\r
84 MemoryProfileLibRecord (\r
85 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
86 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_PAGES,\r
87 EfiBootServicesData,\r
88 Buffer,\r
89 EFI_PAGES_TO_SIZE (Pages),\r
90 NULL\r
91 );\r
92 }\r
93 return Buffer;\r
0ac72713 94}\r
95\r
96/**\r
97 Allocates one or more 4KB pages of type EfiRuntimeServicesData.\r
98\r
99 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the\r
100 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
101 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
102 returned.\r
103\r
104 @param Pages The number of 4 KB pages to allocate.\r
105\r
106 @return A pointer to the allocated buffer or NULL if allocation fails.\r
107\r
108**/\r
109VOID *\r
110EFIAPI\r
111AllocateRuntimePages (\r
112 IN UINTN Pages\r
113 )\r
114{\r
e2735692
SZ
115 VOID *Buffer;\r
116\r
117 Buffer = InternalAllocatePages (EfiRuntimeServicesData, Pages);\r
118 if (Buffer != NULL) {\r
119 MemoryProfileLibRecord (\r
120 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
121 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_PAGES,\r
122 EfiRuntimeServicesData,\r
123 Buffer,\r
124 EFI_PAGES_TO_SIZE (Pages),\r
125 NULL\r
126 );\r
127 }\r
128 return Buffer;\r
0ac72713 129}\r
130\r
131/**\r
132 Allocates one or more 4KB pages of type EfiReservedMemoryType.\r
133\r
134 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the\r
135 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
136 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
137 returned.\r
138\r
139 @param Pages The number of 4 KB pages to allocate.\r
140\r
141 @return A pointer to the allocated buffer or NULL if allocation fails.\r
142\r
143**/\r
144VOID *\r
145EFIAPI\r
146AllocateReservedPages (\r
147 IN UINTN Pages\r
148 )\r
149{\r
e2735692
SZ
150 VOID *Buffer;\r
151\r
152 Buffer = InternalAllocatePages (EfiReservedMemoryType, Pages);\r
153 if (Buffer != NULL) {\r
154 MemoryProfileLibRecord (\r
155 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
156 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_PAGES,\r
157 EfiReservedMemoryType,\r
158 Buffer,\r
159 EFI_PAGES_TO_SIZE (Pages),\r
160 NULL\r
161 );\r
162 }\r
163 return Buffer;\r
0ac72713 164}\r
165\r
166/**\r
167 Frees one or more 4KB pages that were previously allocated with one of the page allocation\r
168 functions in the Memory Allocation Library.\r
169\r
170 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer\r
171 must have been allocated on a previous call to the page allocation services of the Memory\r
aa2f249e 172 Allocation Library. If it is not possible to free allocated pages, then this function will\r
446b94b0 173 perform no actions.\r
f6998888 174 \r
0ac72713 175 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,\r
176 then ASSERT().\r
177 If Pages is zero, then ASSERT().\r
178 \r
179 @param Buffer Pointer to the buffer of pages to free.\r
180 @param Pages The number of 4 KB pages to free.\r
181\r
182**/\r
183VOID\r
184EFIAPI\r
185FreePages (\r
186 IN VOID *Buffer,\r
187 IN UINTN Pages\r
188 )\r
189{\r
190 EFI_STATUS Status;\r
191\r
192 ASSERT (Pages != 0);\r
193 Status = CoreFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
194 ASSERT_EFI_ERROR (Status);\r
195}\r
196\r
197/**\r
198 Allocates one or more 4KB pages of a certain memory type at a specified alignment.\r
199\r
200 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment\r
201 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.\r
202 If there is not enough memory at the specified alignment remaining to satisfy the request, then\r
203 NULL is returned.\r
204 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
91403ce9 205 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().\r
0ac72713 206\r
207 @param MemoryType The type of memory to allocate.\r
208 @param Pages The number of 4 KB pages to allocate.\r
209 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
210 If Alignment is zero, then byte alignment is used.\r
211\r
212 @return A pointer to the allocated buffer or NULL if allocation fails.\r
213\r
214**/\r
215VOID *\r
216InternalAllocateAlignedPages (\r
217 IN EFI_MEMORY_TYPE MemoryType, \r
218 IN UINTN Pages,\r
219 IN UINTN Alignment\r
220 )\r
221{\r
222 EFI_STATUS Status;\r
223 EFI_PHYSICAL_ADDRESS Memory;\r
224 UINTN AlignedMemory;\r
225 UINTN AlignmentMask;\r
226 UINTN UnalignedPages;\r
227 UINTN RealPages;\r
228\r
229 //\r
230 // Alignment must be a power of two or zero.\r
231 //\r
232 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
233 \r
234 if (Pages == 0) {\r
235 return NULL;\r
236 }\r
237 if (Alignment > EFI_PAGE_SIZE) {\r
238 //\r
e50a226b 239 // Calculate the total number of pages since alignment is larger than page size.\r
0ac72713 240 //\r
241 AlignmentMask = Alignment - 1;\r
242 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);\r
243 //\r
244 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.\r
245 //\r
246 ASSERT (RealPages > Pages);\r
247 \r
248 Status = CoreAllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);\r
249 if (EFI_ERROR (Status)) {\r
250 return NULL;\r
251 }\r
252 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;\r
253 UnalignedPages = EFI_SIZE_TO_PAGES (AlignedMemory - (UINTN) Memory);\r
254 if (UnalignedPages > 0) {\r
255 //\r
256 // Free first unaligned page(s).\r
257 //\r
258 Status = CoreFreePages (Memory, UnalignedPages);\r
259 ASSERT_EFI_ERROR (Status);\r
260 }\r
16f69227 261 Memory = AlignedMemory + EFI_PAGES_TO_SIZE (Pages);\r
0ac72713 262 UnalignedPages = RealPages - Pages - UnalignedPages;\r
263 if (UnalignedPages > 0) {\r
264 //\r
265 // Free last unaligned page(s).\r
266 //\r
267 Status = CoreFreePages (Memory, UnalignedPages);\r
268 ASSERT_EFI_ERROR (Status);\r
269 }\r
270 } else {\r
271 //\r
272 // Do not over-allocate pages in this case.\r
273 //\r
274 Status = CoreAllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);\r
275 if (EFI_ERROR (Status)) {\r
276 return NULL;\r
277 }\r
278 AlignedMemory = (UINTN) Memory;\r
279 }\r
280 return (VOID *) AlignedMemory;\r
281}\r
282\r
283/**\r
284 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.\r
285\r
286 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an\r
287 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
288 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
289 request, then NULL is returned.\r
f6998888 290 \r
0ac72713 291 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
91403ce9 292 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().\r
0ac72713 293\r
294 @param Pages The number of 4 KB pages to allocate.\r
295 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
296 If Alignment is zero, then byte alignment is used.\r
297\r
298 @return A pointer to the allocated buffer or NULL if allocation fails.\r
299\r
300**/\r
301VOID *\r
302EFIAPI\r
303AllocateAlignedPages (\r
304 IN UINTN Pages,\r
305 IN UINTN Alignment\r
306 )\r
307{\r
e2735692
SZ
308 VOID *Buffer;\r
309\r
310 Buffer = InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);\r
311 if (Buffer != NULL) {\r
312 MemoryProfileLibRecord (\r
313 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
314 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_PAGES,\r
315 EfiBootServicesData,\r
316 Buffer,\r
317 EFI_PAGES_TO_SIZE (Pages),\r
318 NULL\r
319 );\r
320 }\r
321 return Buffer;\r
0ac72713 322}\r
323\r
324/**\r
325 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.\r
326\r
327 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an\r
328 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
329 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
330 request, then NULL is returned.\r
f6998888 331 \r
0ac72713 332 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
91403ce9 333 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().\r
0ac72713 334\r
335 @param Pages The number of 4 KB pages to allocate.\r
336 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
337 If Alignment is zero, then byte alignment is used.\r
338\r
339 @return A pointer to the allocated buffer or NULL if allocation fails.\r
340\r
341**/\r
342VOID *\r
343EFIAPI\r
344AllocateAlignedRuntimePages (\r
345 IN UINTN Pages,\r
346 IN UINTN Alignment\r
347 )\r
348{\r
e2735692
SZ
349 VOID *Buffer;\r
350\r
351 Buffer = InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);\r
352 if (Buffer != NULL) {\r
353 MemoryProfileLibRecord (\r
354 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
355 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RUNTIME_PAGES,\r
356 EfiRuntimeServicesData,\r
357 Buffer,\r
358 EFI_PAGES_TO_SIZE (Pages),\r
359 NULL\r
360 );\r
361 }\r
362 return Buffer;\r
0ac72713 363}\r
364\r
365/**\r
366 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.\r
367\r
368 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an\r
369 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
370 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
371 request, then NULL is returned.\r
f6998888 372 \r
0ac72713 373 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
91403ce9 374 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().\r
0ac72713 375\r
376 @param Pages The number of 4 KB pages to allocate.\r
377 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
378 If Alignment is zero, then byte alignment is used.\r
379\r
380 @return A pointer to the allocated buffer or NULL if allocation fails.\r
381\r
382**/\r
383VOID *\r
384EFIAPI\r
385AllocateAlignedReservedPages (\r
386 IN UINTN Pages,\r
387 IN UINTN Alignment\r
388 )\r
389{\r
e2735692
SZ
390 VOID *Buffer;\r
391\r
392 Buffer = InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);\r
393 if (Buffer != NULL) {\r
394 MemoryProfileLibRecord (\r
395 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
396 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ALIGNED_RESERVED_PAGES,\r
397 EfiReservedMemoryType,\r
398 Buffer,\r
399 EFI_PAGES_TO_SIZE (Pages),\r
400 NULL\r
401 );\r
402 }\r
403 return Buffer;\r
0ac72713 404}\r
405\r
406/**\r
407 Frees one or more 4KB pages that were previously allocated with one of the aligned page\r
408 allocation functions in the Memory Allocation Library.\r
409\r
410 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer\r
411 must have been allocated on a previous call to the aligned page allocation services of the Memory\r
aa2f249e 412 Allocation Library. If it is not possible to free allocated pages, then this function will \r
446b94b0 413 perform no actions.\r
f6998888 414 \r
0ac72713 415 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation\r
416 Library, then ASSERT().\r
417 If Pages is zero, then ASSERT().\r
418 \r
419 @param Buffer Pointer to the buffer of pages to free.\r
420 @param Pages The number of 4 KB pages to free.\r
421\r
422**/\r
423VOID\r
424EFIAPI\r
425FreeAlignedPages (\r
426 IN VOID *Buffer,\r
427 IN UINTN Pages\r
428 )\r
429{\r
430 EFI_STATUS Status;\r
431\r
432 ASSERT (Pages != 0);\r
433 Status = CoreFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
434 ASSERT_EFI_ERROR (Status);\r
435}\r
436\r
437/**\r
438 Allocates a buffer of a certain pool type.\r
439\r
440 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a\r
441 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
442 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
443\r
444 @param MemoryType The type of memory to allocate.\r
445 @param AllocationSize The number of bytes to allocate.\r
446\r
447 @return A pointer to the allocated buffer or NULL if allocation fails.\r
448\r
449**/\r
450VOID *\r
451InternalAllocatePool (\r
452 IN EFI_MEMORY_TYPE MemoryType, \r
453 IN UINTN AllocationSize\r
454 )\r
455{\r
456 EFI_STATUS Status;\r
457 VOID *Memory;\r
458\r
4e1005ec
ED
459 Memory = NULL;\r
460\r
0ac72713 461 Status = CoreAllocatePool (MemoryType, AllocationSize, &Memory);\r
462 if (EFI_ERROR (Status)) {\r
463 Memory = NULL;\r
464 }\r
465 return Memory;\r
466}\r
467\r
468/**\r
469 Allocates a buffer of type EfiBootServicesData.\r
470\r
471 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a\r
472 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
473 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
474\r
475 @param AllocationSize The number of bytes to allocate.\r
476\r
477 @return A pointer to the allocated buffer or NULL if allocation fails.\r
478\r
479**/\r
480VOID *\r
481EFIAPI\r
482AllocatePool (\r
483 IN UINTN AllocationSize\r
484 )\r
485{\r
e2735692
SZ
486 VOID *Buffer;\r
487\r
488 Buffer = InternalAllocatePool (EfiBootServicesData, AllocationSize);\r
489 if (Buffer != NULL) {\r
490 MemoryProfileLibRecord (\r
491 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
492 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_POOL,\r
493 EfiBootServicesData,\r
494 Buffer,\r
495 AllocationSize,\r
496 NULL\r
497 );\r
498 }\r
499 return Buffer;\r
0ac72713 500}\r
501\r
502/**\r
503 Allocates a buffer of type EfiRuntimeServicesData.\r
504\r
505 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns\r
506 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
507 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
508\r
509 @param AllocationSize The number of bytes to allocate.\r
510\r
511 @return A pointer to the allocated buffer or NULL if allocation fails.\r
512\r
513**/\r
514VOID *\r
515EFIAPI\r
516AllocateRuntimePool (\r
517 IN UINTN AllocationSize\r
518 )\r
519{\r
e2735692
SZ
520 VOID *Buffer;\r
521\r
522 Buffer = InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
523 if (Buffer != NULL) {\r
524 MemoryProfileLibRecord (\r
525 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
526 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_POOL,\r
527 EfiRuntimeServicesData,\r
528 Buffer,\r
529 AllocationSize,\r
530 NULL\r
531 );\r
532 }\r
533 return Buffer;\r
0ac72713 534}\r
535\r
536/**\r
31771abd 537 Allocates a buffer of type EfiReservedMemoryType.\r
0ac72713 538\r
31771abd 539 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns\r
0ac72713 540 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
541 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
542\r
543 @param AllocationSize The number of bytes to allocate.\r
544\r
545 @return A pointer to the allocated buffer or NULL if allocation fails.\r
546\r
547**/\r
548VOID *\r
549EFIAPI\r
550AllocateReservedPool (\r
551 IN UINTN AllocationSize\r
552 )\r
553{\r
e2735692
SZ
554 VOID *Buffer;\r
555\r
556 Buffer = InternalAllocatePool (EfiReservedMemoryType, AllocationSize);\r
557 if (Buffer != NULL) {\r
558 MemoryProfileLibRecord (\r
559 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
560 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_POOL,\r
561 EfiReservedMemoryType,\r
562 Buffer,\r
563 AllocationSize,\r
564 NULL\r
565 );\r
566 }\r
567 return Buffer;\r
0ac72713 568}\r
569\r
570/**\r
446b94b0 571 Allocates and zeros a buffer of a certain pool type.\r
0ac72713 572\r
446b94b0 573 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer\r
0ac72713 574 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid\r
575 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,\r
576 then NULL is returned.\r
577\r
578 @param PoolType The type of memory to allocate.\r
579 @param AllocationSize The number of bytes to allocate and zero.\r
580\r
581 @return A pointer to the allocated buffer or NULL if allocation fails.\r
582\r
583**/\r
584VOID *\r
585InternalAllocateZeroPool (\r
586 IN EFI_MEMORY_TYPE PoolType, \r
587 IN UINTN AllocationSize\r
588 ) \r
589{\r
590 VOID *Memory;\r
591\r
592 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
593 if (Memory != NULL) {\r
594 Memory = ZeroMem (Memory, AllocationSize);\r
595 }\r
596 return Memory;\r
597}\r
598\r
599/**\r
600 Allocates and zeros a buffer of type EfiBootServicesData.\r
601\r
602 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the\r
603 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
604 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
605 request, then NULL is returned.\r
606\r
607 @param AllocationSize The number of bytes to allocate and zero.\r
608\r
609 @return A pointer to the allocated buffer or NULL if allocation fails.\r
610\r
611**/\r
612VOID *\r
613EFIAPI\r
614AllocateZeroPool (\r
615 IN UINTN AllocationSize\r
616 )\r
617{\r
e2735692
SZ
618 VOID *Buffer;\r
619\r
620 Buffer = InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);\r
621 if (Buffer != NULL) {\r
622 MemoryProfileLibRecord (\r
623 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
624 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_ZERO_POOL,\r
625 EfiBootServicesData,\r
626 Buffer,\r
627 AllocationSize,\r
628 NULL\r
629 );\r
630 }\r
631 return Buffer;\r
0ac72713 632}\r
633\r
634/**\r
635 Allocates and zeros a buffer of type EfiRuntimeServicesData.\r
636\r
637 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the\r
638 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
639 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
640 request, then NULL is returned.\r
641\r
642 @param AllocationSize The number of bytes to allocate and zero.\r
643\r
644 @return A pointer to the allocated buffer or NULL if allocation fails.\r
645\r
646**/\r
647VOID *\r
648EFIAPI\r
649AllocateRuntimeZeroPool (\r
650 IN UINTN AllocationSize\r
651 )\r
652{\r
e2735692
SZ
653 VOID *Buffer;\r
654\r
655 Buffer = InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
656 if (Buffer != NULL) {\r
657 MemoryProfileLibRecord (\r
658 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
659 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_ZERO_POOL,\r
660 EfiRuntimeServicesData,\r
661 Buffer,\r
662 AllocationSize,\r
663 NULL\r
664 );\r
665 }\r
666 return Buffer;\r
0ac72713 667}\r
668\r
669/**\r
670 Allocates and zeros a buffer of type EfiReservedMemoryType.\r
671\r
672 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the\r
673 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
674 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
675 request, then NULL is returned.\r
676\r
677 @param AllocationSize The number of bytes to allocate and zero.\r
678\r
679 @return A pointer to the allocated buffer or NULL if allocation fails.\r
680\r
681**/\r
682VOID *\r
683EFIAPI\r
684AllocateReservedZeroPool (\r
685 IN UINTN AllocationSize\r
686 )\r
687{\r
e2735692
SZ
688 VOID *Buffer;\r
689\r
690 Buffer = InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);\r
691 if (Buffer != NULL) {\r
692 MemoryProfileLibRecord (\r
693 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
694 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_ZERO_POOL,\r
695 EfiReservedMemoryType,\r
696 Buffer,\r
697 AllocationSize,\r
698 NULL\r
699 );\r
700 }\r
701 return Buffer;\r
0ac72713 702}\r
703\r
704/**\r
446b94b0 705 Copies a buffer to an allocated buffer of a certain pool type.\r
0ac72713 706\r
446b94b0 707 Allocates the number bytes specified by AllocationSize of a certain pool type, copies\r
0ac72713 708 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
709 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
710 is not enough memory remaining to satisfy the request, then NULL is returned.\r
711 If Buffer is NULL, then ASSERT().\r
712 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
713\r
714 @param PoolType The type of pool to allocate.\r
715 @param AllocationSize The number of bytes to allocate and zero.\r
716 @param Buffer The buffer to copy to the allocated buffer.\r
717\r
718 @return A pointer to the allocated buffer or NULL if allocation fails.\r
719\r
720**/\r
721VOID *\r
722InternalAllocateCopyPool (\r
723 IN EFI_MEMORY_TYPE PoolType, \r
724 IN UINTN AllocationSize,\r
725 IN CONST VOID *Buffer\r
726 ) \r
727{\r
728 VOID *Memory;\r
729\r
730 ASSERT (Buffer != NULL);\r
731 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
732\r
733 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
734 if (Memory != NULL) {\r
735 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
736 }\r
737 return Memory;\r
738} \r
739\r
740/**\r
741 Copies a buffer to an allocated buffer of type EfiBootServicesData.\r
742\r
743 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies\r
744 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
745 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
746 is not enough memory remaining to satisfy the request, then NULL is returned.\r
f6998888 747 \r
0ac72713 748 If Buffer is NULL, then ASSERT().\r
749 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
750\r
751 @param AllocationSize The number of bytes to allocate and zero.\r
752 @param Buffer The buffer to copy to the allocated buffer.\r
753\r
754 @return A pointer to the allocated buffer or NULL if allocation fails.\r
755\r
756**/\r
757VOID *\r
758EFIAPI\r
759AllocateCopyPool (\r
760 IN UINTN AllocationSize,\r
761 IN CONST VOID *Buffer\r
762 )\r
763{\r
e2735692
SZ
764 VOID *NewBuffer;\r
765\r
766 NewBuffer = InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);\r
767 if (NewBuffer != NULL) {\r
768 MemoryProfileLibRecord (\r
769 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
770 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_COPY_POOL,\r
771 EfiBootServicesData,\r
772 NewBuffer,\r
773 AllocationSize,\r
774 NULL\r
775 );\r
776 }\r
777 return NewBuffer;\r
0ac72713 778}\r
779\r
780/**\r
781 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.\r
782\r
783 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies\r
784 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
785 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
786 is not enough memory remaining to satisfy the request, then NULL is returned.\r
f6998888 787 \r
0ac72713 788 If Buffer is NULL, then ASSERT().\r
789 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
790\r
791 @param AllocationSize The number of bytes to allocate and zero.\r
792 @param Buffer The buffer to copy to the allocated buffer.\r
793\r
794 @return A pointer to the allocated buffer or NULL if allocation fails.\r
795\r
796**/\r
797VOID *\r
798EFIAPI\r
799AllocateRuntimeCopyPool (\r
800 IN UINTN AllocationSize,\r
801 IN CONST VOID *Buffer\r
802 )\r
803{\r
e2735692
SZ
804 VOID *NewBuffer;\r
805\r
806 NewBuffer = InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
807 if (NewBuffer != NULL) {\r
808 MemoryProfileLibRecord (\r
809 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
810 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RUNTIME_COPY_POOL,\r
811 EfiRuntimeServicesData,\r
812 NewBuffer,\r
813 AllocationSize,\r
814 NULL\r
815 );\r
816 }\r
817 return NewBuffer;\r
0ac72713 818}\r
819\r
820/**\r
821 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.\r
822\r
823 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies\r
824 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
825 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
826 is not enough memory remaining to satisfy the request, then NULL is returned.\r
f6998888 827 \r
0ac72713 828 If Buffer is NULL, then ASSERT().\r
829 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
830\r
831 @param AllocationSize The number of bytes to allocate and zero.\r
832 @param Buffer The buffer to copy to the allocated buffer.\r
833\r
834 @return A pointer to the allocated buffer or NULL if allocation fails.\r
835\r
836**/\r
837VOID *\r
838EFIAPI\r
839AllocateReservedCopyPool (\r
840 IN UINTN AllocationSize,\r
841 IN CONST VOID *Buffer\r
842 )\r
843{\r
e2735692
SZ
844 VOID *NewBuffer;\r
845\r
846 NewBuffer = InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);\r
847 if (NewBuffer != NULL) {\r
848 MemoryProfileLibRecord (\r
849 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
850 MEMORY_PROFILE_ACTION_LIB_ALLOCATE_RESERVED_COPY_POOL,\r
851 EfiRuntimeServicesData,\r
852 NewBuffer,\r
853 AllocationSize,\r
854 NULL\r
855 );\r
856 }\r
857 return NewBuffer;\r
0ac72713 858}\r
859\r
f6998888 860/**\r
861 Reallocates a buffer of a specified memory type.\r
862\r
863 Allocates and zeros the number bytes specified by NewSize from memory of the type\r
864 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and \r
865 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and \r
866 OldBuffer is freed. A pointer to the newly allocated buffer is returned. \r
867 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not \r
868 enough memory remaining to satisfy the request, then NULL is returned.\r
869 \r
56304569 870 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
871 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
f6998888 872\r
873 @param PoolType The type of pool to allocate.\r
874 @param OldSize The size, in bytes, of OldBuffer.\r
875 @param NewSize The size, in bytes, of the buffer to reallocate.\r
876 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional \r
877 parameter that may be NULL.\r
878\r
879 @return A pointer to the allocated buffer or NULL if allocation fails.\r
880\r
881**/\r
882VOID *\r
883InternalReallocatePool (\r
884 IN EFI_MEMORY_TYPE PoolType, \r
885 IN UINTN OldSize,\r
886 IN UINTN NewSize,\r
887 IN VOID *OldBuffer OPTIONAL\r
888 )\r
889{\r
890 VOID *NewBuffer;\r
891\r
ae55f4eb 892 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);\r
f6998888 893 if (NewBuffer != NULL && OldBuffer != NULL) {\r
894 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));\r
895 FreePool (OldBuffer);\r
896 }\r
897 return NewBuffer;\r
898}\r
899\r
900/**\r
901 Reallocates a buffer of type EfiBootServicesData.\r
902\r
903 Allocates and zeros the number bytes specified by NewSize from memory of type\r
904 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and \r
905 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and \r
906 OldBuffer is freed. A pointer to the newly allocated buffer is returned. \r
907 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not \r
908 enough memory remaining to satisfy the request, then NULL is returned.\r
909 \r
56304569 910 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
911 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
f6998888 912\r
913 @param OldSize The size, in bytes, of OldBuffer.\r
914 @param NewSize The size, in bytes, of the buffer to reallocate.\r
915 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional \r
916 parameter that may be NULL.\r
917\r
918 @return A pointer to the allocated buffer or NULL if allocation fails.\r
919\r
920**/\r
921VOID *\r
922EFIAPI\r
923ReallocatePool (\r
924 IN UINTN OldSize,\r
925 IN UINTN NewSize,\r
926 IN VOID *OldBuffer OPTIONAL\r
927 )\r
928{\r
e2735692
SZ
929 VOID *Buffer;\r
930\r
931 Buffer = InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);\r
932 if (Buffer != NULL) {\r
933 MemoryProfileLibRecord (\r
934 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
935 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_POOL,\r
936 EfiBootServicesData,\r
937 Buffer,\r
938 NewSize,\r
939 NULL\r
940 );\r
941 }\r
942 return Buffer;\r
f6998888 943}\r
944\r
945/**\r
946 Reallocates a buffer of type EfiRuntimeServicesData.\r
947\r
948 Allocates and zeros the number bytes specified by NewSize from memory of type\r
949 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and \r
950 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and \r
951 OldBuffer is freed. A pointer to the newly allocated buffer is returned. \r
952 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not \r
953 enough memory remaining to satisfy the request, then NULL is returned.\r
954\r
56304569 955 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
956 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
f6998888 957\r
958 @param OldSize The size, in bytes, of OldBuffer.\r
959 @param NewSize The size, in bytes, of the buffer to reallocate.\r
960 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional \r
961 parameter that may be NULL.\r
962\r
963 @return A pointer to the allocated buffer or NULL if allocation fails.\r
964\r
965**/\r
966VOID *\r
967EFIAPI\r
968ReallocateRuntimePool (\r
969 IN UINTN OldSize,\r
970 IN UINTN NewSize,\r
971 IN VOID *OldBuffer OPTIONAL\r
972 )\r
973{\r
e2735692
SZ
974 VOID *Buffer;\r
975\r
976 Buffer = InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);\r
977 if (Buffer != NULL) {\r
978 MemoryProfileLibRecord (\r
979 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
980 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RUNTIME_POOL,\r
981 EfiRuntimeServicesData,\r
982 Buffer,\r
983 NewSize,\r
984 NULL\r
985 );\r
986 }\r
987 return Buffer;\r
f6998888 988}\r
989\r
990/**\r
991 Reallocates a buffer of type EfiReservedMemoryType.\r
992\r
993 Allocates and zeros the number bytes specified by NewSize from memory of type\r
994 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and \r
995 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and \r
996 OldBuffer is freed. A pointer to the newly allocated buffer is returned. \r
997 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not \r
998 enough memory remaining to satisfy the request, then NULL is returned.\r
6a30c6d0 999\r
56304569 1000 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
1001 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
f6998888 1002\r
1003 @param OldSize The size, in bytes, of OldBuffer.\r
1004 @param NewSize The size, in bytes, of the buffer to reallocate.\r
1005 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional \r
1006 parameter that may be NULL.\r
1007\r
1008 @return A pointer to the allocated buffer or NULL if allocation fails.\r
1009\r
1010**/\r
1011VOID *\r
1012EFIAPI\r
1013ReallocateReservedPool (\r
1014 IN UINTN OldSize,\r
1015 IN UINTN NewSize,\r
1016 IN VOID *OldBuffer OPTIONAL\r
1017 )\r
1018{\r
e2735692
SZ
1019 VOID *Buffer;\r
1020\r
1021 Buffer = InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);\r
1022 if (Buffer != NULL) {\r
1023 MemoryProfileLibRecord (\r
1024 (PHYSICAL_ADDRESS) (UINTN) RETURN_ADDRESS(0),\r
1025 MEMORY_PROFILE_ACTION_LIB_REALLOCATE_RESERVED_POOL,\r
1026 EfiReservedMemoryType,\r
1027 Buffer,\r
1028 NewSize,\r
1029 NULL\r
1030 );\r
1031 }\r
1032 return Buffer;\r
f6998888 1033}\r
1034\r
0ac72713 1035/**\r
1036 Frees a buffer that was previously allocated with one of the pool allocation functions in the\r
1037 Memory Allocation Library.\r
1038\r
1039 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the\r
aa2f249e 1040 pool allocation services of the Memory Allocation Library. If it is not possible to free pool\r
446b94b0 1041 resources, then this function will perform no actions.\r
f6998888 1042 \r
0ac72713 1043 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,\r
1044 then ASSERT().\r
1045\r
1046 @param Buffer Pointer to the buffer to free.\r
1047\r
1048**/\r
1049VOID\r
1050EFIAPI\r
1051FreePool (\r
1052 IN VOID *Buffer\r
1053 )\r
1054{\r
1055 EFI_STATUS Status;\r
1056\r
1057 Status = CoreFreePool (Buffer);\r
1058 ASSERT_EFI_ERROR (Status);\r
1059}\r
1060\r