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