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