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