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