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