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