]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/DxeMemoryAllocationLib/MemoryAllocationLib.c
Initial import.
[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
171 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);\r
172 if (EFI_ERROR (Status)) {\r
173 return NULL;\r
174 }\r
175 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;\r
176 UnalignedPages = EFI_SIZE_TO_PAGES ((UINTN) Memory - AlignedMemory);\r
177 if (UnalignedPages > 0) {\r
178 //\r
179 // Free first unaligned page(s).\r
180 //\r
181 Status = gBS->FreePages (Memory, UnalignedPages);\r
182 ASSERT_EFI_ERROR (Status);\r
183 }\r
184 Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));\r
185 UnalignedPages = RealPages - Pages - UnalignedPages;\r
186 if (UnalignedPages > 0) {\r
187 //\r
188 // Free last unaligned page(s).\r
189 //\r
190 Status = gBS->FreePages (Memory, UnalignedPages);\r
191 ASSERT_EFI_ERROR (Status);\r
192 }\r
193 } else {\r
194 //\r
195 // Do not over-allocate pages in this case.\r
196 //\r
197 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);\r
198 if (EFI_ERROR (Status)) {\r
199 return NULL;\r
200 }\r
201 AlignedMemory = (UINTN) Memory;\r
202 }\r
203 return (VOID *) AlignedMemory;\r
204}\r
205\r
206/**\r
207 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData\r
208 with an alignment specified by Alignment. \r
209\r
210 @param Pages The number of 4 KB pages to allocate.\r
211 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
212 If Alignment is zero, then byte alignment is used.\r
213\r
214 @return The allocated buffer is returned.<BR>\r
215 If Pages is 0, then NULL is returned.<BR>\r
216 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
217\r
218**/\r
219VOID *\r
220EFIAPI\r
221AllocateAlignedPages (\r
222 IN UINTN Pages,\r
223 IN UINTN Alignment\r
224 )\r
225{\r
226 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);\r
227}\r
228\r
229/**\r
230 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData\r
231 with an alignment specified by Alignment. \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 The allocated buffer is returned. If Pages is 0, then NULL is returned.\r
238 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
239\r
240**/\r
241VOID *\r
242EFIAPI\r
243AllocateAlignedRuntimePages (\r
244 IN UINTN Pages,\r
245 IN UINTN Alignment\r
246 )\r
247{\r
248 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);\r
249}\r
250\r
251/**\r
252 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.\r
253\r
254 @param Pages The number of 4 KB pages to allocate.\r
255 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
256 If Alignment is zero, then byte alignment is used.\r
257\r
258 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.\r
259 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
260\r
261**/\r
262VOID *\r
263EFIAPI\r
264AllocateAlignedReservedPages (\r
265 IN UINTN Pages,\r
266 IN UINTN Alignment\r
267 )\r
268{\r
269 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);\r
270}\r
271\r
272/**\r
273 Frees one or more 4KB pages that were previously allocated with \r
274 one of the aligned page allocation functions in the Memory Allocation Library.\r
275\r
276 @param Buffer Pointer to the buffer of pages to free.\r
277 @param Pages The number of 4 KB pages to free.\r
278\r
279**/\r
280VOID\r
281EFIAPI\r
282FreeAlignedPages (\r
283 IN VOID *Buffer,\r
284 IN UINTN Pages\r
285 )\r
286{\r
287 EFI_STATUS Status;\r
288\r
289 ASSERT (Pages != 0);\r
290 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
291 ASSERT_EFI_ERROR (Status);\r
292}\r
293\r
294/**\r
295 Allocates a buffer of a certain memory type.\r
296\r
297 @param MemoryType The type of memory to allocate.\r
298 @param AllocationSize The number of bytes to allocate.\r
299\r
300 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
301 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
302\r
303**/\r
304VOID *\r
305InternalAllocatePool (\r
306 IN EFI_MEMORY_TYPE MemoryType, \r
307 IN UINTN AllocationSize\r
308 )\r
309{\r
310 EFI_STATUS Status;\r
311 VOID *Memory;\r
312\r
313 Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);\r
314 if (EFI_ERROR (Status)) {\r
315 Memory = NULL;\r
316 }\r
317 return Memory;\r
318}\r
319\r
320/**\r
321 Allocates a buffer of type EfiBootServicesData.\r
322\r
323 @param AllocationSize The number of bytes to allocate.\r
324\r
325 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
326 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
327\r
328**/\r
329VOID *\r
330EFIAPI\r
331AllocatePool (\r
332 IN UINTN AllocationSize\r
333 )\r
334{\r
335 return InternalAllocatePool (EfiBootServicesData, AllocationSize);\r
336}\r
337\r
338/**\r
339 Allocates a buffer of type EfiRuntimeServicesData.\r
340\r
341 @param AllocationSize The number of bytes to allocate.\r
342\r
343 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
344 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
345\r
346**/\r
347VOID *\r
348EFIAPI\r
349AllocateRuntimePool (\r
350 IN UINTN AllocationSize\r
351 )\r
352{\r
353 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
354}\r
355\r
356/**\r
357 Allocates a buffer of type EfiReservedMemoryType.\r
358\r
359 @param AllocationSize The number of bytes to allocate.\r
360\r
361 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
362 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
363\r
364**/\r
365VOID *\r
366EFIAPI\r
367AllocateReservedPool (\r
368 IN UINTN AllocationSize\r
369 )\r
370{\r
371 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);\r
372}\r
373\r
374/**\r
375 Allocates and zeros a buffer of a certian pool type.\r
376\r
377 @param PoolType The type of memory to allocate.\r
378 @param AllocationSize The number of bytes to allocate and zero.\r
379\r
380 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
381 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
382\r
383**/\r
384VOID *\r
385InternalAllocateZeroPool (\r
386 IN EFI_MEMORY_TYPE PoolType, \r
387 IN UINTN AllocationSize\r
388 ) \r
389{\r
390 VOID *Memory;\r
391 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
392 if (Memory != NULL) {\r
393 Memory = ZeroMem (Memory, AllocationSize);\r
394 }\r
395 return Memory;\r
396}\r
397\r
398/**\r
399 Allocates and zeros a buffer of type EfiBootServicesData.\r
400\r
401 @param AllocationSize The number of bytes to allocate and zero.\r
402\r
403 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
404 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
405\r
406**/\r
407VOID *\r
408EFIAPI\r
409AllocateZeroPool (\r
410 IN UINTN AllocationSize\r
411 )\r
412{\r
413 return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);\r
414}\r
415\r
416/**\r
417 Allocates and zeros a buffer of type EfiRuntimeServicesData.\r
418\r
419 @param AllocationSize The number of bytes to allocate and zero.\r
420\r
421 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
422 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
423\r
424**/\r
425VOID *\r
426EFIAPI\r
427AllocateRuntimeZeroPool (\r
428 IN UINTN AllocationSize\r
429 )\r
430{\r
431 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
432}\r
433\r
434/**\r
435 Allocates and zeros a buffer of type EfiReservedMemoryType.\r
436\r
437 @param AllocationSize The number of bytes to allocate and zero.\r
438\r
439 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
440 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
441\r
442**/\r
443VOID *\r
444EFIAPI\r
445AllocateReservedZeroPool (\r
446 IN UINTN AllocationSize\r
447 )\r
448{\r
449 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);\r
450}\r
451\r
452/**\r
453 Copies a buffer to an allocated buffer of a certian memory type. \r
454\r
455 @param MemoryType The type of pool to allocate.\r
456 @param AllocationSize The number of bytes to allocate and zero.\r
457 @param Buffer The buffer to copy to the allocated buffer.\r
458\r
459 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
460 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
461\r
462**/\r
463VOID *\r
464InternalAllocateCopyPool (\r
465 IN EFI_MEMORY_TYPE PoolType, \r
466 IN UINTN AllocationSize,\r
467 IN CONST VOID *Buffer\r
468 ) \r
469{\r
470 VOID *Memory;\r
471\r
472 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
473 if (Memory != NULL) {\r
474 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
475 }\r
476 return Memory;\r
477} \r
478\r
479/**\r
480 Copies a buffer to an allocated buffer of type EfiBootServicesData. \r
481\r
482 @param AllocationSize The number of bytes to allocate.\r
483 @param Buffer The buffer to copy to the allocated buffer.\r
484\r
485 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
486 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
487\r
488**/\r
489VOID *\r
490EFIAPI\r
491AllocateCopyPool (\r
492 IN UINTN AllocationSize,\r
493 IN CONST VOID *Buffer\r
494 )\r
495{\r
496 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);\r
497}\r
498\r
499/**\r
500 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. \r
501\r
502 @param AllocationSize The number of bytes to allocate.\r
503 @param Buffer The buffer to copy to the allocated buffer.\r
504\r
505 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
506 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
507\r
508**/\r
509VOID *\r
510EFIAPI\r
511AllocateRuntimeCopyPool (\r
512 IN UINTN AllocationSize,\r
513 IN CONST VOID *Buffer\r
514 )\r
515{\r
516 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
517}\r
518\r
519/**\r
520 Copies a buffer to an allocated buffer of type EfiReservedMemoryType. \r
521\r
522 @param AllocationSize The number of bytes to allocate.\r
523 @param Buffer The buffer to copy to the allocated buffer.\r
524\r
525 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
526 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
527\r
528**/\r
529VOID *\r
530EFIAPI\r
531AllocateReservedCopyPool (\r
532 IN UINTN AllocationSize,\r
533 IN CONST VOID *Buffer\r
534 )\r
535{\r
536 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);\r
537}\r
538\r
539/**\r
540 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.\r
541\r
542 @param Buffer Pointer to the buffer to free.\r
543\r
544**/\r
545VOID\r
546EFIAPI\r
547FreePool (\r
548 IN VOID *Buffer\r
549 )\r
550{\r
551 EFI_STATUS Status;\r
552\r
553 Status = gBS->FreePool (Buffer);\r
554 ASSERT_EFI_ERROR (Status);\r
555}\r
556\r
557/**\r
558 Allocates a buffer of a certain pool type at a specified alignment.\r
559\r
560 @param PoolType The type of pool to allocate.\r
561 @param AllocationSize The number of bytes to allocate.\r
562 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.\r
563\r
564 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
565 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
566\r
567**/\r
568VOID *\r
569InternalAllocateAlignedPool (\r
570 IN EFI_MEMORY_TYPE PoolType,\r
571 IN UINTN AllocationSize,\r
572 IN UINTN Alignment\r
573 )\r
574{\r
575 VOID *RawAddress;\r
576 UINTN AlignedAddress;\r
577 UINTN AlignmentMask;\r
578 UINTN OverAllocationSize;\r
579 VOID **FreePointer;\r
580 EFI_STATUS Status;\r
581\r
582 //\r
583 // Alignment must be a power of two or zero.\r
584 //\r
585 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
586 \r
587 if (Alignment == 0) {\r
588 AlignmentMask = Alignment;\r
589 } else {\r
590 AlignmentMask = Alignment - 1;\r
591 }\r
592 //\r
593 // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address. \r
594 //\r
595 OverAllocationSize = sizeof (RawAddress) + AlignmentMask;\r
596 Status = gBS->AllocatePool (PoolType, AllocationSize + OverAllocationSize, &RawAddress);\r
597 if (EFI_ERROR (Status)) {\r
598 return NULL;\r
599 }\r
600 AlignedAddress = ((UINTN) RawAddress + OverAllocationSize) & ~AlignmentMask;\r
601 //\r
602 // Save the original memory address just before the aligned address.\r
603 //\r
604 FreePointer = (VOID **)(AlignedAddress - sizeof (RawAddress));\r
605 *FreePointer = RawAddress;\r
606\r
607 return (VOID *) AlignedAddress;\r
608}\r
609\r
610/**\r
611 Allocates a buffer of type EfiBootServicesData at a specified alignment.\r
612\r
613 @param AllocationSize The number of bytes to allocate.\r
614 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.\r
615\r
616 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
617 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
618\r
619**/\r
620VOID *\r
621EFIAPI\r
622AllocateAlignedPool (\r
623 IN UINTN AllocationSize,\r
624 IN UINTN Alignment\r
625 )\r
626{\r
627 return InternalAllocateAlignedPool (EfiBootServicesData, AllocationSize, Alignment);\r
628}\r
629\r
630/**\r
631 Allocates a buffer of type EfiRuntimeServicesData at a specified alignment.\r
632\r
633 @param AllocationSize The number of bytes to allocate.\r
634 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
635 If Alignment is zero, then byte alignment is used.\r
636\r
637 A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
638 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
639\r
640**/\r
641VOID *\r
642EFIAPI\r
643AllocateAlignedRuntimePool (\r
644 IN UINTN AllocationSize,\r
645 IN UINTN Alignment\r
646 )\r
647{\r
648 return InternalAllocateAlignedPool (EfiRuntimeServicesData, AllocationSize, Alignment);\r
649}\r
650\r
651/**\r
652 Allocates a buffer of type EfiReservedMemoryType at a specified alignment.\r
653\r
654 @param AllocationSize The number of bytes to allocate.\r
655 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
656 If Alignment is zero, then byte alignment is used.\r
657\r
658 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
659 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
660\r
661**/\r
662VOID *\r
663EFIAPI\r
664AllocateAlignedReservedPool (\r
665 IN UINTN AllocationSize,\r
666 IN UINTN Alignment\r
667 )\r
668{\r
669 return InternalAllocateAlignedPool (EfiReservedMemoryType, AllocationSize, Alignment);\r
670}\r
671\r
672/**\r
673 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.\r
674\r
675 @param PoolType The type of pool to allocate.\r
676 @param AllocationSize The number of bytes to allocate.\r
677 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
678 If Alignment is zero, then byte alignment is used.\r
679\r
680 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
681 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
682\r
683**/\r
684VOID *\r
685InternalAllocateAlignedZeroPool (\r
686 IN EFI_MEMORY_TYPE PoolType,\r
687 IN UINTN AllocationSize,\r
688 IN UINTN Alignment\r
689 )\r
690{\r
691 VOID *Memory;\r
692 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);\r
693 if (Memory != NULL) {\r
694 Memory = ZeroMem (Memory, AllocationSize);\r
695 }\r
696 return Memory;\r
697}\r
698\r
699/**\r
700 Allocates and zeros a buffer of type EfiBootServicesData at a specified alignment.\r
701\r
702 @param AllocationSize The number of bytes to allocate.\r
703 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
704 If Alignment is zero, then byte alignment is used.\r
705\r
706 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
707 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
708\r
709**/\r
710VOID *\r
711EFIAPI\r
712AllocateAlignedZeroPool (\r
713 IN UINTN AllocationSize,\r
714 IN UINTN Alignment\r
715 )\r
716{\r
717 return InternalAllocateAlignedZeroPool (EfiBootServicesData, AllocationSize, Alignment);\r
718}\r
719\r
720/**\r
721 Allocates and zeros a buffer of type EfiRuntimeServicesData at a specified alignment.\r
722\r
723 @param AllocationSize The number of bytes to allocate.\r
724 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
725 If Alignment is zero, then byte alignment is used.\r
726\r
727 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
728 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
729\r
730**/\r
731VOID *\r
732EFIAPI\r
733AllocateAlignedRuntimeZeroPool (\r
734 IN UINTN AllocationSize,\r
735 IN UINTN Alignment\r
736 )\r
737{\r
738 return InternalAllocateAlignedZeroPool (EfiRuntimeServicesData, AllocationSize, Alignment);\r
739}\r
740\r
741/**\r
742 Allocates and zeros a buffer of type EfiReservedMemoryType at a specified alignment.\r
743\r
744 @param AllocationSize The number of bytes to allocate.\r
745 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
746 If Alignment is zero, then byte alignment is used.\r
747\r
748 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
749 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
750\r
751**/\r
752VOID *\r
753EFIAPI\r
754AllocateAlignedReservedZeroPool (\r
755 IN UINTN AllocationSize,\r
756 IN UINTN Alignment\r
757 )\r
758{\r
759 return InternalAllocateAlignedZeroPool (EfiReservedMemoryType, AllocationSize, Alignment);\r
760}\r
761\r
762/**\r
763 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.\r
764\r
765 @param PoolType The type of pool to allocate.\r
766 @param AllocationSize The number of bytes to allocate.\r
767 @param Buffer The buffer to copy to the allocated buffer.\r
768 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
769 If Alignment is zero, then byte alignment is used.\r
770\r
771 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
772 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
773\r
774**/\r
775VOID *\r
776InternalAllocateAlignedCopyPool (\r
777 IN EFI_MEMORY_TYPE PoolType,\r
778 IN UINTN AllocationSize,\r
779 IN CONST VOID *Buffer,\r
780 IN UINTN Alignment\r
781 )\r
782{\r
783 VOID *Memory;\r
784 \r
785 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);\r
786 if (Memory != NULL) {\r
787 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
788 }\r
789 return Memory;\r
790}\r
791\r
792/**\r
793 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.\r
794\r
795 @param AllocationSize The number of bytes to allocate.\r
796 @param Buffer The buffer to copy to the allocated buffer.\r
797 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
798 If Alignment is zero, then byte alignment is used.\r
799\r
800 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
801 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
802\r
803**/\r
804VOID *\r
805EFIAPI\r
806AllocateAlignedCopyPool (\r
807 IN UINTN AllocationSize,\r
808 IN CONST VOID *Buffer,\r
809 IN UINTN Alignment\r
810 )\r
811{\r
812 return InternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);\r
813}\r
814\r
815/**\r
816 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.\r
817\r
818 @param AllocationSize The number of bytes to allocate.\r
819 @param Buffer The buffer to copy to the allocated buffer.\r
820 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
821 If Alignment is zero, then byte alignment is used.\r
822\r
823 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
824 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
825\r
826**/\r
827VOID *\r
828EFIAPI\r
829AllocateAlignedRuntimeCopyPool (\r
830 IN UINTN AllocationSize,\r
831 IN CONST VOID *Buffer,\r
832 IN UINTN Alignment\r
833 )\r
834{\r
835 return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);\r
836}\r
837\r
838/**\r
839 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.\r
840\r
841 @param AllocationSize The number of bytes to allocate.\r
842 @param Buffer The buffer to copy to the allocated buffer.\r
843 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
844 If Alignment is zero, then byte alignment is used.\r
845\r
846 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
847 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
848\r
849**/\r
850VOID *\r
851EFIAPI\r
852AllocateAlignedReservedCopyPool (\r
853 IN UINTN AllocationSize,\r
854 IN CONST VOID *Buffer,\r
855 IN UINTN Alignment\r
856 )\r
857{\r
858 return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);\r
859}\r
860\r
861/**\r
862 Frees a buffer that was previously allocated with one of the aligned pool allocation functions \r
863 in the Memory Allocation Library.\r
864\r
865 @param Buffer Pointer to the buffer to free.\r
866\r
867**/\r
868VOID\r
869EFIAPI\r
870FreeAlignedPool (\r
871 IN VOID *Buffer\r
872 )\r
873{\r
874 VOID *RawAddress;\r
875 VOID **FreePointer;\r
876 EFI_STATUS Status;\r
877\r
878 //\r
879 // Get the pre-saved original address in the over-allocate pool.\r
880 //\r
881 FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));\r
882 RawAddress = *FreePointer;\r
883\r
884 Status = gBS->FreePool (RawAddress);\r
885 ASSERT_EFI_ERROR (Status);\r
886}\r