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