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