]> git.proxmox.com Git - mirror_edk2.git/blame - MdePkg/Library/DxeMemoryAllocationLib/MemoryAllocationLib.c
PeiSmbusLib & DxeSmbusLib
[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
abea19db 171 if (RealPages <= Pages) {\r
172 //\r
173 // This extra checking is to make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow. \r
174 //\r
175 return NULL;\r
176 }\r
177\r
878ddf1f 178 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, RealPages, &Memory);\r
179 if (EFI_ERROR (Status)) {\r
180 return NULL;\r
181 }\r
182 AlignedMemory = ((UINTN) Memory + AlignmentMask) & ~AlignmentMask;\r
183 UnalignedPages = EFI_SIZE_TO_PAGES ((UINTN) Memory - AlignedMemory);\r
184 if (UnalignedPages > 0) {\r
185 //\r
186 // Free first unaligned page(s).\r
187 //\r
188 Status = gBS->FreePages (Memory, UnalignedPages);\r
189 ASSERT_EFI_ERROR (Status);\r
190 }\r
191 Memory = (EFI_PHYSICAL_ADDRESS) (AlignedMemory + EFI_PAGES_TO_SIZE (Pages));\r
192 UnalignedPages = RealPages - Pages - UnalignedPages;\r
193 if (UnalignedPages > 0) {\r
194 //\r
195 // Free last unaligned page(s).\r
196 //\r
197 Status = gBS->FreePages (Memory, UnalignedPages);\r
198 ASSERT_EFI_ERROR (Status);\r
199 }\r
200 } else {\r
201 //\r
202 // Do not over-allocate pages in this case.\r
203 //\r
204 Status = gBS->AllocatePages (AllocateAnyPages, MemoryType, Pages, &Memory);\r
205 if (EFI_ERROR (Status)) {\r
206 return NULL;\r
207 }\r
208 AlignedMemory = (UINTN) Memory;\r
209 }\r
210 return (VOID *) AlignedMemory;\r
211}\r
212\r
213/**\r
214 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData\r
215 with an alignment specified by Alignment. \r
216\r
217 @param Pages The number of 4 KB pages to allocate.\r
218 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
219 If Alignment is zero, then byte alignment is used.\r
220\r
221 @return The allocated buffer is returned.<BR>\r
222 If Pages is 0, then NULL is returned.<BR>\r
223 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
224\r
225**/\r
226VOID *\r
227EFIAPI\r
228AllocateAlignedPages (\r
229 IN UINTN Pages,\r
230 IN UINTN Alignment\r
231 )\r
232{\r
233 return InternalAllocateAlignedPages (EfiBootServicesData, Pages, Alignment);\r
234}\r
235\r
236/**\r
237 Allocates the number of 4KB pages specified by Pages of type EfiRuntimeServicesData\r
238 with an alignment specified by Alignment. \r
239\r
240 @param Pages The number of 4 KB pages to allocate.\r
241 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
242 If Alignment is zero, then byte alignment is used.\r
243\r
244 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.\r
245 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
246\r
247**/\r
248VOID *\r
249EFIAPI\r
250AllocateAlignedRuntimePages (\r
251 IN UINTN Pages,\r
252 IN UINTN Alignment\r
253 )\r
254{\r
255 return InternalAllocateAlignedPages (EfiRuntimeServicesData, Pages, Alignment);\r
256}\r
257\r
258/**\r
259 Allocates one or more 4KB pages of type EfiReservedMemoryType at a specified alignment.\r
260\r
261 @param Pages The number of 4 KB pages to allocate.\r
262 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
263 If Alignment is zero, then byte alignment is used.\r
264\r
265 @return The allocated buffer is returned. If Pages is 0, then NULL is returned.\r
266 If there is not enough memory at the specified alignment remaining to satisfy the request, then NULL is returned.\r
267\r
268**/\r
269VOID *\r
270EFIAPI\r
271AllocateAlignedReservedPages (\r
272 IN UINTN Pages,\r
273 IN UINTN Alignment\r
274 )\r
275{\r
276 return InternalAllocateAlignedPages (EfiReservedMemoryType, Pages, Alignment);\r
277}\r
278\r
279/**\r
280 Frees one or more 4KB pages that were previously allocated with \r
281 one of the aligned page allocation functions in the Memory Allocation Library.\r
282\r
283 @param Buffer Pointer to the buffer of pages to free.\r
284 @param Pages The number of 4 KB pages to free.\r
285\r
286**/\r
287VOID\r
288EFIAPI\r
289FreeAlignedPages (\r
290 IN VOID *Buffer,\r
291 IN UINTN Pages\r
292 )\r
293{\r
294 EFI_STATUS Status;\r
295\r
296 ASSERT (Pages != 0);\r
297 Status = gBS->FreePages ((EFI_PHYSICAL_ADDRESS) (UINTN) Buffer, Pages);\r
298 ASSERT_EFI_ERROR (Status);\r
299}\r
300\r
301/**\r
302 Allocates a buffer of a certain memory type.\r
303\r
304 @param MemoryType The type of memory to allocate.\r
305 @param AllocationSize The number of bytes to allocate.\r
306\r
307 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
308 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
309\r
310**/\r
311VOID *\r
312InternalAllocatePool (\r
313 IN EFI_MEMORY_TYPE MemoryType, \r
314 IN UINTN AllocationSize\r
315 )\r
316{\r
317 EFI_STATUS Status;\r
318 VOID *Memory;\r
319\r
320 Status = gBS->AllocatePool (MemoryType, AllocationSize, &Memory);\r
321 if (EFI_ERROR (Status)) {\r
322 Memory = NULL;\r
323 }\r
324 return Memory;\r
325}\r
326\r
327/**\r
328 Allocates a buffer of type EfiBootServicesData.\r
329\r
330 @param AllocationSize The number of bytes to allocate.\r
331\r
332 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
333 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
334\r
335**/\r
336VOID *\r
337EFIAPI\r
338AllocatePool (\r
339 IN UINTN AllocationSize\r
340 )\r
341{\r
342 return InternalAllocatePool (EfiBootServicesData, AllocationSize);\r
343}\r
344\r
345/**\r
346 Allocates a buffer of type EfiRuntimeServicesData.\r
347\r
348 @param AllocationSize The number of bytes to allocate.\r
349\r
350 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
351 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
352\r
353**/\r
354VOID *\r
355EFIAPI\r
356AllocateRuntimePool (\r
357 IN UINTN AllocationSize\r
358 )\r
359{\r
360 return InternalAllocatePool (EfiRuntimeServicesData, AllocationSize);\r
361}\r
362\r
363/**\r
364 Allocates a buffer of type EfiReservedMemoryType.\r
365\r
366 @param AllocationSize The number of bytes to allocate.\r
367\r
368 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
369 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
370\r
371**/\r
372VOID *\r
373EFIAPI\r
374AllocateReservedPool (\r
375 IN UINTN AllocationSize\r
376 )\r
377{\r
378 return InternalAllocatePool (EfiReservedMemoryType, AllocationSize);\r
379}\r
380\r
381/**\r
382 Allocates and zeros a buffer of a certian pool type.\r
383\r
384 @param PoolType The type of memory to allocate.\r
385 @param AllocationSize The number of bytes to allocate and zero.\r
386\r
387 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
388 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
389\r
390**/\r
391VOID *\r
392InternalAllocateZeroPool (\r
393 IN EFI_MEMORY_TYPE PoolType, \r
394 IN UINTN AllocationSize\r
395 ) \r
396{\r
397 VOID *Memory;\r
398 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
399 if (Memory != NULL) {\r
400 Memory = ZeroMem (Memory, AllocationSize);\r
401 }\r
402 return Memory;\r
403}\r
404\r
405/**\r
406 Allocates and zeros a buffer of type EfiBootServicesData.\r
407\r
408 @param AllocationSize The number of bytes to allocate and zero.\r
409\r
410 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
411 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
412\r
413**/\r
414VOID *\r
415EFIAPI\r
416AllocateZeroPool (\r
417 IN UINTN AllocationSize\r
418 )\r
419{\r
420 return InternalAllocateZeroPool (EfiBootServicesData, AllocationSize);\r
421}\r
422\r
423/**\r
424 Allocates and zeros a buffer of type EfiRuntimeServicesData.\r
425\r
426 @param AllocationSize The number of bytes to allocate and zero.\r
427\r
428 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
429 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
430\r
431**/\r
432VOID *\r
433EFIAPI\r
434AllocateRuntimeZeroPool (\r
435 IN UINTN AllocationSize\r
436 )\r
437{\r
438 return InternalAllocateZeroPool (EfiRuntimeServicesData, AllocationSize);\r
439}\r
440\r
441/**\r
442 Allocates and zeros a buffer of type EfiReservedMemoryType.\r
443\r
444 @param AllocationSize The number of bytes to allocate and zero.\r
445\r
446 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
447 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
448\r
449**/\r
450VOID *\r
451EFIAPI\r
452AllocateReservedZeroPool (\r
453 IN UINTN AllocationSize\r
454 )\r
455{\r
456 return InternalAllocateZeroPool (EfiReservedMemoryType, AllocationSize);\r
457}\r
458\r
459/**\r
460 Copies a buffer to an allocated buffer of a certian memory type. \r
461\r
462 @param MemoryType The type of pool to allocate.\r
463 @param AllocationSize The number of bytes to allocate and zero.\r
464 @param Buffer The buffer to copy to the allocated buffer.\r
465\r
466 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
467 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
468\r
469**/\r
470VOID *\r
471InternalAllocateCopyPool (\r
472 IN EFI_MEMORY_TYPE PoolType, \r
473 IN UINTN AllocationSize,\r
474 IN CONST VOID *Buffer\r
475 ) \r
476{\r
477 VOID *Memory;\r
478\r
479 Memory = InternalAllocatePool (PoolType, AllocationSize);\r
480 if (Memory != NULL) {\r
481 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
482 }\r
483 return Memory;\r
484} \r
485\r
486/**\r
487 Copies a buffer to an allocated buffer of type EfiBootServicesData. \r
488\r
489 @param AllocationSize The number of bytes to allocate.\r
490 @param Buffer The buffer to copy to the allocated buffer.\r
491\r
492 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
493 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
494\r
495**/\r
496VOID *\r
497EFIAPI\r
498AllocateCopyPool (\r
499 IN UINTN AllocationSize,\r
500 IN CONST VOID *Buffer\r
501 )\r
502{\r
503 return InternalAllocateCopyPool (EfiBootServicesData, AllocationSize, Buffer);\r
504}\r
505\r
506/**\r
507 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData. \r
508\r
509 @param AllocationSize The number of bytes to allocate.\r
510 @param Buffer The buffer to copy to the allocated buffer.\r
511\r
512 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
513 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
514\r
515**/\r
516VOID *\r
517EFIAPI\r
518AllocateRuntimeCopyPool (\r
519 IN UINTN AllocationSize,\r
520 IN CONST VOID *Buffer\r
521 )\r
522{\r
523 return InternalAllocateCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer);\r
524}\r
525\r
526/**\r
527 Copies a buffer to an allocated buffer of type EfiReservedMemoryType. \r
528\r
529 @param AllocationSize The number of bytes to allocate.\r
530 @param Buffer The buffer to copy to the allocated buffer.\r
531\r
532 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
533 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
534\r
535**/\r
536VOID *\r
537EFIAPI\r
538AllocateReservedCopyPool (\r
539 IN UINTN AllocationSize,\r
540 IN CONST VOID *Buffer\r
541 )\r
542{\r
543 return InternalAllocateCopyPool (EfiReservedMemoryType, AllocationSize, Buffer);\r
544}\r
545\r
546/**\r
547 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.\r
548\r
549 @param Buffer Pointer to the buffer to free.\r
550\r
551**/\r
552VOID\r
553EFIAPI\r
554FreePool (\r
555 IN VOID *Buffer\r
556 )\r
557{\r
558 EFI_STATUS Status;\r
559\r
560 Status = gBS->FreePool (Buffer);\r
561 ASSERT_EFI_ERROR (Status);\r
562}\r
563\r
564/**\r
565 Allocates a buffer of a certain pool type at a specified alignment.\r
566\r
567 @param PoolType The type of pool to allocate.\r
568 @param AllocationSize The number of bytes to allocate.\r
569 @param Alignment The requested alignment of the allocation. Must be a power of two. If Alignment is zero, then byte alignment is used.\r
570\r
571 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
572 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
573\r
574**/\r
575VOID *\r
576InternalAllocateAlignedPool (\r
577 IN EFI_MEMORY_TYPE PoolType,\r
578 IN UINTN AllocationSize,\r
579 IN UINTN Alignment\r
580 )\r
581{\r
582 VOID *RawAddress;\r
583 UINTN AlignedAddress;\r
584 UINTN AlignmentMask;\r
585 UINTN OverAllocationSize;\r
abea19db 586 UINTN RealAllocationSize;\r
878ddf1f 587 VOID **FreePointer;\r
878ddf1f 588\r
589 //\r
590 // Alignment must be a power of two or zero.\r
591 //\r
592 ASSERT ((Alignment & (Alignment - 1)) == 0);\r
593 \r
594 if (Alignment == 0) {\r
595 AlignmentMask = Alignment;\r
596 } else {\r
597 AlignmentMask = Alignment - 1;\r
598 }\r
599 //\r
600 // Calculate the extra memory size, over-allocate memory pool and get the aligned memory address. \r
601 //\r
602 OverAllocationSize = sizeof (RawAddress) + AlignmentMask;\r
abea19db 603 RealAllocationSize = AllocationSize + OverAllocationSize;\r
604 if (RealAllocationSize <= AllocationSize ) {\r
605 //\r
606 // This extra checking is to make sure that AllocationSize plus OverAllocationSize does not overflow. \r
607 //\r
608 return NULL;\r
609 }\r
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
799 Memory = InternalAllocateAlignedPool (PoolType, AllocationSize, Alignment);\r
800 if (Memory != NULL) {\r
801 Memory = CopyMem (Memory, Buffer, AllocationSize);\r
802 }\r
803 return Memory;\r
804}\r
805\r
806/**\r
807 Copies a buffer to an allocated buffer of type EfiBootServicesData at a specified alignment.\r
808\r
809 @param AllocationSize The number of bytes to allocate.\r
810 @param Buffer The buffer to copy to the allocated buffer.\r
811 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
812 If Alignment is zero, then byte alignment is used.\r
813\r
814 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
815 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
816\r
817**/\r
818VOID *\r
819EFIAPI\r
820AllocateAlignedCopyPool (\r
821 IN UINTN AllocationSize,\r
822 IN CONST VOID *Buffer,\r
823 IN UINTN Alignment\r
824 )\r
825{\r
826 return InternalAllocateAlignedCopyPool (EfiBootServicesData, AllocationSize, Buffer, Alignment);\r
827}\r
828\r
829/**\r
830 Copies a buffer to an allocated buffer of type EfiRuntimeServicesData at a specified alignment.\r
831\r
832 @param AllocationSize The number of bytes to allocate.\r
833 @param Buffer The buffer to copy to the allocated buffer.\r
834 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
835 If Alignment is zero, then byte alignment is used.\r
836\r
837 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
838 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
839\r
840**/\r
841VOID *\r
842EFIAPI\r
843AllocateAlignedRuntimeCopyPool (\r
844 IN UINTN AllocationSize,\r
845 IN CONST VOID *Buffer,\r
846 IN UINTN Alignment\r
847 )\r
848{\r
849 return InternalAllocateAlignedCopyPool (EfiRuntimeServicesData, AllocationSize, Buffer, Alignment);\r
850}\r
851\r
852/**\r
853 Copies a buffer to an allocated buffer of type EfiReservedMemoryType at a specified alignment.\r
854\r
855 @param AllocationSize The number of bytes to allocate.\r
856 @param Buffer The buffer to copy to the allocated buffer.\r
857 @param Alignment The requested alignment of the allocation. Must be a power of two.\r
858 If Alignment is zero, then byte alignment is used.\r
859\r
860 @return A pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is returned.\r
861 If there is not enough memory remaining to satisfy the request, then NULL is returned.\r
862\r
863**/\r
864VOID *\r
865EFIAPI\r
866AllocateAlignedReservedCopyPool (\r
867 IN UINTN AllocationSize,\r
868 IN CONST VOID *Buffer,\r
869 IN UINTN Alignment\r
870 )\r
871{\r
872 return InternalAllocateAlignedCopyPool (EfiReservedMemoryType, AllocationSize, Buffer, Alignment);\r
873}\r
874\r
875/**\r
876 Frees a buffer that was previously allocated with one of the aligned pool allocation functions \r
877 in the Memory Allocation Library.\r
878\r
879 @param Buffer Pointer to the buffer to free.\r
880\r
881**/\r
882VOID\r
883EFIAPI\r
884FreeAlignedPool (\r
885 IN VOID *Buffer\r
886 )\r
887{\r
888 VOID *RawAddress;\r
889 VOID **FreePointer;\r
890 EFI_STATUS Status;\r
891\r
892 //\r
893 // Get the pre-saved original address in the over-allocate pool.\r
894 //\r
895 FreePointer = (VOID **)((UINTN) Buffer - sizeof (RawAddress));\r
896 RawAddress = *FreePointer;\r
897\r
898 Status = gBS->FreePool (RawAddress);\r
899 ASSERT_EFI_ERROR (Status);\r
900}\r