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