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