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