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