TianoCore EDK2 master
Loading...
Searching...
No Matches
Dispatcher.c
Go to the documentation of this file.
1
11#include "PeiMain.h"
12
13//
14// Utility global variables
15//
16
29BOOLEAN
31 IN DELAYED_DISPATCH_TABLE *DelayedDispatchTable,
32 IN EFI_GUID *DelayedGroupId OPTIONAL
33 );
34
47EFIAPI
49 IN EFI_PEI_SERVICES **PeiServices,
50 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
51 IN VOID *Ppi
52 );
53
55EFI_PEI_PPI_DESCRIPTOR mDelayedDispatchDesc = {
56 (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
57 &gEfiPeiDelayedDispatchPpiGuid,
58 &mDelayedDispatchPpi
59};
60
61EFI_PEI_NOTIFY_DESCRIPTOR mDelayedDispatchNotifyDesc = {
62 EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
63 &gEfiEndOfPeiSignalPpiGuid,
65};
66
74 VOID
75 )
76{
77 EFI_HOB_GUID_TYPE *GuidHob;
78
79 GuidHob = GetFirstGuidHob (&gEfiDelayedDispatchTableGuid);
80 if (GuidHob == NULL) {
81 // There is something off about the build if this happens. We do want to
82 // assert here to catch it during development.
83 DEBUG ((DEBUG_ERROR, "%a - Delayed Dispatch Hob not available.\n", __func__));
84 ASSERT (FALSE);
85 return NULL;
86 }
87
88 return (DELAYED_DISPATCH_TABLE *)GET_GUID_HOB_DATA (GuidHob);
89}
90
108EFIAPI
112 IN UINT64 Context,
113 IN EFI_GUID *DelayedGroupId OPTIONAL,
114 IN UINT32 Delay
115 )
116{
117 DELAYED_DISPATCH_TABLE *DelayedDispatchTable;
119 EFI_STATUS Status;
120
121 // Check input parameters
122 if ((Function == NULL) || (Delay > FixedPcdGet32 (PcdDelayedDispatchMaxDelayUs)) || (This == NULL)) {
123 DEBUG ((DEBUG_ERROR, "%a Invalid parameter. Function: %Lx, Delay: %u, This: %p\n", __func__, (UINT64)(UINTN)Function, Delay, This));
124 Status = EFI_INVALID_PARAMETER;
125 goto Exit;
126 }
127
128 // Get delayed dispatch table
129 DelayedDispatchTable = GetDelayedDispatchTable ();
130 if (DelayedDispatchTable == NULL) {
131 DEBUG ((DEBUG_ERROR, "%a Unable to locate dispatch table\n", __func__));
132 Status = EFI_UNSUPPORTED;
133 goto Exit;
134 }
135
136 // Check for available entry slots
137 if (DelayedDispatchTable->Count >= PcdGet32 (PcdDelayedDispatchMaxEntries)) {
138 DEBUG ((
139 DEBUG_ERROR,
140 "%a DelayedDispatchTable->Count = %d. PcdDelayedDispatchMaxEntries (%d) is too small.\n",
141 __func__,
142 DelayedDispatchTable->Count,
143 PcdGet32 (PcdDelayedDispatchMaxEntries)
144 ));
145 ASSERT (DelayedDispatchTable->Count < PcdGet32 (PcdDelayedDispatchMaxEntries));
146 Status = EFI_OUT_OF_RESOURCES;
147 goto Exit;
148 }
149
150 Entry = &DelayedDispatchTable->Entry[DelayedDispatchTable->Count];
151 Entry->Function = Function;
152 Entry->Context = Context;
153 Status = SafeUint64Add (GET_TIME_IN_US (), Delay, &Entry->DispatchTime);
154 if (EFI_ERROR (Status)) {
155 DEBUG ((DEBUG_ERROR, "%a Delay overflow\n", __func__));
156 Status = EFI_INVALID_PARAMETER;
157 goto Exit;
158 }
159
160 if (DelayedGroupId == NULL) {
161 ZeroMem (&Entry->DelayedGroupId, sizeof (EFI_GUID));
162 } else {
163 CopyGuid (&Entry->DelayedGroupId, DelayedGroupId);
164 }
165
166 Entry->MicrosecondDelay = Delay;
167 DelayedDispatchTable->Count++;
168
169 DEBUG ((DEBUG_INFO, "%a Adding dispatch Entry\n", __func__));
170 DEBUG ((DEBUG_INFO, " Requested Delay = %d\n", Delay));
171 DEBUG ((DEBUG_INFO, " Trigger Time = %d\n", Entry->DispatchTime));
172 DEBUG ((DEBUG_INFO, " Context = 0x%016lx\n", Entry->Context));
173 DEBUG ((DEBUG_INFO, " Function = %Lx\n", (UINT64)(UINTN)Entry->Function));
174 DEBUG ((DEBUG_INFO, " DelayedGroupId = %g\n", &Entry->DelayedGroupId));
175
176 if (Delay == 0) {
177 // Force early dispatch point
178 DelayedDispatchDispatcher (DelayedDispatchTable, NULL);
179 }
180
181 Status = EFI_SUCCESS;
182
183Exit:
184 return Status;
185}
186
199BOOLEAN
201 IN DELAYED_DISPATCH_TABLE *DelayedDispatchTable,
202 IN EFI_GUID *DelayedGroupId OPTIONAL
203 )
204{
205 BOOLEAN Dispatched;
206 UINT64 TimeCurrent;
207 UINT64 MaxDispatchTime;
208 UINTN Index1;
209 BOOLEAN DelayedGroupIdPresent;
211 EFI_STATUS Status;
212
213 Dispatched = FALSE;
214 DelayedGroupIdPresent = TRUE;
215 Status = SafeUint64Add (GET_TIME_IN_US (), FixedPcdGet32 (PcdDelayedDispatchCompletionTimeoutUs), &MaxDispatchTime);
216 if (EFI_ERROR (Status)) {
217 DEBUG ((DEBUG_ERROR, "%a Delay overflow\n", __func__));
218 return FALSE;
219 }
220
221 while ((DelayedDispatchTable->Count > 0) && (DelayedGroupIdPresent)) {
222 DelayedGroupIdPresent = FALSE;
223 DelayedDispatchTable->DispCount++;
224
225 // If dispatching is messed up, clear DelayedDispatchTable and exit.
226 TimeCurrent = GET_TIME_IN_US ();
227 if (TimeCurrent > MaxDispatchTime) {
228 DEBUG ((DEBUG_ERROR, "%a - DelayedDispatch Completion timeout!\n", __func__));
229 ReportStatusCode ((EFI_ERROR_MAJOR | EFI_ERROR_CODE), (EFI_SOFTWARE_PEI_CORE | EFI_SW_EC_ABORTED));
230 ASSERT (FALSE);
231 DelayedDispatchTable->Count = 0;
232 break;
233 }
234
235 // Check each entry in the table for possible dispatch
236 for (Index1 = 0; Index1 < DelayedDispatchTable->Count;) {
237 Entry = &DelayedDispatchTable->Entry[Index1];
238 // If DelayedGroupId is present, insure there is an additional check of the table.
239 if (DelayedGroupId != NULL) {
240 if (CompareGuid (DelayedGroupId, &Entry->DelayedGroupId)) {
241 DelayedGroupIdPresent = TRUE;
242 }
243 }
244
245 TimeCurrent = GET_TIME_IN_US ();
246 if (TimeCurrent >= Entry->DispatchTime) {
247 // Time expired, invoked the function
248 DEBUG ((
249 DEBUG_ERROR,
250 "Delayed dispatch entry %d @ %p, Target=%d, Act=%d Disp=%d\n",
251 Index1,
252 Entry->Function,
253 Entry->DispatchTime,
254 TimeCurrent,
255 DelayedDispatchTable->DispCount
256 ));
257 Dispatched = TRUE;
258 Entry->MicrosecondDelay = 0;
259 Entry->Function (
260 &Entry->Context,
261 &Entry->MicrosecondDelay
262 );
263 DEBUG ((DEBUG_ERROR, "Delayed dispatch Function returned delay=%d\n", Entry->MicrosecondDelay));
264 if (Entry->MicrosecondDelay == 0) {
265 // NewTime = 0 = delete this entry from the table
266 DelayedDispatchTable->Count--;
267 CopyMem (Entry, Entry+1, sizeof (DELAYED_DISPATCH_ENTRY) * (DelayedDispatchTable->Count - Index1));
268 } else {
269 if (Entry->MicrosecondDelay > FixedPcdGet32 (PcdDelayedDispatchMaxDelayUs)) {
270 DEBUG ((DEBUG_ERROR, "%a Illegal new delay %d requested\n", __func__, Entry->MicrosecondDelay));
271 ASSERT (FALSE);
272 Entry->MicrosecondDelay = FixedPcdGet32 (PcdDelayedDispatchMaxDelayUs);
273 }
274
275 // NewTime != 0 - update the time from us to Dispatch time
276 Status = SafeUint64Add (GET_TIME_IN_US (), Entry->MicrosecondDelay, &Entry->DispatchTime);
277 if (EFI_ERROR (Status)) {
278 DEBUG ((DEBUG_ERROR, "%a Delay overflow, this event will likely never be fired...\n", __func__));
279 Entry->DispatchTime = MAX_UINT64;
280 }
281
282 Index1++;
283 }
284 } else {
285 Index1++;
286 }
287 }
288 }
289
290 return Dispatched;
291}
292
312EFIAPI
315 IN EFI_GUID DelayedGroupId
316 )
317{
319 EFI_STATUS Status;
320 DELAYED_DISPATCH_TABLE *DelayedDispatchTable;
321
322 // Get delayed dispatch table
323 DelayedDispatchTable = GetDelayedDispatchTable ();
324 if (DelayedDispatchTable == NULL) {
325 DEBUG ((DEBUG_ERROR, "%a Unable to locate dispatch table\n", __func__));
326 Status = EFI_UNSUPPORTED;
327 goto Exit;
328 }
329
330 if (IsZeroGuid (&DelayedGroupId)) {
331 DEBUG ((DEBUG_ERROR, "%a Delayed Group ID is a null GUID\n", __func__));
332 Status = EFI_UNSUPPORTED;
333 goto Exit;
334 }
335
336 DEBUG ((DEBUG_INFO, "Delayed dispatch on %g. Count=%d, DispatchCount=%d\n", &DelayedGroupId, DelayedDispatchTable->Count, DelayedDispatchTable->DispCount));
337 PERF_EVENT_SIGNAL_BEGIN (&DelayedGroupId);
338 DelayedDispatchDispatcher (DelayedDispatchTable, &DelayedGroupId);
339 PERF_EVENT_SIGNAL_END (&DelayedGroupId);
340
341 Status = EFI_SUCCESS;
342
343Exit:
345 return Status;
346}
347
360EFIAPI
362 IN EFI_PEI_SERVICES **PeiServices,
363 IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
364 IN VOID *Ppi
365 )
366{
367 DELAYED_DISPATCH_TABLE *DelayedDispatchTable;
368
369 // Get delayed dispatch table
370 DelayedDispatchTable = GetDelayedDispatchTable ();
371 if (DelayedDispatchTable == NULL) {
372 DEBUG ((DEBUG_ERROR, "%a Unable to locate dispatch table\n", __func__));
373 return EFI_UNSUPPORTED;
374 }
375
376 PERF_INMODULE_BEGIN ("PerfDelayedDispatchEndOfPei");
377 while (DelayedDispatchTable->Count > 0) {
378 DelayedDispatchDispatcher (DelayedDispatchTable, NULL);
379 }
380
381 DEBUG ((DEBUG_ERROR, "%a Count of dispatch cycles is %d\n", __func__, DelayedDispatchTable->DispCount));
382 PERF_INMODULE_END ("PerfDelayedDispatchEndOfPei");
383
384 return EFI_SUCCESS;
385}
386
396VOID
398 IN PEI_CORE_INSTANCE *Private,
399 IN PEI_CORE_FV_HANDLE *CoreFileHandle
400 )
401{
402 EFI_STATUS Status;
403 EFI_PEI_FILE_HANDLE FileHandle;
404 EFI_PEI_FILE_HANDLE AprioriFileHandle;
405 EFI_GUID *Apriori;
406 UINTN Index;
407 UINTN Index2;
408 UINTN PeimIndex;
409 UINTN PeimCount;
410 EFI_GUID *Guid;
411 EFI_PEI_FILE_HANDLE *TempFileHandles;
412 EFI_GUID *TempFileGuid;
415
416 FvPpi = CoreFileHandle->FvPpi;
417
418 //
419 // Walk the FV and find all the PEIMs and the Apriori file.
420 //
421 AprioriFileHandle = NULL;
422 Private->CurrentFvFileHandles = NULL;
423 Guid = NULL;
424
425 //
426 // If the current FV has been scanned, directly get its cached records.
427 //
428 if (CoreFileHandle->ScanFv) {
429 Private->CurrentFvFileHandles = CoreFileHandle->FvFileHandles;
430 return;
431 }
432
433 TempFileHandles = Private->TempFileHandles;
434 TempFileGuid = Private->TempFileGuid;
435
436 //
437 // Go ahead to scan this FV, get PeimCount and cache FileHandles within it to TempFileHandles.
438 //
439 PeimCount = 0;
440 FileHandle = NULL;
441 do {
442 Status = FvPpi->FindFileByType (FvPpi, PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE, CoreFileHandle->FvHandle, &FileHandle);
443 if (!EFI_ERROR (Status)) {
444 if (PeimCount >= Private->TempPeimCount) {
445 //
446 // Run out of room, grow the buffer.
447 //
448 TempFileHandles = AllocatePool (
449 sizeof (EFI_PEI_FILE_HANDLE) * (Private->TempPeimCount + TEMP_FILE_GROWTH_STEP)
450 );
451 if (TempFileHandles == NULL) {
452 ASSERT (TempFileHandles != NULL);
453 return;
454 }
455
456 CopyMem (
457 TempFileHandles,
458 Private->TempFileHandles,
459 sizeof (EFI_PEI_FILE_HANDLE) * Private->TempPeimCount
460 );
461 Private->TempFileHandles = TempFileHandles;
462 TempFileGuid = AllocatePool (
463 sizeof (EFI_GUID) * (Private->TempPeimCount + TEMP_FILE_GROWTH_STEP)
464 );
465 if (TempFileGuid == NULL) {
466 ASSERT (TempFileGuid != NULL);
467 return;
468 }
469
470 CopyMem (
471 TempFileGuid,
472 Private->TempFileGuid,
473 sizeof (EFI_GUID) * Private->TempPeimCount
474 );
475 Private->TempFileGuid = TempFileGuid;
476 Private->TempPeimCount = Private->TempPeimCount + TEMP_FILE_GROWTH_STEP;
477 }
478
479 TempFileHandles[PeimCount++] = FileHandle;
480 }
481 } while (!EFI_ERROR (Status));
482
483 DEBUG ((
484 DEBUG_INFO,
485 "%a(): Found 0x%x PEI FFS files in the %dth FV\n",
486 __func__,
487 PeimCount,
488 Private->CurrentPeimFvCount
489 ));
490
491 if (PeimCount == 0) {
492 //
493 // No PEIM FFS file is found, set ScanFv flag and return.
494 //
495 CoreFileHandle->ScanFv = TRUE;
496 return;
497 }
498
499 //
500 // Record PeimCount, allocate buffer for PeimState and FvFileHandles.
501 //
502 CoreFileHandle->PeimCount = PeimCount;
503 CoreFileHandle->PeimState = AllocateZeroPool (sizeof (UINT8) * PeimCount);
504 ASSERT (CoreFileHandle->PeimState != NULL);
505 CoreFileHandle->FvFileHandles = AllocateZeroPool (sizeof (EFI_PEI_FILE_HANDLE) * PeimCount);
506 ASSERT (CoreFileHandle->FvFileHandles != NULL);
507
508 //
509 // Get Apriori File handle
510 //
511 Private->AprioriCount = 0;
512 Status = FvPpi->FindFileByName (FvPpi, &gPeiAprioriFileNameGuid, &CoreFileHandle->FvHandle, &AprioriFileHandle);
513 if (!EFI_ERROR (Status) && (AprioriFileHandle != NULL)) {
514 //
515 // Read the Apriori file
516 //
517 Status = FvPpi->FindSectionByType (FvPpi, EFI_SECTION_RAW, AprioriFileHandle, (VOID **)&Apriori);
518 if (!EFI_ERROR (Status)) {
519 //
520 // Calculate the number of PEIMs in the Apriori file
521 //
522 Status = FvPpi->GetFileInfo (FvPpi, AprioriFileHandle, &FileInfo);
523 ASSERT_EFI_ERROR (Status);
524 Private->AprioriCount = FileInfo.BufferSize;
525 if (IS_SECTION2 (FileInfo.Buffer)) {
526 Private->AprioriCount -= sizeof (EFI_COMMON_SECTION_HEADER2);
527 } else {
528 Private->AprioriCount -= sizeof (EFI_COMMON_SECTION_HEADER);
529 }
530
531 Private->AprioriCount /= sizeof (EFI_GUID);
532
533 for (Index = 0; Index < PeimCount; Index++) {
534 //
535 // Make an array of file name GUIDs that matches the FileHandle array so we can convert
536 // quickly from file name to file handle
537 //
538 Status = FvPpi->GetFileInfo (FvPpi, TempFileHandles[Index], &FileInfo);
539 ASSERT_EFI_ERROR (Status);
540 CopyMem (&TempFileGuid[Index], &FileInfo.FileName, sizeof (EFI_GUID));
541 }
542
543 //
544 // Walk through TempFileGuid array to find out who is invalid PEIM GUID in Apriori file.
545 // Add available PEIMs in Apriori file into FvFileHandles array.
546 //
547 Index = 0;
548 for (Index2 = 0; Index2 < Private->AprioriCount; Index2++) {
549 Guid = ScanGuid (TempFileGuid, PeimCount * sizeof (EFI_GUID), &Apriori[Index2]);
550 if (Guid != NULL) {
551 PeimIndex = ((UINTN)Guid - (UINTN)&TempFileGuid[0])/sizeof (EFI_GUID);
552 CoreFileHandle->FvFileHandles[Index++] = TempFileHandles[PeimIndex];
553
554 //
555 // Since we have copied the file handle we can remove it from this list.
556 //
557 TempFileHandles[PeimIndex] = NULL;
558 }
559 }
560
561 //
562 // Update valid AprioriCount
563 //
564 Private->AprioriCount = Index;
565
566 //
567 // Add in any PEIMs not in the Apriori file
568 //
569 for (Index2 = 0; Index2 < PeimCount; Index2++) {
570 if (TempFileHandles[Index2] != NULL) {
571 CoreFileHandle->FvFileHandles[Index++] = TempFileHandles[Index2];
572 TempFileHandles[Index2] = NULL;
573 }
574 }
575
576 ASSERT (Index == PeimCount);
577 }
578 } else {
579 CopyMem (CoreFileHandle->FvFileHandles, TempFileHandles, sizeof (EFI_PEI_FILE_HANDLE) * PeimCount);
580 }
581
582 //
583 // The current FV File Handles have been cached. So that we don't have to scan the FV again.
584 // Instead, we can retrieve the file handles within this FV from cached records.
585 //
586 CoreFileHandle->ScanFv = TRUE;
587 Private->CurrentFvFileHandles = CoreFileHandle->FvFileHandles;
588}
589
590//
591// This is the minimum memory required by DxeCore initialization. When LMFA feature enabled,
592// This part of memory still need reserved on the very top of memory so that the DXE Core could
593// use these memory for data initialization. This macro should be sync with the same marco
594// defined in DXE Core.
595//
596#define MINIMUM_INITIAL_MEMORY_SIZE 0x10000
597
608BOOLEAN
610 IN PEI_CORE_INSTANCE *PrivateData,
612 )
613{
614 EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
615 BOOLEAN IsAvailable;
617
618 IsAvailable = TRUE;
619 if ((PrivateData == NULL) || (ResourceHob == NULL)) {
620 return FALSE;
621 }
622
623 //
624 // test if the memory range describe in the HOB is already allocated.
625 //
626 for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
627 //
628 // See if this is a memory allocation HOB
629 //
630 if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
631 MemoryHob = Hob.MemoryAllocation;
632 if ((MemoryHob->AllocDescriptor.MemoryBaseAddress == ResourceHob->PhysicalStart) &&
633 (MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength == ResourceHob->PhysicalStart + ResourceHob->ResourceLength))
634 {
635 IsAvailable = FALSE;
636 break;
637 }
638 }
639 }
640
641 return IsAvailable;
642}
643
655VOID
657 IN PEI_CORE_INSTANCE *PrivateData
658 )
659{
660 EFI_PHYSICAL_ADDRESS TopLoadingAddress;
661 UINT64 PeiMemorySize;
662 UINT64 TotalReservedMemorySize;
663 UINT64 MemoryRangeEnd;
664 EFI_PHYSICAL_ADDRESS HighAddress;
665 EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob;
666 EFI_HOB_RESOURCE_DESCRIPTOR *NextResourceHob;
667 EFI_HOB_RESOURCE_DESCRIPTOR *CurrentResourceHob;
668 EFI_PEI_HOB_POINTERS CurrentHob;
670 EFI_PEI_HOB_POINTERS NextHob;
671 EFI_HOB_MEMORY_ALLOCATION *MemoryHob;
672
673 //
674 // Initialize Local Variables
675 //
676 CurrentResourceHob = NULL;
677 ResourceHob = NULL;
678 NextResourceHob = NULL;
679 HighAddress = 0;
680 TopLoadingAddress = 0;
681 MemoryRangeEnd = 0;
682 CurrentHob.Raw = PrivateData->HobList.Raw;
683 PeiMemorySize = PrivateData->PhysicalMemoryLength;
684 //
685 // The top reserved memory include 3 parts: the topest range is for DXE core initialization with the size MINIMUM_INITIAL_MEMORY_SIZE
686 // then RuntimeCodePage range and Boot time code range.
687 //
688 TotalReservedMemorySize = MINIMUM_INITIAL_MEMORY_SIZE + EFI_PAGES_TO_SIZE (PcdGet32 (PcdLoadFixAddressRuntimeCodePageNumber));
689 TotalReservedMemorySize += EFI_PAGES_TO_SIZE (PcdGet32 (PcdLoadFixAddressBootTimeCodePageNumber));
690 //
691 // PEI memory range lies below the top reserved memory
692 //
693 TotalReservedMemorySize += PeiMemorySize;
694
695 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressRuntimeCodePageNumber= 0x%x.\n", PcdGet32 (PcdLoadFixAddressRuntimeCodePageNumber)));
696 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressBootTimeCodePageNumber= 0x%x.\n", PcdGet32 (PcdLoadFixAddressBootTimeCodePageNumber)));
697 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED INFO: PcdLoadFixAddressPeiCodePageNumber= 0x%x.\n", PcdGet32 (PcdLoadFixAddressPeiCodePageNumber)));
698 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED INFO: Total Reserved Memory Size = 0x%lx.\n", TotalReservedMemorySize));
699 //
700 // Loop through the system memory typed HOB to merge the adjacent memory range
701 //
702 for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
703 //
704 // See if this is a resource descriptor HOB
705 //
706 if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
707 ResourceHob = Hob.ResourceDescriptor;
708 //
709 // If range described in this HOB is not system memory or higher than MAX_ADDRESS, ignored.
710 //
711 if ((ResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) ||
712 (ResourceHob->PhysicalStart + ResourceHob->ResourceLength > MAX_ADDRESS))
713 {
714 continue;
715 }
716
717 for (NextHob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST (NextHob); NextHob.Raw = GET_NEXT_HOB (NextHob)) {
718 if (NextHob.Raw == Hob.Raw) {
719 continue;
720 }
721
722 //
723 // See if this is a resource descriptor HOB
724 //
725 if (GET_HOB_TYPE (NextHob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
726 NextResourceHob = NextHob.ResourceDescriptor;
727 //
728 // test if range described in this NextResourceHob is system memory and have the same attribute.
729 // Note: Here is a assumption that system memory should always be healthy even without test.
730 //
731 if ((NextResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
732 (((NextResourceHob->ResourceAttribute^ResourceHob->ResourceAttribute) & (~EFI_RESOURCE_ATTRIBUTE_TESTED)) == 0))
733 {
734 //
735 // See if the memory range described in ResourceHob and NextResourceHob is adjacent
736 //
737 if (((ResourceHob->PhysicalStart <= NextResourceHob->PhysicalStart) &&
738 (ResourceHob->PhysicalStart + ResourceHob->ResourceLength >= NextResourceHob->PhysicalStart)) ||
739 ((ResourceHob->PhysicalStart >= NextResourceHob->PhysicalStart) &&
740 (ResourceHob->PhysicalStart <= NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength)))
741 {
742 MemoryRangeEnd = ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength) > (NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength)) ?
743 (ResourceHob->PhysicalStart + ResourceHob->ResourceLength) : (NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength);
744
745 ResourceHob->PhysicalStart = (ResourceHob->PhysicalStart < NextResourceHob->PhysicalStart) ?
746 ResourceHob->PhysicalStart : NextResourceHob->PhysicalStart;
747
748 ResourceHob->ResourceLength = (MemoryRangeEnd - ResourceHob->PhysicalStart);
749
750 ResourceHob->ResourceAttribute = ResourceHob->ResourceAttribute & (~EFI_RESOURCE_ATTRIBUTE_TESTED);
751 //
752 // Delete the NextResourceHob by marking it as unused.
753 //
754 GET_HOB_TYPE (NextHob) = EFI_HOB_TYPE_UNUSED;
755 }
756 }
757 }
758 }
759 }
760 }
761
762 //
763 // Some platform is already allocated pages before the HOB re-org. Here to build dedicated resource HOB to describe
764 // the allocated memory range
765 //
766 for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
767 //
768 // See if this is a memory allocation HOB
769 //
770 if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
771 MemoryHob = Hob.MemoryAllocation;
772 for (NextHob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST (NextHob); NextHob.Raw = GET_NEXT_HOB (NextHob)) {
773 //
774 // See if this is a resource descriptor HOB
775 //
776 if (GET_HOB_TYPE (NextHob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
777 NextResourceHob = NextHob.ResourceDescriptor;
778 //
779 // If range described in this HOB is not system memory or higher than MAX_ADDRESS, ignored.
780 //
781 if ((NextResourceHob->ResourceType != EFI_RESOURCE_SYSTEM_MEMORY) || (NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength > MAX_ADDRESS)) {
782 continue;
783 }
784
785 //
786 // If the range describe in memory allocation HOB belongs to the memory range described by the resource HOB
787 //
788 if ((MemoryHob->AllocDescriptor.MemoryBaseAddress >= NextResourceHob->PhysicalStart) &&
789 (MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength <= NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength))
790 {
791 //
792 // Build separate resource HOB for this allocated range
793 //
794 if (MemoryHob->AllocDescriptor.MemoryBaseAddress > NextResourceHob->PhysicalStart) {
796 EFI_RESOURCE_SYSTEM_MEMORY,
797 NextResourceHob->ResourceAttribute,
798 NextResourceHob->PhysicalStart,
799 (MemoryHob->AllocDescriptor.MemoryBaseAddress - NextResourceHob->PhysicalStart)
800 );
801 }
802
803 if (MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength < NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength) {
805 EFI_RESOURCE_SYSTEM_MEMORY,
806 NextResourceHob->ResourceAttribute,
808 (NextResourceHob->PhysicalStart + NextResourceHob->ResourceLength -(MemoryHob->AllocDescriptor.MemoryBaseAddress + MemoryHob->AllocDescriptor.MemoryLength))
809 );
810 }
811
812 NextResourceHob->PhysicalStart = MemoryHob->AllocDescriptor.MemoryBaseAddress;
813 NextResourceHob->ResourceLength = MemoryHob->AllocDescriptor.MemoryLength;
814 break;
815 }
816 }
817 }
818 }
819 }
820
821 //
822 // Try to find and validate the TOP address.
823 //
824 if ((INT64)PcdGet64 (PcdLoadModuleAtFixAddressEnable) > 0 ) {
825 //
826 // The LMFA feature is enabled as load module at fixed absolute address.
827 //
828 TopLoadingAddress = (EFI_PHYSICAL_ADDRESS)PcdGet64 (PcdLoadModuleAtFixAddressEnable);
829 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED INFO: Loading module at fixed absolute address.\n"));
830 //
831 // validate the Address. Loop the resource descriptor HOB to make sure the address is in valid memory range
832 //
833 if ((TopLoadingAddress & EFI_PAGE_MASK) != 0) {
834 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED ERROR:Top Address 0x%lx is invalid since top address should be page align. \n", TopLoadingAddress));
835 ASSERT (FALSE);
836 }
837
838 //
839 // Search for a memory region that is below MAX_ADDRESS and in which TopLoadingAddress lies
840 //
841 for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
842 //
843 // See if this is a resource descriptor HOB
844 //
845 if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
846 ResourceHob = Hob.ResourceDescriptor;
847 //
848 // See if this resource descriptor HOB describes tested system memory below MAX_ADDRESS
849 //
850 if ((ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
851 (ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS))
852 {
853 //
854 // See if Top address specified by user is valid.
855 //
856 if ((ResourceHob->PhysicalStart + TotalReservedMemorySize < TopLoadingAddress) &&
857 ((ResourceHob->PhysicalStart + ResourceHob->ResourceLength - MINIMUM_INITIAL_MEMORY_SIZE) >= TopLoadingAddress) &&
858 PeiLoadFixAddressIsMemoryRangeAvailable (PrivateData, ResourceHob))
859 {
860 CurrentResourceHob = ResourceHob;
861 CurrentHob = Hob;
862 break;
863 }
864 }
865 }
866 }
867
868 if (CurrentResourceHob != NULL) {
869 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED INFO:Top Address 0x%lx is valid \n", TopLoadingAddress));
870 TopLoadingAddress += MINIMUM_INITIAL_MEMORY_SIZE;
871 } else {
872 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED ERROR:Top Address 0x%lx is invalid \n", TopLoadingAddress));
873 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED ERROR:The recommended Top Address for the platform is: \n"));
874 //
875 // Print the recommended Top address range.
876 //
877 for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
878 //
879 // See if this is a resource descriptor HOB
880 //
881 if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
882 ResourceHob = Hob.ResourceDescriptor;
883 //
884 // See if this resource descriptor HOB describes tested system memory below MAX_ADDRESS
885 //
886 if ((ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
887 (ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS))
888 {
889 //
890 // See if Top address specified by user is valid.
891 //
892 if ((ResourceHob->ResourceLength > TotalReservedMemorySize) && PeiLoadFixAddressIsMemoryRangeAvailable (PrivateData, ResourceHob)) {
893 DEBUG ((
894 DEBUG_INFO,
895 "(0x%lx, 0x%lx)\n",
896 (ResourceHob->PhysicalStart + TotalReservedMemorySize -MINIMUM_INITIAL_MEMORY_SIZE),
897 (ResourceHob->PhysicalStart + ResourceHob->ResourceLength -MINIMUM_INITIAL_MEMORY_SIZE)
898 ));
899 }
900 }
901 }
902 }
903
904 //
905 // Assert here
906 //
907 ASSERT (FALSE);
908 return;
909 }
910 } else {
911 //
912 // The LMFA feature is enabled as load module at fixed offset relative to TOLM
913 // Parse the Hob list to find the topest available memory. Generally it is (TOLM - TSEG)
914 //
915 //
916 // Search for a tested memory region that is below MAX_ADDRESS
917 //
918 for (Hob.Raw = PrivateData->HobList.Raw; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
919 //
920 // See if this is a resource descriptor HOB
921 //
922 if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_RESOURCE_DESCRIPTOR) {
923 ResourceHob = Hob.ResourceDescriptor;
924 //
925 // See if this resource descriptor HOB describes tested system memory below MAX_ADDRESS
926 //
927 if ((ResourceHob->ResourceType == EFI_RESOURCE_SYSTEM_MEMORY) &&
928 (ResourceHob->PhysicalStart + ResourceHob->ResourceLength <= MAX_ADDRESS) &&
929 (ResourceHob->ResourceLength > TotalReservedMemorySize) && PeiLoadFixAddressIsMemoryRangeAvailable (PrivateData, ResourceHob))
930 {
931 //
932 // See if this is the highest largest system memory region below MaxAddress
933 //
934 if (ResourceHob->PhysicalStart > HighAddress) {
935 CurrentResourceHob = ResourceHob;
936 CurrentHob = Hob;
937 HighAddress = CurrentResourceHob->PhysicalStart;
938 }
939 }
940 }
941 }
942
943 if (CurrentResourceHob == NULL) {
944 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED ERROR:The System Memory is too small\n"));
945 //
946 // Assert here
947 //
948 ASSERT (FALSE);
949 return;
950 } else {
951 TopLoadingAddress = CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength;
952 }
953 }
954
955 if (CurrentResourceHob != NULL) {
956 //
957 // rebuild resource HOB for PEI memory and reserved memory
958 //
960 EFI_RESOURCE_SYSTEM_MEMORY,
961 (
962 EFI_RESOURCE_ATTRIBUTE_PRESENT |
963 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
964 EFI_RESOURCE_ATTRIBUTE_TESTED |
965 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
966 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
967 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
968 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
969 ),
970 (TopLoadingAddress - TotalReservedMemorySize),
971 TotalReservedMemorySize
972 );
973 //
974 // rebuild resource for the remain memory if necessary
975 //
976 if (CurrentResourceHob->PhysicalStart < TopLoadingAddress - TotalReservedMemorySize) {
978 EFI_RESOURCE_SYSTEM_MEMORY,
979 (
980 EFI_RESOURCE_ATTRIBUTE_PRESENT |
981 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
982 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
983 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
984 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
985 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
986 ),
987 CurrentResourceHob->PhysicalStart,
988 (TopLoadingAddress - TotalReservedMemorySize - CurrentResourceHob->PhysicalStart)
989 );
990 }
991
992 if (CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength > TopLoadingAddress ) {
994 EFI_RESOURCE_SYSTEM_MEMORY,
995 (
996 EFI_RESOURCE_ATTRIBUTE_PRESENT |
997 EFI_RESOURCE_ATTRIBUTE_INITIALIZED |
998 EFI_RESOURCE_ATTRIBUTE_UNCACHEABLE |
999 EFI_RESOURCE_ATTRIBUTE_WRITE_COMBINEABLE |
1000 EFI_RESOURCE_ATTRIBUTE_WRITE_THROUGH_CACHEABLE |
1001 EFI_RESOURCE_ATTRIBUTE_WRITE_BACK_CACHEABLE
1002 ),
1003 TopLoadingAddress,
1004 (CurrentResourceHob->PhysicalStart + CurrentResourceHob->ResourceLength - TopLoadingAddress)
1005 );
1006 }
1007
1008 //
1009 // Delete CurrentHob by marking it as unused since the memory range described by is rebuilt.
1010 //
1011 GET_HOB_TYPE (CurrentHob) = EFI_HOB_TYPE_UNUSED;
1012 }
1013
1014 //
1015 // Cache the top address for Loading Module at Fixed Address feature
1016 //
1017 PrivateData->LoadModuleAtFixAddressTopAddress = TopLoadingAddress - MINIMUM_INITIAL_MEMORY_SIZE;
1018 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED INFO: Top address = 0x%lx\n", PrivateData->LoadModuleAtFixAddressTopAddress));
1019 //
1020 // reinstall the PEI memory relative to TopLoadingAddress
1021 //
1022 PrivateData->PhysicalMemoryBegin = TopLoadingAddress - TotalReservedMemorySize;
1023 PrivateData->FreePhysicalMemoryTop = PrivateData->PhysicalMemoryBegin + PeiMemorySize;
1024}
1025
1035VOID
1036EFIAPI
1038 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
1039 IN PEI_CORE_INSTANCE *Private
1040 )
1041{
1042 //
1043 // Entry PEI Phase 2
1044 //
1045 PeiCore (SecCoreData, NULL, Private);
1046}
1047
1057VOID
1059 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
1060 IN PEI_CORE_INSTANCE *Private
1061 )
1062{
1063 VOID *LoadFixPeiCodeBegin;
1064 EFI_STATUS Status;
1065 CONST EFI_PEI_SERVICES **PeiServices;
1066 UINT64 NewStackSize;
1067 EFI_PHYSICAL_ADDRESS TopOfOldStack;
1068 EFI_PHYSICAL_ADDRESS TopOfNewStack;
1069 UINTN StackOffset;
1070 BOOLEAN StackOffsetPositive;
1071 EFI_PHYSICAL_ADDRESS TemporaryRamBase;
1072 UINTN TemporaryRamSize;
1073 UINTN TemporaryStackSize;
1074 VOID *TemporaryStackBase;
1075 UINTN PeiTemporaryRamSize;
1076 VOID *PeiTemporaryRamBase;
1077 EFI_PEI_TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;
1078 EFI_PHYSICAL_ADDRESS BaseOfNewHeap;
1079 EFI_PHYSICAL_ADDRESS HoleMemBase;
1080 UINTN HoleMemSize;
1081 UINTN HeapTemporaryRamSize;
1082 EFI_PHYSICAL_ADDRESS TempBase1;
1083 UINTN TempSize1;
1084 EFI_PHYSICAL_ADDRESS TempBase2;
1085 UINTN TempSize2;
1086 UINTN Index;
1087
1088 PeiServices = (CONST EFI_PEI_SERVICES **)&Private->Ps;
1089
1090 if (Private->SwitchStackSignal) {
1091 //
1092 // Before switch stack from temporary memory to permanent memory, calculate the heap and stack
1093 // usage in temporary memory for debugging.
1094 //
1096 UINT32 *StackPointer;
1098
1099 for ( StackPointer = (UINT32 *)SecCoreData->StackBase;
1100 (StackPointer < (UINT32 *)((UINTN)SecCoreData->StackBase + SecCoreData->StackSize)) \
1101 && (*StackPointer == PcdGet32 (PcdInitValueInTempStack));
1102 StackPointer++)
1103 {
1104 }
1105
1106 DEBUG ((DEBUG_INFO, "Temp Stack : BaseAddress=0x%p Length=0x%X\n", SecCoreData->StackBase, (UINT32)SecCoreData->StackSize));
1107 DEBUG ((DEBUG_INFO, "Temp Heap : BaseAddress=0x%p Length=0x%X\n", SecCoreData->PeiTemporaryRamBase, (UINT32)SecCoreData->PeiTemporaryRamSize));
1108 DEBUG ((DEBUG_INFO, "Total temporary memory: %d bytes.\n", (UINT32)SecCoreData->TemporaryRamSize));
1109 DEBUG ((
1110 DEBUG_INFO,
1111 " temporary memory stack ever used: %d bytes.\n",
1112 (UINT32)(SecCoreData->StackSize - ((UINTN)StackPointer - (UINTN)SecCoreData->StackBase))
1113 ));
1114 DEBUG ((
1115 DEBUG_INFO,
1116 " temporary memory heap used for HobList: %d bytes.\n",
1117 (UINT32)((UINTN)Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - (UINTN)Private->HobList.Raw)
1118 ));
1119 DEBUG ((
1120 DEBUG_INFO,
1121 " temporary memory heap occupied by memory pages: %d bytes.\n",
1122 (UINT32)(UINTN)(Private->HobList.HandoffInformationTable->EfiMemoryTop - Private->HobList.HandoffInformationTable->EfiFreeMemoryTop)
1123 ));
1124 for (Hob.Raw = Private->HobList.Raw; !END_OF_HOB_LIST (Hob); Hob.Raw = GET_NEXT_HOB (Hob)) {
1125 if (GET_HOB_TYPE (Hob) == EFI_HOB_TYPE_MEMORY_ALLOCATION) {
1126 DEBUG ((
1127 DEBUG_INFO,
1128 "Memory Allocation 0x%08x 0x%0lx - 0x%0lx\n", \
1129 Hob.MemoryAllocation->AllocDescriptor.MemoryType, \
1130 Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress, \
1131 Hob.MemoryAllocation->AllocDescriptor.MemoryBaseAddress + Hob.MemoryAllocation->AllocDescriptor.MemoryLength - 1
1132 ));
1133 }
1134 }
1135
1136 DEBUG_CODE_END ();
1137
1138 if ((PcdGet64 (PcdLoadModuleAtFixAddressEnable) != 0) && (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
1139 //
1140 // Loading Module at Fixed Address is enabled
1141 //
1142 PeiLoadFixAddressHook (Private);
1143
1144 //
1145 // If Loading Module at Fixed Address is enabled, Allocating memory range for Pei code range.
1146 //
1147 LoadFixPeiCodeBegin = AllocatePages ((UINTN)PcdGet32 (PcdLoadFixAddressPeiCodePageNumber));
1148 DEBUG ((DEBUG_INFO, "LOADING MODULE FIXED INFO: PeiCodeBegin = 0x%lX, PeiCodeTop= 0x%lX\n", (UINT64)(UINTN)LoadFixPeiCodeBegin, (UINT64)((UINTN)LoadFixPeiCodeBegin + PcdGet32 (PcdLoadFixAddressPeiCodePageNumber) * EFI_PAGE_SIZE)));
1149 }
1150
1151 //
1152 // Reserve the size of new stack at bottom of physical memory
1153 //
1154 // The size of new stack in permanent memory must be the same size
1155 // or larger than the size of old stack in temporary memory.
1156 // But if new stack is smaller than the size of old stack, we also reserve
1157 // the size of old stack at bottom of permanent memory.
1158 //
1159 NewStackSize = RShiftU64 (Private->PhysicalMemoryLength, 1);
1160 NewStackSize = ALIGN_VALUE (NewStackSize, EFI_PAGE_SIZE);
1161 NewStackSize = MIN (PcdGet32 (PcdPeiCoreMaxPeiStackSize), NewStackSize);
1162 DEBUG ((DEBUG_INFO, "Old Stack size %d, New stack size %d\n", (UINT32)SecCoreData->StackSize, (UINT32)NewStackSize));
1163 ASSERT (NewStackSize >= SecCoreData->StackSize);
1164
1165 //
1166 // Calculate stack offset and heap offset between temporary memory and new permanent
1167 // memory separately.
1168 //
1169 TopOfOldStack = (UINTN)SecCoreData->StackBase + SecCoreData->StackSize;
1170 TopOfNewStack = Private->PhysicalMemoryBegin + NewStackSize;
1171 if (TopOfNewStack >= TopOfOldStack) {
1172 StackOffsetPositive = TRUE;
1173 StackOffset = (UINTN)(TopOfNewStack - TopOfOldStack);
1174 } else {
1175 StackOffsetPositive = FALSE;
1176 StackOffset = (UINTN)(TopOfOldStack - TopOfNewStack);
1177 }
1178
1179 Private->StackOffsetPositive = StackOffsetPositive;
1180 Private->StackOffset = StackOffset;
1181
1182 //
1183 // Build Stack HOB that describes the permanent memory stack
1184 //
1185 DEBUG ((DEBUG_INFO, "Stack Hob: BaseAddress=0x%lX Length=0x%lX\n", TopOfNewStack - NewStackSize, NewStackSize));
1186 BuildStackHob (TopOfNewStack - NewStackSize, NewStackSize);
1187
1188 //
1189 // Cache information from SecCoreData into locals before SecCoreData is converted to a permanent memory address
1190 //
1191 TemporaryRamBase = (EFI_PHYSICAL_ADDRESS)(UINTN)SecCoreData->TemporaryRamBase;
1192 TemporaryRamSize = SecCoreData->TemporaryRamSize;
1193 TemporaryStackSize = SecCoreData->StackSize;
1194 TemporaryStackBase = SecCoreData->StackBase;
1195 PeiTemporaryRamSize = SecCoreData->PeiTemporaryRamSize;
1196 PeiTemporaryRamBase = SecCoreData->PeiTemporaryRamBase;
1197
1198 //
1199 // TemporaryRamSupportPpi is produced by platform's SEC
1200 //
1201 Status = PeiServicesLocatePpi (
1202 &gEfiTemporaryRamSupportPpiGuid,
1203 0,
1204 NULL,
1205 (VOID **)&TemporaryRamSupportPpi
1206 );
1207 if (!EFI_ERROR (Status)) {
1208 //
1209 // Heap Offset
1210 //
1211 BaseOfNewHeap = TopOfNewStack;
1212 if (BaseOfNewHeap >= (UINTN)SecCoreData->PeiTemporaryRamBase) {
1213 Private->HeapOffsetPositive = TRUE;
1214 Private->HeapOffset = (UINTN)(BaseOfNewHeap - (UINTN)SecCoreData->PeiTemporaryRamBase);
1215 } else {
1216 Private->HeapOffsetPositive = FALSE;
1217 Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap);
1218 }
1219
1220 DEBUG ((DEBUG_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64)Private->HeapOffset, (UINT64)Private->StackOffset));
1221
1222 //
1223 // Calculate new HandOffTable and PrivateData address in permanent memory's stack
1224 //
1225 if (StackOffsetPositive) {
1226 SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData + StackOffset);
1227 Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private + StackOffset);
1228 } else {
1229 SecCoreData = (CONST EFI_SEC_PEI_HAND_OFF *)((UINTN)(VOID *)SecCoreData - StackOffset);
1230 Private = (PEI_CORE_INSTANCE *)((UINTN)(VOID *)Private - StackOffset);
1231 }
1232
1233 //
1234 // Temporary Ram Support PPI is provided by platform, it will copy
1235 // temporary memory to permanent memory and do stack switching.
1236 // After invoking Temporary Ram Support PPI, the following code's
1237 // stack is in permanent memory.
1238 //
1239 TemporaryRamSupportPpi->TemporaryRamMigration (
1240 PeiServices,
1241 TemporaryRamBase,
1242 (EFI_PHYSICAL_ADDRESS)(UINTN)(TopOfNewStack - TemporaryStackSize),
1243 TemporaryRamSize
1244 );
1245
1246 //
1247 // Migrate memory pages allocated in pre-memory phase.
1248 // It could not be called before calling TemporaryRamSupportPpi->TemporaryRamMigration()
1249 // as the migrated memory pages may be overridden by TemporaryRamSupportPpi->TemporaryRamMigration().
1250 //
1251 MigrateMemoryPages (Private, TRUE);
1252
1253 //
1254 // Entry PEI Phase 2
1255 //
1256 PeiCore (SecCoreData, NULL, Private);
1257 } else {
1258 //
1259 // Migrate memory pages allocated in pre-memory phase.
1260 //
1261 MigrateMemoryPages (Private, FALSE);
1262
1263 //
1264 // Migrate the PEI Services Table pointer from temporary RAM to permanent RAM.
1265 //
1267
1268 //
1269 // Heap Offset
1270 //
1271 BaseOfNewHeap = TopOfNewStack;
1272 HoleMemBase = TopOfNewStack;
1273 HoleMemSize = TemporaryRamSize - PeiTemporaryRamSize - TemporaryStackSize;
1274 if (HoleMemSize != 0) {
1275 //
1276 // Make sure HOB List start address is 8 byte alignment.
1277 //
1278 BaseOfNewHeap = ALIGN_VALUE (BaseOfNewHeap + HoleMemSize, 8);
1279 }
1280
1281 if (BaseOfNewHeap >= (UINTN)SecCoreData->PeiTemporaryRamBase) {
1282 Private->HeapOffsetPositive = TRUE;
1283 Private->HeapOffset = (UINTN)(BaseOfNewHeap - (UINTN)SecCoreData->PeiTemporaryRamBase);
1284 } else {
1285 Private->HeapOffsetPositive = FALSE;
1286 Private->HeapOffset = (UINTN)((UINTN)SecCoreData->PeiTemporaryRamBase - BaseOfNewHeap);
1287 }
1288
1289 DEBUG ((DEBUG_INFO, "Heap Offset = 0x%lX Stack Offset = 0x%lX\n", (UINT64)Private->HeapOffset, (UINT64)Private->StackOffset));
1290
1291 //
1292 // Migrate Heap
1293 //
1294 HeapTemporaryRamSize = (UINTN)(Private->HobList.HandoffInformationTable->EfiFreeMemoryBottom - Private->HobList.HandoffInformationTable->EfiMemoryBottom);
1295 ASSERT (BaseOfNewHeap + HeapTemporaryRamSize <= Private->FreePhysicalMemoryTop);
1296 CopyMem ((UINT8 *)(UINTN)BaseOfNewHeap, PeiTemporaryRamBase, HeapTemporaryRamSize);
1297
1298 //
1299 // Migrate Stack
1300 //
1301 CopyMem ((UINT8 *)(UINTN)(TopOfNewStack - TemporaryStackSize), TemporaryStackBase, TemporaryStackSize);
1302
1303 //
1304 // Copy Hole Range Data
1305 //
1306 if (HoleMemSize != 0) {
1307 //
1308 // Prepare Hole
1309 //
1310 if (PeiTemporaryRamBase < TemporaryStackBase) {
1311 TempBase1 = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiTemporaryRamBase;
1312 TempSize1 = PeiTemporaryRamSize;
1313 TempBase2 = (EFI_PHYSICAL_ADDRESS)(UINTN)TemporaryStackBase;
1314 TempSize2 = TemporaryStackSize;
1315 } else {
1316 TempBase1 = (EFI_PHYSICAL_ADDRESS)(UINTN)TemporaryStackBase;
1317 TempSize1 = TemporaryStackSize;
1318 TempBase2 = (EFI_PHYSICAL_ADDRESS)(UINTN)PeiTemporaryRamBase;
1319 TempSize2 = PeiTemporaryRamSize;
1320 }
1321
1322 if (TemporaryRamBase < TempBase1) {
1323 Private->HoleData[0].Base = TemporaryRamBase;
1324 Private->HoleData[0].Size = (UINTN)(TempBase1 - TemporaryRamBase);
1325 }
1326
1327 if (TempBase1 + TempSize1 < TempBase2) {
1328 Private->HoleData[1].Base = TempBase1 + TempSize1;
1329 Private->HoleData[1].Size = (UINTN)(TempBase2 - TempBase1 - TempSize1);
1330 }
1331
1332 if (TempBase2 + TempSize2 < TemporaryRamBase + TemporaryRamSize) {
1333 Private->HoleData[2].Base = TempBase2 + TempSize2;
1334 Private->HoleData[2].Size = (UINTN)(TemporaryRamBase + TemporaryRamSize - TempBase2 - TempSize2);
1335 }
1336
1337 //
1338 // Copy Hole Range data.
1339 //
1340 for (Index = 0; Index < HOLE_MAX_NUMBER; Index++) {
1341 if (Private->HoleData[Index].Size > 0) {
1342 if (HoleMemBase > Private->HoleData[Index].Base) {
1343 Private->HoleData[Index].OffsetPositive = TRUE;
1344 Private->HoleData[Index].Offset = (UINTN)(HoleMemBase - Private->HoleData[Index].Base);
1345 } else {
1346 Private->HoleData[Index].OffsetPositive = FALSE;
1347 Private->HoleData[Index].Offset = (UINTN)(Private->HoleData[Index].Base - HoleMemBase);
1348 }
1349
1350 CopyMem ((VOID *)(UINTN)HoleMemBase, (VOID *)(UINTN)Private->HoleData[Index].Base, Private->HoleData[Index].Size);
1351 HoleMemBase = HoleMemBase + Private->HoleData[Index].Size;
1352 }
1353 }
1354 }
1355
1356 //
1357 // Switch new stack
1358 //
1359 SwitchStack (
1361 (VOID *)SecCoreData,
1362 (VOID *)Private,
1363 (VOID *)(UINTN)TopOfNewStack
1364 );
1365 }
1366
1367 //
1368 // Code should not come here
1369 //
1370 ASSERT (FALSE);
1371 }
1372}
1373
1384EFIAPI
1386 IN EFI_PEI_FILE_HANDLE FileHandle,
1387 IN EFI_PEI_FILE_HANDLE MigratedFileHandle
1388 )
1389{
1390 EFI_STATUS Status;
1391 EFI_FFS_FILE_HEADER *FileHeader;
1392 VOID *Pe32Data;
1393 VOID *ImageAddress;
1394 CHAR8 *AsciiString;
1395 UINTN Index;
1396
1397 Status = EFI_SUCCESS;
1398
1399 FileHeader = (EFI_FFS_FILE_HEADER *)FileHandle;
1400 ASSERT (!IS_FFS_FILE2 (FileHeader));
1401
1402 ImageAddress = NULL;
1403 PeiGetPe32Data (MigratedFileHandle, &ImageAddress);
1404 if (ImageAddress != NULL) {
1406 AsciiString = PeCoffLoaderGetPdbPointer (ImageAddress);
1407 for (Index = 0; AsciiString[Index] != 0; Index++) {
1408 if ((AsciiString[Index] == '\\') || (AsciiString[Index] == '/')) {
1409 AsciiString = AsciiString + Index + 1;
1410 Index = 0;
1411 } else if (AsciiString[Index] == '.') {
1412 AsciiString[Index] = 0;
1413 }
1414 }
1415
1416 DEBUG ((DEBUG_VERBOSE, "%a", AsciiString));
1417 DEBUG_CODE_END ();
1418
1419 Pe32Data = (VOID *)((UINTN)ImageAddress - (UINTN)MigratedFileHandle + (UINTN)FileHandle);
1420 Status = LoadAndRelocatePeCoffImageInPlace (Pe32Data, ImageAddress);
1421 ASSERT_EFI_ERROR (Status);
1422 }
1423
1424 return Status;
1425}
1426
1435VOID
1437 IN UINTN OrgFvHandle,
1438 IN UINTN FvHandle,
1439 IN UINTN FvSize
1440 )
1441{
1443 UINTN *NumberOfEntries;
1444 UINTN *CallbackEntry;
1445 UINTN Index;
1446
1447 Hob.Raw = GetFirstGuidHob (&gStatusCodeCallbackGuid);
1448 while (Hob.Raw != NULL) {
1449 NumberOfEntries = GET_GUID_HOB_DATA (Hob);
1450 CallbackEntry = NumberOfEntries + 1;
1451 for (Index = 0; Index < *NumberOfEntries; Index++) {
1452 if (((VOID *)CallbackEntry[Index]) != NULL) {
1453 if ((CallbackEntry[Index] >= OrgFvHandle) && (CallbackEntry[Index] < (OrgFvHandle + FvSize))) {
1454 DEBUG ((
1455 DEBUG_INFO,
1456 "Migrating CallbackEntry[%Lu] from 0x%0*Lx to ",
1457 (UINT64)Index,
1458 (sizeof CallbackEntry[Index]) * 2,
1459 (UINT64)CallbackEntry[Index]
1460 ));
1461 if (OrgFvHandle > FvHandle) {
1462 CallbackEntry[Index] = CallbackEntry[Index] - (OrgFvHandle - FvHandle);
1463 } else {
1464 CallbackEntry[Index] = CallbackEntry[Index] + (FvHandle - OrgFvHandle);
1465 }
1466
1467 DEBUG ((
1468 DEBUG_INFO,
1469 "0x%0*Lx\n",
1470 (sizeof CallbackEntry[Index]) * 2,
1471 (UINT64)CallbackEntry[Index]
1472 ));
1473 }
1474 }
1475 }
1476
1477 Hob.Raw = GET_NEXT_HOB (Hob);
1478 Hob.Raw = GetNextGuidHob (&gStatusCodeCallbackGuid, Hob.Raw);
1479 }
1480}
1481
1495EFIAPI
1497 IN PEI_CORE_INSTANCE *Private,
1498 IN UINTN FvIndex,
1499 IN UINTN OrgFvHandle,
1500 IN UINTN FvHandle
1501 )
1502{
1503 EFI_STATUS Status;
1504 volatile UINTN FileIndex;
1505 EFI_PEI_FILE_HANDLE MigratedFileHandle;
1506 EFI_PEI_FILE_HANDLE FileHandle;
1507
1508 if ((Private == NULL) || (FvIndex >= Private->FvCount)) {
1509 return EFI_INVALID_PARAMETER;
1510 }
1511
1512 if (Private->Fv[FvIndex].ScanFv) {
1513 for (FileIndex = 0; FileIndex < Private->Fv[FvIndex].PeimCount; FileIndex++) {
1514 if (Private->Fv[FvIndex].FvFileHandles[FileIndex] != NULL) {
1515 FileHandle = Private->Fv[FvIndex].FvFileHandles[FileIndex];
1516
1517 MigratedFileHandle = (EFI_PEI_FILE_HANDLE)((UINTN)FileHandle - OrgFvHandle + FvHandle);
1518
1519 DEBUG ((DEBUG_VERBOSE, " Migrating FileHandle %2d ", FileIndex));
1520 Status = MigratePeim (FileHandle, MigratedFileHandle);
1521 DEBUG ((DEBUG_VERBOSE, "\n"));
1522 ASSERT_EFI_ERROR (Status);
1523
1524 if (!EFI_ERROR (Status)) {
1525 Private->Fv[FvIndex].FvFileHandles[FileIndex] = MigratedFileHandle;
1526 if (FvIndex == Private->CurrentPeimFvCount) {
1527 Private->CurrentFvFileHandles[FileIndex] = MigratedFileHandle;
1528 }
1529 }
1530 }
1531 }
1532 }
1533
1534 return EFI_SUCCESS;
1535}
1536
1550EFIAPI
1552 IN PEI_CORE_INSTANCE *Private,
1553 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
1554 )
1555{
1556 EFI_STATUS Status;
1557 volatile UINTN FvIndex;
1558 volatile UINTN FvChildIndex;
1559 UINTN ChildFvOffset;
1560 EFI_PHYSICAL_ADDRESS FvHeaderAddress;
1562 EFI_FIRMWARE_VOLUME_HEADER *ChildFvHeader;
1563 EFI_FIRMWARE_VOLUME_HEADER *MigratedFvHeader;
1564 EFI_FIRMWARE_VOLUME_HEADER *RawDataFvHeader;
1565 EFI_FIRMWARE_VOLUME_HEADER *MigratedChildFvHeader;
1566
1567 PEI_CORE_FV_HANDLE PeiCoreFvHandle;
1568 EFI_PEI_CORE_FV_LOCATION_PPI *PeiCoreFvLocationPpi;
1570 EDKII_MIGRATION_INFO *MigrationInfo;
1571 TO_MIGRATE_FV_INFO *ToMigrateFvInfo;
1572 UINT32 FvMigrationFlags;
1573 EDKII_MIGRATED_FV_INFO MigratedFvInfo;
1574 UINTN Index;
1575
1576 ASSERT (Private->PeiMemoryInstalled);
1577
1578 DEBUG ((DEBUG_VERBOSE, "Beginning evacuation of content in temporary RAM.\n"));
1579
1580 //
1581 // By default migrate all FVs and copy raw data
1582 //
1583 FvMigrationFlags = FLAGS_FV_RAW_DATA_COPY;
1584
1585 //
1586 // Migrate PPI Pointers of PEI_CORE from temporary memory to newly loaded PEI_CORE in permanent memory.
1587 //
1588 Status = PeiLocatePpi ((CONST EFI_PEI_SERVICES **)&Private->Ps, &gEfiPeiCoreFvLocationPpiGuid, 0, NULL, (VOID **)&PeiCoreFvLocationPpi);
1589 if (!EFI_ERROR (Status) && (PeiCoreFvLocationPpi->PeiCoreFvLocation != NULL)) {
1590 PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE)PeiCoreFvLocationPpi->PeiCoreFvLocation;
1591 } else {
1592 PeiCoreFvHandle.FvHandle = (EFI_PEI_FV_HANDLE)SecCoreData->BootFirmwareVolumeBase;
1593 }
1594
1595 if (Private->PeimDispatcherReenter) {
1596 //
1597 // PEI_CORE should be migrated after dispatcher re-enters from main memory.
1598 //
1599 for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) {
1600 if (Private->Fv[FvIndex].FvHandle == PeiCoreFvHandle.FvHandle) {
1601 CopyMem (&PeiCoreFvHandle, &Private->Fv[FvIndex], sizeof (PEI_CORE_FV_HANDLE));
1602 break;
1603 }
1604 }
1605
1606 Status = EFI_SUCCESS;
1607
1608 ConvertPeiCorePpiPointers (Private, &PeiCoreFvHandle);
1609 }
1610
1611 Hob.Raw = GetFirstGuidHob (&gEdkiiMigrationInfoGuid);
1612 if (Hob.Raw != NULL) {
1613 MigrationInfo = GET_GUID_HOB_DATA (Hob);
1614 } else {
1615 MigrationInfo = NULL;
1616 }
1617
1618 for (FvIndex = 0; FvIndex < Private->FvCount; FvIndex++) {
1619 FvHeader = Private->Fv[FvIndex].FvHeader;
1620 ASSERT (FvHeader != NULL);
1621 ASSERT (FvIndex < Private->FvCount);
1622
1623 DEBUG ((DEBUG_VERBOSE, "FV[%02d] at 0x%x.\n", FvIndex, (UINTN)FvHeader));
1624 if (
1625 !(
1626 ((EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader >= Private->PhysicalMemoryBegin) &&
1627 (((EFI_PHYSICAL_ADDRESS)(UINTN)FvHeader + (FvHeader->FvLength - 1)) < Private->FreePhysicalMemoryTop)
1628 )
1629 )
1630 {
1631 if ((MigrationInfo == NULL) || (MigrationInfo->MigrateAll == TRUE)) {
1632 if (!Private->PeimDispatcherReenter) {
1633 //
1634 // Migration before dispatcher reentery is supported only when gEdkiiMigrationInfoGuid
1635 // HOB is built for selective FV migration.
1636 //
1637 return EFI_SUCCESS;
1638 }
1639 } else {
1640 for (Index = 0; Index < MigrationInfo->ToMigrateFvCount; Index++) {
1641 ToMigrateFvInfo = ((TO_MIGRATE_FV_INFO *)(MigrationInfo + 1)) + Index;
1642 if (ToMigrateFvInfo->FvOrgBaseOnTempRam == (UINT32)(UINTN)FvHeader) {
1643 //
1644 // This FV is to migrate
1645 //
1646 FvMigrationFlags = ToMigrateFvInfo->FvMigrationFlags;
1647 break;
1648 }
1649 }
1650
1651 if ((Index == MigrationInfo->ToMigrateFvCount) ||
1652 ((!Private->PeimDispatcherReenter) &&
1653 (((FvMigrationFlags & FLAGS_FV_MIGRATE_BEFORE_PEI_CORE_REENTRY) == 0) ||
1654 (FvHeader == PeiCoreFvHandle.FvHandle))))
1655 {
1656 //
1657 // This FV is not expected to migrate
1658 //
1659 // FV should not be migrated before dispatcher reentry if any of the below condition is true:
1660 // a. MigrationInfo HOB is not built with flag FLAGS_FV_MIGRATE_BEFORE_PEI_CORE_REENTRY.
1661 // b. FV contains currently executing PEI Core.
1662 //
1663 continue;
1664 }
1665 }
1666
1667 //
1668 // Allocate pages to save the rebased PEIMs, the PEIMs will get dispatched later.
1669 //
1670 Status = PeiServicesAllocatePages (
1672 EFI_SIZE_TO_PAGES ((UINTN)FvHeader->FvLength),
1673 &FvHeaderAddress
1674 );
1675 ASSERT_EFI_ERROR (Status);
1676 MigratedFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHeaderAddress;
1677 CopyMem (MigratedFvHeader, FvHeader, (UINTN)FvHeader->FvLength);
1678
1679 DEBUG ((
1680 DEBUG_VERBOSE,
1681 " Migrating FV[%d] from 0x%08X to 0x%08X\n",
1682 FvIndex,
1683 (UINTN)FvHeader,
1684 (UINTN)MigratedFvHeader
1685 ));
1686
1687 //
1688 // Create hob to save MigratedFvInfo, this hob will only be produced when
1689 // Migration feature PCD PcdMigrateTemporaryRamFirmwareVolumes is set to TRUE.
1690 //
1691 MigratedFvInfo.FvOrgBase = (UINT32)(UINTN)FvHeader;
1692 MigratedFvInfo.FvNewBase = (UINT32)(UINTN)MigratedFvHeader;
1693 MigratedFvInfo.FvDataBase = 0;
1694 MigratedFvInfo.FvLength = (UINT32)(UINTN)FvHeader->FvLength;
1695
1696 //
1697 // When FLAGS_FV_RAW_DATA_COPY bit is set, copy the context to the raw pages and
1698 // reset raw data base address in MigratedFvInfo hob.
1699 //
1700 if ((FvMigrationFlags & FLAGS_FV_RAW_DATA_COPY) == FLAGS_FV_RAW_DATA_COPY) {
1701 //
1702 // Allocate pages to save the raw PEIMs
1703 //
1704 Status = PeiServicesAllocatePages (
1706 EFI_SIZE_TO_PAGES ((UINTN)FvHeader->FvLength),
1707 &FvHeaderAddress
1708 );
1709 ASSERT_EFI_ERROR (Status);
1710 RawDataFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)(UINTN)FvHeaderAddress;
1711 CopyMem (RawDataFvHeader, FvHeader, (UINTN)FvHeader->FvLength);
1712 MigratedFvInfo.FvDataBase = (UINT32)(UINTN)RawDataFvHeader;
1713 }
1714
1715 BuildGuidDataHob (&gEdkiiMigratedFvInfoGuid, &MigratedFvInfo, sizeof (MigratedFvInfo));
1716
1717 //
1718 // Migrate any children for this FV now
1719 //
1720 for (FvChildIndex = FvIndex; FvChildIndex < Private->FvCount; FvChildIndex++) {
1721 ChildFvHeader = Private->Fv[FvChildIndex].FvHeader;
1722 if (
1723 ((UINTN)ChildFvHeader > (UINTN)FvHeader) &&
1724 (((UINTN)ChildFvHeader + ChildFvHeader->FvLength) < ((UINTN)FvHeader) + FvHeader->FvLength)
1725 )
1726 {
1727 DEBUG ((DEBUG_VERBOSE, " Child FV[%02d] is being migrated.\n", FvChildIndex));
1728 ChildFvOffset = (UINTN)ChildFvHeader - (UINTN)FvHeader;
1729 DEBUG ((DEBUG_VERBOSE, " Child FV offset = 0x%x.\n", ChildFvOffset));
1730 MigratedChildFvHeader = (EFI_FIRMWARE_VOLUME_HEADER *)((UINTN)MigratedFvHeader + ChildFvOffset);
1731 Private->Fv[FvChildIndex].FvHeader = MigratedChildFvHeader;
1732 Private->Fv[FvChildIndex].FvHandle = (EFI_PEI_FV_HANDLE)MigratedChildFvHeader;
1733 DEBUG ((DEBUG_VERBOSE, " Child migrated FV header at 0x%x.\n", (UINTN)MigratedChildFvHeader));
1734
1735 Status = MigratePeimsInFv (Private, FvChildIndex, (UINTN)ChildFvHeader, (UINTN)MigratedChildFvHeader);
1736 ASSERT_EFI_ERROR (Status);
1737
1739 Private,
1740 (UINTN)ChildFvHeader,
1741 (UINTN)MigratedChildFvHeader,
1742 (UINTN)ChildFvHeader->FvLength - 1
1743 );
1744
1746 (UINTN)ChildFvHeader,
1747 (UINTN)MigratedChildFvHeader,
1748 (UINTN)ChildFvHeader->FvLength - 1
1749 );
1750
1751 ConvertFvHob (Private, (UINTN)ChildFvHeader, (UINTN)MigratedChildFvHeader);
1752 }
1753 }
1754
1755 Private->Fv[FvIndex].FvHeader = MigratedFvHeader;
1756 Private->Fv[FvIndex].FvHandle = (EFI_PEI_FV_HANDLE)MigratedFvHeader;
1757
1758 Status = MigratePeimsInFv (Private, FvIndex, (UINTN)FvHeader, (UINTN)MigratedFvHeader);
1759 ASSERT_EFI_ERROR (Status);
1760
1762 Private,
1763 (UINTN)FvHeader,
1764 (UINTN)MigratedFvHeader,
1765 (UINTN)FvHeader->FvLength - 1
1766 );
1767
1769 (UINTN)FvHeader,
1770 (UINTN)MigratedFvHeader,
1771 (UINTN)FvHeader->FvLength - 1
1772 );
1773
1774 ConvertFvHob (Private, (UINTN)FvHeader, (UINTN)MigratedFvHeader);
1775 }
1776 }
1777
1778 return Status;
1779}
1780
1790VOID
1792 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData,
1793 IN PEI_CORE_INSTANCE *Private
1794 )
1795{
1796 EFI_STATUS Status;
1797 UINT32 Index1;
1798 UINT32 Index2;
1799 CONST EFI_PEI_SERVICES **PeiServices;
1800 EFI_PEI_FILE_HANDLE PeimFileHandle;
1801 UINTN FvCount;
1802 UINTN PeimCount;
1803 UINT32 AuthenticationState;
1804 EFI_PHYSICAL_ADDRESS EntryPoint;
1805 EFI_PEIM_ENTRY_POINT2 PeimEntryPoint;
1806 UINTN SaveCurrentPeimCount;
1807 UINTN SaveCurrentFvCount;
1808 EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;
1809 EFI_FV_FILE_INFO FvFileInfo;
1810 PEI_CORE_FV_HANDLE *CoreFvHandle;
1811 EFI_HOB_GUID_TYPE *GuidHob;
1812 UINT32 TableSize;
1813
1814 PeiServices = (CONST EFI_PEI_SERVICES **)&Private->Ps;
1815 PeimEntryPoint = NULL;
1816 PeimFileHandle = NULL;
1817 EntryPoint = 0;
1818
1819 if (Private->DelayedDispatchTable == NULL) {
1820 GuidHob = GetFirstGuidHob (&gEfiDelayedDispatchTableGuid);
1821 if (GuidHob != NULL) {
1822 Private->DelayedDispatchTable = (DELAYED_DISPATCH_TABLE *)(GET_GUID_HOB_DATA (GuidHob));
1823 } else {
1824 TableSize = sizeof (DELAYED_DISPATCH_TABLE) + (PcdGet32 (PcdDelayedDispatchMaxEntries) * sizeof (DELAYED_DISPATCH_ENTRY));
1825 Private->DelayedDispatchTable = BuildGuidHob (&gEfiDelayedDispatchTableGuid, TableSize);
1826 if (Private->DelayedDispatchTable != NULL) {
1827 ZeroMem (Private->DelayedDispatchTable, TableSize);
1828 Status = PeiServicesInstallPpi (&mDelayedDispatchDesc);
1829 if (EFI_ERROR (Status)) {
1830 DEBUG ((DEBUG_ERROR, "%a Failed to install Delayed Dispatch PPI: %r!\n", __func__, Status));
1831 ASSERT_EFI_ERROR (Status);
1832 } else {
1833 Status = PeiServicesNotifyPpi (&mDelayedDispatchNotifyDesc);
1834 if (EFI_ERROR (Status)) {
1835 DEBUG ((DEBUG_ERROR, "%a Failed to notify Delayed Dispatch on End of Pei: %r!\n", __func__, Status));
1836 ASSERT_EFI_ERROR (Status);
1837 }
1838 }
1839 }
1840 }
1841 }
1842
1843 if ((Private->PeiMemoryInstalled) &&
1844 (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) ||
1845 (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) ||
1846 PcdGetBool (PcdShadowPeimOnS3Boot))
1847 )
1848 {
1849 //
1850 // Once real memory is available, shadow the RegisterForShadow modules. And meanwhile
1851 // update the modules' status from PEIM_STATE_REGISTER_FOR_SHADOW to PEIM_STATE_DONE.
1852 //
1853 SaveCurrentPeimCount = Private->CurrentPeimCount;
1854 SaveCurrentFvCount = Private->CurrentPeimFvCount;
1855 SaveCurrentFileHandle = Private->CurrentFileHandle;
1856
1857 for (Index1 = 0; Index1 < Private->FvCount; Index1++) {
1858 for (Index2 = 0; Index2 < Private->Fv[Index1].PeimCount; Index2++) {
1859 if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISTER_FOR_SHADOW) {
1860 PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];
1861 Private->CurrentFileHandle = PeimFileHandle;
1862 Private->CurrentPeimFvCount = Index1;
1863 Private->CurrentPeimCount = Index2;
1864 Status = PeiLoadImage (
1865 (CONST EFI_PEI_SERVICES **)&Private->Ps,
1866 PeimFileHandle,
1867 PEIM_STATE_REGISTER_FOR_SHADOW,
1868 &EntryPoint,
1869 &AuthenticationState
1870 );
1871 if (Status == EFI_SUCCESS) {
1872 //
1873 // PEIM_STATE_REGISTER_FOR_SHADOW move to PEIM_STATE_DONE
1874 //
1875 Private->Fv[Index1].PeimState[Index2]++;
1876 //
1877 // Call the PEIM entry point
1878 //
1879 PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;
1880
1881 PERF_START_IMAGE_BEGIN (PeimFileHandle);
1882 PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **)&Private->Ps);
1883 PERF_START_IMAGE_END (PeimFileHandle);
1884 }
1885
1886 //
1887 // Process the Notify list and dispatch any notifies for
1888 // newly installed PPIs.
1889 //
1890 ProcessDispatchNotifyList (Private);
1891 }
1892 }
1893 }
1894
1895 Private->CurrentFileHandle = SaveCurrentFileHandle;
1896 Private->CurrentPeimFvCount = SaveCurrentFvCount;
1897 Private->CurrentPeimCount = SaveCurrentPeimCount;
1898 }
1899
1900 //
1901 // This is the main dispatch loop. It will search known FVs for PEIMs and
1902 // attempt to dispatch them. If any PEIM gets dispatched through a single
1903 // pass of the dispatcher, it will start over from the BFV again to see
1904 // if any new PEIMs dependencies got satisfied. With a well ordered
1905 // FV where PEIMs are found in the order their dependencies are also
1906 // satisfied, this dispatcher should run only once.
1907 //
1908 do {
1909 //
1910 // In case that reenter PeiCore happens, the last pass record is still available.
1911 //
1912 if (!Private->PeimDispatcherReenter) {
1913 Private->PeimNeedingDispatch = FALSE;
1914 Private->PeimDispatchOnThisPass = FALSE;
1915 } else {
1916 Private->PeimDispatcherReenter = FALSE;
1917 }
1918
1919 for (FvCount = Private->CurrentPeimFvCount; FvCount < Private->FvCount; FvCount++) {
1920 CoreFvHandle = FindNextCoreFvHandle (Private, FvCount);
1921 if (CoreFvHandle == NULL) {
1922 ASSERT (CoreFvHandle != NULL);
1923 continue;
1924 }
1925
1926 //
1927 // If the FV has corresponding EFI_PEI_FIRMWARE_VOLUME_PPI instance, then dispatch it.
1928 //
1929 if (CoreFvHandle->FvPpi == NULL) {
1930 continue;
1931 }
1932
1933 Private->CurrentPeimFvCount = FvCount;
1934
1935 if (Private->CurrentPeimCount == 0) {
1936 //
1937 // When going through each FV, at first, search Apriori file to
1938 // reorder all PEIMs to ensure the PEIMs in Apriori file to get
1939 // dispatch at first.
1940 //
1941 DiscoverPeimsAndOrderWithApriori (Private, CoreFvHandle);
1942 }
1943
1944 //
1945 // Start to dispatch all modules within the current FV.
1946 //
1947 for (PeimCount = Private->CurrentPeimCount;
1948 PeimCount < Private->Fv[FvCount].PeimCount;
1949 PeimCount++)
1950 {
1951 Private->CurrentPeimCount = PeimCount;
1952 PeimFileHandle = Private->CurrentFileHandle = Private->CurrentFvFileHandles[PeimCount];
1953
1954 if (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_NOT_DISPATCHED) {
1955 if (!DepexSatisfied (Private, PeimFileHandle, PeimCount)) {
1956 Private->PeimNeedingDispatch = TRUE;
1957 } else {
1958 Status = CoreFvHandle->FvPpi->GetFileInfo (CoreFvHandle->FvPpi, PeimFileHandle, &FvFileInfo);
1959 ASSERT_EFI_ERROR (Status);
1960 if (FvFileInfo.FileType == EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
1961 //
1962 // For FV type file, Produce new FvInfo PPI and FV HOB
1963 //
1964 Status = ProcessFvFile (Private, &Private->Fv[FvCount], PeimFileHandle);
1965 if (Status == EFI_SUCCESS) {
1966 //
1967 // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
1968 //
1969 Private->Fv[FvCount].PeimState[PeimCount]++;
1970 Private->PeimDispatchOnThisPass = TRUE;
1971 } else {
1972 //
1973 // The related GuidedSectionExtraction/Decompress PPI for the
1974 // encapsulated FV image section may be installed in the rest
1975 // of this do-while loop, so need to make another pass.
1976 //
1977 Private->PeimNeedingDispatch = TRUE;
1978 }
1979 } else {
1980 //
1981 // For PEIM driver, Load its entry point
1982 //
1983 Status = PeiLoadImage (
1984 PeiServices,
1985 PeimFileHandle,
1986 PEIM_STATE_NOT_DISPATCHED,
1987 &EntryPoint,
1988 &AuthenticationState
1989 );
1990 if (Status == EFI_SUCCESS) {
1991 //
1992 // The PEIM has its dependencies satisfied, and its entry point
1993 // has been found, so invoke it.
1994 //
1995 PERF_START_IMAGE_BEGIN (PeimFileHandle);
1996
1999 (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_BEGIN),
2000 (VOID *)(&PeimFileHandle),
2001 sizeof (PeimFileHandle)
2002 );
2003
2004 Status = VerifyPeim (Private, CoreFvHandle->FvHandle, PeimFileHandle, AuthenticationState);
2005 if (Status != EFI_SECURITY_VIOLATION) {
2006 //
2007 // PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
2008 //
2009 Private->Fv[FvCount].PeimState[PeimCount]++;
2010 //
2011 // Call the PEIM entry point for PEIM driver
2012 //
2013 PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;
2014 PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **)PeiServices);
2015 Private->PeimDispatchOnThisPass = TRUE;
2016 } else {
2017 //
2018 // The related GuidedSectionExtraction PPI for the
2019 // signed PEIM image section may be installed in the rest
2020 // of this do-while loop, so need to make another pass.
2021 //
2022 Private->PeimNeedingDispatch = TRUE;
2023 }
2024
2027 (EFI_SOFTWARE_PEI_CORE | EFI_SW_PC_INIT_END),
2028 (VOID *)(&PeimFileHandle),
2029 sizeof (PeimFileHandle)
2030 );
2031 PERF_START_IMAGE_END (PeimFileHandle);
2032 }
2033 }
2034
2035 PeiCheckAndSwitchStack (SecCoreData, Private);
2036
2037 //
2038 // Process the Notify list and dispatch any notifies for
2039 // newly installed PPIs.
2040 //
2041 ProcessDispatchNotifyList (Private);
2042
2043 //
2044 // Recheck SwitchStackSignal after ProcessDispatchNotifyList()
2045 // in case PeiInstallPeiMemory() is done in a callback with
2046 // EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH.
2047 //
2048 PeiCheckAndSwitchStack (SecCoreData, Private);
2049
2050 if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISTER_FOR_SHADOW) && \
2051 (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) ||
2052 (Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) ||
2053 PcdGetBool (PcdShadowPeimOnS3Boot))
2054 )
2055 {
2056 //
2057 // If memory is available we shadow images by default for performance reasons.
2058 // We call the entry point a 2nd time so the module knows it's shadowed.
2059 //
2060 // PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
2061 if ((Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME) && !PcdGetBool (PcdShadowPeimOnBoot) &&
2062 !PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes))
2063 {
2064 //
2065 // Load PEIM into Memory for Register for shadow PEIM.
2066 //
2067 Status = PeiLoadImage (
2068 PeiServices,
2069 PeimFileHandle,
2070 PEIM_STATE_REGISTER_FOR_SHADOW,
2071 &EntryPoint,
2072 &AuthenticationState
2073 );
2074 if (Status == EFI_SUCCESS) {
2075 PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;
2076 }
2077 }
2078
2079 ASSERT (PeimEntryPoint != NULL);
2080 PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **)PeiServices);
2081 // PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
2082
2083 //
2084 // PEIM_STATE_REGISTER_FOR_SHADOW move to PEIM_STATE_DONE
2085 //
2086 Private->Fv[FvCount].PeimState[PeimCount]++;
2087
2088 //
2089 // Process the Notify list and dispatch any notifies for
2090 // newly installed PPIs.
2091 //
2092 ProcessDispatchNotifyList (Private);
2093 }
2094 }
2095 }
2096
2097 // Dispatch pending delalyed dispatch requests
2098 if (Private->DelayedDispatchTable != NULL) {
2099 if (DelayedDispatchDispatcher (Private->DelayedDispatchTable, NULL)) {
2100 ProcessDispatchNotifyList (Private);
2101 }
2102 }
2103 }
2104
2105 //
2106 // Before walking through the next FV, we should set them to NULL/0 to
2107 // start at the beginning of the next FV.
2108 //
2109 Private->CurrentFileHandle = NULL;
2110 Private->CurrentPeimCount = 0;
2111 Private->CurrentFvFileHandles = NULL;
2112 Private->AprioriCount = 0;
2113 }
2114
2115 //
2116 // Before making another pass, we should set it to 0 to
2117 // go through all the FVs.
2118 //
2119 Private->CurrentPeimFvCount = 0;
2120
2121 //
2122 // PeimNeedingDispatch being TRUE means we found a PEIM/FV that did not get
2123 // dispatched. So we need to make another pass
2124 //
2125 // PeimDispatchOnThisPass being TRUE means we dispatched a PEIM/FV on this
2126 // pass. If we did not dispatch a PEIM/FV there is no point in trying again
2127 // as it will fail the next time too (nothing has changed).
2128 //
2129 // Also continue dispatch loop if there are outstanding delay-
2130 // dispatch registrations still running.
2131 } while ((Private->PeimNeedingDispatch && Private->PeimDispatchOnThisPass) ||
2132 (Private->DelayedDispatchTable->Count > 0));
2133}
2134
2148VOID
2150 IN PEI_CORE_INSTANCE *PrivateData,
2151 IN PEI_CORE_INSTANCE *OldCoreData,
2152 IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData
2153 )
2154{
2155 if (OldCoreData == NULL) {
2156 PrivateData->PeimDispatcherReenter = FALSE;
2157 PeiInitializeFv (PrivateData, SecCoreData);
2158 } else {
2159 PeiReinitializeFv (PrivateData);
2160 }
2161
2162 return;
2163}
2164
2178BOOLEAN
2180 IN PEI_CORE_INSTANCE *Private,
2181 IN EFI_PEI_FILE_HANDLE FileHandle,
2182 IN UINTN PeimCount
2183 )
2184{
2185 EFI_STATUS Status;
2186 VOID *DepexData;
2188
2189 Status = PeiServicesFfsGetFileInfo (FileHandle, &FileInfo);
2190 if (EFI_ERROR (Status)) {
2191 DEBUG ((DEBUG_DISPATCH, "Evaluate PEI DEPEX for FFS(Unknown)\n"));
2192 } else {
2193 DEBUG ((DEBUG_DISPATCH, "Evaluate PEI DEPEX for FFS(%g)\n", &FileInfo.FileName));
2194 }
2195
2196 if (PeimCount < Private->AprioriCount) {
2197 //
2198 // If it's in the Apriori file then we set DEPEX to TRUE
2199 //
2200 DEBUG ((DEBUG_DISPATCH, " RESULT = TRUE (Apriori)\n"));
2201 return TRUE;
2202 }
2203
2204 //
2205 // Depex section not in the encapsulated section.
2206 //
2208 EFI_SECTION_PEI_DEPEX,
2209 FileHandle,
2210 (VOID **)&DepexData
2211 );
2212
2213 if (EFI_ERROR (Status)) {
2214 //
2215 // If there is no DEPEX, assume the module can be executed
2216 //
2217 DEBUG ((DEBUG_DISPATCH, " RESULT = TRUE (No DEPEX)\n"));
2218 return TRUE;
2219 }
2220
2221 //
2222 // Evaluate a given DEPEX
2223 //
2224 return PeimDispatchReadiness (&Private->Ps, DepexData);
2225}
2226
2239EFIAPI
2241 IN EFI_PEI_FILE_HANDLE FileHandle
2242 )
2243{
2244 PEI_CORE_INSTANCE *Private;
2245
2247
2248 if (Private->CurrentFileHandle != FileHandle) {
2249 //
2250 // The FileHandle must be for the current PEIM
2251 //
2252 return EFI_NOT_FOUND;
2253 }
2254
2255 if (Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] >= PEIM_STATE_REGISTER_FOR_SHADOW) {
2256 //
2257 // If the PEIM has already entered the PEIM_STATE_REGISTER_FOR_SHADOW or PEIM_STATE_DONE then it's already been started
2258 //
2259 return EFI_ALREADY_STARTED;
2260 }
2261
2262 Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] = PEIM_STATE_REGISTER_FOR_SHADOW;
2263
2264 return EFI_SUCCESS;
2265}
UINT64 UINTN
#define MAX_ADDRESS
VOID EFIAPI MigratePeiServicesTablePointer(VOID)
CONST EFI_PEI_SERVICES **EFIAPI GetPeiServicesTablePointer(VOID)
VOID *EFIAPI GetFirstGuidHob(IN CONST EFI_GUID *Guid)
Definition: HobLib.c:215
VOID *EFIAPI BuildGuidDataHob(IN CONST EFI_GUID *Guid, IN VOID *Data, IN UINTN DataLength)
Definition: HobLib.c:375
VOID EFIAPI BuildResourceDescriptorHob(IN EFI_RESOURCE_TYPE ResourceType, IN EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute, IN EFI_PHYSICAL_ADDRESS PhysicalStart, IN UINT64 NumberOfBytes)
Definition: HobLib.c:299
VOID *EFIAPI BuildGuidHob(IN CONST EFI_GUID *Guid, IN UINTN DataLength)
Definition: HobLib.c:336
VOID *EFIAPI GetNextGuidHob(IN CONST EFI_GUID *Guid, IN CONST VOID *HobStart)
Definition: HobLib.c:176
VOID EFIAPI BuildStackHob(IN EFI_PHYSICAL_ADDRESS BaseAddress, IN UINT64 Length)
Definition: HobLib.c:546
VOID EFIAPI SwitchStack(IN SWITCH_STACK_ENTRY_POINT EntryPoint, IN VOID *Context1 OPTIONAL, IN VOID *Context2 OPTIONAL, IN VOID *NewStack,...)
Definition: SwitchStack.c:42
UINT64 EFIAPI RShiftU64(IN UINT64 Operand, IN UINTN Count)
Definition: RShiftU64.c:28
VOID(EFIAPI * SWITCH_STACK_ENTRY_POINT)(IN VOID *Context1 OPTIONAL, IN VOID *Context2 OPTIONAL)
Definition: BaseLib.h:5094
VOID *EFIAPI ScanGuid(IN CONST VOID *Buffer, IN UINTN Length, IN CONST GUID *Guid)
Definition: MemLibGuid.c:115
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
GUID *EFIAPI CopyGuid(OUT GUID *DestinationGuid, IN CONST GUID *SourceGuid)
Definition: MemLibGuid.c:39
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
BOOLEAN EFIAPI IsZeroGuid(IN CONST GUID *Guid)
Definition: MemLibGuid.c:156
EFI_STATUS PeiLoadImage(IN CONST EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_FILE_HANDLE FileHandle, IN UINT8 PeimState, OUT EFI_PHYSICAL_ADDRESS *EntryPoint, OUT UINT32 *AuthenticationState)
Definition: Image.c:881
EFI_STATUS LoadAndRelocatePeCoffImageInPlace(IN VOID *Pe32Data, IN VOID *ImageAddress)
Definition: Image.c:482
EFI_STATUS PeiGetPe32Data(IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **Pe32Data)
Definition: Image.c:541
EFI_STATUS EFIAPI ReportStatusCode(IN EFI_STATUS_CODE_TYPE Type, IN EFI_STATUS_CODE_VALUE Value)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
EFI_STATUS EFIAPI PeiServicesFfsGetFileInfo(IN CONST EFI_PEI_FILE_HANDLE FileHandle, OUT EFI_FV_FILE_INFO *FileInfo)
EFI_STATUS EFIAPI PeiServicesFfsFindSectionData(IN EFI_SECTION_TYPE SectionType, IN EFI_PEI_FILE_HANDLE FileHandle, OUT VOID **SectionData)
EFI_STATUS EFIAPI PeiServicesLocatePpi(IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
EFI_STATUS EFIAPI PeiServicesNotifyPpi(IN CONST EFI_PEI_NOTIFY_DESCRIPTOR *NotifyList)
EFI_STATUS EFIAPI PeiServicesAllocatePages(IN EFI_MEMORY_TYPE MemoryType, IN UINTN Pages, OUT EFI_PHYSICAL_ADDRESS *Memory)
EFI_STATUS EFIAPI PeiServicesInstallPpi(IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList)
BOOLEAN PeimDispatchReadiness(IN EFI_PEI_SERVICES **PeiServices, IN VOID *DependencyExpression)
Definition: Dependency.c:92
VOID PeiDispatcher(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN PEI_CORE_INSTANCE *Private)
Definition: Dispatcher.c:1791
EFI_STATUS EFIAPI PeiDelayedDispatchRegister(IN EFI_DELAYED_DISPATCH_PPI *This, IN EFI_DELAYED_DISPATCH_FUNCTION Function, IN UINT64 Context, IN EFI_GUID *DelayedGroupId OPTIONAL, IN UINT32 Delay)
Definition: Dispatcher.c:109
VOID InitializeDispatcherData(IN PEI_CORE_INSTANCE *PrivateData, IN PEI_CORE_INSTANCE *OldCoreData, IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData)
Definition: Dispatcher.c:2149
EFI_STATUS EFIAPI MigratePeim(IN EFI_PEI_FILE_HANDLE FileHandle, IN EFI_PEI_FILE_HANDLE MigratedFileHandle)
Definition: Dispatcher.c:1385
VOID ConvertStatusCodeCallbacks(IN UINTN OrgFvHandle, IN UINTN FvHandle, IN UINTN FvSize)
Definition: Dispatcher.c:1436
EFI_STATUS EFIAPI PeiDelayedDispatchOnEndOfPei(IN EFI_PEI_SERVICES **PeiServices, IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, IN VOID *Ppi)
Definition: Dispatcher.c:361
VOID PeiLoadFixAddressHook(IN PEI_CORE_INSTANCE *PrivateData)
Definition: Dispatcher.c:656
VOID DiscoverPeimsAndOrderWithApriori(IN PEI_CORE_INSTANCE *Private, IN PEI_CORE_FV_HANDLE *CoreFileHandle)
Definition: Dispatcher.c:397
VOID EFIAPI PeiCoreEntry(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN PEI_CORE_INSTANCE *Private)
Definition: Dispatcher.c:1037
EFI_STATUS EFIAPI MigratePeimsInFv(IN PEI_CORE_INSTANCE *Private, IN UINTN FvIndex, IN UINTN OrgFvHandle, IN UINTN FvHandle)
Definition: Dispatcher.c:1496
BOOLEAN DelayedDispatchDispatcher(IN DELAYED_DISPATCH_TABLE *DelayedDispatchTable, IN EFI_GUID *DelayedGroupId OPTIONAL)
Definition: Dispatcher.c:200
DELAYED_DISPATCH_TABLE * GetDelayedDispatchTable(VOID)
Definition: Dispatcher.c:73
BOOLEAN PeiLoadFixAddressIsMemoryRangeAvailable(IN PEI_CORE_INSTANCE *PrivateData, IN EFI_HOB_RESOURCE_DESCRIPTOR *ResourceHob)
Definition: Dispatcher.c:609
BOOLEAN DepexSatisfied(IN PEI_CORE_INSTANCE *Private, IN EFI_PEI_FILE_HANDLE FileHandle, IN UINTN PeimCount)
Definition: Dispatcher.c:2179
EFI_STATUS EFIAPI PeiDelayedDispatchWaitOnEvent(IN EFI_DELAYED_DISPATCH_PPI *This, IN EFI_GUID DelayedGroupId)
Definition: Dispatcher.c:313
VOID PeiCheckAndSwitchStack(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN PEI_CORE_INSTANCE *Private)
Definition: Dispatcher.c:1058
EFI_STATUS EFIAPI PeiRegisterForShadow(IN EFI_PEI_FILE_HANDLE FileHandle)
Definition: Dispatcher.c:2240
EFI_STATUS EFIAPI EvacuateTempRam(IN PEI_CORE_INSTANCE *Private, IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData)
Definition: Dispatcher.c:1551
PEI_CORE_FV_HANDLE * FindNextCoreFvHandle(IN PEI_CORE_INSTANCE *Private, IN UINTN Instance)
Definition: FwVol.c:2168
VOID PeiReinitializeFv(IN PEI_CORE_INSTANCE *PrivateData)
Definition: FwVol.c:2189
VOID PeiInitializeFv(IN PEI_CORE_INSTANCE *PrivateData, IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData)
Definition: FwVol.c:488
EFI_STATUS ProcessFvFile(IN PEI_CORE_INSTANCE *PrivateData, IN PEI_CORE_FV_HANDLE *ParentFvCoreHandle, IN EFI_PEI_FILE_HANDLE ParentFvFileHandle)
Definition: FwVol.c:1431
#define NULL
Definition: Base.h:319
#define CONST
Definition: Base.h:259
#define MIN(a, b)
Definition: Base.h:1007
#define VOID
Definition: Base.h:269
#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 ASSERT_EFI_ERROR(StatusParameter)
Definition: DebugLib.h:463
#define DEBUG_CODE_BEGIN()
Definition: DebugLib.h:565
#define DEBUG(Expression)
Definition: DebugLib.h:435
#define DEBUG_CODE_END()
Definition: DebugLib.h:579
#define REPORT_STATUS_CODE_WITH_EXTENDED_DATA(Type, Value, ExtendedData, ExtendedDataSize)
VOID(EFIAPI * EFI_DELAYED_DISPATCH_FUNCTION)(IN OUT UINT64 *Context, OUT UINT32 *NewDelay)
VOID ConvertFvHob(IN PEI_CORE_INSTANCE *PrivateData, IN UINTN OrgFvHandle, IN UINTN FvHandle)
VOID MigrateMemoryPages(IN PEI_CORE_INSTANCE *Private, IN BOOLEAN TemporaryRamMigrated)
#define PcdGet64(TokenName)
Definition: PcdLib.h:375
#define FixedPcdGet32(TokenName)
Definition: PcdLib.h:92
#define PcdGet32(TokenName)
Definition: PcdLib.h:362
#define PcdGetBool(TokenName)
Definition: PcdLib.h:401
EFI_STATUS EFIAPI PeiLocatePpi(IN CONST EFI_PEI_SERVICES **PeiServices, IN CONST EFI_GUID *Guid, IN UINTN Instance, IN OUT EFI_PEI_PPI_DESCRIPTOR **PpiDescriptor, IN OUT VOID **Ppi)
Definition: Ppi.c:666
VOID ConvertPeiCorePpiPointers(IN PEI_CORE_INSTANCE *PrivateData, IN PEI_CORE_FV_HANDLE *CoreFvHandle)
Definition: Ppi.c:1092
VOID ProcessDispatchNotifyList(IN PEI_CORE_INSTANCE *PrivateData)
Definition: Ppi.c:902
EFI_STATUS VerifyPeim(IN PEI_CORE_INSTANCE *PrivateData, IN EFI_PEI_FV_HANDLE VolumeHandle, IN EFI_PEI_FILE_HANDLE FileHandle, IN UINT32 AuthenticationStatus)
Definition: Security.c:88
#define PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE
Definition: PeiMain.h:59
VOID EFIAPI PeiCore(IN CONST EFI_SEC_PEI_HAND_OFF *SecCoreData, IN CONST EFI_PEI_PPI_DESCRIPTOR *PpiList, IN VOID *Data)
Definition: PeiMain.c:169
VOID ConvertPpiPointersFv(IN PEI_CORE_INSTANCE *PrivateData, IN UINTN OrgFvHandle, IN UINTN FvHandle, IN UINTN FvSize)
Definition: Ppi.c:213
#define PEI_CORE_INSTANCE_FROM_PS_THIS(a)
Definition: PeiMain.h:343
#define PERF_FUNCTION_END()
#define PERF_START_IMAGE_END(ModuleHandle)
#define PERF_INMODULE_BEGIN(MeasurementString)
#define PERF_FUNCTION_BEGIN()
#define PERF_START_IMAGE_BEGIN(ModuleHandle)
#define PERF_INMODULE_END(MeasurementString)
#define PERF_EVENT_SIGNAL_END(EventGuid)
#define PERF_EVENT_SIGNAL_BEGIN(EventGuid)
EFI_STATUS(EFIAPI * EFI_PEIM_ENTRY_POINT2)(IN EFI_PEI_FILE_HANDLE FileHandle, IN CONST EFI_PEI_SERVICES **PeiServices)
Definition: PiPeiCis.h:54
VOID * EFI_PEI_FILE_HANDLE
Definition: PiPeiCis.h:26
VOID * EFI_PEI_FV_HANDLE
Definition: PiPeiCis.h:21
#define EFI_PROGRESS_CODE
Definition: PiStatusCode.h:44
VOID *EFIAPI AllocatePool(IN UINTN AllocationSize)
VOID *EFIAPI AllocatePages(IN UINTN Pages)
EFI_FILE_INFO * FileInfo(IN EFI_FILE_HANDLE FHand)
RETURN_STATUS EFIAPI SafeUint64Add(IN UINT64 Augend, IN UINT64 Addend, OUT UINT64 *Result)
Definition: SafeIntLib.c:2973
VOID EFIAPI Exit(IN EFI_STATUS Status)
UINT64 EFI_PHYSICAL_ADDRESS
Definition: UefiBaseType.h:50
#define EFI_PAGES_TO_SIZE(Pages)
Definition: UefiBaseType.h:213
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
GUID EFI_GUID
Definition: UefiBaseType.h:25
#define EFI_SIZE_TO_PAGES(Size)
Definition: UefiBaseType.h:200
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
@ EfiBootServicesCode
PEI_CORE_FV_HANDLE * Fv
Definition: PeiMain.h:259
CHAR16 FileName[1]
Definition: FileInfo.h:52
EFI_FV_FILETYPE FileType
Definition: PiPeiCis.h:666
EFI_PHYSICAL_ADDRESS MemoryBaseAddress
Definition: PiHob.h:119
EFI_MEMORY_TYPE MemoryType
Definition: PiHob.h:131
EFI_HOB_MEMORY_ALLOCATION_HEADER AllocDescriptor
Definition: PiHob.h:153
EFI_PHYSICAL_ADDRESS PhysicalStart
Definition: PiHob.h:329
EFI_RESOURCE_TYPE ResourceType
Definition: PiHob.h:321
EFI_RESOURCE_ATTRIBUTE_TYPE ResourceAttribute
Definition: PiHob.h:325
Definition: Base.h:213