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