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