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