]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/DxeMemoryAllocationLib/MemoryAllocationLib.c
UefiLib:
[mirror_edk2.git] / MdePkg / Library / DxeMemoryAllocationLib / MemoryAllocationLib.c
CommitLineData
878ddf1f 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\r
19/**\r
20 Allocates the number of 4KB pages specified by Pages of a certain memory type.\r
21\r
22 @param MemoryType The type of memory to allocate.\r
23 @param Pages The number of 4 KB pages to allocate.\r
24\r
25 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.<BR>\r
26 If Pages is 0, then NULL is returned.<BR>\r
27 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
28\r
29**/\r
30VOID *\r
31InternalAllocatePages (\r
32 IN EFI_MEMORY_TYPE MemoryType, \r
33 IN UINTN Pages\r
34 )\r
35{\r
36 EFI_STATUS Status;\r
37 EFI_PHYSICAL_ADDRESS Memory; \r
38\r
39 if (Pages == 0) {\r
40 return NULL;\r
41 }\r
42\r
43 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);\r
44 if (EFI_ERROR (Status)) {\r
45 Memory = 0;\r
46 }\r
47 return (VOID *) (UINTN) Memory;\r
48}\r
49\r
50/**\r
51 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData.\r
52\r
53 @param Pages The number of 4 KB pages to allocate.\r
54\r
55 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.<BR>\r
56 If Pages is 0, then NULL is returned.<BR>\r
57 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
58\r
59**/\r
60VOID *\r
61EFIAPI\r
62AllocatePages (\r
63 IN UINTN Pages\r
64 )\r
65{\r
66 return InternalAllocatePages (EfiBootServicesData, Pages);\r
67}\r
68\r
69/**\r
70 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData. \r
71\r
72 @param Pages The number of 4 KB pages to allocate.\r
73\r
74 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.<BR>\r
75 If Pages is 0, then NULL is returned.<BR>\r
76 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
77\r
78**/\r
79VOID *\r
80EFIAPI\r
81AllocateRuntimePages (\r
82 IN UINTN Pages\r
83 )\r
84{\r
85 return InternalAllocatePages (EfiRuntimeServicesData, Pages);\r
86}\r
87\r
88/**\r
89 Allocates the number of 4KB pages specified by Pages of type EfiReservedMemoryType. \r
90\r
91 @param Pages The number of 4 KB pages to allocate.\r
92\r
93 @return A pointer to the allocated buffer. The buffer returned is aligned on a 4KB boundary.<BR>\r
94 If Pages is 0, then NULL is returned.<BR>\r
95 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
96\r
97**/\r
98VOID *\r
99EFIAPI\r
100AllocateReservedPages (\r
101 IN UINTN Pages\r
102 )\r
103{\r
104 return InternalAllocatePages (EfiReservedMemoryType, Pages);\r
105}\r
106\r
107/**\r
108 Frees one or more 4KB pages that were previously allocated with \r
109 one of the page allocation functions in the Memory Allocation Library.\r
110\r
111 @param Buffer Pointer to the buffer of pages to free.\r
112 @param Pages The number of 4 KB pages to free.\r
113\r
114**/\r
115VOID\r
116EFIAPI\r
117FreePages (\r
118 IN VOID *Buffer,\r
119 IN UINTN Pages\r
120 )\r
121{\r
122 EFI_STATUS Status;\r
123\r
124 ASSERT (Pages != 0);\r
125 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
126 ASSERT_EFI_ERROR (Status);\r
127}\r
128\r
129/**\r
130 Allocates the number of 4KB pages specified by Pages of a certian memory type \r
131 with an alignment specified by Alignment. \r
132\r
133 @param MemoryType The type of memory to allocate.\r
134 @param Pages The number of 4 KB pages to allocate.\r
135 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
136 If Alignment is zero, then byte alignment is used.\r
137\r
138 @return The allocated buffer is returned.<BR>\r
139 If Pages is 0, then NULL is returned.<BR>\r
140 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
141\r
142**/\r
143VOID *\r
144InternalAllocateAlignedPages (\r
145 IN EFI_MEMORY_TYPE MemoryType, \r
146 IN UINTN Pages,\r
147 IN UINTN Alignment\r
148 )\r
149{\r
150 EFI_STATUS Status;\r
151 EFI_PHYSICAL_ADDRESS Memory;\r
152 UINTN AlignedMemory;\r
153 UINTN AlignmentMask;\r
154 UINTN UnalignedPages;\r
155 UINTN RealPages;\r
156\r
157 //\r
158 // Alignment must be a power of two or zero.\r
159 //\r
160 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
161 \r
162 if (Pages == 0) {\r
163 return NULL;\r
164 }\r
165 if (Alignment > EFI_PAGE_SIZE) {\r
166 //\r
167 // Caculate the total number of pages since alignment is larger than page size.\r
168 //\r
169 AlignmentMask = Alignment - 1;\r
170 RealPages = Pages + EFI_SIZE_TO_PAGES (Alignment);\r
a3657e3e 171 //\r
172 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.\r
173 //\r
174 ASSERT (RealPages > Pages);\r
175 \r
878ddf1f 176 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);\r
177 if (EFI_ERROR (Status)) {\r
178 return NULL;\r
179 }\r
180 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;\r
181 UnalignedPages = EFI_SIZE_TO_PAGES ((UINTN) Memory - AlignedMemory);\r
182 if (UnalignedPages > 0) {\r
183 //\r
184 // Free first unaligned page(s).\r
185 //\r
186 Status = gBS->FreePages (Memory, UnalignedPages);\r
187 ASSERT_EFI_ERROR (Status);\r
188 }\r
189 Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));\r
190 UnalignedPages = RealPages - Pages - UnalignedPages;\r
191 if (UnalignedPages > 0) {\r
192 //\r
193 // Free last unaligned page(s).\r
194 //\r
195 Status = gBS->FreePages (Memory, UnalignedPages);\r
196 ASSERT_EFI_ERROR (Status);\r
197 }\r
198 } else {\r
199 //\r
200 // Do not over-allocate pages in this case.\r
201 //\r
202 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);\r
203 if (EFI_ERROR (Status)) {\r
204 return NULL;\r
205 }\r
206 AlignedMemory = (UINTN) Memory;\r
207 }\r
208 return (VOID *) AlignedMemory;\r
209}\r
210\r
211/**\r
212 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData\r
213 with an alignment specified by Alignment. \r
214\r
215 @param Pages The number of 4 KB pages to allocate.\r
216 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
217 If Alignment is zero, then byte alignment is used.\r
218\r
219 @return The allocated buffer is returned.<BR>\r
220 If Pages is 0, then NULL is returned.<BR>\r
221 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
222\r
223**/\r
224VOID *\r
225EFIAPI\r
226AllocateAlignedPages (\r
227 IN UINTN Pages,\r
228 IN UINTN Alignment\r
229 )\r
230{\r
231 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);\r
232}\r
233\r
234/**\r
235 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData\r
236 with an alignment specified by Alignment. \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 The allocated buffer is returned. If Pages is 0, then NULL is returned.\r
243 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\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 @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 The allocated buffer is returned. If Pages is 0, then NULL is returned.\r
264 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
265\r
266**/\r
267VOID *\r
268EFIAPI\r
269AllocateAlignedReservedPages (\r
270 IN UINTN Pages,\r
271 IN UINTN Alignment\r
272 )\r
273{\r
274 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);\r
275}\r
276\r
277/**\r
278 Frees one or more 4KB pages that were previously allocated with \r
279 one of the aligned page allocation functions in the Memory Allocation Library.\r
280\r
281 @param Buffer Pointer to the buffer of pages to free.\r
282 @param Pages The number of 4 KB pages to free.\r
283\r
284**/\r
285VOID\r
286EFIAPI\r
287FreeAlignedPages (\r
288 IN VOID *Buffer,\r
289 IN UINTN Pages\r
290 )\r
291{\r
292 EFI_STATUS Status;\r
293\r
294 ASSERT (Pages != 0);\r
295 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
296 ASSERT_EFI_ERROR (Status);\r
297}\r
298\r
299/**\r
300 Allocates a buffer of a certain memory type.\r
301\r
302 @param MemoryType The type of memory to allocate.\r
303 @param AllocationSize The number of bytes to allocate.\r
304\r
305 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
306 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
307\r
308**/\r
309VOID *\r
310InternalAllocatePool (\r
311 IN EFI_MEMORY_TYPE MemoryType, \r
312 IN UINTN AllocationSize\r
313 )\r
314{\r
315 EFI_STATUS Status;\r
316 VOID *Memory;\r
317\r
318 Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);\r
319 if (EFI_ERROR (Status)) {\r
320 Memory = NULL;\r
321 }\r
322 return Memory;\r
323}\r
324\r
325/**\r
326 Allocates a buffer of type EfiBootServicesData.\r
327\r
328 @param AllocationSize The number of bytes to allocate.\r
329\r
330 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
331 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
332\r
333**/\r
334VOID *\r
335EFIAPI\r
336AllocatePool (\r
337 IN UINTN AllocationSize\r
338 )\r
339{\r
340 return InternalAllocatePool (EfiBootServicesData, AllocationSize);\r
341}\r
342\r
343/**\r
344 Allocates a buffer of type EfiRuntimeServicesData.\r
345\r
346 @param AllocationSize The number of bytes to allocate.\r
347\r
348 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
349 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
350\r
351**/\r
352VOID *\r
353EFIAPI\r
354AllocateRuntimePool (\r
355 IN UINTN AllocationSize\r
356 )\r
357{\r
358 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
359}\r
360\r
361/**\r
362 Allocates a buffer of type EfiReservedMemoryType.\r
363\r
364 @param AllocationSize The number of bytes to allocate.\r
365\r
366 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
367 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
368\r
369**/\r
370VOID *\r
371EFIAPI\r
372AllocateReservedPool (\r
373 IN UINTN AllocationSize\r
374 )\r
375{\r
376 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);\r
377}\r
378\r
379/**\r
380 Allocates and zeros a buffer of a certian pool type.\r
381\r
382 @param PoolType The type of memory to allocate.\r
383 @param AllocationSize The number of bytes to allocate and zero.\r
384\r
385 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
386 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
387\r
388**/\r
389VOID *\r
390InternalAllocateZeroPool (\r
391 IN EFI_MEMORY_TYPE PoolType, \r
392 IN UINTN AllocationSize\r
393 ) \r
394{\r
395 VOID *Memory;\r
396 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
397 if (Memory != NULL) {\r
398 Memory = ZeroMem (Memory, AllocationSize);\r
399 }\r
400 return Memory;\r
401}\r
402\r
403/**\r
404 Allocates and zeros a buffer of type EfiBootServicesData.\r
405\r
406 @param AllocationSize The number of bytes to allocate and zero.\r
407\r
408 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
409 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
410\r
411**/\r
412VOID *\r
413EFIAPI\r
414AllocateZeroPool (\r
415 IN UINTN AllocationSize\r
416 )\r
417{\r
418 return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);\r
419}\r
420\r
421/**\r
422 Allocates and zeros a buffer of type EfiRuntimeServicesData.\r
423\r
424 @param AllocationSize The number of bytes to allocate and zero.\r
425\r
426 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
427 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
428\r
429**/\r
430VOID *\r
431EFIAPI\r
432AllocateRuntimeZeroPool (\r
433 IN UINTN AllocationSize\r
434 )\r
435{\r
436 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
437}\r
438\r
439/**\r
440 Allocates and zeros a buffer of type EfiReservedMemoryType.\r
441\r
442 @param AllocationSize The number of bytes to allocate and zero.\r
443\r
444 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
445 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
446\r
447**/\r
448VOID *\r
449EFIAPI\r
450AllocateReservedZeroPool (\r
451 IN UINTN AllocationSize\r
452 )\r
453{\r
454 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);\r
455}\r
456\r
457/**\r
458 Copies a buffer to an allocated buffer of a certian memory type. \r
459\r
460 @param MemoryType The type of pool to allocate.\r
461 @param AllocationSize The number of bytes to allocate and zero.\r
462 @param Buffer The buffer to copy to the allocated buffer.\r
463\r
464 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
465 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
466\r
467**/\r
468VOID *\r
469InternalAllocateCopyPool (\r
470 IN EFI_MEMORY_TYPE PoolType, \r
471 IN UINTN AllocationSize,\r
472 IN CONST VOID *Buffer\r
473 ) \r
474{\r
475 VOID *Memory;\r
476\r
9a462b41 477 ASSERT (Buffer != NULL);\r
478 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
479\r
878ddf1f 480 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
481 if (Memory != NULL) {\r
482 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
483 }\r
484 return Memory;\r
485} \r
486\r
487/**\r
488 Copies a buffer to an allocated buffer of type EfiBootServicesData. \r
489\r
490 @param AllocationSize The number of bytes to allocate.\r
491 @param Buffer The buffer to copy to the allocated buffer.\r
492\r
493 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
494 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
495\r
496**/\r
497VOID *\r
498EFIAPI\r
499AllocateCopyPool (\r
500 IN UINTN AllocationSize,\r
501 IN CONST VOID *Buffer\r
502 )\r
503{\r
504 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);\r
505}\r
506\r
507/**\r
508 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. \r
509\r
510 @param AllocationSize The number of bytes to allocate.\r
511 @param Buffer The buffer to copy to the allocated buffer.\r
512\r
513 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
514 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
515\r
516**/\r
517VOID *\r
518EFIAPI\r
519AllocateRuntimeCopyPool (\r
520 IN UINTN AllocationSize,\r
521 IN CONST VOID *Buffer\r
522 )\r
523{\r
524 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
525}\r
526\r
527/**\r
528 Copies a buffer to an allocated buffer of type EfiReservedMemoryType. \r
529\r
530 @param AllocationSize The number of bytes to allocate.\r
531 @param Buffer The buffer to copy to the allocated buffer.\r
532\r
533 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
534 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
535\r
536**/\r
537VOID *\r
538EFIAPI\r
539AllocateReservedCopyPool (\r
540 IN UINTN AllocationSize,\r
541 IN CONST VOID *Buffer\r
542 )\r
543{\r
544 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);\r
545}\r
546\r
547/**\r
548 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.\r
549\r
550 @param Buffer Pointer to the buffer to free.\r
551\r
552**/\r
553VOID\r
554EFIAPI\r
555FreePool (\r
556 IN VOID *Buffer\r
557 )\r
558{\r
559 EFI_STATUS Status;\r
560\r
561 Status = gBS->FreePool (Buffer);\r
562 ASSERT_EFI_ERROR (Status);\r
563}\r
564\r
565/**\r
566 Allocates a buffer of a certain pool type at a specified alignment.\r
567\r
568 @param PoolType The type of pool to allocate.\r
569 @param AllocationSize The number of bytes to allocate.\r
570 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.\r
571\r
572 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
573 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
574\r
575**/\r
576VOID *\r
577InternalAllocateAlignedPool (\r
578 IN EFI_MEMORY_TYPE PoolType,\r
579 IN UINTN AllocationSize,\r
580 IN UINTN Alignment\r
581 )\r
582{\r
583 VOID *RawAddress;\r
584 UINTN AlignedAddress;\r
585 UINTN AlignmentMask;\r
586 UINTN OverAllocationSize;\r
abea19db 587 UINTN RealAllocationSize;\r
878ddf1f 588 VOID **FreePointer;\r
878ddf1f 589\r
590 //\r
591 // Alignment must be a power of two or zero.\r
592 //\r
593 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
594 \r
595 if (Alignment == 0) {\r
596 AlignmentMask = Alignment;\r
597 } else {\r
598 AlignmentMask = Alignment - 1;\r
599 }\r
600 //\r
601 // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address. \r
602 //\r
603 OverAllocationSize = sizeof (RawAddress) + AlignmentMask;\r
abea19db 604 RealAllocationSize = AllocationSize + OverAllocationSize;\r
a3657e3e 605 //\r
606 // Make sure that AllocationSize plus OverAllocationSize does not overflow. \r
607 //\r
608 ASSERT (RealAllocationSize > AllocationSize); \r
609\r
abea19db 610 RawAddress = InternalAllocatePool (PoolType, RealAllocationSize);\r
611 if (RawAddress == NULL) {\r
878ddf1f 612 return NULL;\r
613 }\r
614 AlignedAddress = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask;\r
615 //\r
616 // Save the original memory address just before the aligned address.\r
617 //\r
618 FreePointer = (VOID **)(AlignedAddress - sizeof (RawAddress));\r
619 *FreePointer = RawAddress;\r
620\r
621 return (VOID *) AlignedAddress;\r
622}\r
623\r
624/**\r
625 Allocates a buffer of type EfiBootServicesData at a specified alignment.\r
626\r
627 @param AllocationSize The number of bytes to allocate.\r
628 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.\r
629\r
630 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
631 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
632\r
633**/\r
634VOID *\r
635EFIAPI\r
636AllocateAlignedPool (\r
637 IN UINTN AllocationSize,\r
638 IN UINTN Alignment\r
639 )\r
640{\r
641 return InternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);\r
642}\r
643\r
644/**\r
645 Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.\r
646\r
647 @param AllocationSize The number of bytes to allocate.\r
648 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
649 If Alignment is zero, then byte alignment is used.\r
650\r
651 A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
652 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
653\r
654**/\r
655VOID *\r
656EFIAPI\r
657AllocateAlignedRuntimePool (\r
658 IN UINTN AllocationSize,\r
659 IN UINTN Alignment\r
660 )\r
661{\r
662 return InternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);\r
663}\r
664\r
665/**\r
666 Allocates a buffer of type EfiReservedMemoryType at a specified alignment.\r
667\r
668 @param AllocationSize The number of bytes to allocate.\r
669 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
670 If Alignment is zero, then byte alignment is used.\r
671\r
672 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
673 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
674\r
675**/\r
676VOID *\r
677EFIAPI\r
678AllocateAlignedReservedPool (\r
679 IN UINTN AllocationSize,\r
680 IN UINTN Alignment\r
681 )\r
682{\r
683 return InternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);\r
684}\r
685\r
686/**\r
687 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.\r
688\r
689 @param PoolType The type of pool to allocate.\r
690 @param AllocationSize The number of bytes to allocate.\r
691 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
692 If Alignment is zero, then byte alignment is used.\r
693\r
694 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
695 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
696\r
697**/\r
698VOID *\r
699InternalAllocateAlignedZeroPool (\r
700 IN EFI_MEMORY_TYPE PoolType,\r
701 IN UINTN AllocationSize,\r
702 IN UINTN Alignment\r
703 )\r
704{\r
705 VOID *Memory;\r
706 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);\r
707 if (Memory != NULL) {\r
708 Memory = ZeroMem (Memory, AllocationSize);\r
709 }\r
710 return Memory;\r
711}\r
712\r
713/**\r
714 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.\r
715\r
716 @param AllocationSize The number of bytes to allocate.\r
717 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
718 If Alignment is zero, then byte alignment is used.\r
719\r
720 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
721 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
722\r
723**/\r
724VOID *\r
725EFIAPI\r
726AllocateAlignedZeroPool (\r
727 IN UINTN AllocationSize,\r
728 IN UINTN Alignment\r
729 )\r
730{\r
731 return InternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);\r
732}\r
733\r
734/**\r
735 Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.\r
736\r
737 @param AllocationSize The number of bytes to allocate.\r
738 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
739 If Alignment is zero, then byte alignment is used.\r
740\r
741 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
742 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
743\r
744**/\r
745VOID *\r
746EFIAPI\r
747AllocateAlignedRuntimeZeroPool (\r
748 IN UINTN AllocationSize,\r
749 IN UINTN Alignment\r
750 )\r
751{\r
752 return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);\r
753}\r
754\r
755/**\r
756 Allocates and zeros a buffer of type EfiReservedMemoryType at a specified alignment.\r
757\r
758 @param AllocationSize The number of bytes to allocate.\r
759 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
760 If Alignment is zero, then byte alignment is used.\r
761\r
762 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
763 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
764\r
765**/\r
766VOID *\r
767EFIAPI\r
768AllocateAlignedReservedZeroPool (\r
769 IN UINTN AllocationSize,\r
770 IN UINTN Alignment\r
771 )\r
772{\r
773 return InternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);\r
774}\r
775\r
776/**\r
777 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.\r
778\r
779 @param PoolType The type of pool to allocate.\r
780 @param AllocationSize The number of bytes to allocate.\r
781 @param Buffer The buffer to copy to the allocated buffer.\r
782 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
783 If Alignment is zero, then byte alignment is used.\r
784\r
785 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
786 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
787\r
788**/\r
789VOID *\r
790InternalAllocateAlignedCopyPool (\r
791 IN EFI_MEMORY_TYPE PoolType,\r
792 IN UINTN AllocationSize,\r
793 IN CONST VOID *Buffer,\r
794 IN UINTN Alignment\r
795 )\r
796{\r
797 VOID *Memory;\r
798 \r
9a462b41 799 ASSERT (Buffer != NULL);\r
800 ASSERT (AllocationSize <= (MAX_ADDRESS - (UINTN) Buffer + 1));\r
801\r
878ddf1f 802 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);\r
803 if (Memory != NULL) {\r
804 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
805 }\r
806 return Memory;\r
807}\r
808\r
809/**\r
810 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.\r
811\r
812 @param AllocationSize The number of bytes to allocate.\r
813 @param Buffer The buffer to copy to the allocated buffer.\r
814 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
815 If Alignment is zero, then byte alignment is used.\r
816\r
817 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
818 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
819\r
820**/\r
821VOID *\r
822EFIAPI\r
823AllocateAlignedCopyPool (\r
824 IN UINTN AllocationSize,\r
825 IN CONST VOID *Buffer,\r
826 IN UINTN Alignment\r
827 )\r
828{\r
829 return InternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);\r
830}\r
831\r
832/**\r
833 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.\r
834\r
835 @param AllocationSize The number of bytes to allocate.\r
836 @param Buffer The buffer to copy to the allocated buffer.\r
837 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
838 If Alignment is zero, then byte alignment is used.\r
839\r
840 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
841 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
842\r
843**/\r
844VOID *\r
845EFIAPI\r
846AllocateAlignedRuntimeCopyPool (\r
847 IN UINTN AllocationSize,\r
848 IN CONST VOID *Buffer,\r
849 IN UINTN Alignment\r
850 )\r
851{\r
852 return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);\r
853}\r
854\r
855/**\r
856 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.\r
857\r
858 @param AllocationSize The number of bytes to allocate.\r
859 @param Buffer The buffer to copy to the allocated buffer.\r
860 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
861 If Alignment is zero, then byte alignment is used.\r
862\r
863 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
864 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
865\r
866**/\r
867VOID *\r
868EFIAPI\r
869AllocateAlignedReservedCopyPool (\r
870 IN UINTN AllocationSize,\r
871 IN CONST VOID *Buffer,\r
872 IN UINTN Alignment\r
873 )\r
874{\r
875 return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);\r
876}\r
877\r
878/**\r
879 Frees a buffer that was previously allocated with one of the aligned pool allocation functions \r
880 in the Memory Allocation Library.\r
881\r
882 @param Buffer Pointer to the buffer to free.\r
883\r
884**/\r
885VOID\r
886EFIAPI\r
887FreeAlignedPool (\r
888 IN VOID *Buffer\r
889 )\r
890{\r
891 VOID *RawAddress;\r
892 VOID **FreePointer;\r
893 EFI_STATUS Status;\r
894\r
895 //\r
896 // Get the pre-saved original address in the over-allocate pool.\r
897 //\r
898 FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));\r
899 RawAddress = *FreePointer;\r
900\r
901 Status = gBS->FreePool (RawAddress);\r
902 ASSERT_EFI_ERROR (Status);\r
903}\r