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