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