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