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