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