TianoCore EDK2 master
Loading...
Searching...
No Matches
MemoryServices.c
Go to the documentation of this file.
1
9#include "PeiMain.h"
10
23VOID
25 IN PEI_CORE_INSTANCE *PrivateData,
26 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
27 IN PEI_CORE_INSTANCE *OldCoreData
28 )
29{
30 PrivateData->SwitchStackSignal = FALSE;
31
32 //
33 // First entering PeiCore, following code will initialized some field
34 // in PeiCore's private data according to hand off data from SEC core.
35 //
36 if (OldCoreData == NULL) {
37 PrivateData->PeiMemoryInstalled = FALSE;
38 PrivateData->HobList.Raw = SecCoreData->PeiTemporaryRamBase;
39
41 BOOT_WITH_FULL_CONFIGURATION,
42 (EFI_PHYSICAL_ADDRESS)(UINTN)SecCoreData->PeiTemporaryRamBase,
43 (UINTN)SecCoreData->PeiTemporaryRamSize
44 );
45
46 //
47 // Set Ps to point to ServiceTableShadow in Cache
48 //
49 PrivateData->Ps = &(PrivateData->ServiceTableShadow);
50 }
51
52 return;
53}
54
72EFIAPI
74 IN CONST EFI_PEI_SERVICES **PeiServices,
75 IN EFI_PHYSICAL_ADDRESS MemoryBegin,
76 IN UINT64 MemoryLength
77 )
78{
79 PEI_CORE_INSTANCE *PrivateData;
80
81 DEBUG ((DEBUG_INFO, "PeiInstallPeiMemory MemoryBegin 0x%LX, MemoryLength 0x%LX\n", MemoryBegin, MemoryLength));
82 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
83
84 //
85 // PEI_SERVICE.InstallPeiMemory should only be called one time during whole PEI phase.
86 // If it is invoked more than one time, ASSERT information is given for developer debugging in debug tip and
87 // simply return EFI_SUCCESS in release tip to ignore it.
88 //
89 if (PrivateData->PeiMemoryInstalled) {
90 DEBUG ((DEBUG_ERROR, "ERROR: PeiInstallPeiMemory is called more than once!\n"));
91 ASSERT (FALSE);
92 return EFI_SUCCESS;
93 }
94
95 PrivateData->PhysicalMemoryBegin = MemoryBegin;
96 PrivateData->PhysicalMemoryLength = MemoryLength;
97 PrivateData->FreePhysicalMemoryTop = MemoryBegin + MemoryLength;
98
99 PrivateData->SwitchStackSignal = TRUE;
100
101 return EFI_SUCCESS;
102}
103
112VOID
114 IN PEI_CORE_INSTANCE *Private,
115 IN BOOLEAN TemporaryRamMigrated
116 )
117{
118 EFI_PHYSICAL_ADDRESS NewMemPagesBase;
119 EFI_PHYSICAL_ADDRESS MemPagesBase;
120
121 Private->MemoryPages.Size = (UINTN)(Private->HobList.HandoffInformationTable->EfiMemoryTop -
122 Private->HobList.HandoffInformationTable->EfiFreeMemoryTop);
123 if (Private->MemoryPages.Size == 0) {
124 //
125 // No any memory page allocated in pre-memory phase.
126 //
127 return;
128 }
129
130 Private->MemoryPages.Base = Private->HobList.HandoffInformationTable->EfiFreeMemoryTop;
131
132 ASSERT (Private->MemoryPages.Size <= Private->FreePhysicalMemoryTop);
133 NewMemPagesBase = Private->FreePhysicalMemoryTop - Private->MemoryPages.Size;
134 NewMemPagesBase &= ~(UINT64)EFI_PAGE_MASK;
135 ASSERT (NewMemPagesBase >= Private->PhysicalMemoryBegin);
136 //
137 // Copy memory pages at temporary heap top to permanent heap top.
138 //
139 if (TemporaryRamMigrated) {
140 //
141 // Memory pages at temporary heap top has been migrated to permanent heap,
142 // Here still needs to copy them from permanent heap to permanent heap top.
143 //
144 MemPagesBase = Private->MemoryPages.Base;
145 if (Private->HeapOffsetPositive) {
146 MemPagesBase += Private->HeapOffset;
147 } else {
148 MemPagesBase -= Private->HeapOffset;
149 }
150
151 CopyMem ((VOID *)(UINTN)NewMemPagesBase, (VOID *)(UINTN)MemPagesBase, Private->MemoryPages.Size);
152 } else {
153 CopyMem ((VOID *)(UINTN)NewMemPagesBase, (VOID *)(UINTN)Private->MemoryPages.Base, Private->MemoryPages.Size);
154 }
155
156 if (NewMemPagesBase >= Private->MemoryPages.Base) {
157 Private->MemoryPages.OffsetPositive = TRUE;
158 Private->MemoryPages.Offset = (UINTN)(NewMemPagesBase - Private->MemoryPages.Base);
159 } else {
160 Private->MemoryPages.OffsetPositive = FALSE;
161 Private->MemoryPages.Offset = (UINTN)(Private->MemoryPages.Base - NewMemPagesBase);
162 }
163
164 DEBUG ((DEBUG_INFO, "Pages Offset = 0x%lX\n", (UINT64)Private->MemoryPages.Offset));
165
166 Private->FreePhysicalMemoryTop = NewMemPagesBase;
167}
168
178VOID
180 IN PEI_CORE_INSTANCE *PrivateData,
181 IN UINTN OrgFvHandle,
182 IN UINTN FvHandle
183 )
184{
186 EFI_HOB_FIRMWARE_VOLUME *FirmwareVolumeHob;
187 EFI_HOB_FIRMWARE_VOLUME2 *FirmwareVolume2Hob;
188 EFI_HOB_FIRMWARE_VOLUME3 *FirmwareVolume3Hob;
189
190 DEBUG ((DEBUG_INFO, "Converting FVs in FV HOB.\n"));
191
192 for (Hob.Raw = GetHobList (); !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
193 if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV) {
194 FirmwareVolumeHob = Hob.FirmwareVolume;
195 if (FirmwareVolumeHob->BaseAddress == OrgFvHandle) {
196 FirmwareVolumeHob->BaseAddress = FvHandle;
197 }
198 } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV2) {
199 FirmwareVolume2Hob = Hob.FirmwareVolume2;
200 if (FirmwareVolume2Hob->BaseAddress == OrgFvHandle) {
201 FirmwareVolume2Hob->BaseAddress = FvHandle;
202 }
203 } else if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_FV3) {
204 FirmwareVolume3Hob = Hob.FirmwareVolume3;
205 if (FirmwareVolume3Hob->BaseAddress == OrgFvHandle) {
206 FirmwareVolume3Hob->BaseAddress = FvHandle;
207 }
208 }
209 }
210}
211
219VOID
221 IN PEI_CORE_INSTANCE *PrivateData
222 )
223{
225 EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;
226 EFI_PHYSICAL_ADDRESS OldMemPagesBase;
227 UINTN OldMemPagesSize;
228
229 if (PrivateData->MemoryPages.Size == 0) {
230 //
231 // No any memory page allocated in pre-memory phase.
232 //
233 return;
234 }
235
236 OldMemPagesBase = PrivateData->MemoryPages.Base;
237 OldMemPagesSize = PrivateData->MemoryPages.Size;
238
239 MemoryAllocationHob = NULL;
240 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
241 while (Hob.Raw != NULL) {
242 MemoryAllocationHob = (EFI_HOB_MEMORY_ALLOCATION *)Hob.Raw;
243 if ((MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress >= OldMemPagesBase) &&
244 (MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress < (OldMemPagesBase + OldMemPagesSize))
245 )
246 {
247 if (PrivateData->MemoryPages.OffsetPositive) {
248 MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress += PrivateData->MemoryPages.Offset;
249 } else {
250 MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress -= PrivateData->MemoryPages.Offset;
251 }
252 }
253
254 Hob.Raw = GET_NEXT_HOB (Hob);
255 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);
256 }
257}
258
269VOID
271 IN EFI_PHYSICAL_ADDRESS BaseAddress,
272 IN UINT64 Length,
273 IN EFI_MEMORY_TYPE MemoryType
274 )
275{
277 EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;
278
279 //
280 // Search unused(freed) memory allocation HOB.
281 //
282 MemoryAllocationHob = NULL;
283 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_UNUSED);
284 while (Hob.Raw != NULL) {
285 if (Hob.Header->HobLength == sizeof (EFI_HOB_MEMORY_ALLOCATION)) {
286 MemoryAllocationHob = (EFI_HOB_MEMORY_ALLOCATION *)Hob.Raw;
287 break;
288 }
289
290 Hob.Raw = GET_NEXT_HOB (Hob);
291 Hob.Raw = GetNextHob (EFI_HOB_TYPE_UNUSED, Hob.Raw);
292 }
293
294 if (MemoryAllocationHob != NULL) {
295 //
296 // Reuse the unused(freed) memory allocation HOB.
297 //
298 MemoryAllocationHob->Header.HobType = EFI_HOB_TYPE_MEMORY_ALLOCATION;
299 ZeroMem (&(MemoryAllocationHob->AllocDescriptor.Name), sizeof (EFI_GUID));
300 MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress = BaseAddress;
301 MemoryAllocationHob->AllocDescriptor.MemoryLength = Length;
302 MemoryAllocationHob->AllocDescriptor.MemoryType = MemoryType;
303 //
304 // Zero the reserved space to match HOB spec
305 //
306 ZeroMem (MemoryAllocationHob->AllocDescriptor.Reserved, sizeof (MemoryAllocationHob->AllocDescriptor.Reserved));
307 } else {
308 //
309 // No unused(freed) memory allocation HOB found.
310 // Build memory allocation HOB normally.
311 //
313 BaseAddress,
314 Length,
315 MemoryType
316 );
317 }
318}
319
333VOID
335 IN OUT EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob,
337 IN UINT64 Bytes,
338 IN EFI_MEMORY_TYPE MemoryType
339 )
340{
341 if ((Memory + Bytes) <
342 (MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress + MemoryAllocationHob->AllocDescriptor.MemoryLength))
343 {
344 //
345 // Last pages need to be split out.
346 //
348 Memory + Bytes,
349 (MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress + MemoryAllocationHob->AllocDescriptor.MemoryLength) - (Memory + Bytes),
350 MemoryAllocationHob->AllocDescriptor.MemoryType
351 );
352 }
353
354 if (Memory > MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress) {
355 //
356 // First pages need to be split out.
357 //
359 MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress,
360 Memory - MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress,
361 MemoryAllocationHob->AllocDescriptor.MemoryType
362 );
363 }
364
365 //
366 // Update the memory allocation HOB.
367 //
368 MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress = Memory;
369 MemoryAllocationHob->AllocDescriptor.MemoryLength = Bytes;
370 MemoryAllocationHob->AllocDescriptor.MemoryType = MemoryType;
371}
372
380BOOLEAN
382 VOID
383 )
384{
387 EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
388 EFI_HOB_MEMORY_ALLOCATION *MemoryHob2;
389 UINT64 Start;
390 UINT64 End;
391 BOOLEAN Merged;
392
393 Merged = FALSE;
394
395 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
396 while (Hob.Raw != NULL) {
397 if (Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiConventionalMemory) {
398 MemoryHob = (EFI_HOB_MEMORY_ALLOCATION *)Hob.Raw;
399 Start = MemoryHob->AllocDescriptor.MemoryBaseAddress;
401
402 Hob2.Raw = GET_NEXT_HOB (Hob);
403 Hob2.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);
404 while (Hob2.Raw != NULL) {
405 if (Hob2.MemoryAllocation->AllocDescriptor.MemoryType == EfiConventionalMemory) {
406 MemoryHob2 = (EFI_HOB_MEMORY_ALLOCATION *)Hob2.Raw;
407 if (Start == (MemoryHob2->AllocDescriptor.MemoryBaseAddress + MemoryHob2->AllocDescriptor.MemoryLength)) {
408 //
409 // Merge adjacent two free memory ranges.
410 //
412 Merged = TRUE;
413 //
414 // Mark MemoryHob to be unused(freed).
415 //
416 MemoryHob->Header.HobType = EFI_HOB_TYPE_UNUSED;
417 break;
418 } else if (End == MemoryHob2->AllocDescriptor.MemoryBaseAddress) {
419 //
420 // Merge adjacent two free memory ranges.
421 //
424 Merged = TRUE;
425 //
426 // Mark MemoryHob to be unused(freed).
427 //
428 MemoryHob->Header.HobType = EFI_HOB_TYPE_UNUSED;
429 break;
430 }
431 }
432
433 Hob2.Raw = GET_NEXT_HOB (Hob2);
434 Hob2.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob2.Raw);
435 }
436 }
437
438 Hob.Raw = GET_NEXT_HOB (Hob);
439 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);
440 }
441
442 return Merged;
443}
444
460 IN EFI_MEMORY_TYPE MemoryType,
461 IN UINTN Pages,
462 IN UINTN Granularity,
464 )
465{
467 EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;
468 UINT64 Bytes;
469 EFI_PHYSICAL_ADDRESS BaseAddress;
470
471 Bytes = LShiftU64 (Pages, EFI_PAGE_SHIFT);
472
473 BaseAddress = 0;
474 MemoryAllocationHob = NULL;
475 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
476 while (Hob.Raw != NULL) {
477 if ((Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiConventionalMemory) &&
478 (Hob.MemoryAllocation->AllocDescriptor.MemoryLength >= Bytes))
479 {
480 //
481 // Found one memory allocation HOB with big enough free memory.
482 //
483 MemoryAllocationHob = (EFI_HOB_MEMORY_ALLOCATION *)Hob.Raw;
484 BaseAddress = MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress +
485 MemoryAllocationHob->AllocDescriptor.MemoryLength - Bytes;
486 //
487 // Make sure the granularity could be satisfied.
488 //
489 BaseAddress &= ~((EFI_PHYSICAL_ADDRESS)Granularity - 1);
490 if (BaseAddress >= MemoryAllocationHob->AllocDescriptor.MemoryBaseAddress) {
491 break;
492 }
493
494 BaseAddress = 0;
495 MemoryAllocationHob = NULL;
496 }
497
498 //
499 // Continue to find.
500 //
501 Hob.Raw = GET_NEXT_HOB (Hob);
502 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);
503 }
504
505 if (MemoryAllocationHob != NULL) {
506 UpdateOrSplitMemoryAllocationHob (MemoryAllocationHob, BaseAddress, Bytes, MemoryType);
507 *Memory = BaseAddress;
508 return EFI_SUCCESS;
509 } else {
511 //
512 // Retry if there are free memory ranges merged.
513 //
514 return FindFreeMemoryFromMemoryAllocationHob (MemoryType, Pages, Granularity, Memory);
515 }
516
517 return EFI_NOT_FOUND;
518 }
519}
520
544EFIAPI
546 IN CONST EFI_PEI_SERVICES **PeiServices,
547 IN EFI_MEMORY_TYPE MemoryType,
548 IN UINTN Pages,
550 )
551{
552 EFI_STATUS Status;
553 PEI_CORE_INSTANCE *PrivateData;
555 EFI_PHYSICAL_ADDRESS *FreeMemoryTop;
556 EFI_PHYSICAL_ADDRESS *FreeMemoryBottom;
557 UINTN RemainingPages;
558 UINTN RemainingMemory;
559 UINTN Granularity;
560 UINTN Padding;
561
562 if ((MemoryType != EfiLoaderCode) &&
563 (MemoryType != EfiLoaderData) &&
564 (MemoryType != EfiRuntimeServicesCode) &&
565 (MemoryType != EfiRuntimeServicesData) &&
566 (MemoryType != EfiBootServicesCode) &&
567 (MemoryType != EfiBootServicesData) &&
568 (MemoryType != EfiACPIReclaimMemory) &&
569 (MemoryType != EfiReservedMemoryType) &&
570 (MemoryType != EfiACPIMemoryNVS))
571 {
572 return EFI_INVALID_PARAMETER;
573 }
574
576
577 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
578 Hob.Raw = PrivateData->HobList.Raw;
579
580 if (Hob.Raw == NULL) {
581 //
582 // HOB is not initialized yet.
583 //
585 }
586
587 if ((RUNTIME_PAGE_ALLOCATION_GRANULARITY > DEFAULT_PAGE_ALLOCATION_GRANULARITY) &&
588 ((MemoryType == EfiReservedMemoryType) ||
589 (MemoryType == EfiACPIMemoryNVS) ||
590 (MemoryType == EfiRuntimeServicesCode) ||
591 (MemoryType == EfiRuntimeServicesData)))
592 {
593 Granularity = RUNTIME_PAGE_ALLOCATION_GRANULARITY;
594
595 DEBUG ((
596 DEBUG_INFO,
597 "AllocatePages: aligning allocation to %d KB\n",
598 Granularity / SIZE_1KB
599 ));
600 }
601
602 if (!PrivateData->PeiMemoryInstalled && PrivateData->SwitchStackSignal) {
603 //
604 // When PeiInstallMemory is called but temporary memory has *not* been moved to permanent memory,
605 // the AllocatePage will depend on the field of PEI_CORE_INSTANCE structure.
606 //
607 FreeMemoryTop = &(PrivateData->FreePhysicalMemoryTop);
608 FreeMemoryBottom = &(PrivateData->PhysicalMemoryBegin);
609 } else {
610 FreeMemoryTop = &(Hob.HandoffInformationTable->EfiFreeMemoryTop);
611 FreeMemoryBottom = &(Hob.HandoffInformationTable->EfiFreeMemoryBottom);
612 }
613
614 //
615 // Check to see if on correct boundary for the memory type.
616 // If not aligned, make the allocation aligned.
617 //
618 Padding = *(FreeMemoryTop) & (Granularity - 1);
619 if ((UINTN)(*FreeMemoryTop - *FreeMemoryBottom) < Padding) {
620 DEBUG ((DEBUG_ERROR, "AllocatePages failed: Out of space after padding.\n"));
621 return EFI_OUT_OF_RESOURCES;
622 }
623
624 *(FreeMemoryTop) -= Padding;
625 if (Padding >= EFI_PAGE_SIZE) {
626 //
627 // Create a memory allocation HOB to cover
628 // the pages that we will lose to rounding
629 //
631 *(FreeMemoryTop),
632 Padding & ~(UINTN)EFI_PAGE_MASK,
634 );
635 }
636
637 //
638 // Verify that there is sufficient memory to satisfy the allocation.
639 //
640 RemainingMemory = (UINTN)(*FreeMemoryTop - *FreeMemoryBottom);
641 RemainingPages = (UINTN)(RShiftU64 (RemainingMemory, EFI_PAGE_SHIFT));
642 //
643 // The number of remaining pages needs to be greater than or equal to that of
644 // the request pages. In addition, there should be enough space left to hold a
645 // Memory Allocation HOB.
646 //
647 Pages = ALIGN_VALUE (Pages, EFI_SIZE_TO_PAGES (Granularity));
648 if ((RemainingPages > Pages) ||
649 ((RemainingPages == Pages) &&
650 ((RemainingMemory & EFI_PAGE_MASK) >= sizeof (EFI_HOB_MEMORY_ALLOCATION))))
651 {
652 //
653 // Update the PHIT to reflect the memory usage
654 //
655 *(FreeMemoryTop) -= Pages * EFI_PAGE_SIZE;
656
657 //
658 // Update the value for the caller
659 //
660 *Memory = *(FreeMemoryTop);
661
662 //
663 // Create a memory allocation HOB.
664 //
666 *(FreeMemoryTop),
667 Pages * EFI_PAGE_SIZE,
668 MemoryType
669 );
670
671 return EFI_SUCCESS;
672 } else {
673 //
674 // Try to find free memory by searching memory allocation HOBs.
675 //
676 Status = FindFreeMemoryFromMemoryAllocationHob (MemoryType, Pages, Granularity, Memory);
677 if (!EFI_ERROR (Status)) {
678 return Status;
679 }
680
681 DEBUG ((DEBUG_ERROR, "AllocatePages failed: No 0x%lx Pages is available.\n", (UINT64)Pages));
682 DEBUG ((DEBUG_ERROR, "There is only left 0x%lx pages memory resource to be allocated.\n", (UINT64)RemainingPages));
683 return EFI_OUT_OF_RESOURCES;
684 }
685}
686
695VOID
697 IN PEI_CORE_INSTANCE *PrivateData,
698 IN OUT EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHobToFree
699 )
700{
702 EFI_PHYSICAL_ADDRESS *FreeMemoryTop;
703 EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;
704
705 Hob.Raw = PrivateData->HobList.Raw;
706
707 if (!PrivateData->PeiMemoryInstalled && PrivateData->SwitchStackSignal) {
708 //
709 // When PeiInstallMemory is called but temporary memory has *not* been moved to permanent memory,
710 // use the FreePhysicalMemoryTop field of PEI_CORE_INSTANCE structure.
711 //
712 FreeMemoryTop = &(PrivateData->FreePhysicalMemoryTop);
713 } else {
714 FreeMemoryTop = &(Hob.HandoffInformationTable->EfiFreeMemoryTop);
715 }
716
717 if (MemoryAllocationHobToFree->AllocDescriptor.MemoryBaseAddress == *FreeMemoryTop) {
718 //
719 // Update *FreeMemoryTop.
720 //
721 *FreeMemoryTop += MemoryAllocationHobToFree->AllocDescriptor.MemoryLength;
722 //
723 // Mark the memory allocation HOB to be unused(freed).
724 //
725 MemoryAllocationHobToFree->Header.HobType = EFI_HOB_TYPE_UNUSED;
726
727 MemoryAllocationHob = NULL;
728 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
729 while (Hob.Raw != NULL) {
730 if ((Hob.MemoryAllocation->AllocDescriptor.MemoryType == EfiConventionalMemory) &&
731 (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress == *FreeMemoryTop))
732 {
733 //
734 // Found memory allocation HOB that has EfiConventionalMemory MemoryType and
735 // MemoryBaseAddress == new *FreeMemoryTop.
736 //
737 MemoryAllocationHob = (EFI_HOB_MEMORY_ALLOCATION *)Hob.Raw;
738 break;
739 }
740
741 Hob.Raw = GET_NEXT_HOB (Hob);
742 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);
743 }
744
745 //
746 // Free memory allocation HOB iteratively.
747 //
748 if (MemoryAllocationHob != NULL) {
749 FreeMemoryAllocationHob (PrivateData, MemoryAllocationHob);
750 }
751 }
752}
753
768EFIAPI
770 IN CONST EFI_PEI_SERVICES **PeiServices,
772 IN UINTN Pages
773 )
774{
775 PEI_CORE_INSTANCE *PrivateData;
776 UINT64 Bytes;
777 UINT64 Start;
778 UINT64 End;
780 EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob;
781
782 Bytes = LShiftU64 (Pages, EFI_PAGE_SHIFT);
783 Start = Memory;
784 End = Start + Bytes - 1;
785
786 if ((Pages == 0) || ((Start & EFI_PAGE_MASK) != 0) || (Start >= End)) {
787 return EFI_INVALID_PARAMETER;
788 }
789
790 PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
791 Hob.Raw = PrivateData->HobList.Raw;
792
793 if (Hob.Raw == NULL) {
794 //
795 // HOB is not initialized yet.
796 //
798 }
799
800 MemoryAllocationHob = NULL;
801 Hob.Raw = GetFirstHob (EFI_HOB_TYPE_MEMORY_ALLOCATION);
802 while (Hob.Raw != NULL) {
803 if ((Hob.MemoryAllocation->AllocDescriptor.MemoryType != EfiConventionalMemory) &&
804 (Memory >= Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress) &&
805 ((Memory + Bytes) <= (Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress + Hob.MemoryAllocation->AllocDescriptor.MemoryLength)))
806 {
807 //
808 // Found the memory allocation HOB that includes the memory pages to be freed.
809 //
810 MemoryAllocationHob = (EFI_HOB_MEMORY_ALLOCATION *)Hob.Raw;
811 break;
812 }
813
814 Hob.Raw = GET_NEXT_HOB (Hob);
815 Hob.Raw = GetNextHob (EFI_HOB_TYPE_MEMORY_ALLOCATION, Hob.Raw);
816 }
817
818 if (MemoryAllocationHob != NULL) {
819 UpdateOrSplitMemoryAllocationHob (MemoryAllocationHob, Memory, Bytes, EfiConventionalMemory);
820 FreeMemoryAllocationHob (PrivateData, MemoryAllocationHob);
821 return EFI_SUCCESS;
822 } else {
823 return EFI_NOT_FOUND;
824 }
825}
826
844EFIAPI
846 IN CONST EFI_PEI_SERVICES **PeiServices,
847 IN UINTN Size,
848 OUT VOID **Buffer
849 )
850{
851 EFI_STATUS Status;
853
854 //
855 // If some "post-memory" PEIM wishes to allocate larger pool,
856 // it should use AllocatePages service instead.
857 //
858
859 //
860 // Generally, the size of heap in temporary memory does not exceed 64K,
861 // HobLength is multiples of 8 bytes, so the maximum size of pool is 0xFFF8 - sizeof (EFI_HOB_MEMORY_POOL)
862 //
863 if (Size > (0xFFF8 - sizeof (EFI_HOB_MEMORY_POOL))) {
864 return EFI_OUT_OF_RESOURCES;
865 }
866
867 Status = PeiServicesCreateHob (
868 EFI_HOB_TYPE_MEMORY_POOL,
869 (UINT16)(sizeof (EFI_HOB_MEMORY_POOL) + Size),
870 (VOID **)&Hob
871 );
872 if (EFI_ERROR (Status)) {
873 *Buffer = NULL;
874 } else {
875 *Buffer = Hob + 1;
876 }
877
878 return Status;
879}
#define DEFAULT_PAGE_ALLOCATION_GRANULARITY
UINT64 UINTN
VOID *EFIAPI GetFirstHob(IN UINT16 Type)
Definition: HobLib.c:142
VOID EFIAPI BuildMemoryAllocationHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN EFI_MEMORY_TYPE MemoryType)
Definition: HobLib.c:601
VOID *EFIAPI GetNextHob(IN UINT16 Type, IN CONST VOID *HobStart)
Definition: HobLib.c:103
VOID *EFIAPI GetHobList(VOID)
Definition: HobLib.c:76
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
UINT64 EFIAPI LShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: LShiftU64.c:28
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS EFIAPI PeiServicesCreateHob(IN UINT16 Type, IN UINT16 Length, OUT VOID **Hob)
EFI_STATUS PeiCoreBuildHobHandoffInfoTable(IN EFI_BOOT_MODE BootMode, IN EFI_PHYSICAL_ADDRESS MemoryBegin, IN UINT64 MemoryLength)
Definition: Hob.c:208
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define ALIGN_VALUE(Value, Alignment)
Definition: Base.h:948
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS EFIAPI PeiInstallPeiMemory(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PHYSICAL_ADDRESS MemoryBegin, IN UINT64 MemoryLength)
VOID ConvertMemoryAllocationHobs(IN PEI_CORE_INSTANCE *PrivateData)
BOOLEAN MergeFreeMemoryInMemoryAllocationHob(VOID)
VOID ConvertFvHob(IN PEI_CORE_INSTANCE *PrivateData, IN UINTN OrgFvHandle, IN UINTN FvHandle)
VOID MigrateMemoryPages(IN PEI_CORE_INSTANCE *Private, IN BOOLEAN TemporaryRamMigrated)
EFI_STATUS EFIAPI PeiFreePages(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PHYSICAL_ADDRESS Memory, IN UINTN Pages)
VOID UpdateOrSplitMemoryAllocationHob(IN OUT EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHob, IN EFI_PHYSICAL_ADDRESS Memory, IN UINT64 Bytes, IN EFI_MEMORY_TYPE MemoryType)
EFI_STATUS EFIAPI PeiAllocatePages(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, OUT EFI_PHYSICAL_ADDRESS *Memory)
EFI_STATUS FindFreeMemoryFromMemoryAllocationHob(IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, IN UINTN Granularity, OUT EFI_PHYSICAL_ADDRESS *Memory)
VOID InternalBuildMemoryAllocationHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length, IN EFI_MEMORY_TYPE MemoryType)
VOID InitializeMemoryServices(IN PEI_CORE_INSTANCE *PrivateData, IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN PEI_CORE_INSTANCE *OldCoreData)
EFI_STATUS EFIAPI PeiAllocatePool(IN CONST EFI_PEI_SERVICES **PeiServices, IN UINTN Size, OUT VOID **Buffer)
VOID FreeMemoryAllocationHob(IN PEI_CORE_INSTANCE *PrivateData, IN OUT EFI_HOB_MEMORY_ALLOCATION *MemoryAllocationHobToFree)
#define PEI_CORE_INSTANCE_FROM_PS_THIS(a)
Definition: PeiMain.h:343
#define EFI_NOT_AVAILABLE_YET
Definition: PiMultiPhase.h:54
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_MEMORY_TYPE
@ EfiBootServicesData
@ EfiReservedMemoryType
@ EfiBootServicesCode
@ EfiConventionalMemory
@ EfiLoaderData
@ EfiACPIMemoryNVS
@ EfiACPIReclaimMemory
@ EfiLoaderCode
@ EfiRuntimeServicesCode
@ EfiRuntimeServicesData
EFI_PHYSICAL_ADDRESS BaseAddress
Definition: PiHob.h:383
EFI_PHYSICAL_ADDRESS BaseAddress
Definition: PiHob.h:410
EFI_PHYSICAL_ADDRESS BaseAddress
Definition: PiHob.h:364
EFI_PHYSICAL_ADDRESS EfiFreeMemoryBottom
Definition: PiHob.h:92
EFI_PHYSICAL_ADDRESS EfiFreeMemoryTop
Definition: PiHob.h:88
EFI_PHYSICAL_ADDRESS MemoryBaseAddress
Definition: PiHob.h:119
EFI_MEMORY_TYPE MemoryType
Definition: PiHob.h:131
EFI_HOB_GENERIC_HEADER Header
Definition: PiHob.h:148
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor
Definition: PiHob.h:153
Definition: Base.h:213