]> git.proxmox.com Git - mirror_edk2.git/blob - EmbeddedPkg/Library/PrePiMemoryAllocationLib/MemoryAllocationLib.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / EmbeddedPkg / Library / PrePiMemoryAllocationLib / MemoryAllocationLib.c
1 /** @file
2 Implementation of the 6 PEI Ffs (FV) APIs in library form.
3
4 Copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
5
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7
8 **/
9
10 #include <PiPei.h>
11
12 #include <Library/BaseLib.h>
13 #include <Library/BaseMemoryLib.h>
14 #include <Library/PrePiLib.h>
15 #include <Library/DebugLib.h>
16
17 STATIC
18 VOID *
19 EFIAPI
20 InternalAllocatePages (
21 IN UINTN Pages,
22 IN EFI_MEMORY_TYPE MemoryType
23 )
24 {
25 EFI_PEI_HOB_POINTERS Hob;
26 EFI_PHYSICAL_ADDRESS NewTop;
27
28 Hob.Raw = GetHobList ();
29
30 NewTop = Hob.HandoffInformationTable->EfiFreeMemoryTop & ~(EFI_PHYSICAL_ADDRESS)EFI_PAGE_MASK;
31 NewTop -= Pages * EFI_PAGE_SIZE;
32
33 //
34 // Verify that there is sufficient memory to satisfy the allocation
35 //
36 if (NewTop < (Hob.HandoffInformationTable->EfiFreeMemoryBottom + sizeof (EFI_HOB_MEMORY_ALLOCATION))) {
37 return NULL;
38 }
39
40 //
41 // Update the PHIT to reflect the memory usage
42 //
43 Hob.HandoffInformationTable->EfiFreeMemoryTop = NewTop;
44
45 //
46 // Create a memory allocation HOB.
47 //
48 BuildMemoryAllocationHob (
49 Hob.HandoffInformationTable->EfiFreeMemoryTop,
50 Pages * EFI_PAGE_SIZE,
51 MemoryType
52 );
53
54 return (VOID *)(UINTN)Hob.HandoffInformationTable->EfiFreeMemoryTop;
55 }
56
57 /**
58 Allocates one or more 4KB pages of type EfiBootServicesData.
59
60 Allocates the number of 4KB pages of MemoryType and returns a pointer to the
61 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
62 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
63 returned.
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 **/
70 VOID *
71 EFIAPI
72 AllocatePages (
73 IN UINTN Pages
74 )
75 {
76 return InternalAllocatePages (Pages, EfiBootServicesData);
77 }
78
79 /**
80 Allocates one or more 4KB pages of type EfiRuntimeServicesData.
81
82 Allocates the number of 4KB pages of type EfiRuntimeServicesData and returns a pointer to the
83 allocated buffer. The buffer returned is aligned on a 4KB boundary. If Pages is 0, then NULL
84 is returned. If there is not enough memory remaining to satisfy the request, then NULL is
85 returned.
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 **/
92 VOID *
93 EFIAPI
94 AllocateRuntimePages (
95 IN UINTN Pages
96 )
97 {
98 return InternalAllocatePages (Pages, EfiRuntimeServicesData);
99 }
100
101 /**
102 Allocates one or more 4KB pages of type EfiBootServicesData at a specified alignment.
103
104 Allocates the number of 4KB pages specified by Pages of type EfiBootServicesData with an
105 alignment specified by Alignment. The allocated buffer is returned. If Pages is 0, then NULL is
106 returned. If there is not enough memory at the specified alignment remaining to satisfy the
107 request, then NULL is returned.
108 If Alignment is not a power of two and Alignment is not zero, then ASSERT().
109
110 @param Pages The number of 4 KB pages to allocate.
111 @param Alignment The requested alignment of the allocation. Must be a power of two.
112 If Alignment is zero, then byte alignment is used.
113
114 @return A pointer to the allocated buffer or NULL if allocation fails.
115
116 **/
117 VOID *
118 EFIAPI
119 AllocateAlignedPages (
120 IN UINTN Pages,
121 IN UINTN Alignment
122 )
123 {
124 VOID *Memory;
125 UINTN AlignmentMask;
126
127 //
128 // Alignment must be a power of two or zero.
129 //
130 ASSERT ((Alignment & (Alignment - 1)) == 0);
131
132 if (Pages == 0) {
133 return NULL;
134 }
135
136 //
137 // Make sure that Pages plus EFI_SIZE_TO_PAGES (Alignment) does not overflow.
138 //
139 ASSERT (Pages <= (MAX_ADDRESS - EFI_SIZE_TO_PAGES (Alignment)));
140 //
141 // We would rather waste some memory to save PEI code size.
142 //
143 Memory = (VOID *)(UINTN)AllocatePages (Pages + EFI_SIZE_TO_PAGES (Alignment));
144 if (Alignment == 0) {
145 AlignmentMask = Alignment;
146 } else {
147 AlignmentMask = Alignment - 1;
148 }
149
150 return (VOID *)(UINTN)(((UINTN)Memory + AlignmentMask) & ~AlignmentMask);
151 }
152
153 /**
154 Frees one or more 4KB pages that were previously allocated with one of the page allocation
155 functions in the Memory Allocation Library.
156
157 Frees the number of 4KB pages specified by Pages from the buffer specified by Buffer. Buffer
158 must have been allocated on a previous call to the page allocation services of the Memory
159 Allocation Library. If it is not possible to free allocated pages, then this function will
160 perform no actions.
161
162 If Buffer was not allocated with a page allocation function in the Memory Allocation Library,
163 then ASSERT().
164 If Pages is zero, then ASSERT().
165
166 @param Buffer Pointer to the buffer of pages to free.
167 @param Pages The number of 4 KB pages to free.
168
169 **/
170 VOID
171 EFIAPI
172 FreePages (
173 IN VOID *Buffer,
174 IN UINTN Pages
175 )
176 {
177 // For now, we do not support the ability to free pages in the PrePei Memory Allocator.
178 // The allocated memory is lost.
179 }
180
181 /**
182 Allocates a buffer of type EfiBootServicesData.
183
184 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData and returns a
185 pointer to the allocated buffer. If AllocationSize is 0, then a valid buffer of 0 size is
186 returned. If there is not enough memory remaining to satisfy the request, then NULL is returned.
187
188 @param AllocationSize The number of bytes to allocate.
189
190 @return A pointer to the allocated buffer or NULL if allocation fails.
191
192 **/
193 VOID *
194 EFIAPI
195 AllocatePool (
196 IN UINTN AllocationSize
197 )
198 {
199 EFI_HOB_MEMORY_POOL *Hob;
200
201 Hob = GetHobList ();
202
203 //
204 // Verify that there is sufficient memory to satisfy the allocation
205 //
206 if (AllocationSize > 0x10000) {
207 // Please call AllocatePages for big allocations
208 return 0;
209 } else {
210 Hob = (EFI_HOB_MEMORY_POOL *)CreateHob (
211 EFI_HOB_TYPE_MEMORY_POOL,
212 (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) +
213 AllocationSize)
214 );
215 return (VOID *)(Hob + 1);
216 }
217 }
218
219 /**
220 Allocates and zeros a buffer of type EfiBootServicesData.
221
222 Allocates the number bytes specified by AllocationSize of type EfiBootServicesData, clears the
223 buffer with zeros, and returns a pointer to the allocated buffer. If AllocationSize is 0, then a
224 valid buffer of 0 size is returned. If there is not enough memory remaining to satisfy the
225 request, then NULL is returned.
226
227 @param AllocationSize The number of bytes to allocate and zero.
228
229 @return A pointer to the allocated buffer or NULL if allocation fails.
230
231 **/
232 VOID *
233 EFIAPI
234 AllocateZeroPool (
235 IN UINTN AllocationSize
236 )
237 {
238 VOID *Buffer;
239
240 Buffer = AllocatePool (AllocationSize);
241 if (Buffer == NULL) {
242 return NULL;
243 }
244
245 ZeroMem (Buffer, AllocationSize);
246
247 return Buffer;
248 }
249
250 /**
251 Frees a buffer that was previously allocated with one of the pool allocation functions in the
252 Memory Allocation Library.
253
254 Frees the buffer specified by Buffer. Buffer must have been allocated on a previous call to the
255 pool allocation services of the Memory Allocation Library. If it is not possible to free pool
256 resources, then this function will perform no actions.
257
258 If Buffer was not allocated with a pool allocation function in the Memory Allocation Library,
259 then ASSERT().
260
261 @param Buffer Pointer to the buffer to free.
262
263 **/
264 VOID
265 EFIAPI
266 FreePool (
267 IN VOID *Buffer
268 )
269 {
270 // Not implemented yet
271 }