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