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