]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c
MdePkg PeiMemoryAllocationLib: Update InternalAllocateAlignedPages
[mirror_edk2.git] / MdePkg / Library / PeiMemoryAllocationLib / MemoryAllocationLib.c
... / ...
CommitLineData
1/** @file\r
2 Support routines for memory allocation routines \r
3 based on PeiService for PEI phase drivers.\r
4\r
5 Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>\r
6 This program and the accompanying materials \r
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
9 http://opensource.org/licenses/bsd-license.php. \r
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
14**/\r
15\r
16\r
17#include <PiPei.h>\r
18\r
19\r
20#include <Library/MemoryAllocationLib.h>\r
21#include <Library/PeiServicesLib.h>\r
22#include <Library/BaseMemoryLib.h>\r
23#include <Library/DebugLib.h>\r
24#include <Library/HobLib.h>\r
25\r
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
48\r
49 if (Pages == 0) {\r
50 return NULL;\r
51 }\r
52\r
53 Status = PeiServicesAllocatePages (MemoryType, Pages, &Memory);\r
54 if (EFI_ERROR (Status)) {\r
55 return NULL;\r
56 }\r
57\r
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
133 Allocation Library. If it is not possible to free allocated pages, then this function will\r
134 perform no actions.\r
135 \r
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
140 @param Buffer The pointer to the buffer of pages to free.\r
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
151 EFI_STATUS Status;\r
152\r
153 ASSERT (Pages != 0);\r
154 Status = PeiServicesFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
155 ASSERT_EFI_ERROR (Status);\r
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
166 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().\r
167\r
168 @param MemoryType The type of memory to allocate.\r
169 @param Pages The number of 4 KB pages to allocate.\r
170 @param Alignment The requested alignment of the allocation. \r
171 Must be a power of two.\r
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
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
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
199 if (Alignment > EFI_PAGE_SIZE) {\r
200 //\r
201 // Calculate the total number of pages since alignment is larger than page size.\r
202 //\r
203 AlignmentMask = Alignment - 1;\r
204 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);\r
205 //\r
206 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.\r
207 //\r
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
232 } else {\r
233 //\r
234 // Do not over-allocate pages in this case.\r
235 //\r
236 Status = PeiServicesAllocatePages (MemoryType, Pages, &Memory);\r
237 if (EFI_ERROR (Status)) {\r
238 return NULL;\r
239 }\r
240 AlignedMemory = (UINTN) Memory;\r
241 }\r
242 return (VOID *) AlignedMemory;\r
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
252 \r
253 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
254 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().\r
255\r
256 @param Pages The number of 4 KB pages to allocate.\r
257 @param Alignment The requested alignment of the allocation. \r
258 Must be a power of two.\r
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
281 \r
282 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
283 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().\r
284\r
285 @param Pages The number of 4 KB pages to allocate.\r
286 @param Alignment The requested alignment of the allocation. \r
287 Must be a power of two.\r
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
310 \r
311 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
312 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().\r
313\r
314 @param Pages The number of 4 KB pages to allocate.\r
315 @param Alignment The requested alignment of the allocation. \r
316 Must be a power of two.\r
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
338 Allocation Library. If it is not possible to free allocated pages, then this function will \r
339 perform no actions.\r
340 \r
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
345 @param Buffer The pointer to the buffer of pages to free.\r
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
356 EFI_STATUS Status;\r
357\r
358 ASSERT (Pages != 0);\r
359 Status = PeiServicesFreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
360 ASSERT_EFI_ERROR (Status);\r
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
409 VOID *Buffer;\r
410 \r
411 Status = PeiServicesAllocatePool (AllocationSize, &Buffer);\r
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
440 Allocates a buffer of type EfiReservedMemoryType.\r
441\r
442 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns\r
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
461 Allocates and zeros a buffer of a certain pool type.\r
462\r
463 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer\r
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
562 Copies a buffer to an allocated buffer of a certain pool type.\r
563\r
564 Allocates the number bytes specified by AllocationSize of a certain pool type, copies\r
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
569 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
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
604 \r
605 If Buffer is NULL, then ASSERT().\r
606 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
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
640 \r
641 If Buffer is NULL, then ASSERT().\r
642 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
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
667 \r
668 If Buffer is NULL, then ASSERT().\r
669 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
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
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
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
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
703 @param OldBuffer The buffer to copy to the allocated buffer. This is an \r
704 optional parameter that may be NULL.\r
705\r
706 @return A pointer to the allocated buffer or NULL if allocation fails.\r
707\r
708**/\r
709VOID *\r
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
719 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);\r
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
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
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
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
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
800\r
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
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
806 @param OldBuffer The buffer to copy to the allocated buffer. This is an \r
807 optional parameter that may be NULL.\r
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
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
828 pool allocation services of the Memory Allocation Library. If it is not possible to free pool\r
829 resources, then this function will perform no actions.\r
830 \r
831 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,\r
832 then ASSERT().\r
833\r
834 @param Buffer The pointer to the buffer to free.\r
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
848\r