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