mirror of https://github.com/acidanthera/audk.git
Merge Temporary Ram support patch.
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4782 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
parent
bc4cb041a3
commit
58dcdada56
|
@ -28,13 +28,6 @@ typedef struct {
|
|||
EFI_HANDLE Handle;
|
||||
} PEIM_FILE_HANDLE_EXTENDED_DATA;
|
||||
|
||||
STATIC
|
||||
VOID
|
||||
InvokePeiCore (
|
||||
VOID *Context1,
|
||||
VOID *Context2
|
||||
);
|
||||
|
||||
VOID
|
||||
DiscoverPeimsAndOrderWithApriori (
|
||||
IN PEI_CORE_INSTANCE *Private,
|
||||
|
@ -55,7 +48,7 @@ Returns:
|
|||
|
||||
NONE
|
||||
|
||||
--*/
|
||||
--*/
|
||||
{
|
||||
EFI_STATUS Status;
|
||||
EFI_PEI_FV_HANDLE FileHandle;
|
||||
|
@ -90,20 +83,20 @@ Returns:
|
|||
//
|
||||
for (PeimCount = 0; PeimCount < FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv); PeimCount++) {
|
||||
Status = PeiFindFileEx (
|
||||
VolumeHandle,
|
||||
NULL,
|
||||
PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,
|
||||
VolumeHandle,
|
||||
NULL,
|
||||
PEI_CORE_INTERNAL_FFS_FILE_DISPATCH_TYPE,
|
||||
&FileHandle,
|
||||
&AprioriFileHandle
|
||||
);
|
||||
if (Status != EFI_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Private->CurrentFvFileHandles[PeimCount] = FileHandle;
|
||||
}
|
||||
|
||||
Private->AprioriCount = 0;
|
||||
Private->AprioriCount = 0;
|
||||
if (AprioriFileHandle != NULL) {
|
||||
//
|
||||
// Read the Apriori file
|
||||
|
@ -114,21 +107,21 @@ Returns:
|
|||
// Calculate the number of PEIMs in the A Priori list
|
||||
//
|
||||
Private->AprioriCount = *(UINT32 *)(((EFI_FFS_FILE_HEADER *)AprioriFileHandle)->Size) & 0x00FFFFFF;
|
||||
Private->AprioriCount -= sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_COMMON_SECTION_HEADER);
|
||||
Private->AprioriCount -= sizeof (EFI_FFS_FILE_HEADER) - sizeof (EFI_COMMON_SECTION_HEADER);
|
||||
Private->AprioriCount /= sizeof (EFI_GUID);
|
||||
|
||||
|
||||
SetMem (FileGuid, sizeof (FileGuid), 0);
|
||||
for (Index = 0; Index < PeimCount; Index++) {
|
||||
//
|
||||
// Make an array of file name guids that matches the FileHandle array so we can convert
|
||||
// quickly from file name to file handle
|
||||
//
|
||||
CopyMem (&FileGuid[Index], &((EFI_FFS_FILE_HEADER *)Private->CurrentFvFileHandles[Index])->Name,sizeof(EFI_GUID));
|
||||
CopyMem (&FileGuid[Index], &((EFI_FFS_FILE_HEADER *)Private->CurrentFvFileHandles[Index])->Name,sizeof(EFI_GUID));
|
||||
}
|
||||
|
||||
//
|
||||
// Walk through FileGuid array to find out who is invalid PEIM guid in Apriori file.
|
||||
// Add avalible PEIMs in Apriori file into TempFileHandles array at first.
|
||||
// Add avalible PEIMs in Apriori file into TempFileHandles array at first.
|
||||
//
|
||||
Index2 = 0;
|
||||
for (Index = 0; Index2 < Private->AprioriCount; Index++) {
|
||||
|
@ -139,7 +132,7 @@ Returns:
|
|||
}
|
||||
}
|
||||
if (Guid == NULL) {
|
||||
break;
|
||||
break;
|
||||
}
|
||||
PeimIndex = ((UINTN)Guid - (UINTN)&FileGuid[0])/sizeof (EFI_GUID);
|
||||
TempFileHandles[Index] = Private->CurrentFvFileHandles[PeimIndex];
|
||||
|
@ -154,7 +147,7 @@ Returns:
|
|||
// Update valid Aprioricount
|
||||
//
|
||||
Private->AprioriCount = Index;
|
||||
|
||||
|
||||
//
|
||||
// Add in any PEIMs not in the Apriori file
|
||||
//
|
||||
|
@ -171,11 +164,11 @@ Returns:
|
|||
//Index the end of array contains re-range Pei moudle.
|
||||
//
|
||||
TempFileHandles[Index] = NULL;
|
||||
|
||||
|
||||
//
|
||||
// Private->CurrentFvFileHandles is currently in PEIM in the FV order.
|
||||
// We need to update it to start with files in the A Priori list and
|
||||
// then the remaining files in PEIM order.
|
||||
// We need to update it to start with files in the A Priori list and
|
||||
// then the remaining files in PEIM order.
|
||||
//
|
||||
CopyMem (Private->CurrentFvFileHandles, TempFileHandles, sizeof (Private->CurrentFvFileHandles));
|
||||
}
|
||||
|
@ -186,7 +179,46 @@ Returns:
|
|||
//
|
||||
Private->Fv[Private->CurrentPeimFvCount].ScanFv = TRUE;
|
||||
CopyMem (Private->Fv[Private->CurrentPeimFvCount].FvFileHandles, Private->CurrentFvFileHandles, sizeof (Private->CurrentFvFileHandles));
|
||||
|
||||
|
||||
}
|
||||
|
||||
VOID*
|
||||
ShadowPeiCore(
|
||||
EFI_PEI_SERVICES **PeiServices,
|
||||
PEI_CORE_INSTANCE *PrivateInMem
|
||||
)
|
||||
{
|
||||
EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
|
||||
EFI_PHYSICAL_ADDRESS EntryPoint;
|
||||
EFI_STATUS Status;
|
||||
UINT32 AuthenticationState;
|
||||
|
||||
PeiCoreFileHandle = NULL;
|
||||
|
||||
//
|
||||
// Find the PEI Core in the BFV
|
||||
//
|
||||
Status = PeiFindFileEx (
|
||||
(EFI_PEI_FV_HANDLE)PrivateInMem->Fv[0].FvHeader,
|
||||
NULL,
|
||||
EFI_FV_FILETYPE_PEI_CORE,
|
||||
&PeiCoreFileHandle,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Shadow PEI Core into memory so it will run faster
|
||||
//
|
||||
Status = PeiLoadImage (
|
||||
PeiServices,
|
||||
*((EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle),
|
||||
&EntryPoint,
|
||||
&AuthenticationState
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
return (VOID*) ((UINTN) EntryPoint + (UINTN) PeiCore - (UINTN) _ModuleEntryPoint);
|
||||
}
|
||||
|
||||
VOID
|
||||
|
@ -220,9 +252,8 @@ Returns:
|
|||
UINT32 Index1;
|
||||
UINT32 Index2;
|
||||
EFI_PEI_SERVICES **PeiServices;
|
||||
VOID *PrivateInMem;
|
||||
EFI_PEI_FV_HANDLE VolumeHandle;
|
||||
EFI_PEI_FILE_HANDLE PeiCoreFileHandle;
|
||||
EFI_PEI_FV_HANDLE VolumeHandle;
|
||||
//EFI_PHYSICAL_ADDRESS PeiCoreFileHandle;
|
||||
EFI_PEI_FILE_HANDLE PeimFileHandle;
|
||||
UINTN FvCount;
|
||||
UINTN PeimCount;
|
||||
|
@ -234,10 +265,19 @@ Returns:
|
|||
UINTN SaveCurrentPeimCount;
|
||||
UINTN SaveCurrentFvCount;
|
||||
EFI_PEI_FILE_HANDLE SaveCurrentFileHandle;
|
||||
VOID *TopOfStack;
|
||||
PEI_CORE_PARAMETERS PeiCoreParameters;
|
||||
PEIM_FILE_HANDLE_EXTENDED_DATA ExtendedData;
|
||||
EFI_PHYSICAL_ADDRESS NewPermenentMemoryBase;
|
||||
TEMPORARY_RAM_SUPPORT_PPI *TemporaryRamSupportPpi;
|
||||
EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffTable;
|
||||
EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffTable;
|
||||
INTN Offset;
|
||||
PEI_CORE_INSTANCE *PrivateInMem;
|
||||
UINT64 NewPeiStackSize;
|
||||
UINT64 OldPeiStackSize;
|
||||
UINT64 StackGap;
|
||||
EFI_FV_FILE_INFO FvFileInfo;
|
||||
UINTN OldCheckingTop;
|
||||
UINTN OldCheckingBottom;
|
||||
|
||||
|
||||
PeiServices = &Private->PS;
|
||||
|
@ -257,11 +297,11 @@ Returns:
|
|||
for (Index1 = 0; Index1 <= SaveCurrentFvCount; Index1++) {
|
||||
for (Index2 = 0; (Index2 < FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->Fv[Index1].FvFileHandles[Index2] != NULL); Index2++) {
|
||||
if (Private->Fv[Index1].PeimState[Index2] == PEIM_STATE_REGISITER_FOR_SHADOW) {
|
||||
PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];
|
||||
PeimFileHandle = Private->Fv[Index1].FvFileHandles[Index2];
|
||||
Status = PeiLoadImage (
|
||||
&Private->PS,
|
||||
PeimFileHandle,
|
||||
&EntryPoint,
|
||||
&Private->PS,
|
||||
PeimFileHandle,
|
||||
&EntryPoint,
|
||||
&AuthenticationState
|
||||
);
|
||||
if (Status == EFI_SUCCESS) {
|
||||
|
@ -270,18 +310,18 @@ Returns:
|
|||
//
|
||||
Private->Fv[Index1].PeimState[Index2]++;
|
||||
Private->CurrentFileHandle = PeimFileHandle;
|
||||
Private->CurrentPeimFvCount = Index1;
|
||||
Private->CurrentPeimCount = Index2;
|
||||
Private->CurrentPeimFvCount = Index1;
|
||||
Private->CurrentPeimCount = Index2;
|
||||
//
|
||||
// Call the PEIM entry point
|
||||
//
|
||||
PeimEntryPoint = (EFI_PEIM_ENTRY_POINT2)(UINTN)EntryPoint;
|
||||
|
||||
|
||||
PERF_START (0, "PEIM", NULL, 0);
|
||||
PeimEntryPoint(PeimFileHandle, (const EFI_PEI_SERVICES **) &Private->PS);
|
||||
PERF_END (0, "PEIM", NULL, 0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Process the Notify list and dispatch any notifies for
|
||||
// newly installed PPIs.
|
||||
|
@ -290,9 +330,9 @@ Returns:
|
|||
}
|
||||
}
|
||||
}
|
||||
Private->CurrentFileHandle = SaveCurrentFileHandle;
|
||||
Private->CurrentPeimFvCount = SaveCurrentFvCount;
|
||||
Private->CurrentPeimCount = SaveCurrentPeimCount;
|
||||
Private->CurrentFileHandle = SaveCurrentFileHandle;
|
||||
Private->CurrentPeimFvCount = SaveCurrentFvCount;
|
||||
Private->CurrentPeimCount = SaveCurrentPeimCount;
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -314,7 +354,7 @@ Returns:
|
|||
if (Private->CurrentPeimCount == 0) {
|
||||
//
|
||||
// When going through each FV, at first, search Apriori file to
|
||||
// reorder all PEIMs to ensure the PEIMs in Apriori file to get
|
||||
// reorder all PEIMs to ensure the PEIMs in Apriori file to get
|
||||
// dispatch at first.
|
||||
//
|
||||
DiscoverPeimsAndOrderWithApriori (Private, VolumeHandle);
|
||||
|
@ -323,8 +363,8 @@ Returns:
|
|||
//
|
||||
// Start to dispatch all modules within the current Fv.
|
||||
//
|
||||
for (PeimCount = Private->CurrentPeimCount;
|
||||
(PeimCount < FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->CurrentFvFileHandles[PeimCount] != NULL);
|
||||
for (PeimCount = Private->CurrentPeimCount;
|
||||
(PeimCount < FixedPcdGet32 (PcdPeiCoreMaxPeimPerFv)) && (Private->CurrentFvFileHandles[PeimCount] != NULL);
|
||||
PeimCount++) {
|
||||
Private->CurrentPeimCount = PeimCount;
|
||||
PeimFileHandle = Private->CurrentFileHandle = Private->CurrentFvFileHandles[PeimCount];
|
||||
|
@ -345,16 +385,17 @@ Returns:
|
|||
// For PEIM driver, Load its entry point
|
||||
//
|
||||
Status = PeiLoadImage (
|
||||
PeiServices,
|
||||
PeimFileHandle,
|
||||
&EntryPoint,
|
||||
PeiServices,
|
||||
PeimFileHandle,
|
||||
&EntryPoint,
|
||||
&AuthenticationState
|
||||
);
|
||||
}
|
||||
|
||||
if ((Status == EFI_SUCCESS)) {
|
||||
//
|
||||
// The PEIM has its dependencies satisfied, and is processed.
|
||||
// The PEIM has its dependencies satisfied, and its entry point
|
||||
// has been found, so invoke it.
|
||||
//
|
||||
PERF_START (0, "PEIM", NULL, 0);
|
||||
|
||||
|
@ -373,7 +414,7 @@ Returns:
|
|||
// PEIM_STATE_NOT_DISPATCHED move to PEIM_STATE_DISPATCHED
|
||||
//
|
||||
Private->Fv[FvCount].PeimState[PeimCount]++;
|
||||
|
||||
|
||||
if (FvFileInfo.FileType != EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE) {
|
||||
//
|
||||
// Call the PEIM entry point for PEIM driver
|
||||
|
@ -393,12 +434,185 @@ Returns:
|
|||
);
|
||||
PERF_END (0, "PEIM", NULL, 0);
|
||||
|
||||
} else {
|
||||
}
|
||||
|
||||
if (Private->SwitchStackSignal) {
|
||||
|
||||
//
|
||||
// If PeiLoadImage fails, the section extraction PPI or Decompress PPI may not be ready,
|
||||
// we flag that more Peims need to be dispatched.
|
||||
// Reserve the size of new stack at bottom of physical memory
|
||||
//
|
||||
PeimNeedingDispatch = TRUE;
|
||||
OldPeiStackSize = Private->StackSize;
|
||||
NewPeiStackSize = (RShiftU64 (Private->PhysicalMemoryLength, 1) + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
|
||||
if (FixedPcdGet32(PcdPeiCoreMaxPeiStackSize) > (UINT32) NewPeiStackSize) {
|
||||
Private->StackSize = NewPeiStackSize;
|
||||
} else {
|
||||
Private->StackSize = FixedPcdGet32(PcdPeiCoreMaxPeiStackSize);
|
||||
}
|
||||
|
||||
//
|
||||
// In theory, the size of new stack in permenent memory should large than
|
||||
// size of old stack in temporary memory.
|
||||
// But if new stack is smaller than the size of old stack, we also reserve
|
||||
// the size of old stack at bottom of permenent memory.
|
||||
//
|
||||
StackGap = 0;
|
||||
if (Private->StackSize > OldPeiStackSize) {
|
||||
StackGap = Private->StackSize - OldPeiStackSize;
|
||||
}
|
||||
|
||||
//
|
||||
// Update HandOffHob for new installed permenent memory
|
||||
//
|
||||
OldHandOffTable = Private->HobList.HandoffInformationTable;
|
||||
OldCheckingBottom = (UINTN)OldHandOffTable;
|
||||
OldCheckingTop = (UINTN)(OldCheckingBottom + SecCoreData->TemporaryRamSize);
|
||||
|
||||
//
|
||||
// The whole temporary memory will be migrated to physical memory.
|
||||
// CAUTION: The new base is computed accounding to gap of new stack.
|
||||
//
|
||||
NewPermenentMemoryBase = Private->PhysicalMemoryBegin + StackGap;
|
||||
Offset = (UINTN) NewPermenentMemoryBase - (UINTN) SecCoreData->TemporaryRamBase;
|
||||
NewHandOffTable = (EFI_HOB_HANDOFF_INFO_TABLE *)((UINTN)OldHandOffTable + Offset);
|
||||
PrivateInMem = (PEI_CORE_INSTANCE *)((UINTN) (VOID*) Private + Offset);
|
||||
|
||||
//
|
||||
// TemporaryRamSupportPpi is produced by platform's SEC
|
||||
//
|
||||
Status = PeiLocatePpi (
|
||||
(CONST EFI_PEI_SERVICES **) PeiServices,
|
||||
&gEfiTemporaryRamSupportPpiGuid,
|
||||
0,
|
||||
NULL,
|
||||
(VOID**)&TemporaryRamSupportPpi
|
||||
);
|
||||
|
||||
|
||||
if (!EFI_ERROR (Status)) {
|
||||
TemporaryRamSupportPpi->TemporaryRamMigration (
|
||||
(CONST EFI_PEI_SERVICES **) PeiServices,
|
||||
(EFI_PHYSICAL_ADDRESS)(UINTN) SecCoreData->TemporaryRamBase,
|
||||
(EFI_PHYSICAL_ADDRESS)(UINTN) NewPermenentMemoryBase,
|
||||
SecCoreData->TemporaryRamSize
|
||||
);
|
||||
|
||||
} else {
|
||||
CopyMem (
|
||||
(VOID*)(UINTN) NewPermenentMemoryBase,
|
||||
SecCoreData->TemporaryRamBase,
|
||||
SecCoreData->TemporaryRamSize
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
// Fixup the PeiCore's private data
|
||||
//
|
||||
PrivateInMem->PS = &PrivateInMem->ServiceTableShadow;
|
||||
PrivateInMem->CpuIo = &PrivateInMem->ServiceTableShadow.CpuIo;
|
||||
PrivateInMem->HobList.Raw = (VOID*) ((UINTN) PrivateInMem->HobList.Raw + Offset);
|
||||
PrivateInMem->StackBase = (EFI_PHYSICAL_ADDRESS)(((UINTN)PrivateInMem->PhysicalMemoryBegin + EFI_PAGE_MASK) & ~EFI_PAGE_MASK);
|
||||
|
||||
PeiServices = &PrivateInMem->PS;
|
||||
|
||||
//
|
||||
// Fixup for PeiService's address
|
||||
//
|
||||
SetPeiServicesTablePointer(PeiServices);
|
||||
|
||||
//
|
||||
// Update HandOffHob for new installed permenent memory
|
||||
//
|
||||
NewHandOffTable->EfiEndOfHobList =
|
||||
(EFI_PHYSICAL_ADDRESS)(VOID*)((UINTN) NewHandOffTable->EfiEndOfHobList + Offset);
|
||||
NewHandOffTable->EfiMemoryTop = PrivateInMem->PhysicalMemoryBegin +
|
||||
PrivateInMem->PhysicalMemoryLength;
|
||||
NewHandOffTable->EfiMemoryBottom = PrivateInMem->PhysicalMemoryBegin;
|
||||
NewHandOffTable->EfiFreeMemoryTop = PrivateInMem->FreePhysicalMemoryTop;
|
||||
NewHandOffTable->EfiFreeMemoryBottom = NewHandOffTable->EfiEndOfHobList +
|
||||
sizeof (EFI_HOB_GENERIC_HEADER);
|
||||
|
||||
//
|
||||
// We need convert the PPI desciptor's pointer
|
||||
//
|
||||
ConvertPpiPointers ((CONST EFI_PEI_SERVICES **)PeiServices,
|
||||
OldCheckingBottom,
|
||||
OldCheckingTop,
|
||||
NewHandOffTable);
|
||||
|
||||
DEBUG ((EFI_D_INFO, "Stack Hob: BaseAddress=0x%X Length=0x%X\n",
|
||||
(UINTN)PrivateInMem->StackBase,
|
||||
PrivateInMem->StackSize));
|
||||
BuildStackHob (PrivateInMem->StackBase, PrivateInMem->StackSize);
|
||||
|
||||
//
|
||||
// After the whole temporary memory is migrated, then we can allocate page in
|
||||
// permenent memory.
|
||||
//
|
||||
PrivateInMem->PeiMemoryInstalled = TRUE;
|
||||
|
||||
//
|
||||
// Make sure we don't retry the same PEIM that added memory
|
||||
//
|
||||
PrivateInMem->CurrentPeimCount++;
|
||||
|
||||
//
|
||||
// Shadow PEI Core. When permanent memory is avaiable, shadow
|
||||
// PEI Core and PEIMs to get high performance.
|
||||
//
|
||||
//PeiCoreFileHandle = 0;
|
||||
//
|
||||
// Find the PEI Core in the BFV
|
||||
//
|
||||
//Status = PeiFindFileEx (
|
||||
// (EFI_PEI_FV_HANDLE)PrivateInMem->Fv[0].FvHeader,
|
||||
// NULL,
|
||||
// EFI_FV_FILETYPE_PEI_CORE,
|
||||
// (EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle,
|
||||
// NULL
|
||||
// );
|
||||
//ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Shadow PEI Core into memory so it will run faster
|
||||
//
|
||||
//Status = PeiLoadImage (
|
||||
// PeiServices,
|
||||
// *((EFI_PEI_FILE_HANDLE*)&PeiCoreFileHandle),
|
||||
// &EntryPoint,
|
||||
// &AuthenticationState
|
||||
// );
|
||||
//ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//PrivateInMem->ShadowedPeiCore = (VOID*) ((UINTN) EntryPoint +
|
||||
// (UINTN) PeiCore -
|
||||
// (UINTN) _ModuleEntryPoint);
|
||||
PrivateInMem->ShadowedPeiCore = ShadowPeiCore (
|
||||
PeiServices,
|
||||
PrivateInMem
|
||||
);
|
||||
//
|
||||
// Process the Notify list and dispatch any notifies for
|
||||
// newly installed PPIs.
|
||||
//
|
||||
ProcessNotifyList (PrivateInMem);
|
||||
|
||||
//
|
||||
// Entry PEI Phase 2
|
||||
//
|
||||
PeiCore (SecCoreData, NULL, PrivateInMem);
|
||||
|
||||
//((PEI_CORE_ENTRY_POINT) (UINTN) PrivateInMem->ShadowedPeiCore) (
|
||||
// SecCoreData,
|
||||
// NULL,
|
||||
// PrivateInMem
|
||||
// );
|
||||
|
||||
//
|
||||
// Code should not come here
|
||||
//
|
||||
ASSERT_EFI_ERROR(FALSE);
|
||||
}
|
||||
|
||||
//
|
||||
|
@ -407,88 +621,16 @@ Returns:
|
|||
//
|
||||
ProcessNotifyList (Private);
|
||||
|
||||
//
|
||||
// If permanent memory was discovered and installed by this
|
||||
// PEIM, shadow PEI Core and switch the stacks to the new memory.
|
||||
//
|
||||
if (Private->SwitchStackSignal) {
|
||||
|
||||
//
|
||||
// Make sure we don't retry the same PEIM that added memory
|
||||
//
|
||||
Private->CurrentPeimCount++;
|
||||
|
||||
//
|
||||
// Migrate IDT from CAR into real memory, so after stack switches to
|
||||
// the new memory, the caller can get memory version PeiServiceTable.
|
||||
//
|
||||
MigrateIdtTable (PeiServices);
|
||||
|
||||
//
|
||||
// Since we are at dispatch level, only the Core's private data
|
||||
// is preserved, nobody else should have any data on the stack.
|
||||
// So we need to copy PEI core instance data to memory.
|
||||
//
|
||||
PrivateInMem = AllocateCopyPool (sizeof (PEI_CORE_INSTANCE), Private);
|
||||
ASSERT (PrivateInMem != NULL);
|
||||
|
||||
//
|
||||
// Shadow PEI Core. When permanent memory is avaiable, shadow
|
||||
// PEI Core and PEIMs to get high performance.
|
||||
//
|
||||
PeiCoreFileHandle = NULL;
|
||||
//
|
||||
// Find the PEI Core in the BFV
|
||||
//
|
||||
Status = PeiFindFileEx (
|
||||
(EFI_PEI_FV_HANDLE)Private->Fv[0].FvHeader,
|
||||
NULL,
|
||||
EFI_FV_FILETYPE_PEI_CORE,
|
||||
&PeiCoreFileHandle,
|
||||
NULL
|
||||
);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Shadow PEI Core into memory so it will run faster
|
||||
//
|
||||
Status = PeiLoadImage (PeiServices, PeiCoreFileHandle, &EntryPoint, &AuthenticationState);
|
||||
ASSERT_EFI_ERROR (Status);
|
||||
|
||||
//
|
||||
// Switch to memory based stack and reenter PEI Core that has been
|
||||
// shadowed to memory.
|
||||
//
|
||||
//
|
||||
// Adjust the top of stack to be aligned at CPU_STACK_ALIGNMENT
|
||||
//
|
||||
TopOfStack = (VOID *)((UINTN)Private->StackBase + (UINTN)Private->StackSize - CPU_STACK_ALIGNMENT);
|
||||
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
||||
|
||||
PeiCoreParameters.SecCoreData = SecCoreData;
|
||||
PeiCoreParameters.PpiList = NULL;
|
||||
PeiCoreParameters.Data = PrivateInMem;
|
||||
ASSERT (PeiCoreParameters.Data != 0);
|
||||
|
||||
PeiSwitchStacks (
|
||||
InvokePeiCore,
|
||||
(VOID*) ((UINTN) EntryPoint + ((UINTN) PeiCore - (UINTN) _ModuleEntryPoint)),
|
||||
(VOID*) &PeiCoreParameters,
|
||||
TopOfStack,
|
||||
(VOID*)(UINTN)Private->StackBase
|
||||
);
|
||||
}
|
||||
|
||||
if ((Private->PeiMemoryInstalled) && (Private->Fv[FvCount].PeimState[PeimCount] == PEIM_STATE_REGISITER_FOR_SHADOW) && \
|
||||
(Private->HobList.HandoffInformationTable->BootMode != BOOT_ON_S3_RESUME)) {
|
||||
//
|
||||
// If memory is availble we shadow images by default for performance reasons.
|
||||
// We call the entry point a 2nd time so the module knows it's shadowed.
|
||||
// If memory is availble we shadow images by default for performance reasons.
|
||||
// We call the entry point a 2nd time so the module knows it's shadowed.
|
||||
//
|
||||
//PERF_START (PeiServices, L"PEIM", PeimFileHandle, 0);
|
||||
PeimEntryPoint (PeimFileHandle, (const EFI_PEI_SERVICES **) PeiServices);
|
||||
//PERF_END (PeiServices, L"PEIM", PeimFileHandle, 0);
|
||||
|
||||
|
||||
//
|
||||
// PEIM_STATE_REGISITER_FOR_SHADOW move to PEIM_STATE_DONE
|
||||
//
|
||||
|
@ -518,16 +660,16 @@ Returns:
|
|||
}
|
||||
|
||||
//
|
||||
// Before making another pass, we should set Private->CurrentPeimFvCount =0 to go
|
||||
// Before making another pass, we should set Private->CurrentPeimFvCount =0 to go
|
||||
// through all the FV.
|
||||
//
|
||||
Private->CurrentPeimFvCount = 0;
|
||||
|
||||
//
|
||||
// PeimNeedingDispatch being TRUE means we found a PEIM that did not get
|
||||
// PeimNeedingDispatch being TRUE means we found a PEIM that did not get
|
||||
// dispatched. So we need to make another pass
|
||||
//
|
||||
// PeimDispatchOnThisPass being TRUE means we dispatched a PEIM on this
|
||||
// PeimDispatchOnThisPass being TRUE means we dispatched a PEIM on this
|
||||
// pass. If we did not dispatch a PEIM there is no point in trying again
|
||||
// as it will fail the next time too (nothing has changed).
|
||||
//
|
||||
|
@ -602,13 +744,13 @@ Returns:
|
|||
//
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Depex section not in the encapsulated section.
|
||||
// Depex section not in the encapsulated section.
|
||||
//
|
||||
Status = PeiServicesFfsFindSectionData (
|
||||
EFI_SECTION_PEI_DEPEX,
|
||||
FileHandle,
|
||||
FileHandle,
|
||||
(VOID **)&DepexData
|
||||
);
|
||||
|
||||
|
@ -630,12 +772,12 @@ Returns:
|
|||
discovery permanent memory.
|
||||
|
||||
@param FileHandle File handle of a PEIM.
|
||||
|
||||
|
||||
@retval EFI_NOT_FOUND The file handle doesn't point to PEIM itself.
|
||||
@retval EFI_ALREADY_STARTED Indicate that the PEIM has been registered itself.
|
||||
@retval EFI_SUCCESS Successfully to register itself.
|
||||
|
||||
**/
|
||||
**/
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiRegisterForShadow (
|
||||
|
@ -658,52 +800,13 @@ PeiRegisterForShadow (
|
|||
//
|
||||
return EFI_ALREADY_STARTED;
|
||||
}
|
||||
|
||||
|
||||
Private->Fv[Private->CurrentPeimFvCount].PeimState[Private->CurrentPeimCount] = PEIM_STATE_REGISITER_FOR_SHADOW;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
This routine invoke the PeiCore's entry in new stack environment.
|
||||
|
||||
@param Context1 The first context parameter is entry of PeiCore
|
||||
@param Context2 The second context parameter is parameter structure point for PeiCore
|
||||
|
||||
**/
|
||||
STATIC
|
||||
VOID
|
||||
InvokePeiCore (
|
||||
VOID *Context1,
|
||||
VOID *Context2
|
||||
)
|
||||
{
|
||||
PEI_CORE_ENTRY_POINT PeiCoreEntryPoint;
|
||||
PEI_CORE_PARAMETERS *PeiCoreParameters;
|
||||
|
||||
//
|
||||
// Running on new stack in SEC Core
|
||||
//
|
||||
|
||||
PeiCoreEntryPoint = (PEI_CORE_ENTRY_POINT) (UINTN) Context1;
|
||||
PeiCoreParameters = (PEI_CORE_PARAMETERS *)Context2;
|
||||
|
||||
//
|
||||
// Call PEI Core using new stack
|
||||
//
|
||||
PeiCoreEntryPoint (
|
||||
PeiCoreParameters->SecCoreData,
|
||||
PeiCoreParameters->PpiList,
|
||||
PeiCoreParameters->Data
|
||||
);
|
||||
|
||||
//
|
||||
// Never returns
|
||||
//
|
||||
ASSERT (FALSE);
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
||||
/**
|
||||
Get Fv image from the FV type file, then install FV INFO ppi, Build FV hob.
|
||||
|
@ -712,7 +815,7 @@ InvokePeiCore (
|
|||
@param FileHandle File handle of a Fv type file.
|
||||
@param AuthenticationState Pointer to attestation authentication state of image.
|
||||
|
||||
|
||||
|
||||
@retval EFI_NOT_FOUND FV image can't be found.
|
||||
@retval EFI_SUCCESS Successfully to process it.
|
||||
|
||||
|
@ -730,12 +833,12 @@ ProcessFvFile (
|
|||
UINT32 FvAlignment;
|
||||
VOID *FvBuffer;
|
||||
EFI_PEI_HOB_POINTERS HobFv2;
|
||||
|
||||
|
||||
FvBuffer = NULL;
|
||||
*AuthenticationState = 0;
|
||||
|
||||
//
|
||||
// Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
|
||||
// Check if this EFI_FV_FILETYPE_FIRMWARE_VOLUME_IMAGE file has already
|
||||
// been extracted.
|
||||
//
|
||||
HobFv2.Raw = GetHobList ();
|
||||
|
@ -748,7 +851,7 @@ ProcessFvFile (
|
|||
}
|
||||
HobFv2.Raw = GET_NEXT_HOB (HobFv2);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Find FvImage in FvFile
|
||||
//
|
||||
|
@ -758,7 +861,7 @@ ProcessFvFile (
|
|||
FvFileHandle,
|
||||
(VOID **)&FvImageHandle
|
||||
);
|
||||
|
||||
|
||||
if (EFI_ERROR (Status)) {
|
||||
return Status;
|
||||
}
|
||||
|
@ -774,7 +877,7 @@ ProcessFvFile (
|
|||
if (FvAlignment < 8) {
|
||||
FvAlignment = 8;
|
||||
}
|
||||
//
|
||||
//
|
||||
// Check FvImage
|
||||
//
|
||||
if ((UINTN) FvImageInfo.FvStart % FvAlignment != 0) {
|
||||
|
@ -788,7 +891,7 @@ ProcessFvFile (
|
|||
//
|
||||
PeiFfsGetVolumeInfo ((EFI_PEI_FV_HANDLE) FvBuffer, &FvImageInfo);
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Install FvPpi and Build FvHob
|
||||
//
|
||||
|
@ -817,6 +920,6 @@ ProcessFvFile (
|
|||
&FvImageInfo.FvName,
|
||||
&(((EFI_FFS_FILE_HEADER *)FvFileHandle)->Name)
|
||||
);
|
||||
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -21,6 +21,12 @@ Abstract:
|
|||
|
||||
#include <PeiMain.h>
|
||||
|
||||
static EFI_PEI_PPI_DESCRIPTOR mMemoryDiscoveredPpi = {
|
||||
(EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST),
|
||||
&gEfiPeiMemoryDiscoveredPpiGuid,
|
||||
NULL
|
||||
};
|
||||
|
||||
VOID
|
||||
InitializeMemoryServices (
|
||||
IN PEI_CORE_INSTANCE *PrivateData,
|
||||
|
@ -49,15 +55,18 @@ Returns:
|
|||
|
||||
--*/
|
||||
{
|
||||
PrivateData->SwitchStackSignal = FALSE;
|
||||
|
||||
PrivateData->SwitchStackSignal = FALSE;
|
||||
|
||||
if (OldCoreData == NULL) {
|
||||
|
||||
PrivateData->PeiMemoryInstalled = FALSE;
|
||||
|
||||
PrivateData->BottomOfCarHeap = SecCoreData->PeiTemporaryRamBase;
|
||||
PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + SecCoreData->PeiTemporaryRamSize);
|
||||
|
||||
PrivateData->BottomOfCarHeap = SecCoreData->PeiTemporaryRamBase;
|
||||
PrivateData->TopOfCarHeap = (VOID *)((UINTN)(PrivateData->BottomOfCarHeap) + SecCoreData->PeiTemporaryRamSize);
|
||||
PrivateData->SizeOfTemporaryMemory = SecCoreData->TemporaryRamSize;
|
||||
PrivateData->StackSize = (UINT64) SecCoreData->StackSize;
|
||||
|
||||
DEBUG_CODE_BEGIN ();
|
||||
PrivateData->SizeOfCacheAsRam = SecCoreData->PeiTemporaryRamSize + SecCoreData->StackSize;
|
||||
PrivateData->MaxTopOfCarHeap = (VOID *) ((UINTN) PrivateData->BottomOfCarHeap + (UINTN) PrivateData->SizeOfCacheAsRam);
|
||||
|
@ -85,9 +94,9 @@ Returns:
|
|||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiInstallPeiMemory (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PHYSICAL_ADDRESS MemoryBegin,
|
||||
IN UINT64 MemoryLength
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PHYSICAL_ADDRESS MemoryBegin,
|
||||
IN UINT64 MemoryLength
|
||||
)
|
||||
/*++
|
||||
|
||||
|
@ -109,72 +118,15 @@ Returns:
|
|||
--*/
|
||||
{
|
||||
PEI_CORE_INSTANCE *PrivateData;
|
||||
EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob;
|
||||
EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob;
|
||||
UINT64 PeiStackSize;
|
||||
UINT64 EfiFreeMemorySize;
|
||||
EFI_PHYSICAL_ADDRESS PhysicalAddressOfOldHob;
|
||||
|
||||
if (MemoryLength > (MAX_ADDRESS - MemoryBegin + 1))
|
||||
return EFI_INVALID_PARAMETER;
|
||||
|
||||
|
||||
DEBUG ((EFI_D_INFO, "PeiInstallPeiMemory MemoryBegin 0x%LX, MemoryLength 0x%LX\n", MemoryBegin, MemoryLength));
|
||||
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
|
||||
|
||||
PrivateData->SwitchStackSignal = TRUE;
|
||||
PrivateData->PeiMemoryInstalled = TRUE;
|
||||
|
||||
//
|
||||
// Ensure the stack base is in page alignment
|
||||
//
|
||||
PrivateData->StackBase = ((UINTN)MemoryBegin + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
|
||||
PeiStackSize = (RShiftU64 (MemoryLength, 1) + EFI_PAGE_MASK) & ~EFI_PAGE_MASK;
|
||||
|
||||
if (PEI_STACK_SIZE > PeiStackSize) {
|
||||
PrivateData->StackSize = PeiStackSize;
|
||||
} else {
|
||||
PrivateData->StackSize = PEI_STACK_SIZE;
|
||||
}
|
||||
|
||||
OldHandOffHob = PrivateData->HobList.HandoffInformationTable;
|
||||
|
||||
PrivateData->HobList.Raw = (VOID *)((UINTN)(PrivateData->StackBase + PrivateData->StackSize));
|
||||
NewHandOffHob = PrivateData->HobList.HandoffInformationTable;
|
||||
PhysicalAddressOfOldHob = (EFI_PHYSICAL_ADDRESS) (UINTN) OldHandOffHob;
|
||||
|
||||
EfiFreeMemorySize = OldHandOffHob->EfiFreeMemoryBottom - PhysicalAddressOfOldHob;
|
||||
|
||||
DEBUG ((EFI_D_INFO, "HOBLIST address before memory init = 0x%p\n", OldHandOffHob));
|
||||
DEBUG ((EFI_D_INFO, "HOBLIST address after memory init = 0x%p\n", NewHandOffHob));
|
||||
|
||||
CopyMem (
|
||||
NewHandOffHob,
|
||||
OldHandOffHob,
|
||||
(UINTN)EfiFreeMemorySize
|
||||
);
|
||||
|
||||
NewHandOffHob->EfiMemoryTop = MemoryBegin + MemoryLength;
|
||||
NewHandOffHob->EfiFreeMemoryTop = NewHandOffHob->EfiMemoryTop;
|
||||
NewHandOffHob->EfiMemoryBottom = MemoryBegin;
|
||||
|
||||
NewHandOffHob->EfiFreeMemoryBottom = (UINTN)NewHandOffHob + EfiFreeMemorySize;
|
||||
|
||||
NewHandOffHob->EfiEndOfHobList = (UINTN)NewHandOffHob +
|
||||
(OldHandOffHob->EfiEndOfHobList -
|
||||
PhysicalAddressOfOldHob);
|
||||
|
||||
//
|
||||
// For IPF in CAR mode the real memory access is uncached,in InstallPeiMemory()
|
||||
// the 63-bit of address is set to 1.
|
||||
//
|
||||
SWITCH_TO_CACHE_MODE (PrivateData);
|
||||
|
||||
ConvertPpiPointers (PeiServices, OldHandOffHob, NewHandOffHob);
|
||||
|
||||
BuildStackHob (PrivateData->StackBase, PrivateData->StackSize);
|
||||
|
||||
PrivateData->PhysicalMemoryBegin = MemoryBegin;
|
||||
PrivateData->PhysicalMemoryLength = MemoryLength;
|
||||
PrivateData->FreePhysicalMemoryTop = MemoryBegin + MemoryLength;
|
||||
|
||||
PrivateData->SwitchStackSignal = TRUE;
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
@ -214,56 +166,70 @@ Returns:
|
|||
PEI_CORE_INSTANCE *PrivateData;
|
||||
EFI_PEI_HOB_POINTERS Hob;
|
||||
EFI_PHYSICAL_ADDRESS Offset;
|
||||
EFI_PHYSICAL_ADDRESS *FreeMemoryTop;
|
||||
EFI_PHYSICAL_ADDRESS *FreeMemoryBottom;
|
||||
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS (PeiServices);
|
||||
|
||||
Hob.Raw = PrivateData->HobList.Raw;
|
||||
|
||||
//
|
||||
// Check if Hob already available
|
||||
//
|
||||
if (!PrivateData->PeiMemoryInstalled) {
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
//
|
||||
// When PeiInstallMemory is called but CAR has *not* been moved to temporary memory,
|
||||
// the AllocatePage will dependent the field of PEI_CORE_INSTANCE structure.
|
||||
//
|
||||
if (!PrivateData->SwitchStackSignal) {
|
||||
return EFI_NOT_AVAILABLE_YET;
|
||||
} else {
|
||||
FreeMemoryTop = &(PrivateData->FreePhysicalMemoryTop);
|
||||
FreeMemoryBottom = &(PrivateData->PhysicalMemoryBegin);
|
||||
}
|
||||
} else {
|
||||
FreeMemoryTop = &(Hob.HandoffInformationTable->EfiFreeMemoryTop);
|
||||
FreeMemoryBottom = &(Hob.HandoffInformationTable->EfiFreeMemoryBottom);
|
||||
}
|
||||
|
||||
Hob.Raw = PrivateData->HobList.Raw;
|
||||
|
||||
|
||||
//
|
||||
// Check to see if on 4k boundary
|
||||
//
|
||||
Offset = Hob.HandoffInformationTable->EfiFreeMemoryTop & 0xFFF;
|
||||
|
||||
Offset = *(FreeMemoryTop) & 0xFFF;
|
||||
|
||||
//
|
||||
// If not aligned, make the allocation aligned.
|
||||
//
|
||||
if (Offset != 0) {
|
||||
Hob.HandoffInformationTable->EfiFreeMemoryTop -= Offset;
|
||||
*(FreeMemoryTop) -= Offset;
|
||||
}
|
||||
|
||||
ASSERT (Hob.HandoffInformationTable->EfiFreeMemoryTop >= Hob.HandoffInformationTable->EfiFreeMemoryBottom);
|
||||
|
||||
//
|
||||
// Verify that there is sufficient memory to satisfy the allocation
|
||||
//
|
||||
if (Hob.HandoffInformationTable->EfiFreeMemoryTop - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) <
|
||||
Hob.HandoffInformationTable->EfiFreeMemoryBottom) {
|
||||
if (*(FreeMemoryTop) - ((Pages * EFI_PAGE_SIZE) + sizeof (EFI_HOB_MEMORY_ALLOCATION)) <
|
||||
*(FreeMemoryBottom)) {
|
||||
DEBUG ((EFI_D_ERROR, "AllocatePages failed: No 0x%x Pages is available.\n", Pages));
|
||||
DEBUG ((EFI_D_ERROR, "There is only left 0x%x pages memory resource to be allocated.\n", \
|
||||
EFI_SIZE_TO_PAGES ((UINTN) (Hob.HandoffInformationTable->EfiFreeMemoryTop - Hob.HandoffInformationTable->EfiFreeMemoryBottom))));
|
||||
EFI_SIZE_TO_PAGES ((UINTN) (*(FreeMemoryTop) - *(FreeMemoryBottom)))));
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
} else {
|
||||
//
|
||||
// Update the PHIT to reflect the memory usage
|
||||
//
|
||||
Hob.HandoffInformationTable->EfiFreeMemoryTop -= Pages * EFI_PAGE_SIZE;
|
||||
*(FreeMemoryTop) -= Pages * EFI_PAGE_SIZE;
|
||||
|
||||
//
|
||||
// Update the value for the caller
|
||||
//
|
||||
*Memory = Hob.HandoffInformationTable->EfiFreeMemoryTop;
|
||||
*Memory = *(FreeMemoryTop);
|
||||
|
||||
//
|
||||
// Create a memory allocation HOB.
|
||||
//
|
||||
BuildMemoryAllocationHob (
|
||||
Hob.HandoffInformationTable->EfiFreeMemoryTop,
|
||||
*(FreeMemoryTop),
|
||||
Pages * EFI_PAGE_SIZE,
|
||||
MemoryType
|
||||
);
|
||||
|
|
|
@ -35,6 +35,7 @@ Revision History
|
|||
#include <Ppi/GuidedSectionExtraction.h>
|
||||
#include <Ppi/LoadFile.h>
|
||||
#include <Ppi/Security2.h>
|
||||
#include <Ppi/TemporaryRamSupport.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PeiCoreEntryPoint.h>
|
||||
#include <Library/BaseLib.h>
|
||||
|
@ -66,9 +67,7 @@ typedef union {
|
|||
VOID *Raw;
|
||||
} PEI_PPI_LIST_POINTERS;
|
||||
|
||||
#define PEI_STACK_SIZE 0x20000
|
||||
|
||||
#define MAX_PPI_DESCRIPTORS 128
|
||||
#define MAX_PPI_DESCRIPTORS 64
|
||||
|
||||
typedef struct {
|
||||
INTN PpiListEnd;
|
||||
|
@ -135,9 +134,14 @@ typedef struct{
|
|||
VOID *CpuIo;
|
||||
EFI_PEI_SECURITY2_PPI *PrivateSecurityPpi;
|
||||
EFI_PEI_SERVICES ServiceTableShadow;
|
||||
UINTN SizeOfTemporaryMemory;
|
||||
UINTN SizeOfCacheAsRam;
|
||||
VOID *MaxTopOfCarHeap;
|
||||
EFI_PEI_PPI_DESCRIPTOR *XipLoadFile;
|
||||
EFI_PHYSICAL_ADDRESS PhysicalMemoryBegin;
|
||||
UINT64 PhysicalMemoryLength;
|
||||
EFI_PHYSICAL_ADDRESS FreePhysicalMemoryTop;
|
||||
VOID* ShadowedPeiCore;
|
||||
CACHE_SECTION_DATA CacheSection;
|
||||
} PEI_CORE_INSTANCE;
|
||||
|
||||
|
@ -307,6 +311,35 @@ Returns:
|
|||
;
|
||||
|
||||
|
||||
EFI_STATUS
|
||||
FindNextPeim (
|
||||
IN EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_FIRMWARE_VOLUME_HEADER *FwVolHeader,
|
||||
IN OUT EFI_FFS_FILE_HEADER **PeimFileHeader
|
||||
)
|
||||
/*++
|
||||
|
||||
Routine Description:
|
||||
Given the input file pointer, search for the next matching file in the
|
||||
FFS volume. The search starts from FileHeader inside
|
||||
the Firmware Volume defined by FwVolHeader.
|
||||
|
||||
Arguments:
|
||||
PeiServices - Pointer to the PEI Core Services Table.
|
||||
|
||||
FwVolHeader - Pointer to the FV header of the volume to search.
|
||||
This parameter must point to a valid FFS volume.
|
||||
|
||||
PeimFileHeader - Pointer to the current file from which to begin searching.
|
||||
This pointer will be updated upon return to reflect the file found.
|
||||
|
||||
Returns:
|
||||
EFI_NOT_FOUND - No files matching the search criteria were found
|
||||
EFI_SUCCESS
|
||||
|
||||
--*/
|
||||
;
|
||||
|
||||
BOOLEAN
|
||||
Dispatched (
|
||||
IN UINT8 CurrentPeim,
|
||||
|
@ -439,8 +472,9 @@ Returns:
|
|||
|
||||
VOID
|
||||
ConvertPpiPointers (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob,
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN UINTN OldCheckingBottom,
|
||||
IN UINTN OldCheckingTop,
|
||||
IN EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob
|
||||
)
|
||||
/*++
|
||||
|
@ -451,9 +485,10 @@ Routine Description:
|
|||
|
||||
Arguments:
|
||||
|
||||
PeiServices - The PEI core services table.
|
||||
OldHandOffHob - The old handoff HOB list.
|
||||
NewHandOffHob - The new handoff HOB list.
|
||||
PeiServices - The PEI core services table.
|
||||
OldCheckingBottom - The old checking bottom.
|
||||
OldCheckingTop - The old checking top.
|
||||
NewHandOffHob - The new handoff HOB list.
|
||||
|
||||
Returns:
|
||||
|
||||
|
|
|
@ -96,12 +96,18 @@
|
|||
gEfiPeiFirmwareVolumeInfoPpiGuid
|
||||
gEfiPeiLoadFilePpiGuid
|
||||
gEfiPeiSecurity2PpiGuid
|
||||
gEfiTemporaryRamSupportPpiGuid
|
||||
|
||||
[FixedPcd.common]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeimPerFv
|
||||
gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValuePeimDispatch
|
||||
gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValuePeiCoreEntry
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize
|
||||
|
||||
|
||||
[FeaturePcd.common]
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst
|
||||
|
||||
[BuildOptions.common]
|
||||
MSFT:*_*_*_CC_FLAGS = /Fa$* /FAsc /FR$(@R).SBR
|
||||
|
|
|
@ -122,6 +122,7 @@ Returns:
|
|||
PEI_CORE_INSTANCE *OldCoreData;
|
||||
EFI_PEI_CPU_IO_PPI *CpuIo;
|
||||
EFI_PEI_PCI_CFG2_PPI *PciCfg;
|
||||
PEI_CORE_ENTRY_POINT ShadowedPeiCore;
|
||||
|
||||
mTick = 0;
|
||||
OldCoreData = (PEI_CORE_INSTANCE *) Data;
|
||||
|
@ -133,6 +134,16 @@ Returns:
|
|||
}
|
||||
|
||||
if (OldCoreData != NULL) {
|
||||
ShadowedPeiCore = (PEI_CORE_ENTRY_POINT) (UINTN) OldCoreData->ShadowedPeiCore;
|
||||
if (ShadowedPeiCore != NULL) {
|
||||
OldCoreData->ShadowedPeiCore = NULL;
|
||||
ShadowedPeiCore (
|
||||
SecCoreData,
|
||||
PpiList,
|
||||
OldCoreData
|
||||
);
|
||||
}
|
||||
|
||||
CopyMem (&PrivateData, OldCoreData, sizeof (PEI_CORE_INSTANCE));
|
||||
|
||||
CpuIo = (VOID*)PrivateData.ServiceTableShadow.CpuIo;
|
||||
|
@ -181,8 +192,8 @@ Returns:
|
|||
UINTN StackValue;
|
||||
|
||||
StackValue = INIT_CAR_VALUE;
|
||||
for (StackPointer = (UINTN *) OldCoreData->TopOfCarHeap;
|
||||
((UINTN) StackPointer < ((UINTN) OldCoreData->MaxTopOfCarHeap))
|
||||
for (StackPointer = (UINTN *) OldCoreData->MaxTopOfCarHeap;
|
||||
((UINTN) StackPointer < ((UINTN) OldCoreData->BottomOfCarHeap + OldCoreData->SizeOfCacheAsRam))
|
||||
&& StackValue == INIT_CAR_VALUE;
|
||||
StackPointer++) {
|
||||
StackValue = *StackPointer;
|
||||
|
@ -190,7 +201,7 @@ Returns:
|
|||
|
||||
DEBUG ((EFI_D_INFO, "Total Cache as RAM: %d bytes.\n", OldCoreData->SizeOfCacheAsRam));
|
||||
DEBUG ((EFI_D_INFO, " CAR stack ever used: %d bytes.\n",
|
||||
((UINTN) OldCoreData->MaxTopOfCarHeap - (UINTN) StackPointer)
|
||||
((UINTN) OldCoreData->TopOfCarHeap - (UINTN) StackPointer)
|
||||
));
|
||||
DEBUG ((EFI_D_INFO, " CAR heap used: %d bytes.\n",
|
||||
((UINTN) OldCoreData->HobList.HandoffInformationTable->EfiFreeMemoryBottom -
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
/*++
|
||||
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
Copyright (c) 2006, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
are licensed and made available under the terms and conditions of the BSD License
|
||||
which accompanies this distribution. The full text of the license may be found at
|
||||
http://opensource.org/licenses/bsd-license.php
|
||||
|
||||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
|
@ -50,14 +50,15 @@ Returns:
|
|||
PrivateData->PpiData.DispatchListEnd = MAX_PPI_DESCRIPTORS-1;
|
||||
PrivateData->PpiData.LastDispatchedNotify = MAX_PPI_DESCRIPTORS-1;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
VOID
|
||||
ConvertPpiPointers (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_HOB_HANDOFF_INFO_TABLE *OldHandOffHob,
|
||||
IN UINTN OldCheckingBottom,
|
||||
IN UINTN OldCheckingTop,
|
||||
IN EFI_HOB_HANDOFF_INFO_TABLE *NewHandOffHob
|
||||
)
|
||||
/*++
|
||||
|
@ -68,12 +69,13 @@ Routine Description:
|
|||
|
||||
Arguments:
|
||||
|
||||
PeiServices - The PEI core services table.
|
||||
OldHandOffHob - The old handoff HOB list.
|
||||
NewHandOffHob - The new handoff HOB list.
|
||||
PeiServices - The PEI core services table.
|
||||
OldCheckingBottom - The old checking bottom.
|
||||
OldCheckingTop - The old checking top.
|
||||
NewHandOffHob - The new handoff HOB list.
|
||||
|
||||
Returns:
|
||||
|
||||
|
||||
--*/
|
||||
{
|
||||
PEI_CORE_INSTANCE *PrivateData;
|
||||
|
@ -83,15 +85,15 @@ Returns:
|
|||
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
|
||||
|
||||
Fixup = (UINTN)NewHandOffHob - (UINTN)OldHandOffHob;
|
||||
|
||||
Fixup = (UINTN)NewHandOffHob - OldCheckingBottom;
|
||||
|
||||
for (Index = 0; Index < MAX_PPI_DESCRIPTORS; Index++) {
|
||||
if (Index < PrivateData->PpiData.PpiListEnd ||
|
||||
Index > PrivateData->PpiData.NotifyListEnd) {
|
||||
PpiPointer = &PrivateData->PpiData.PpiListPtrs[Index];
|
||||
|
||||
if (((UINTN)PpiPointer->Raw < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
|
||||
((UINTN)PpiPointer->Raw >= (UINTN)OldHandOffHob)) {
|
||||
|
||||
if (((UINTN)PpiPointer->Raw < OldCheckingTop) &&
|
||||
((UINTN)PpiPointer->Raw >= OldCheckingBottom)) {
|
||||
//
|
||||
// Convert the pointer to the PEIM descriptor from the old HOB heap
|
||||
// to the relocated HOB heap.
|
||||
|
@ -102,9 +104,9 @@ Returns:
|
|||
// Only when the PEIM descriptor is in the old HOB should it be necessary
|
||||
// to try to convert the pointers in the PEIM descriptor
|
||||
//
|
||||
|
||||
if (((UINTN)PpiPointer->Ppi->Guid < (UINTN)OldHandOffHob->EfiFreeMemoryBottom) &&
|
||||
((UINTN)PpiPointer->Ppi->Guid >= (UINTN)OldHandOffHob)) {
|
||||
|
||||
if (((UINTN)PpiPointer->Ppi->Guid < OldCheckingTop) &&
|
||||
((UINTN)PpiPointer->Ppi->Guid >= OldCheckingBottom)) {
|
||||
//
|
||||
// Convert the pointer to the GUID in the PPI or NOTIFY descriptor
|
||||
// from the old HOB heap to the relocated HOB heap.
|
||||
|
@ -117,13 +119,13 @@ Returns:
|
|||
// the notification function in the NOTIFY descriptor needs not be converted.
|
||||
//
|
||||
if (Index < PrivateData->PpiData.PpiListEnd &&
|
||||
(UINTN)PpiPointer->Ppi->Ppi < (UINTN)OldHandOffHob->EfiFreeMemoryBottom &&
|
||||
(UINTN)PpiPointer->Ppi->Ppi >= (UINTN)OldHandOffHob) {
|
||||
(UINTN)PpiPointer->Ppi->Ppi < OldCheckingTop &&
|
||||
(UINTN)PpiPointer->Ppi->Ppi >= OldCheckingBottom) {
|
||||
//
|
||||
// Convert the pointer to the PPI interface structure in the PPI descriptor
|
||||
// from the old HOB heap to the relocated HOB heap.
|
||||
//
|
||||
PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup);
|
||||
PpiPointer->Ppi->Ppi = (VOID *) ((UINTN)PpiPointer->Ppi->Ppi+ Fixup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +179,7 @@ Returns:
|
|||
// by the EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST being set in the last
|
||||
// EFI_PEI_PPI_DESCRIPTOR in the list.
|
||||
//
|
||||
|
||||
|
||||
for (;;) {
|
||||
//
|
||||
// Since PpiData is used for NotifyList and InstallList, max resource
|
||||
|
@ -187,7 +189,7 @@ Returns:
|
|||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
//
|
||||
// Check if it is a valid PPI.
|
||||
// Check if it is a valid PPI.
|
||||
// If not, rollback list to exclude all in this list.
|
||||
// Try to indicate which item failed.
|
||||
//
|
||||
|
@ -197,14 +199,14 @@ Returns:
|
|||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
DEBUG((EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid));
|
||||
PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR*) PpiList;
|
||||
DEBUG((EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid));
|
||||
PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR*) PpiList;
|
||||
PrivateData->PpiData.PpiListEnd++;
|
||||
|
||||
|
||||
//
|
||||
// Continue until the end of the PPI List.
|
||||
//
|
||||
if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
|
||||
if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
|
||||
EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) {
|
||||
break;
|
||||
}
|
||||
|
@ -220,7 +222,7 @@ Returns:
|
|||
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
|
||||
LastCallbackInstall,
|
||||
PrivateData->PpiData.PpiListEnd,
|
||||
PrivateData->PpiData.DispatchListEnd,
|
||||
PrivateData->PpiData.DispatchListEnd,
|
||||
PrivateData->PpiData.NotifyListEnd
|
||||
);
|
||||
|
||||
|
@ -286,7 +288,7 @@ Returns:
|
|||
|
||||
//
|
||||
// Remove the old PPI from the database, add the new one.
|
||||
//
|
||||
//
|
||||
DEBUG((EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid));
|
||||
PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *) NewPpi;
|
||||
|
||||
|
@ -298,7 +300,7 @@ Returns:
|
|||
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK,
|
||||
Index,
|
||||
Index+1,
|
||||
PrivateData->PpiData.DispatchListEnd,
|
||||
PrivateData->PpiData.DispatchListEnd,
|
||||
PrivateData->PpiData.NotifyListEnd
|
||||
);
|
||||
|
||||
|
@ -333,7 +335,7 @@ Arguments:
|
|||
|
||||
Returns:
|
||||
|
||||
Status - EFI_SUCCESS if the PPI is in the database
|
||||
Status - EFI_SUCCESS if the PPI is in the database
|
||||
EFI_NOT_FOUND if the PPI is not in the database
|
||||
--*/
|
||||
{
|
||||
|
@ -342,7 +344,7 @@ Returns:
|
|||
EFI_GUID *CheckGuid;
|
||||
EFI_PEI_PPI_DESCRIPTOR *TempPtr;
|
||||
|
||||
|
||||
|
||||
PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices);
|
||||
|
||||
//
|
||||
|
@ -440,7 +442,7 @@ Returns:
|
|||
if (Index == PrivateData->PpiData.PpiListEnd - 1) {
|
||||
return EFI_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// If some of the PPI data is invalid restore original Notify PPI database value
|
||||
//
|
||||
|
@ -449,13 +451,13 @@ Returns:
|
|||
DEBUG((EFI_D_ERROR, "ERROR -> InstallNotify: %g %x\n", NotifyList->Guid, NotifyList->Notify));
|
||||
return EFI_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
|
||||
if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
|
||||
NotifyDispatchCount ++;
|
||||
}
|
||||
|
||||
PrivateData->PpiData.PpiListPtrs[Index].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *) NotifyList;
|
||||
|
||||
NotifyDispatchCount ++;
|
||||
}
|
||||
|
||||
PrivateData->PpiData.PpiListPtrs[Index].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *) NotifyList;
|
||||
|
||||
PrivateData->PpiData.NotifyListEnd--;
|
||||
DEBUG((EFI_D_INFO, "Register PPI Notify: %g\n", NotifyList->Guid));
|
||||
if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST) ==
|
||||
|
@ -468,26 +470,26 @@ Returns:
|
|||
NotifyList++;
|
||||
Index--;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// If there is Dispatch Notify PPI installed put them on the bottom
|
||||
// If there is Dispatch Notify PPI installed put them on the bottom
|
||||
//
|
||||
if (NotifyDispatchCount > 0) {
|
||||
for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) {
|
||||
for (NotifyIndex = LastCallbackNotify; NotifyIndex > PrivateData->PpiData.NotifyListEnd; NotifyIndex--) {
|
||||
if ((PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) {
|
||||
NotifyPtr = PrivateData->PpiData.PpiListPtrs[NotifyIndex].Notify;
|
||||
|
||||
|
||||
for (Index = NotifyIndex; Index < PrivateData->PpiData.DispatchListEnd; Index++){
|
||||
PrivateData->PpiData.PpiListPtrs[Index].Notify = PrivateData->PpiData.PpiListPtrs[Index + 1].Notify;
|
||||
}
|
||||
PrivateData->PpiData.PpiListPtrs[Index].Notify = NotifyPtr;
|
||||
PrivateData->PpiData.DispatchListEnd--;
|
||||
PrivateData->PpiData.DispatchListEnd--;
|
||||
}
|
||||
}
|
||||
|
||||
LastCallbackNotify -= NotifyDispatchCount;
|
||||
|
||||
LastCallbackNotify -= NotifyDispatchCount;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Dispatch any callback level notifies for all previously installed PPIs.
|
||||
//
|
||||
|
@ -499,8 +501,8 @@ Returns:
|
|||
LastCallbackNotify,
|
||||
PrivateData->PpiData.NotifyListEnd
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -525,13 +527,13 @@ Returns:
|
|||
|
||||
{
|
||||
INTN TempValue;
|
||||
|
||||
|
||||
while (TRUE) {
|
||||
//
|
||||
// Check if the PEIM that was just dispatched resulted in any
|
||||
// Notifies getting installed. If so, go process any dispatch
|
||||
// level Notifies that match the previouly installed PPIs.
|
||||
// Use "while" instead of "if" since DispatchNotify can modify
|
||||
// Use "while" instead of "if" since DispatchNotify can modify
|
||||
// DispatchListEnd (with NotifyPpi) so we have to iterate until the same.
|
||||
//
|
||||
while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) {
|
||||
|
@ -546,13 +548,13 @@ Returns:
|
|||
);
|
||||
PrivateData->PpiData.LastDispatchedNotify = TempValue;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Check if the PEIM that was just dispatched resulted in any
|
||||
// PPIs getting installed. If so, go process any dispatch
|
||||
// level Notifies that match the installed PPIs.
|
||||
// Use "while" instead of "if" since DispatchNotify can modify
|
||||
// Use "while" instead of "if" since DispatchNotify can modify
|
||||
// PpiListEnd (with InstallPpi) so we have to iterate until the same.
|
||||
//
|
||||
while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) {
|
||||
|
@ -567,11 +569,11 @@ Returns:
|
|||
);
|
||||
PrivateData->PpiData.LastDispatchedInstall = TempValue;
|
||||
}
|
||||
|
||||
|
||||
if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -629,8 +631,8 @@ Returns: None
|
|||
(((INT32 *)SearchGuid)[1] == ((INT32 *)CheckGuid)[1]) &&
|
||||
(((INT32 *)SearchGuid)[2] == ((INT32 *)CheckGuid)[2]) &&
|
||||
(((INT32 *)SearchGuid)[3] == ((INT32 *)CheckGuid)[3])) {
|
||||
DEBUG ((EFI_D_INFO, "Notify: PPI Guid: %g, Peim notify entry point: %x\n",
|
||||
SearchGuid,
|
||||
DEBUG ((EFI_D_INFO, "Notify: PPI Guid: %g, Peim notify entry point: %x\n",
|
||||
SearchGuid,
|
||||
NotifyDescriptor->Notify
|
||||
));
|
||||
NotifyDescriptor->Notify (
|
||||
|
|
|
@ -136,6 +136,7 @@
|
|||
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxPeiPerformanceLogEntries|40|UINT8|0x0001002f
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported|6|UINT32|0x00010030
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeimPerFv|32|UINT32|0x00010031
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize|0x20000|UINT32|0x00010032
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableBase|0x0|UINT32|0x30000001
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize|0x0|UINT32|0x30000002
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize|0x400|UINT32|0x30000003
|
||||
|
|
|
@ -239,6 +239,7 @@
|
|||
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported|6
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeimPerFv|32
|
||||
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize|0x20000
|
||||
|
||||
|
||||
[PcdsFixedAtBuild.IPF]
|
||||
|
|
|
@ -69,7 +69,7 @@ GetPeiServicesTablePointer (
|
|||
EFI_STATUS
|
||||
EFIAPI
|
||||
PeiServicesTablePointerLibConstructor (
|
||||
IN EFI_PEI_FILE_HANDLE FileHandle,
|
||||
IN EFI_PEI_FILE_HANDLE *FfsHeader,
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
|
@ -77,17 +77,4 @@ PeiServicesTablePointerLibConstructor (
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
/**
|
||||
After memory initialization in PEI phase, the IDT table in temporary memory should
|
||||
be migrated to memory, and the address of PeiServicesPointer also need to be updated
|
||||
immediately preceding the new IDT table.
|
||||
|
||||
@param PeiServices The address of PeiServices pointer.
|
||||
**/
|
||||
VOID
|
||||
MigrateIdtTable (
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -74,20 +74,9 @@ SetPeiServicesTablePointer (
|
|||
EFI_PEI_SERVICES ** PeiServicesTablePointer
|
||||
)
|
||||
{
|
||||
AsmWriteKr7 ((UINT64)(UINTN)PeiServicesTablePointer);
|
||||
}
|
||||
|
||||
/**
|
||||
After memory initialization in PEI phase, the IDT table in temporary memory should
|
||||
be migrated to memory, and the address of PeiServicesPointer also need to be updated
|
||||
immediately preceding the new IDT table.
|
||||
|
||||
@param PeiServices The address of PeiServices pointer.
|
||||
**/
|
||||
VOID
|
||||
MigrateIdtTable (
|
||||
IN EFI_PEI_SERVICES **PeiServices
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -360,7 +360,7 @@
|
|||
gEfiMdePkgTokenSpaceGuid.PcdStatusCodeValueDxeDriverEnd|0x3040003|UINT32|0x30001014 # EFI_SOFTWARE_DXE_CORE | EFI_SW_PC_INIT_END
|
||||
|
||||
[PcdsFixedAtBuild.IPF]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdIoBlockBaseAddressForIpf|0x0ffffc000000|UINT64|0x0000000f
|
||||
gEfiMdePkgTokenSpaceGuid.PcdIoBlockBaseAddressForIpf|0x0ffffc000000|UINT64|0x0000000f # comments
|
||||
|
||||
[PcdsPatchableInModule.common]
|
||||
gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress|0xE0000000|UINT64|0x0000000a
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
/*++
|
||||
/*! \addtogroup Library EdkGenericBdsLib */
|
||||
/*@{ */
|
||||
/**@file
|
||||
BDS library definition, include the file and data structure
|
||||
|
||||
Copyright (c) 2006 - 2007, Intel Corporation
|
||||
All rights reserved. This program and the accompanying materials
|
||||
|
@ -9,15 +12,7 @@ http://opensource.org/licenses/bsd-license.php
|
|||
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
|
||||
Module Name:
|
||||
|
||||
BdsLib.h
|
||||
|
||||
Abstract:
|
||||
|
||||
BDS library definition, include the file and data structure
|
||||
|
||||
--*/
|
||||
**/
|
||||
|
||||
#ifndef _BDS_LIB_H_
|
||||
#define _BDS_LIB_H_
|
||||
|
@ -110,6 +105,11 @@ BdsLibBootNext (
|
|||
VOID
|
||||
);
|
||||
|
||||
/*!
|
||||
\fn BdsLibBootViaBootOption
|
||||
\param BDS_COMMON_OPTION
|
||||
\param EFI_DEVICE_PATH_PROTOCOL
|
||||
*/
|
||||
EFI_STATUS
|
||||
BdsLibBootViaBootOption (
|
||||
IN BDS_COMMON_OPTION * Option,
|
||||
|
@ -394,3 +394,4 @@ BdsLibGetHiiHandles (
|
|||
);
|
||||
|
||||
#endif // _BDS_LIB_H_
|
||||
/*@} */
|
|
@ -15,6 +15,7 @@
|
|||
#
|
||||
#**/
|
||||
|
||||
|
||||
################################################################################
|
||||
#
|
||||
# Defines Section - statements that will be processed to create a Makefile.
|
||||
|
@ -22,6 +23,7 @@
|
|||
################################################################################
|
||||
|
||||
[Defines]
|
||||
|
||||
DEC_SPECIFICATION = 0x00010005
|
||||
PACKAGE_NAME = Nt32Pkg
|
||||
PACKAGE_GUID = 0fb2aa2d-10d5-40a5-a9dc-060c12a4a3f3
|
||||
|
|
|
@ -247,6 +247,7 @@
|
|||
gEfiMdeModulePkgTokenSpaceGuid.PcdConOutUgaSupport|TRUE
|
||||
|
||||
[PcdsFixedAtBuild.IA32]
|
||||
#gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize|0x20000
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeMemorySize|1
|
||||
gEfiIntelFrameworkModulePkgTokenSpaceGuid.PcdStatusCodeRuntimeMemorySize|128
|
||||
gEfiNt32PkgTokenSpaceGuid.PcdWinNtMemorySizeForSecMain|L"64!64"|VOID*|12
|
||||
|
|
|
@ -162,9 +162,9 @@ INF IntelFrameworkModulePkg/Universal/StatusCode/Pei/PeiStatusCode.inf
|
|||
INF Nt32Pkg/BootModePei/BootModePei.inf
|
||||
INF Nt32Pkg/WinNtFlashMapPei/WinNtFlashMapPei.inf
|
||||
INF MdeModulePkg/Universal/MemoryTest/BaseMemoryTestPei/BaseMemoryTestPei.inf
|
||||
INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
|
||||
INF Nt32Pkg/WinNtAutoScanPei/WinNtAutoScanPei.inf
|
||||
INF Nt32Pkg/WinNtFirmwareVolumePei/WinNtFirmwareVolumePei.inf
|
||||
INF MdeModulePkg/Universal/Variable/Pei/VariablePei.inf
|
||||
INF Nt32Pkg/WinNtThunkPPIToProtocolPei/WinNtThunkPPIToProtocolPei.inf
|
||||
INF MdeModulePkg/Core/DxeIplPeim/DxeIpl.inf
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ EFI_PEI_PROGRESS_CODE_PPI mSecStatusCodePpi = { SecPeiReport
|
|||
|
||||
NT_FWH_PPI mSecFwhInformationPpi = { SecWinNtFdAddress };
|
||||
|
||||
TEMPORARY_RAM_SUPPORT_PPI mSecTemporaryRamSupportPpi = {SecTemporaryRamSupport};
|
||||
|
||||
EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable[] = {
|
||||
{
|
||||
|
@ -85,6 +86,11 @@ EFI_PEI_PPI_DESCRIPTOR gPrivateDispatchTable[] = {
|
|||
&gEfiPeiStatusCodePpiGuid,
|
||||
&mSecStatusCodePpi
|
||||
},
|
||||
{
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI,
|
||||
&gEfiTemporaryRamSupportPpiGuid,
|
||||
&mSecTemporaryRamSupportPpi
|
||||
},
|
||||
{
|
||||
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
|
||||
&gNtFwhPpiGuid,
|
||||
|
@ -116,7 +122,12 @@ UINTN mPdbNameModHandleArraySize = 0;
|
|||
PDB_NAME_TO_MOD_HANDLE *mPdbNameModHandleArray = NULL;
|
||||
|
||||
|
||||
|
||||
VOID
|
||||
EFIAPI
|
||||
SecSwitchStack (
|
||||
UINT32 TemporaryMemoryBase,
|
||||
UINT32 PermenentMemoryBase
|
||||
);
|
||||
|
||||
INTN
|
||||
EFIAPI
|
||||
|
@ -566,18 +577,31 @@ Returns:
|
|||
EFI_PHYSICAL_ADDRESS PeiCoreEntryPoint;
|
||||
EFI_PHYSICAL_ADDRESS PeiImageAddress;
|
||||
EFI_SEC_PEI_HAND_OFF *SecCoreData;
|
||||
UINTN PeiStackSize;
|
||||
|
||||
//
|
||||
// Compute Top Of Memory for Stack and PEI Core Allocations
|
||||
//
|
||||
TopOfMemory = LargestRegion + LargestRegionSize;
|
||||
TopOfMemory = LargestRegion + LargestRegionSize;
|
||||
PeiStackSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1);
|
||||
|
||||
//
|
||||
// Allocate 128KB for the Stack
|
||||
// |-----------| <---- TemporaryRamBase + TemporaryRamSize
|
||||
// | Heap |
|
||||
// | |
|
||||
// |-----------| <---- StackBase / PeiTemporaryMemoryBase
|
||||
// | |
|
||||
// | Stack |
|
||||
// |-----------| <---- TemporaryRamBase
|
||||
//
|
||||
TopOfStack = (VOID *)(LargestRegion + PeiStackSize);
|
||||
TopOfMemory = LargestRegion + PeiStackSize;
|
||||
|
||||
//
|
||||
TopOfStack = (VOID *)((UINTN)TopOfMemory - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT);
|
||||
// Reservet space for storing PeiCore's parament in stack.
|
||||
//
|
||||
TopOfStack = (VOID *)((UINTN)TopOfStack - sizeof (EFI_SEC_PEI_HAND_OFF) - CPU_STACK_ALIGNMENT);
|
||||
TopOfStack = ALIGN_POINTER (TopOfStack, CPU_STACK_ALIGNMENT);
|
||||
TopOfMemory = TopOfMemory - STACK_SIZE;
|
||||
|
||||
//
|
||||
// Patch value in dispatch table values
|
||||
|
@ -591,12 +615,12 @@ Returns:
|
|||
SecCoreData->DataSize = sizeof(EFI_SEC_PEI_HAND_OFF);
|
||||
SecCoreData->BootFirmwareVolumeBase = (VOID*)BootFirmwareVolumeBase;
|
||||
SecCoreData->BootFirmwareVolumeSize = FixedPcdGet32(PcdWinNtFirmwareFdSize);
|
||||
SecCoreData->TemporaryRamBase = (VOID*)(UINTN)TopOfMemory;
|
||||
SecCoreData->TemporaryRamBase = (VOID*)(UINTN)LargestRegion;
|
||||
SecCoreData->TemporaryRamSize = STACK_SIZE;
|
||||
SecCoreData->PeiTemporaryRamBase = SecCoreData->TemporaryRamBase;
|
||||
SecCoreData->PeiTemporaryRamSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1);
|
||||
SecCoreData->StackBase = (VOID*)((UINTN)SecCoreData->TemporaryRamBase + (UINTN)SecCoreData->TemporaryRamSize);
|
||||
SecCoreData->StackSize = (UINTN)RShiftU64((UINT64)STACK_SIZE,1);
|
||||
SecCoreData->StackBase = (VOID*) ((UINTN) SecCoreData->TemporaryRamBase + PeiStackSize);
|
||||
SecCoreData->StackSize = PeiStackSize;
|
||||
SecCoreData->PeiTemporaryRamBase = SecCoreData->StackBase;
|
||||
SecCoreData->PeiTemporaryRamSize = STACK_SIZE - PeiStackSize;
|
||||
|
||||
//
|
||||
// Load the PEI Core from a Firmware Volume
|
||||
|
@ -1209,3 +1233,44 @@ _ModuleEntryPoint (
|
|||
{
|
||||
}
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecTemporaryRamSupport (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
|
||||
IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
|
||||
IN UINTN CopySize
|
||||
)
|
||||
{
|
||||
//
|
||||
// Migrate the whole temporary memory to permenent memory.
|
||||
//
|
||||
CopyMem (
|
||||
(VOID*)(UINTN)PermanentMemoryBase,
|
||||
(VOID*)(UINTN)TemporaryMemoryBase,
|
||||
CopySize
|
||||
);
|
||||
|
||||
//
|
||||
// SecSwitchStack function must be invoked after the memory migration
|
||||
// immediatly, also we need fixup the stack change caused by new call into
|
||||
// permenent memory.
|
||||
//
|
||||
SecSwitchStack (
|
||||
(UINT32) TemporaryMemoryBase,
|
||||
(UINT32) PermanentMemoryBase
|
||||
);
|
||||
|
||||
//
|
||||
// We need *not* fix the return address because currently,
|
||||
// The PeiCore is excuted in flash.
|
||||
//
|
||||
|
||||
//
|
||||
// Simulate to invalid CAR, terminate CAR
|
||||
//
|
||||
//ZeroMem ((VOID*)(UINTN)TemporaryMemoryBase, CopySize);
|
||||
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ Abstract:
|
|||
#include <Ppi/NtThunk.h>
|
||||
#include <Ppi/StatusCode.h>
|
||||
#include <Ppi/NtFwh.h>
|
||||
#include <Ppi/TemporaryRamSupport.h>
|
||||
#include <Library/PcdLib.h>
|
||||
#include <Library/DebugLib.h>
|
||||
#include <Library/PrintLib.h>
|
||||
|
@ -576,6 +577,14 @@ SecNt32PeCoffUnloadimage (
|
|||
IN PE_COFF_LOADER_IMAGE_CONTEXT *ImageContext
|
||||
);
|
||||
|
||||
EFI_STATUS
|
||||
EFIAPI
|
||||
SecTemporaryRamSupport (
|
||||
IN CONST EFI_PEI_SERVICES **PeiServices,
|
||||
IN EFI_PHYSICAL_ADDRESS TemporaryMemoryBase,
|
||||
IN EFI_PHYSICAL_ADDRESS PermanentMemoryBase,
|
||||
IN UINTN CopySize
|
||||
);
|
||||
|
||||
typedef struct {
|
||||
EFI_PEI_PE_COFF_LOADER_PROTOCOL PeCoff;
|
||||
|
|
|
@ -33,6 +33,7 @@
|
|||
WinNtThunk.c
|
||||
FwVol.c
|
||||
SecMain.c
|
||||
Stack.asm
|
||||
|
||||
[Packages]
|
||||
MdePkg/MdePkg.dec
|
||||
|
@ -58,6 +59,7 @@
|
|||
gNtFwhPpiGuid # PPI ALWAYS_PRODUCED
|
||||
gPeiNtAutoScanPpiGuid # PPI ALWAYS_PRODUCED
|
||||
gPeiNtThunkPpiGuid # PPI ALWAYS_PRODUCED
|
||||
gEfiTemporaryRamSupportPpiGuid
|
||||
|
||||
|
||||
[FixedPcd.common]
|
||||
|
@ -69,4 +71,6 @@
|
|||
[BuildOptions.common]
|
||||
MSFT:*_*_IA32_DLINK_FLAGS = /out:"$(BIN_DIR)\SecMain.exe" /base:0x10000000 /pdb:"$(BIN_DIR)\SecMain.pdb" /LIBPATH:"$(VCINSTALLDIR)\Lib" /LIBPATH:"$(VCINSTALLDIR)\PlatformSdk\Lib" /NOLOGO /SUBSYSTEM:CONSOLE /NODEFAULTLIB /IGNORE:4086 /MAP /OPT:REF /DEBUG /MACHINE:I386 /LTCG Kernel32.lib MSVCRTD.lib Gdi32.lib User32.lib Winmm.lib
|
||||
MSFT:*_*_IA32_CC_FLAGS = /nologo /W4 /WX /Gy /c /D UNICODE /Od /FI$(DEST_DIR_DEBUG)/AutoGen.h /EHs-c- /GF /Gs8192 /Zi /Gm /D _CRT_SECURE_NO_WARNINGS /D _CRT_SECURE_NO_DEPRECATE
|
||||
|
||||
MSFT:*_*_IA32_PP_FLAGS = /nologo /E /TC /FI$(DEST_DIR_DEBUG)/AutoGen.h
|
||||
MSFT:*_*_IA32_ASM_FLAGS = /nologo /W3 /WX /c /coff /Cx /Zd /W0 /Zi
|
||||
MSFT:*_*_IA32_ASMLINK_FLAGS = /link /nologo /tiny
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
;------------------------------------------------------------------------------
|
||||
;
|
||||
; Copyright (c) 2007, Intel Corporation
|
||||
; All rights reserved. This program and the accompanying materials
|
||||
; are licensed and made available under the terms and conditions of the BSD License
|
||||
; which accompanies this distribution. The full text of the license may be found at
|
||||
; http://opensource.org/licenses/bsd-license.php
|
||||
;
|
||||
; THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
||||
; WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
||||
;
|
||||
; Module Name:
|
||||
;
|
||||
; Stack.asm
|
||||
;
|
||||
; Abstract:
|
||||
;
|
||||
; Switch the stack from temporary memory to permenent memory.
|
||||
;
|
||||
;------------------------------------------------------------------------------
|
||||
|
||||
.586p
|
||||
.model flat,C
|
||||
.code
|
||||
|
||||
;------------------------------------------------------------------------------
|
||||
; VOID
|
||||
; EFIAPI
|
||||
; SecSwitchStack (
|
||||
; UINT32 TemporaryMemoryBase,
|
||||
; UINT32 PermenentMemoryBase
|
||||
; );
|
||||
;------------------------------------------------------------------------------
|
||||
SecSwitchStack PROC
|
||||
;
|
||||
; Save three register: eax, ebx, ecx
|
||||
;
|
||||
push eax
|
||||
push ebx
|
||||
push ecx
|
||||
push edx
|
||||
|
||||
;
|
||||
; !!CAUTION!! this function address's is pushed into stack after
|
||||
; migration of whole temporary memory, so need save it to permenent
|
||||
; memory at first!
|
||||
;
|
||||
|
||||
mov ebx, [esp + 20] ; Save the first parameter
|
||||
mov ecx, [esp + 24] ; Save the second parameter
|
||||
|
||||
;
|
||||
; Save this function's return address into permenent memory at first.
|
||||
; Then, Fixup the esp point to permenent memory
|
||||
;
|
||||
mov eax, esp
|
||||
sub eax, ebx
|
||||
add eax, ecx
|
||||
mov edx, dword ptr [esp] ; copy pushed register's value to permenent memory
|
||||
mov dword ptr [eax], edx
|
||||
mov edx, dword ptr [esp + 4]
|
||||
mov dword ptr [eax + 4], edx
|
||||
mov edx, dword ptr [esp + 8]
|
||||
mov dword ptr [eax + 8], edx
|
||||
mov edx, dword ptr [esp + 12]
|
||||
mov dword ptr [eax + 12], edx
|
||||
mov edx, dword ptr [esp + 16] ; Update this function's return address into permenent memory
|
||||
mov dword ptr [eax + 16], edx
|
||||
mov esp, eax ; From now, esp is pointed to permenent memory
|
||||
|
||||
;
|
||||
; Fixup the ebp point to permenent memory
|
||||
;
|
||||
mov eax, ebp
|
||||
sub eax, ebx
|
||||
add eax, ecx
|
||||
mov ebp, eax ; From now, ebp is pointed to permenent memory
|
||||
|
||||
;
|
||||
; Fixup callee's ebp point for PeiDispatch
|
||||
;
|
||||
mov eax, dword ptr [ebp]
|
||||
sub eax, ebx
|
||||
add eax, ecx
|
||||
mov dword ptr [ebp], eax ; From now, Temporary's PPI caller's stack is in permenent memory
|
||||
|
||||
pop edx
|
||||
pop ecx
|
||||
pop ebx
|
||||
pop eax
|
||||
ret
|
||||
SecSwitchStack ENDP
|
||||
|
||||
END
|
Loading…
Reference in New Issue