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