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