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