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