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