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