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