]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c
Don't initialize local variables in its declaration.
[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
6809c872 5 Copyright (c) 2006 - 2014, 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
6809c872
LG
210 EFI_PHYSICAL_ADDRESS Memory;\r
211 EFI_PHYSICAL_ADDRESS AlignedMemory;\r
212 EFI_PEI_HOB_POINTERS Hob;\r
4c103c55
LG
213 BOOLEAN SkipBeforeMemHob;\r
214 BOOLEAN SkipAfterMemHob;\r
6809c872
LG
215 EFI_PHYSICAL_ADDRESS HobBaseAddress;\r
216 UINT64 HobLength;\r
217 EFI_MEMORY_TYPE HobMemoryType;\r
218 UINTN TotalPages;\r
e386b444 219\r
220 //\r
221 // Alignment must be a power of two or zero.\r
222 //\r
223 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
224\r
225 if (Pages == 0) {\r
226 return NULL;\r
227 }\r
228 //\r
229 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.\r
230 //\r
6809c872
LG
231 ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment))); \r
232\r
e386b444 233 //\r
234 // We would rather waste some memory to save PEI code size.\r
6809c872
LG
235 // meaning in addition to the requested size for the aligned mem,\r
236 // we simply reserve an overhead memory equal to Alignmemt(page-aligned), no matter what.\r
237 // The overhead mem size could be reduced later with more involved malloc mechanisms\r
238 // (e.g., somthing that can detect the alignment boundary before allocating memory or \r
239 // can request that memory be allocated at a certain address that is aleady aligned).\r
240 //\r
241 TotalPages = Pages + (Alignment <= EFI_PAGE_SIZE ? 0 : EFI_SIZE_TO_PAGES(Alignment));\r
242 Memory = (EFI_PHYSICAL_ADDRESS) (UINTN) InternalAllocatePages (MemoryType, TotalPages);\r
243 if (Memory == 0) {\r
244 DEBUG((DEBUG_INFO, "Out of memory resource! \n"));\r
245 return NULL;\r
246 }\r
247 DEBUG ((DEBUG_INFO, "Allocated Memory unaligned: Address = 0x%LX, Pages = 0x%X, Type = %d \n", Memory, TotalPages, (UINTN) MemoryType));\r
248\r
249 //\r
250 // Alignment calculation\r
251 //\r
252 AlignedMemory = Memory;\r
253 if (Alignment > EFI_PAGE_SIZE) {\r
254 AlignedMemory = ALIGN_VALUE (Memory, Alignment);\r
255 }\r
256 DEBUG ((DEBUG_INFO, "After aligning to 0x%X bytes: Address = 0x%LX, Pages = 0x%X \n", Alignment, AlignedMemory, Pages));\r
257\r
258 //\r
259 // In general three HOBs cover the total allocated space.\r
260 // The aligned portion is covered by the aligned mem HOB and\r
261 // the unaligned(to be freed) portions before and after the aligned portion are covered by newly created HOBs.\r
e386b444 262 //\r
6809c872
LG
263 // Before mem HOB covers the region between "Memory" and "AlignedMemory"\r
264 // Aligned mem HOB covers the region between "AlignedMemory" and "AlignedMemory + EFI_PAGES_TO_SIZE(Pages)"\r
265 // After mem HOB covers the region between "AlignedMemory + EFI_PAGES_TO_SIZE(Pages)" and "Memory + EFI_PAGES_TO_SIZE(TotalPages)"\r
266 //\r
267 // The before or after mem HOBs need to be skipped under special cases where the aligned portion\r
268 // touches either the top or bottom of the original allocated space.\r
269 //\r
4c103c55
LG
270 SkipBeforeMemHob = FALSE;\r
271 SkipAfterMemHob = FALSE;\r
6809c872
LG
272 if (Memory == AlignedMemory) {\r
273 SkipBeforeMemHob = TRUE;\r
274 }\r
275 if ((Memory + EFI_PAGES_TO_SIZE(TotalPages)) == (AlignedMemory + EFI_PAGES_TO_SIZE(Pages))) {\r
276 //\r
277 // This condition is never met in the current implementation.\r
278 // There is always some after-mem since the overhead mem(used in TotalPages)\r
279 // is no less than Alignment.\r
280 //\r
281 SkipAfterMemHob = TRUE;\r
282 }\r
283\r
284 // \r
285 // Search for the mem HOB referring to the original(unaligned) allocation \r
286 // and update the size and type if needed.\r
287 //\r
288 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);\r
289 while (Hob.Raw != NULL) {\r
290 if (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == Memory) {\r
291 break;\r
292 }\r
293 Hob.Raw = GET_NEXT_HOB (Hob);\r
294 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);\r
295 }\r
296 ASSERT (Hob.Raw != NULL);\r
297 if (SkipBeforeMemHob) {\r
298 //\r
299 // Use this HOB as aligned mem HOB as there is no portion before it.\r
300 //\r
301 HobLength = EFI_PAGES_TO_SIZE(Pages);\r
302 Hob.MemoryAllocation->AllocDescriptor.MemoryLength = HobLength;\r
303 } else {\r
304 //\r
305 // Use this HOB as before mem HOB and create a new HOB for the aligned portion \r
306 //\r
307 HobLength = (AlignedMemory - Memory); \r
308 Hob.MemoryAllocation->AllocDescriptor.MemoryLength = HobLength;\r
309 Hob.MemoryAllocation->AllocDescriptor.MemoryType = EfiConventionalMemory;\r
310 }\r
311\r
312 HobBaseAddress = Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress;\r
313 HobMemoryType = Hob.MemoryAllocation->AllocDescriptor.MemoryType;\r
314\r
315 //\r
316 // Build the aligned mem HOB if needed\r
317 //\r
318 if (!SkipBeforeMemHob) {\r
319 DEBUG((DEBUG_INFO, "Updated before-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",\r
320 HobBaseAddress, HobLength, (UINTN) HobMemoryType));\r
321\r
322 HobBaseAddress = AlignedMemory;\r
323 HobLength = EFI_PAGES_TO_SIZE(Pages);\r
324 HobMemoryType = MemoryType;\r
325\r
326 BuildMemoryAllocationHob (\r
327 HobBaseAddress,\r
328 HobLength,\r
329 HobMemoryType\r
330 );\r
331\r
332 DEBUG((DEBUG_INFO, "Created aligned-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",\r
333 HobBaseAddress, HobLength, (UINTN) HobMemoryType));\r
e386b444 334 } else {\r
6809c872
LG
335 if (HobBaseAddress != 0) {\r
336 DEBUG((DEBUG_INFO, "Updated aligned-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",\r
337 HobBaseAddress, HobLength, (UINTN) HobMemoryType));\r
338 }\r
e386b444 339 }\r
6809c872
LG
340\r
341\r
342 //\r
343 // Build the after mem HOB if needed\r
344 //\r
345 if (!SkipAfterMemHob) {\r
346 HobBaseAddress = AlignedMemory + EFI_PAGES_TO_SIZE(Pages);\r
347 HobLength = (Memory + EFI_PAGES_TO_SIZE(TotalPages)) - (AlignedMemory + EFI_PAGES_TO_SIZE(Pages));\r
348 HobMemoryType = EfiConventionalMemory;\r
349\r
350 BuildMemoryAllocationHob (\r
351 HobBaseAddress,\r
352 HobLength,\r
353 HobMemoryType\r
354 );\r
355\r
356 DEBUG((DEBUG_INFO, "Created after-mem HOB with BaseAddress = %LX, Length = %LX, MemoryType = %d \n",\r
357 HobBaseAddress, HobLength, (UINTN) HobMemoryType));\r
358 }\r
359\r
360 return (VOID *) (UINTN) AlignedMemory;\r
e386b444 361}\r
362\r
363/**\r
364 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.\r
365\r
366 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an\r
367 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
368 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
369 request, then NULL is returned.\r
9638ba6d 370 \r
e386b444 371 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
1346352d 372 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().\r
e386b444 373\r
374 @param Pages The number of 4 KB pages to allocate.\r
58380e9c 375 @param Alignment The requested alignment of the allocation. \r
376 Must be a power of two.\r
e386b444 377 If Alignment is zero, then byte alignment is used.\r
378\r
379 @return A pointer to the allocated buffer or NULL if allocation fails.\r
380\r
381**/\r
382VOID *\r
383EFIAPI\r
384AllocateAlignedPages (\r
385 IN UINTN Pages,\r
386 IN UINTN Alignment\r
387 )\r
388{\r
389 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);\r
390}\r
391\r
392/**\r
393 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.\r
394\r
395 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an\r
396 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
397 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
398 request, then NULL is returned.\r
9638ba6d 399 \r
e386b444 400 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
1346352d 401 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().\r
e386b444 402\r
403 @param Pages The number of 4 KB pages to allocate.\r
58380e9c 404 @param Alignment The requested alignment of the allocation. \r
405 Must be a power of two.\r
e386b444 406 If Alignment is zero, then byte alignment is used.\r
407\r
408 @return A pointer to the allocated buffer or NULL if allocation fails.\r
409\r
410**/\r
411VOID *\r
412EFIAPI\r
413AllocateAlignedRuntimePages (\r
414 IN UINTN Pages,\r
415 IN UINTN Alignment\r
416 )\r
417{\r
418 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);\r
419}\r
420\r
421/**\r
422 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.\r
423\r
424 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an\r
425 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
426 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
427 request, then NULL is returned.\r
9638ba6d 428 \r
e386b444 429 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
1346352d 430 If Pages plus EFI_SIZE_TO_PAGES (Alignment) overflows, then ASSERT().\r
e386b444 431\r
432 @param Pages The number of 4 KB pages to allocate.\r
58380e9c 433 @param Alignment The requested alignment of the allocation. \r
434 Must be a power of two.\r
e386b444 435 If Alignment is zero, then byte alignment is used.\r
436\r
437 @return A pointer to the allocated buffer or NULL if allocation fails.\r
438\r
439**/\r
440VOID *\r
441EFIAPI\r
442AllocateAlignedReservedPages (\r
443 IN UINTN Pages,\r
444 IN UINTN Alignment\r
445 )\r
446{\r
447 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);\r
448}\r
449\r
450/**\r
451 Frees one or more 4KB pages that were previously allocated with one of the aligned page\r
452 allocation functions in the Memory Allocation Library.\r
453\r
454 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer\r
455 must have been allocated on a previous call to the aligned page allocation services of the Memory\r
6e10b70a 456 Allocation Library. If it is not possible to free allocated pages, then this function will \r
446b94b0 457 perform no actions.\r
9638ba6d 458 \r
e386b444 459 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation\r
460 Library, then ASSERT().\r
461 If Pages is zero, then ASSERT().\r
462 \r
2fc59a00 463 @param Buffer The pointer to the buffer of pages to free.\r
e386b444 464 @param Pages The number of 4 KB pages to free.\r
465\r
466**/\r
467VOID\r
468EFIAPI\r
469FreeAlignedPages (\r
470 IN VOID *Buffer,\r
471 IN UINTN Pages\r
472 )\r
473{\r
6e10b70a 474 ASSERT (Pages != 0);\r
e386b444 475 //\r
476 // PEI phase does not support to free pages, so leave it as NOP.\r
477 //\r
478}\r
479\r
480/**\r
481 Allocates a buffer of a certain pool type.\r
482\r
483 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a\r
484 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
485 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
486\r
487 @param MemoryType The type of memory to allocate.\r
488 @param AllocationSize The number of bytes to allocate.\r
489\r
490 @return A pointer to the allocated buffer or NULL if allocation fails.\r
491\r
492**/\r
493VOID *\r
494InternalAllocatePool (\r
495 IN EFI_MEMORY_TYPE MemoryType, \r
496 IN UINTN AllocationSize\r
497 )\r
498{\r
499 //\r
500 // If we need lots of small runtime/reserved memory type from PEI in the future, \r
501 // we can consider providing a more complex algorithm that allocates runtime pages and \r
502 // provide pool allocations from those pages. \r
503 //\r
504 return InternalAllocatePages (MemoryType, EFI_SIZE_TO_PAGES (AllocationSize));\r
505}\r
506\r
507/**\r
508 Allocates a buffer of type EfiBootServicesData.\r
509\r
510 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a\r
511 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
512 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
513\r
514 @param AllocationSize The number of bytes to allocate.\r
515\r
516 @return A pointer to the allocated buffer or NULL if allocation fails.\r
517\r
518**/\r
519VOID *\r
520EFIAPI\r
521AllocatePool (\r
522 IN UINTN AllocationSize\r
523 )\r
524{\r
525 EFI_STATUS Status;\r
e386b444 526 VOID *Buffer;\r
527 \r
1c280088 528 Status = PeiServicesAllocatePool (AllocationSize, &Buffer);\r
e386b444 529 if (EFI_ERROR (Status)) {\r
530 Buffer = NULL;\r
531 }\r
532 return Buffer;\r
533}\r
534\r
535/**\r
536 Allocates a buffer of type EfiRuntimeServicesData.\r
537\r
538 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns\r
539 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
540 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
541\r
542 @param AllocationSize The number of bytes to allocate.\r
543\r
544 @return A pointer to the allocated buffer or NULL if allocation fails.\r
545\r
546**/\r
547VOID *\r
548EFIAPI\r
549AllocateRuntimePool (\r
550 IN UINTN AllocationSize\r
551 )\r
552{\r
553 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
554}\r
555\r
556/**\r
8789c5e0 557 Allocates a buffer of type EfiReservedMemoryType.\r
e386b444 558\r
8789c5e0 559 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType and returns\r
e386b444 560 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
561 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
562\r
563 @param AllocationSize The number of bytes to allocate.\r
564\r
565 @return A pointer to the allocated buffer or NULL if allocation fails.\r
566\r
567**/\r
568VOID *\r
569EFIAPI\r
570AllocateReservedPool (\r
571 IN UINTN AllocationSize\r
572 )\r
573{\r
574 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);\r
575}\r
576\r
577/**\r
446b94b0 578 Allocates and zeros a buffer of a certain pool type.\r
e386b444 579\r
446b94b0 580 Allocates the number bytes specified by AllocationSize of a certain pool type, clears the buffer\r
e386b444 581 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid\r
582 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,\r
583 then NULL is returned.\r
584\r
585 @param PoolType The type of memory to allocate.\r
586 @param AllocationSize The number of bytes to allocate and zero.\r
587\r
588 @return A pointer to the allocated buffer or NULL if allocation fails.\r
589\r
590**/\r
591VOID *\r
592InternalAllocateZeroPool (\r
593 IN EFI_MEMORY_TYPE PoolType, \r
594 IN UINTN AllocationSize\r
595 ) \r
596{\r
597 VOID *Memory;\r
598\r
599 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
600 if (Memory != NULL) {\r
601 Memory = ZeroMem (Memory, AllocationSize);\r
602 }\r
603 return Memory;\r
604}\r
605\r
606/**\r
607 Allocates and zeros a buffer of type EfiBootServicesData.\r
608\r
609 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the\r
610 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
611 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
612 request, then NULL is returned.\r
613\r
614 @param AllocationSize The number of bytes to allocate and zero.\r
615\r
616 @return A pointer to the allocated buffer or NULL if allocation fails.\r
617\r
618**/\r
619VOID *\r
620EFIAPI\r
621AllocateZeroPool (\r
622 IN UINTN AllocationSize\r
623 )\r
624{\r
625 VOID *Memory;\r
626\r
627 Memory = AllocatePool (AllocationSize);\r
628 if (Memory != NULL) {\r
629 Memory = ZeroMem (Memory, AllocationSize);\r
630 }\r
631 return Memory;\r
632}\r
633\r
634/**\r
635 Allocates and zeros a buffer of type EfiRuntimeServicesData.\r
636\r
637 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the\r
638 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
639 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
640 request, then NULL is returned.\r
641\r
642 @param AllocationSize The number of bytes to allocate and zero.\r
643\r
644 @return A pointer to the allocated buffer or NULL if allocation fails.\r
645\r
646**/\r
647VOID *\r
648EFIAPI\r
649AllocateRuntimeZeroPool (\r
650 IN UINTN AllocationSize\r
651 )\r
652{\r
653 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
654}\r
655\r
656/**\r
657 Allocates and zeros a buffer of type EfiReservedMemoryType.\r
658\r
659 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the\r
660 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
661 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
662 request, then NULL is returned.\r
663\r
664 @param AllocationSize The number of bytes to allocate and zero.\r
665\r
666 @return A pointer to the allocated buffer or NULL if allocation fails.\r
667\r
668**/\r
669VOID *\r
670EFIAPI\r
671AllocateReservedZeroPool (\r
672 IN UINTN AllocationSize\r
673 )\r
674{\r
675 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);\r
676}\r
677\r
678/**\r
446b94b0 679 Copies a buffer to an allocated buffer of a certain pool type.\r
e386b444 680\r
446b94b0 681 Allocates the number bytes specified by AllocationSize of a certain pool type, copies\r
e386b444 682 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
683 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
684 is not enough memory remaining to satisfy the request, then NULL is returned.\r
685 If Buffer is NULL, then ASSERT().\r
9e6fa6d2 686 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
e386b444 687\r
688 @param PoolType The type of pool to allocate.\r
689 @param AllocationSize The number of bytes to allocate and zero.\r
690 @param Buffer The buffer to copy to the allocated buffer.\r
691\r
692 @return A pointer to the allocated buffer or NULL if allocation fails.\r
693\r
694**/\r
695VOID *\r
696InternalAllocateCopyPool (\r
697 IN EFI_MEMORY_TYPE PoolType, \r
698 IN UINTN AllocationSize,\r
699 IN CONST VOID *Buffer\r
700 ) \r
701{\r
702 VOID *Memory;\r
703\r
704 ASSERT (Buffer != NULL);\r
705 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
706\r
707 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
708 if (Memory != NULL) {\r
709 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
710 }\r
711 return Memory;\r
712} \r
713\r
714/**\r
715 Copies a buffer to an allocated buffer of type EfiBootServicesData.\r
716\r
717 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies\r
718 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
719 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
720 is not enough memory remaining to satisfy the request, then NULL is returned.\r
9638ba6d 721 \r
e386b444 722 If Buffer is NULL, then ASSERT().\r
9e6fa6d2 723 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
e386b444 724\r
725 @param AllocationSize The number of bytes to allocate and zero.\r
726 @param Buffer The buffer to copy to the allocated buffer.\r
727\r
728 @return A pointer to the allocated buffer or NULL if allocation fails.\r
729\r
730**/\r
731VOID *\r
732EFIAPI\r
733AllocateCopyPool (\r
734 IN UINTN AllocationSize,\r
735 IN CONST VOID *Buffer\r
736 )\r
737{\r
738 VOID *Memory;\r
739\r
740 ASSERT (Buffer != NULL);\r
741 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
742\r
743 Memory = AllocatePool (AllocationSize);\r
744 if (Memory != NULL) {\r
745 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
746 }\r
747 return Memory;\r
748}\r
749\r
750/**\r
751 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.\r
752\r
753 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies\r
754 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
755 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
756 is not enough memory remaining to satisfy the request, then NULL is returned.\r
9638ba6d 757 \r
e386b444 758 If Buffer is NULL, then ASSERT().\r
9e6fa6d2 759 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
e386b444 760\r
761 @param AllocationSize The number of bytes to allocate and zero.\r
762 @param Buffer The buffer to copy to the allocated buffer.\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
769AllocateRuntimeCopyPool (\r
770 IN UINTN AllocationSize,\r
771 IN CONST VOID *Buffer\r
772 )\r
773{\r
774 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
775}\r
776\r
777/**\r
778 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.\r
779\r
780 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies\r
781 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
782 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
783 is not enough memory remaining to satisfy the request, then NULL is returned.\r
9638ba6d 784 \r
e386b444 785 If Buffer is NULL, then ASSERT().\r
9e6fa6d2 786 If AllocationSize is greater than (MAX_ADDRESS - Buffer + 1), then ASSERT(). \r
e386b444 787\r
788 @param AllocationSize The number of bytes to allocate and zero.\r
789 @param Buffer The buffer to copy to the allocated buffer.\r
790\r
791 @return A pointer to the allocated buffer or NULL if allocation fails.\r
792\r
793**/\r
794VOID *\r
795EFIAPI\r
796AllocateReservedCopyPool (\r
797 IN UINTN AllocationSize,\r
798 IN CONST VOID *Buffer\r
799 )\r
800{\r
801 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);\r
802}\r
803\r
3b6a71fc 804/**\r
805 Reallocates a buffer of a specified memory type.\r
806\r
807 Allocates and zeros the number bytes specified by NewSize from memory of the type\r
808 specified by PoolType. If OldBuffer is not NULL, then the smaller of OldSize and \r
809 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and \r
810 OldBuffer is freed. A pointer to the newly allocated buffer is returned. \r
811 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not \r
812 enough memory remaining to satisfy the request, then NULL is returned.\r
813 \r
56304569 814 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
815 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
3b6a71fc 816\r
817 @param PoolType The type of pool to allocate.\r
818 @param OldSize The size, in bytes, of OldBuffer.\r
819 @param NewSize The size, in bytes, of the buffer to reallocate.\r
58380e9c 820 @param OldBuffer The buffer to copy to the allocated buffer. This is an \r
821 optional parameter that may be NULL.\r
3b6a71fc 822\r
823 @return A pointer to the allocated buffer or NULL if allocation fails.\r
824\r
825**/\r
826VOID *\r
3b6a71fc 827InternalReallocatePool (\r
828 IN EFI_MEMORY_TYPE PoolType, \r
829 IN UINTN OldSize,\r
830 IN UINTN NewSize,\r
831 IN VOID *OldBuffer OPTIONAL\r
832 )\r
833{\r
834 VOID *NewBuffer;\r
835\r
6babbe1f 836 NewBuffer = InternalAllocateZeroPool (PoolType, NewSize);\r
3b6a71fc 837 if (NewBuffer != NULL && OldBuffer != NULL) {\r
838 CopyMem (NewBuffer, OldBuffer, MIN (OldSize, NewSize));\r
839 FreePool (OldBuffer);\r
840 }\r
841 return NewBuffer;\r
842}\r
843\r
844/**\r
845 Reallocates a buffer of type EfiBootServicesData.\r
846\r
847 Allocates and zeros the number bytes specified by NewSize from memory of type\r
848 EfiBootServicesData. If OldBuffer is not NULL, then the smaller of OldSize and \r
849 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and \r
850 OldBuffer is freed. A pointer to the newly allocated buffer is returned. \r
851 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not \r
852 enough memory remaining to satisfy the request, then NULL is returned.\r
853 \r
56304569 854 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
855 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
3b6a71fc 856\r
857 @param OldSize The size, in bytes, of OldBuffer.\r
858 @param NewSize The size, in bytes, of the buffer to reallocate.\r
859 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional \r
860 parameter that may be NULL.\r
861\r
862 @return A pointer to the allocated buffer or NULL if allocation fails.\r
863\r
864**/\r
865VOID *\r
866EFIAPI\r
867ReallocatePool (\r
868 IN UINTN OldSize,\r
869 IN UINTN NewSize,\r
870 IN VOID *OldBuffer OPTIONAL\r
871 )\r
872{\r
873 return InternalReallocatePool (EfiBootServicesData, OldSize, NewSize, OldBuffer);\r
874}\r
875\r
876/**\r
877 Reallocates a buffer of type EfiRuntimeServicesData.\r
878\r
879 Allocates and zeros the number bytes specified by NewSize from memory of type\r
880 EfiRuntimeServicesData. If OldBuffer is not NULL, then the smaller of OldSize and \r
881 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and \r
882 OldBuffer is freed. A pointer to the newly allocated buffer is returned. \r
883 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not \r
884 enough memory remaining to satisfy the request, then NULL is returned.\r
885\r
56304569 886 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
887 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
3b6a71fc 888\r
889 @param OldSize The size, in bytes, of OldBuffer.\r
890 @param NewSize The size, in bytes, of the buffer to reallocate.\r
891 @param OldBuffer The buffer to copy to the allocated buffer. This is an optional \r
892 parameter that may be NULL.\r
893\r
894 @return A pointer to the allocated buffer or NULL if allocation fails.\r
895\r
896**/\r
897VOID *\r
898EFIAPI\r
899ReallocateRuntimePool (\r
900 IN UINTN OldSize,\r
901 IN UINTN NewSize,\r
902 IN VOID *OldBuffer OPTIONAL\r
903 )\r
904{\r
905 return InternalReallocatePool (EfiRuntimeServicesData, OldSize, NewSize, OldBuffer);\r
906}\r
907\r
908/**\r
909 Reallocates a buffer of type EfiReservedMemoryType.\r
910\r
911 Allocates and zeros the number bytes specified by NewSize from memory of type\r
912 EfiReservedMemoryType. If OldBuffer is not NULL, then the smaller of OldSize and \r
913 NewSize bytes are copied from OldBuffer to the newly allocated buffer, and \r
914 OldBuffer is freed. A pointer to the newly allocated buffer is returned. \r
915 If NewSize is 0, then a valid buffer of 0 size is returned. If there is not \r
916 enough memory remaining to satisfy the request, then NULL is returned.\r
2297186d 917\r
56304569 918 If the allocation of the new buffer is successful and the smaller of NewSize and OldSize\r
919 is greater than (MAX_ADDRESS - OldBuffer + 1), then ASSERT().\r
3b6a71fc 920\r
921 @param OldSize The size, in bytes, of OldBuffer.\r
922 @param NewSize The size, in bytes, of the buffer to reallocate.\r
58380e9c 923 @param OldBuffer The buffer to copy to the allocated buffer. This is an \r
924 optional parameter that may be NULL.\r
3b6a71fc 925\r
926 @return A pointer to the allocated buffer or NULL if allocation fails.\r
927\r
928**/\r
929VOID *\r
930EFIAPI\r
931ReallocateReservedPool (\r
932 IN UINTN OldSize,\r
933 IN UINTN NewSize,\r
934 IN VOID *OldBuffer OPTIONAL\r
935 )\r
936{\r
937 return InternalReallocatePool (EfiReservedMemoryType, OldSize, NewSize, OldBuffer);\r
938}\r
939\r
e386b444 940/**\r
941 Frees a buffer that was previously allocated with one of the pool allocation functions in the\r
942 Memory Allocation Library.\r
943\r
944 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the\r
6e10b70a 945 pool allocation services of the Memory Allocation Library. If it is not possible to free pool\r
446b94b0 946 resources, then this function will perform no actions.\r
9638ba6d 947 \r
e386b444 948 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,\r
949 then ASSERT().\r
950\r
2fc59a00 951 @param Buffer The pointer to the buffer to free.\r
e386b444 952\r
953**/\r
954VOID\r
955EFIAPI\r
956FreePool (\r
957 IN VOID *Buffer\r
958 )\r
959{\r
960 //\r
961 // PEI phase does not support to free pool, so leave it as NOP.\r
962 //\r
963}\r
964\r
7d582d6b 965\r