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