microsoft/mu_feature_ffa

Public

mirrored from https://github.com/microsoft/mu_feature_ffaAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
c9842c888abc6eba92f034d4796a26f76abb2f42

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

FfaFeaturePkg/Library/SecurePartitionMemoryAllocationLib/SecurePartitionMemoryAllocationLib.c

1054lines · modeblame

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