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