]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - MdePkg/Library/PeiMemoryAllocationLib/MemoryAllocationLib.c
BDS code calls Hii->FindHandles() with hardcoded length.
[mirror_edk2.git] / MdePkg / Library / PeiMemoryAllocationLib / MemoryAllocationLib.c
... / ...
CommitLineData
1/** @file\r
2 Support routines for memory allocation routines for use with drivers.\r
3\r
4 Copyright (c) 2006, Intel Corporation<BR>\r
5 All rights reserved. This program and the accompanying materials \r
6 are licensed and made available under the terms and conditions of the BSD License \r
7 which accompanies this distribution. The full text of the license may be found at \r
8 http://opensource.org/licenses/bsd-license.php \r
9\r
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
12\r
13 Module Name: MemoryAllocationLib.c\r
14\r
15**/\r
16\r
17\r
18/**\r
19 Allocates one or more 4KB pages of a certain memory type.\r
20\r
21 Allocates the number of 4KB pages of a certain memory type and returns a pointer to the allocated\r
22 buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL is returned.\r
23 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
24\r
25 @param MemoryType The type of memory to allocate.\r
26 @param Pages The number of 4 KB pages to allocate.\r
27\r
28 @return A pointer to the allocated buffer or NULL if allocation fails.\r
29\r
30**/\r
31VOID *\r
32InternalAllocatePages (\r
33 IN EFI_MEMORY_TYPE MemoryType, \r
34 IN UINTN Pages\r
35 )\r
36{\r
37 EFI_STATUS Status;\r
38 EFI_PHYSICAL_ADDRESS Memory; \r
39 EFI_PEI_SERVICES **PeiServices;\r
40\r
41 if (Pages == 0) {\r
42 return NULL;\r
43 }\r
44\r
45 PeiServices = GetPeiServicesTablePointer ();\r
46 Status = (*PeiServices)->AllocatePages (PeiServices, MemoryType, Pages, &Memory);\r
47 if (EFI_ERROR (Status)) {\r
48 Memory = 0;\r
49 }\r
50 return (VOID *) (UINTN) Memory;\r
51}\r
52\r
53/**\r
54 Allocates one or more 4KB pages of type EfiBootServicesData.\r
55\r
56 Allocates the number of 4KB pages of type EfiBootServicesData and returns a pointer to the\r
57 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
58 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
59 returned.\r
60\r
61 @param Pages The number of 4 KB pages to allocate.\r
62\r
63 @return A pointer to the allocated buffer or NULL if allocation fails.\r
64\r
65**/\r
66VOID *\r
67EFIAPI\r
68AllocatePages (\r
69 IN UINTN Pages\r
70 )\r
71{\r
72 return InternalAllocatePages (EfiBootServicesData, Pages);\r
73}\r
74\r
75/**\r
76 Allocates one or more 4KB pages of type EfiRuntimeServicesData.\r
77\r
78 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the\r
79 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
80 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
81 returned.\r
82\r
83 @param Pages The number of 4 KB pages to allocate.\r
84\r
85 @return A pointer to the allocated buffer or NULL if allocation fails.\r
86\r
87**/\r
88VOID *\r
89EFIAPI\r
90AllocateRuntimePages (\r
91 IN UINTN Pages\r
92 )\r
93{\r
94 return InternalAllocatePages (EfiRuntimeServicesData, Pages);\r
95}\r
96\r
97/**\r
98 Allocates one or more 4KB pages of type EfiReservedMemoryType.\r
99\r
100 Allocates the number of 4KB pages of type EfiReservedMemoryType and returns a pointer to the\r
101 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL\r
102 is returned. If there is not enough memory remaining to satisfy the request, then NULL is\r
103 returned.\r
104\r
105 @param Pages The number of 4 KB pages to allocate.\r
106\r
107 @return A pointer to the allocated buffer or NULL if allocation fails.\r
108\r
109**/\r
110VOID *\r
111EFIAPI\r
112AllocateReservedPages (\r
113 IN UINTN Pages\r
114 )\r
115{\r
116 return InternalAllocatePages (EfiReservedMemoryType, Pages);\r
117}\r
118\r
119/**\r
120 Frees one or more 4KB pages that were previously allocated with one of the page allocation\r
121 functions in the Memory Allocation Library.\r
122\r
123 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer\r
124 must have been allocated on a previous call to the page allocation services of the Memory\r
125 Allocation Library.\r
126 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,\r
127 then ASSERT().\r
128 If Pages is zero, then ASSERT().\r
129 \r
130 @param Buffer Pointer to the buffer of pages to free.\r
131 @param Pages The number of 4 KB pages to free.\r
132\r
133**/\r
134VOID\r
135EFIAPI\r
136FreePages (\r
137 IN VOID *Buffer,\r
138 IN UINTN Pages\r
139 )\r
140{\r
141 //\r
142 // PEI phase does not support to free pages, so leave it as NOP.\r
143 //\r
144}\r
145\r
146/**\r
147 Allocates one or more 4KB pages of a certain memory type at a specified alignment.\r
148\r
149 Allocates the number of 4KB pages specified by Pages of a certain memory type with an alignment\r
150 specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is returned.\r
151 If there is not enough memory at the specified alignment remaining to satisfy the request, then\r
152 NULL is returned.\r
153 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
154\r
155 @param MemoryType The type of memory to allocate.\r
156 @param Pages The number of 4 KB pages to allocate.\r
157 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
158 If Alignment is zero, then byte alignment is used.\r
159\r
160 @return A pointer to the allocated buffer or NULL if allocation fails.\r
161\r
162**/\r
163VOID *\r
164InternalAllocateAlignedPages (\r
165 IN EFI_MEMORY_TYPE MemoryType, \r
166 IN UINTN Pages,\r
167 IN UINTN Alignment\r
168 )\r
169{\r
170 VOID *Memory;\r
171 UINTN AlignmentMask;\r
172\r
173 //\r
174 // Alignment must be a power of two or zero.\r
175 //\r
176 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
177\r
178 if (Pages == 0) {\r
179 return NULL;\r
180 }\r
181 //\r
182 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.\r
183 //\r
184 ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment)));\r
185 //\r
186 // We would rather waste some memory to save PEI code size.\r
187 //\r
188 Memory = InternalAllocatePages (MemoryType, Pages + EFI_SIZE_TO_PAGES (Alignment));\r
189 if (Alignment == 0) {\r
190 AlignmentMask = Alignment;\r
191 } else {\r
192 AlignmentMask = Alignment - 1; \r
193 }\r
194 return (VOID *) (UINTN) (((UINTN) Memory + AlignmentMask) & ~AlignmentMask);\r
195}\r
196\r
197/**\r
198 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.\r
199\r
200 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an\r
201 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
202 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
203 request, then NULL is returned.\r
204 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
205\r
206 @param Pages The number of 4 KB pages to allocate.\r
207 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
208 If Alignment is zero, then byte alignment is used.\r
209\r
210 @return A pointer to the allocated buffer or NULL if allocation fails.\r
211\r
212**/\r
213VOID *\r
214EFIAPI\r
215AllocateAlignedPages (\r
216 IN UINTN Pages,\r
217 IN UINTN Alignment\r
218 )\r
219{\r
220 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);\r
221}\r
222\r
223/**\r
224 Allocates one or more 4KB pages of type EfiRuntimeServicesData at a specified alignment.\r
225\r
226 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData with an\r
227 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
228 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
229 request, then NULL is returned.\r
230 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
231\r
232 @param Pages The number of 4 KB pages to allocate.\r
233 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
234 If Alignment is zero, then byte alignment is used.\r
235\r
236 @return A pointer to the allocated buffer or NULL if allocation fails.\r
237\r
238**/\r
239VOID *\r
240EFIAPI\r
241AllocateAlignedRuntimePages (\r
242 IN UINTN Pages,\r
243 IN UINTN Alignment\r
244 )\r
245{\r
246 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);\r
247}\r
248\r
249/**\r
250 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.\r
251\r
252 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType with an\r
253 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is\r
254 returned. If there is not enough memory at the specified alignment remaining to satisfy the\r
255 request, then NULL is returned.\r
256 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
257\r
258 @param Pages The number of 4 KB pages to allocate.\r
259 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
260 If Alignment is zero, then byte alignment is used.\r
261\r
262 @return A pointer to the allocated buffer or NULL if allocation fails.\r
263\r
264**/\r
265VOID *\r
266EFIAPI\r
267AllocateAlignedReservedPages (\r
268 IN UINTN Pages,\r
269 IN UINTN Alignment\r
270 )\r
271{\r
272 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);\r
273}\r
274\r
275/**\r
276 Frees one or more 4KB pages that were previously allocated with one of the aligned page\r
277 allocation functions in the Memory Allocation Library.\r
278\r
279 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer\r
280 must have been allocated on a previous call to the aligned page allocation services of the Memory\r
281 Allocation Library.\r
282 If Buffer was not allocated with an aligned page allocation function in the Memory Allocation\r
283 Library, then ASSERT().\r
284 If Pages is zero, then ASSERT().\r
285 \r
286 @param Buffer Pointer to the buffer of pages to free.\r
287 @param Pages The number of 4 KB pages to free.\r
288\r
289**/\r
290VOID\r
291EFIAPI\r
292FreeAlignedPages (\r
293 IN VOID *Buffer,\r
294 IN UINTN Pages\r
295 )\r
296{\r
297 //\r
298 // PEI phase does not support to free pages, so leave it as NOP.\r
299 //\r
300}\r
301\r
302/**\r
303 Allocates a buffer of a certain pool type.\r
304\r
305 Allocates the number bytes specified by AllocationSize of a certain pool type and returns a\r
306 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
307 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
308\r
309 @param MemoryType The type of memory to allocate.\r
310 @param AllocationSize The number of bytes to allocate.\r
311\r
312 @return A pointer to the allocated buffer or NULL if allocation fails.\r
313\r
314**/\r
315VOID *\r
316InternalAllocatePool (\r
317 IN EFI_MEMORY_TYPE MemoryType, \r
318 IN UINTN AllocationSize\r
319 )\r
320{\r
321 //\r
322 // If we need lots of small runtime/reserved memory type from PEI in the future, \r
323 // we can consider providing a more complex algorithm that allocates runtime pages and \r
324 // provide pool allocations from those pages. \r
325 //\r
326 return InternalAllocatePages (MemoryType, EFI_SIZE_TO_PAGES (AllocationSize));\r
327}\r
328\r
329/**\r
330 Allocates a buffer of type EfiBootServicesData.\r
331\r
332 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a\r
333 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
334 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
335\r
336 @param AllocationSize The number of bytes to allocate.\r
337\r
338 @return A pointer to the allocated buffer or NULL if allocation fails.\r
339\r
340**/\r
341VOID *\r
342EFIAPI\r
343AllocatePool (\r
344 IN UINTN AllocationSize\r
345 )\r
346{\r
347 EFI_STATUS Status;\r
348 EFI_PEI_SERVICES **PeiServices;\r
349 VOID *Buffer;\r
350 \r
351 PeiServices = GetPeiServicesTablePointer ();\r
352\r
353 Status = (*PeiServices)->AllocatePool (PeiServices, AllocationSize, &Buffer);\r
354 if (EFI_ERROR (Status)) {\r
355 Buffer = NULL;\r
356 }\r
357 return Buffer;\r
358}\r
359\r
360/**\r
361 Allocates a buffer of type EfiRuntimeServicesData.\r
362\r
363 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData and returns\r
364 a pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is\r
365 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
366\r
367 @param AllocationSize The number of bytes to allocate.\r
368\r
369 @return A pointer to the allocated buffer or NULL if allocation fails.\r
370\r
371**/\r
372VOID *\r
373EFIAPI\r
374AllocateRuntimePool (\r
375 IN UINTN AllocationSize\r
376 )\r
377{\r
378 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
379}\r
380\r
381/**\r
382 Allocates a buffer of type EfieservedMemoryType.\r
383\r
384 Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType and returns\r
385 a 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
395AllocateReservedPool (\r
396 IN UINTN AllocationSize\r
397 )\r
398{\r
399 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);\r
400}\r
401\r
402/**\r
403 Allocates and zeros a buffer of a certian pool type.\r
404\r
405 Allocates the number bytes specified by AllocationSize of a certian pool type, clears the buffer\r
406 with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a valid\r
407 buffer of 0 size is returned. If there is not enough memory remaining to satisfy the request,\r
408 then NULL is returned.\r
409\r
410 @param PoolType The type of memory to allocate.\r
411 @param AllocationSize The number of bytes to allocate and zero.\r
412\r
413 @return A pointer to the allocated buffer or NULL if allocation fails.\r
414\r
415**/\r
416VOID *\r
417InternalAllocateZeroPool (\r
418 IN EFI_MEMORY_TYPE PoolType, \r
419 IN UINTN AllocationSize\r
420 ) \r
421{\r
422 VOID *Memory;\r
423\r
424 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
425 if (Memory != NULL) {\r
426 Memory = ZeroMem (Memory, AllocationSize);\r
427 }\r
428 return Memory;\r
429}\r
430\r
431/**\r
432 Allocates and zeros a buffer of type EfiBootServicesData.\r
433\r
434 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the\r
435 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
436 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
437 request, then NULL is returned.\r
438\r
439 @param AllocationSize The number of bytes to allocate and zero.\r
440\r
441 @return A pointer to the allocated buffer or NULL if allocation fails.\r
442\r
443**/\r
444VOID *\r
445EFIAPI\r
446AllocateZeroPool (\r
447 IN UINTN AllocationSize\r
448 )\r
449{\r
450 VOID *Memory;\r
451\r
452 Memory = AllocatePool (AllocationSize);\r
453 if (Memory != NULL) {\r
454 Memory = ZeroMem (Memory, AllocationSize);\r
455 }\r
456 return Memory;\r
457}\r
458\r
459/**\r
460 Allocates and zeros a buffer of type EfiRuntimeServicesData.\r
461\r
462 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, clears the\r
463 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
464 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
465 request, then NULL is returned.\r
466\r
467 @param AllocationSize The number of bytes to allocate and zero.\r
468\r
469 @return A pointer to the allocated buffer or NULL if allocation fails.\r
470\r
471**/\r
472VOID *\r
473EFIAPI\r
474AllocateRuntimeZeroPool (\r
475 IN UINTN AllocationSize\r
476 )\r
477{\r
478 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
479}\r
480\r
481/**\r
482 Allocates and zeros a buffer of type EfiReservedMemoryType.\r
483\r
484 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, clears the\r
485 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a\r
486 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the\r
487 request, then NULL is returned.\r
488\r
489 @param AllocationSize The number of bytes to allocate and zero.\r
490\r
491 @return A pointer to the allocated buffer or NULL if allocation fails.\r
492\r
493**/\r
494VOID *\r
495EFIAPI\r
496AllocateReservedZeroPool (\r
497 IN UINTN AllocationSize\r
498 )\r
499{\r
500 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);\r
501}\r
502\r
503/**\r
504 Copies a buffer to an allocated buffer of a certian pool type.\r
505\r
506 Allocates the number bytes specified by AllocationSize of a certian pool type, copies\r
507 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
508 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
509 is not enough memory remaining to satisfy the request, then NULL is returned.\r
510 If Buffer is NULL, then ASSERT().\r
511 If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). \r
512\r
513 @param PoolType The type of pool to allocate.\r
514 @param AllocationSize The number of bytes to allocate and zero.\r
515 @param Buffer The buffer to copy to the allocated buffer.\r
516\r
517 @return A pointer to the allocated buffer or NULL if allocation fails.\r
518\r
519**/\r
520VOID *\r
521InternalAllocateCopyPool (\r
522 IN EFI_MEMORY_TYPE PoolType, \r
523 IN UINTN AllocationSize,\r
524 IN CONST VOID *Buffer\r
525 ) \r
526{\r
527 VOID *Memory;\r
528\r
529 ASSERT (Buffer != NULL);\r
530 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
531\r
532 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
533 if (Memory != NULL) {\r
534 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
535 }\r
536 return Memory;\r
537} \r
538\r
539/**\r
540 Copies a buffer to an allocated buffer of type EfiBootServicesData.\r
541\r
542 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, copies\r
543 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
544 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
545 is not enough memory remaining to satisfy the request, then NULL is returned.\r
546 If Buffer is NULL, then ASSERT().\r
547 If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). \r
548\r
549 @param AllocationSize The number of bytes to allocate and zero.\r
550 @param Buffer The buffer to copy to the allocated buffer.\r
551\r
552 @return A pointer to the allocated buffer or NULL if allocation fails.\r
553\r
554**/\r
555VOID *\r
556EFIAPI\r
557AllocateCopyPool (\r
558 IN UINTN AllocationSize,\r
559 IN CONST VOID *Buffer\r
560 )\r
561{\r
562 VOID *Memory;\r
563\r
564 ASSERT (Buffer != NULL);\r
565 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
566\r
567 Memory = AllocatePool (AllocationSize);\r
568 if (Memory != NULL) {\r
569 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
570 }\r
571 return Memory;\r
572}\r
573\r
574/**\r
575 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData.\r
576\r
577 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData, copies\r
578 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
579 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
580 is not enough memory remaining to satisfy the request, then NULL is returned.\r
581 If Buffer is NULL, then ASSERT().\r
582 If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). \r
583\r
584 @param AllocationSize The number of bytes to allocate and zero.\r
585 @param Buffer The buffer to copy to the allocated buffer.\r
586\r
587 @return A pointer to the allocated buffer or NULL if allocation fails.\r
588\r
589**/\r
590VOID *\r
591EFIAPI\r
592AllocateRuntimeCopyPool (\r
593 IN UINTN AllocationSize,\r
594 IN CONST VOID *Buffer\r
595 )\r
596{\r
597 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
598}\r
599\r
600/**\r
601 Copies a buffer to an allocated buffer of type EfiReservedMemoryType.\r
602\r
603 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType, copies\r
604 AllocationSize bytes from Buffer to the newly allocated buffer, and returns a pointer to the\r
605 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
606 is not enough memory remaining to satisfy the request, then NULL is returned.\r
607 If Buffer is NULL, then ASSERT().\r
608 If AllocationSize is greater than (MAX_ADDRESS ? Buffer + 1), then ASSERT(). \r
609\r
610 @param AllocationSize The number of bytes to allocate and zero.\r
611 @param Buffer The buffer to copy to the allocated buffer.\r
612\r
613 @return A pointer to the allocated buffer or NULL if allocation fails.\r
614\r
615**/\r
616VOID *\r
617EFIAPI\r
618AllocateReservedCopyPool (\r
619 IN UINTN AllocationSize,\r
620 IN CONST VOID *Buffer\r
621 )\r
622{\r
623 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);\r
624}\r
625\r
626/**\r
627 Frees a buffer that was previously allocated with one of the pool allocation functions in the\r
628 Memory Allocation Library.\r
629\r
630 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the\r
631 pool allocation services of the Memory Allocation Library.\r
632 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,\r
633 then ASSERT().\r
634\r
635 @param Buffer Pointer to the buffer to free.\r
636\r
637**/\r
638VOID\r
639EFIAPI\r
640FreePool (\r
641 IN VOID *Buffer\r
642 )\r
643{\r
644 //\r
645 // PEI phase does not support to free pool, so leave it as NOP.\r
646 //\r
647}\r
648\r
649/**\r
650 Allocates a buffer of a certain pool type at a specified alignment.\r
651\r
652 Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment\r
653 specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, then a valid\r
654 buffer of 0 size is returned. If there is not enough memory at the specified alignment remaining\r
655 to satisfy the request, then NULL is returned.\r
656 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
657\r
658 @param PoolType The type of pool to allocate.\r
659 @param AllocationSize The number of bytes to allocate.\r
660 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.\r
661 If Alignment is zero, then byte alignment is used.\r
662\r
663 @return A pointer to the allocated buffer or NULL if allocation fails.\r
664\r
665**/\r
666VOID *\r
667InternalAllocateAlignedPool (\r
668 IN EFI_MEMORY_TYPE PoolType,\r
669 IN UINTN AllocationSize,\r
670 IN UINTN Alignment\r
671 )\r
672{\r
673 VOID *RawAddress;\r
674 UINTN AlignedAddress;\r
675 UINTN AlignmentMask;\r
676\r
677 //\r
678 // Alignment must be a power of two or zero.\r
679 //\r
680 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
681 \r
682 if (Alignment == 0) {\r
683 AlignmentMask = Alignment;\r
684 } else {\r
685 AlignmentMask = Alignment - 1;\r
686 }\r
687 //\r
688 // Make sure that AllocationSize plus AlignmentMask does not overflow.\r
689 //\r
690 ASSERT (AllocationSize <= (MAX_ADDRESS - AlignmentMask));\r
691\r
692 RawAddress = InternalAllocatePool (PoolType, AllocationSize + AlignmentMask);\r
693 \r
694 AlignedAddress = ((UINTN) RawAddress + AlignmentMask) & ~AlignmentMask;\r
695 \r
696 return (VOID *) AlignedAddress;\r
697}\r
698\r
699/**\r
700 Allocates a buffer of type EfiBootServicesData at a specified alignment.\r
701\r
702 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an\r
703 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,\r
704 then a valid buffer of 0 size is returned. If there is not enough memory at the specified\r
705 alignment remaining to satisfy the request, then NULL is returned.\r
706 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
707\r
708 @param AllocationSize The number of bytes to allocate.\r
709 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
710 If Alignment is zero, then byte alignment is used.\r
711\r
712 @return A pointer to the allocated buffer or NULL if allocation fails.\r
713\r
714**/\r
715VOID *\r
716EFIAPI\r
717AllocateAlignedPool (\r
718 IN UINTN AllocationSize,\r
719 IN UINTN Alignment\r
720 )\r
721{\r
722 VOID *RawAddress;\r
723 UINTN AlignedAddress;\r
724 UINTN AlignmentMask;\r
725\r
726 //\r
727 // Alignment must be a power of two or zero.\r
728 //\r
729 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
730\r
731 if (Alignment == 0) {\r
732 AlignmentMask = Alignment;\r
733 } else {\r
734 AlignmentMask = Alignment - 1;\r
735 }\r
736\r
737 //\r
738 // Make sure that AllocationSize plus AlignmentMask does not overflow.\r
739 //\r
740 ASSERT (AllocationSize <= (MAX_ADDRESS - AlignmentMask));\r
741\r
742 RawAddress = AllocatePool (AllocationSize + AlignmentMask);\r
743 \r
744 AlignedAddress = ((UINTN) RawAddress + AlignmentMask) & ~AlignmentMask;\r
745 \r
746 return (VOID *) AlignedAddress;\r
747}\r
748\r
749/**\r
750 Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.\r
751\r
752 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an\r
753 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,\r
754 then a valid buffer of 0 size is returned. If there is not enough memory at the specified\r
755 alignment remaining to satisfy the request, then NULL is returned.\r
756 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
757\r
758 @param AllocationSize The number of bytes to allocate.\r
759 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
760 If Alignment is zero, then byte alignment is used.\r
761\r
762 @return A pointer to the allocated buffer or NULL if allocation fails.\r
763\r
764**/\r
765VOID *\r
766EFIAPI\r
767AllocateAlignedRuntimePool (\r
768 IN UINTN AllocationSize,\r
769 IN UINTN Alignment\r
770 )\r
771{\r
772 return InternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);\r
773}\r
774\r
775/**\r
776 Allocates a buffer of type EfieservedMemoryType at a specified alignment.\r
777\r
778 Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an\r
779 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,\r
780 then a valid buffer of 0 size is returned. If there is not enough memory at the specified\r
781 alignment remaining to satisfy the request, then NULL is returned.\r
782 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
783\r
784 @param AllocationSize The number of bytes to allocate.\r
785 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
786 If Alignment is zero, then byte alignment is used.\r
787\r
788 @return A pointer to the allocated buffer or NULL if allocation fails.\r
789\r
790**/\r
791VOID *\r
792EFIAPI\r
793AllocateAlignedReservedPool (\r
794 IN UINTN AllocationSize,\r
795 IN UINTN Alignment\r
796 )\r
797{\r
798 return InternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);\r
799}\r
800\r
801/**\r
802 Allocates and zeros a buffer of a certain pool type at a specified alignment.\r
803\r
804 Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment\r
805 specified by Alignment, clears the buffer with zeros, and returns a pointer to the allocated\r
806 buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there is not\r
807 enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
808 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
809\r
810 @param PoolType The type of pool to allocate.\r
811 @param AllocationSize The number of bytes to allocate.\r
812 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
813 If Alignment is zero, then byte alignment is used.\r
814\r
815 @return A pointer to the allocated buffer or NULL if allocation fails.\r
816\r
817**/\r
818VOID *\r
819InternalAllocateAlignedZeroPool (\r
820 IN EFI_MEMORY_TYPE PoolType,\r
821 IN UINTN AllocationSize,\r
822 IN UINTN Alignment\r
823 )\r
824{\r
825 VOID *Memory;\r
826\r
827 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);\r
828 if (Memory != NULL) {\r
829 Memory = ZeroMem (Memory, AllocationSize);\r
830 }\r
831 return Memory;\r
832}\r
833\r
834/**\r
835 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.\r
836\r
837 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData with an\r
838 alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the\r
839 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
840 is not enough memory at the specified alignment remaining to satisfy the request, then NULL is\r
841 returned.\r
842 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
843\r
844 @param AllocationSize The number of bytes to allocate.\r
845 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
846 If Alignment is zero, then byte alignment is used.\r
847\r
848 @return A pointer to the allocated buffer or NULL if allocation fails.\r
849\r
850**/\r
851VOID *\r
852EFIAPI\r
853AllocateAlignedZeroPool (\r
854 IN UINTN AllocationSize,\r
855 IN UINTN Alignment\r
856 )\r
857{\r
858 VOID *Memory;\r
859\r
860 Memory = AllocateAlignedPool (AllocationSize, Alignment);\r
861 if (Memory != NULL) {\r
862 Memory = ZeroMem (Memory, AllocationSize);\r
863 }\r
864 return Memory;\r
865}\r
866\r
867/**\r
868 Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.\r
869\r
870 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData with an\r
871 alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the\r
872 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
873 is not enough memory at the specified alignment remaining to satisfy the request, then NULL is\r
874 returned.\r
875 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
876\r
877 @param AllocationSize The number of bytes to allocate.\r
878 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
879 If Alignment is zero, then byte alignment is used.\r
880\r
881 @return A pointer to the allocated buffer or NULL if allocation fails.\r
882\r
883**/\r
884VOID *\r
885EFIAPI\r
886AllocateAlignedRuntimeZeroPool (\r
887 IN UINTN AllocationSize,\r
888 IN UINTN Alignment\r
889 )\r
890{\r
891 return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);\r
892}\r
893\r
894/**\r
895 Allocates and zeros a buffer of type EfieservedMemoryType at a specified alignment.\r
896\r
897 Allocates the number bytes specified by AllocationSize of type EfieservedMemoryType with an\r
898 alignment specified by Alignment, clears the buffer with zeros, and returns a pointer to the\r
899 allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned. If there\r
900 is not enough memory at the specified alignment remaining to satisfy the request, then NULL is\r
901 returned.\r
902 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
903\r
904 @param AllocationSize The number of bytes to allocate.\r
905 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
906 If Alignment is zero, then byte alignment is used.\r
907\r
908 @return A pointer to the allocated buffer or NULL if allocation fails.\r
909\r
910**/\r
911VOID *\r
912EFIAPI\r
913AllocateAlignedReservedZeroPool (\r
914 IN UINTN AllocationSize,\r
915 IN UINTN Alignment\r
916 )\r
917{\r
918 return InternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);\r
919}\r
920\r
921/**\r
922 Copies a buffer to an allocated buffer of a certain pool type at a specified alignment.\r
923\r
924 Allocates the number bytes specified by AllocationSize of a certain pool type with an alignment\r
925 specified by Alignment. The allocated buffer is returned. If AllocationSize is 0, then a valid\r
926 buffer of 0 size is returned. If there is not enough memory at the specified alignment remaining\r
927 to satisfy the request, then NULL is returned.\r
928 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
929\r
930 @param PoolType The type of pool to allocate.\r
931 @param AllocationSize The number of bytes to allocate.\r
932 @param Buffer The buffer to copy to the allocated buffer.\r
933 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
934 If Alignment is zero, then byte alignment is used.\r
935\r
936 @return A pointer to the allocated buffer or NULL if allocation fails.\r
937\r
938**/\r
939VOID *\r
940InternalAllocateAlignedCopyPool (\r
941 IN EFI_MEMORY_TYPE PoolType,\r
942 IN UINTN AllocationSize,\r
943 IN CONST VOID *Buffer,\r
944 IN UINTN Alignment\r
945 )\r
946{\r
947 VOID *Memory;\r
948 \r
949 ASSERT (Buffer != NULL);\r
950 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
951\r
952 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);\r
953 if (Memory != NULL) {\r
954 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
955 }\r
956 return Memory;\r
957}\r
958\r
959/**\r
960 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.\r
961\r
962 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData type with an\r
963 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,\r
964 then a valid buffer of 0 size is returned. If there is not enough memory at the specified\r
965 alignment remaining to satisfy the request, then NULL is returned.\r
966 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
967\r
968 @param AllocationSize The number of bytes to allocate.\r
969 @param Buffer The buffer to copy to the allocated buffer.\r
970 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
971 If Alignment is zero, then byte alignment is used.\r
972\r
973 @return A pointer to the allocated buffer or NULL if allocation fails.\r
974\r
975**/\r
976VOID *\r
977EFIAPI\r
978AllocateAlignedCopyPool (\r
979 IN UINTN AllocationSize,\r
980 IN CONST VOID *Buffer,\r
981 IN UINTN Alignment\r
982 )\r
983{\r
984 VOID *Memory;\r
985 \r
986 ASSERT (Buffer != NULL);\r
987 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
988\r
989 Memory = AllocateAlignedPool (AllocationSize, Alignment);\r
990 if (Memory != NULL) {\r
991 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
992 }\r
993 return Memory;\r
994}\r
995\r
996/**\r
997 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.\r
998\r
999 Allocates the number bytes specified by AllocationSize of type EfiRuntimeServicesData type with an\r
1000 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,\r
1001 then a valid buffer of 0 size is returned. If there is not enough memory at the specified\r
1002 alignment remaining to satisfy the request, then NULL is returned.\r
1003 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
1004\r
1005 @param AllocationSize The number of bytes to allocate.\r
1006 @param Buffer The buffer to copy to the allocated buffer.\r
1007 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
1008 If Alignment is zero, then byte alignment is used.\r
1009\r
1010 @return A pointer to the allocated buffer or NULL if allocation fails.\r
1011\r
1012**/\r
1013VOID *\r
1014EFIAPI\r
1015AllocateAlignedRuntimeCopyPool (\r
1016 IN UINTN AllocationSize,\r
1017 IN CONST VOID *Buffer,\r
1018 IN UINTN Alignment\r
1019 )\r
1020{\r
1021 return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);\r
1022}\r
1023\r
1024/**\r
1025 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.\r
1026\r
1027 Allocates the number bytes specified by AllocationSize of type EfiReservedMemoryType type with an\r
1028 alignment specified by Alignment. The allocated buffer is returned. If AllocationSize is 0,\r
1029 then a valid buffer of 0 size is returned. If there is not enough memory at the specified\r
1030 alignment remaining to satisfy the request, then NULL is returned.\r
1031 If Alignment is not a power of two and Alignment is not zero, then ASSERT().\r
1032\r
1033 @param AllocationSize The number of bytes to allocate.\r
1034 @param Buffer The buffer to copy to the allocated buffer.\r
1035 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
1036 If Alignment is zero, then byte alignment is used.\r
1037\r
1038 @return A pointer to the allocated buffer or NULL if allocation fails.\r
1039\r
1040**/\r
1041VOID *\r
1042EFIAPI\r
1043AllocateAlignedReservedCopyPool (\r
1044 IN UINTN AllocationSize,\r
1045 IN CONST VOID *Buffer,\r
1046 IN UINTN Alignment\r
1047 )\r
1048{\r
1049 return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);\r
1050}\r
1051\r
1052/**\r
1053 Frees a buffer that was previously allocated with one of the aligned pool allocation functions \r
1054 in the Memory Allocation Library.\r
1055\r
1056 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the\r
1057 aligned pool allocation services of the Memory Allocation Library.\r
1058 If Buffer was not allocated with an aligned pool allocation function in the Memory Allocation\r
1059 Library, then ASSERT().\r
1060\r
1061 @param Buffer Pointer to the buffer to free.\r
1062\r
1063**/\r
1064VOID\r
1065EFIAPI\r
1066FreeAlignedPool (\r
1067 IN VOID *Buffer\r
1068 )\r
1069{\r
1070 //\r
1071 // PEI phase does not support to free pool, so leave it as NOP.\r
1072 //\r
1073}\r