From 58dcdada561c36394c819d3105e867208b84227d Mon Sep 17 00:00:00 2001 From: klu2 Date: Fri, 29 Feb 2008 18:24:43 +0000 Subject: [PATCH] Merge Temporary Ram support patch. git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@4782 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 427 +++++++++++------- MdeModulePkg/Core/Pei/Memory/MemoryServices.c | 134 ++---- MdeModulePkg/Core/Pei/PeiMain.h | 51 ++- MdeModulePkg/Core/Pei/PeiMain.inf | 6 + MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 17 +- MdeModulePkg/Core/Pei/Ppi/Ppi.c | 128 +++--- MdeModulePkg/MdeModulePkg.dec | 1 + MdeModulePkg/MdeModulePkg.dsc | 1 + .../PeiServicesTablePointer.c | 15 +- .../PeiServicesTablePointer.c | 15 +- MdePkg/MdePkg.dec | 2 +- Nt32Pkg/Include/Library/EdkGenericBdsLib.h | 21 +- Nt32Pkg/Nt32Pkg.dec | 2 + Nt32Pkg/Nt32Pkg.dsc | 1 + Nt32Pkg/Nt32Pkg.fdf | 2 +- Nt32Pkg/Sec/SecMain.c | 85 +++- Nt32Pkg/Sec/SecMain.h | 9 + Nt32Pkg/Sec/SecMain.inf | 6 +- Nt32Pkg/Sec/Stack.asm | 94 ++++ 19 files changed, 647 insertions(+), 370 deletions(-) create mode 100644 Nt32Pkg/Sec/Stack.asm diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c index 73a6245b7e..cf9ea5d173 100644 --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c +++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c @@ -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,102 +434,203 @@ 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); + } - // - // Process the Notify list and dispatch any notifies for - // newly installed PPIs. - // - ProcessNotifyList (Private); + // + // 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; + } - // - // If permanent memory was discovered and installed by this - // PEIM, shadow PEI Core and switch the stacks to the new memory. - // - if (Private->SwitchStackSignal) { + // + // Update HandOffHob for new installed permenent memory + // + OldHandOffTable = Private->HobList.HandoffInformationTable; + OldCheckingBottom = (UINTN)OldHandOffTable; + OldCheckingTop = (UINTN)(OldCheckingBottom + SecCoreData->TemporaryRamSize); // - // Make sure we don't retry the same PEIM that added memory + // The whole temporary memory will be migrated to physical memory. + // CAUTION: The new base is computed accounding to gap of new stack. // - Private->CurrentPeimCount++; + 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); // - // Migrate IDT from CAR into real memory, so after stack switches to - // the new memory, the caller can get memory version PeiServiceTable. + // TemporaryRamSupportPpi is produced by platform's SEC // - MigrateIdtTable (PeiServices); + 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 + ); + } + + + // // - // 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. + // Fixup the PeiCore's private data // - PrivateInMem = AllocateCopyPool (sizeof (PEI_CORE_INSTANCE), Private); - ASSERT (PrivateInMem != NULL); + 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 = NULL; + //PeiCoreFileHandle = 0; // // 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); - + //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, PeiCoreFileHandle, &EntryPoint, &AuthenticationState); - ASSERT_EFI_ERROR (Status); - + //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 + ); // - // Switch to memory based stack and reenter PEI Core that has been - // shadowed to memory. + // Process the Notify list and dispatch any notifies for + // newly installed PPIs. // + ProcessNotifyList (PrivateInMem); + // - // Adjust the top of stack to be aligned at CPU_STACK_ALIGNMENT + // Entry PEI Phase 2 // - 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); + PeiCore (SecCoreData, NULL, PrivateInMem); - PeiSwitchStacks ( - InvokePeiCore, - (VOID*) ((UINTN) EntryPoint + ((UINTN) PeiCore - (UINTN) _ModuleEntryPoint)), - (VOID*) &PeiCoreParameters, - TopOfStack, - (VOID*)(UINTN)Private->StackBase - ); + //((PEI_CORE_ENTRY_POINT) (UINTN) PrivateInMem->ShadowedPeiCore) ( + // SecCoreData, + // NULL, + // PrivateInMem + // ); + + // + // Code should not come here + // + ASSERT_EFI_ERROR(FALSE); } + // + // Process the Notify list and dispatch any notifies for + // newly installed PPIs. + // + ProcessNotifyList (Private); + 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; } diff --git a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c index 05e65ce75e..457804fef2 100644 --- a/MdeModulePkg/Core/Pei/Memory/MemoryServices.c +++ b/MdeModulePkg/Core/Pei/Memory/MemoryServices.c @@ -21,6 +21,12 @@ Abstract: #include +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 ); diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h index ef2d592a5e..319bf87711 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.h +++ b/MdeModulePkg/Core/Pei/PeiMain.h @@ -35,6 +35,7 @@ Revision History #include #include #include +#include #include #include #include @@ -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: diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf index 1d2c8fc5df..08d6da475a 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.inf +++ b/MdeModulePkg/Core/Pei/PeiMain.inf @@ -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 diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c index 4e2d9b10aa..a6feaeb91f 100644 --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c +++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c @@ -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 - diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c index 2ee45c44f7..bb358a25d3 100644 --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c +++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c @@ -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 ( diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index dbe872062f..22ce7d5eca 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -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 diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc index 59a6a56dd1..20211ff572 100644 --- a/MdeModulePkg/MdeModulePkg.dsc +++ b/MdeModulePkg/MdeModulePkg.dsc @@ -239,6 +239,7 @@ gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxFvSupported|6 gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeimPerFv|32 + gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize|0x20000 [PcdsFixedAtBuild.IPF] diff --git a/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c b/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c index 21669d717e..21c2009143 100644 --- a/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c +++ b/MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointer.c @@ -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 - ) -{ -} diff --git a/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointer.c b/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointer.c index 961aea9010..3680fbc78a 100644 --- a/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointer.c +++ b/MdePkg/Library/PeiServicesTablePointerLibKr7/PeiServicesTablePointer.c @@ -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 - ) -{ -} + diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec index 0811cd66fb..28aac1dcf6 100644 --- a/MdePkg/MdePkg.dec +++ b/MdePkg/MdePkg.dec @@ -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 diff --git a/Nt32Pkg/Include/Library/EdkGenericBdsLib.h b/Nt32Pkg/Include/Library/EdkGenericBdsLib.h index bc2066fc46..bfdcbe3111 100644 --- a/Nt32Pkg/Include/Library/EdkGenericBdsLib.h +++ b/Nt32Pkg/Include/Library/EdkGenericBdsLib.h @@ -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_ +/*@} */ \ No newline at end of file diff --git a/Nt32Pkg/Nt32Pkg.dec b/Nt32Pkg/Nt32Pkg.dec index f54d7ea733..2d87f2d4f5 100644 --- a/Nt32Pkg/Nt32Pkg.dec +++ b/Nt32Pkg/Nt32Pkg.dec @@ -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 diff --git a/Nt32Pkg/Nt32Pkg.dsc b/Nt32Pkg/Nt32Pkg.dsc index e34191bcc9..2287ae725f 100644 --- a/Nt32Pkg/Nt32Pkg.dsc +++ b/Nt32Pkg/Nt32Pkg.dsc @@ -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 diff --git a/Nt32Pkg/Nt32Pkg.fdf b/Nt32Pkg/Nt32Pkg.fdf index b931f803b8..edd69ad173 100644 --- a/Nt32Pkg/Nt32Pkg.fdf +++ b/Nt32Pkg/Nt32Pkg.fdf @@ -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 diff --git a/Nt32Pkg/Sec/SecMain.c b/Nt32Pkg/Sec/SecMain.c index 4054d61bd0..ccfc6bb3f8 100644 --- a/Nt32Pkg/Sec/SecMain.c +++ b/Nt32Pkg/Sec/SecMain.c @@ -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; +} + diff --git a/Nt32Pkg/Sec/SecMain.h b/Nt32Pkg/Sec/SecMain.h index 7102d5f5fa..1f54fd0dd2 100644 --- a/Nt32Pkg/Sec/SecMain.h +++ b/Nt32Pkg/Sec/SecMain.h @@ -31,6 +31,7 @@ Abstract: #include #include #include +#include #include #include #include @@ -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; diff --git a/Nt32Pkg/Sec/SecMain.inf b/Nt32Pkg/Sec/SecMain.inf index 20e4726465..95cd30e2ea 100644 --- a/Nt32Pkg/Sec/SecMain.inf +++ b/Nt32Pkg/Sec/SecMain.inf @@ -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 diff --git a/Nt32Pkg/Sec/Stack.asm b/Nt32Pkg/Sec/Stack.asm new file mode 100644 index 0000000000..ca6b7faaaa --- /dev/null +++ b/Nt32Pkg/Sec/Stack.asm @@ -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 -- 2.39.2