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