From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=192.55.52.115; helo=mga14.intel.com; envelope-from=star.zeng@intel.com; receiver=edk2-devel@lists.01.org Received: from mga14.intel.com (mga14.intel.com [192.55.52.115]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ml01.01.org (Postfix) with ESMTPS id A00632119EBD8 for ; Mon, 17 Dec 2018 22:08:17 -0800 (PST) X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from orsmga005.jf.intel.com ([10.7.209.41]) by fmsmga103.fm.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 17 Dec 2018 22:08:17 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.56,367,1539673200"; d="scan'208";a="284368772" Received: from shwdeopenpsi068.ccr.corp.intel.com ([10.239.158.46]) by orsmga005.jf.intel.com with ESMTP; 17 Dec 2018 22:08:14 -0800 From: Star Zeng To: edk2-devel@lists.01.org Cc: Star Zeng , Jian J Wang , Hao Wu , Liming Gao , Ruiyu Ni , Michael D Kinney , Nate DeSimone , Chasel Chiu Date: Tue, 18 Dec 2018 14:08:03 +0800 Message-Id: <1545113286-49760-5-git-send-email-star.zeng@intel.com> X-Mailer: git-send-email 2.7.0.windows.1 In-Reply-To: <1545113286-49760-1-git-send-email-star.zeng@intel.com> References: <1545113286-49760-1-git-send-email-star.zeng@intel.com> Subject: [PATCH V2 4/7] MdeModulePkg PeiCore: Remove the using of PcdPeiCoreMaxPpiSupported X-BeenThere: edk2-devel@lists.01.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: EDK II Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 18 Dec 2018 06:08:17 -0000 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=1405 Background as below. Problem: As static configuration from the PCDs, the binary PeiCore (for example in FSP binary with dispatch mode) could not predict how many FVs, Files or PPIs for different platforms. Burden: Platform developers need configure the PCDs accordingly for different platforms. To solve the problem and remove the burden, we can update code to remove the using of PcdPeiCoreMaxFvSupported, PcdPeiCoreMaxPeimPerFv and PcdPeiCoreMaxPpiSupported by extending buffer dynamically for FV, File and PPI management. This patch removes the using of PcdPeiCoreMaxPpiSupported in PeiCore. Cc: Jian J Wang Cc: Hao Wu Cc: Liming Gao Cc: Ruiyu Ni Cc: Michael D Kinney Cc: Nate DeSimone Cc: Chasel Chiu Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Star Zeng Reviewed-by: Chasel Chiu --- MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 8 +- MdeModulePkg/Core/Pei/PeiMain.h | 59 +++-- MdeModulePkg/Core/Pei/PeiMain.inf | 1 - MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 30 ++- MdeModulePkg/Core/Pei/Ppi/Ppi.c | 355 ++++++++++++++------------ 5 files changed, 254 insertions(+), 199 deletions(-) diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c index 9692e2f6bf51..68670f43e0b3 100644 --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c +++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c @@ -1036,7 +1036,7 @@ PeiDispatcher ( // Process the Notify list and dispatch any notifies for // newly installed PPIs. // - ProcessNotifyList (Private); + ProcessDispatchNotifyList (Private); } } } @@ -1183,10 +1183,10 @@ PeiDispatcher ( // Process the Notify list and dispatch any notifies for // newly installed PPIs. // - ProcessNotifyList (Private); + ProcessDispatchNotifyList (Private); // - // Recheck SwitchStackSignal after ProcessNotifyList() + // Recheck SwitchStackSignal after ProcessDispatchNotifyList() // in case PeiInstallPeiMemory() is done in a callback with // EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH. // @@ -1227,7 +1227,7 @@ PeiDispatcher ( // Process the Notify list and dispatch any notifies for // newly installed PPIs. // - ProcessNotifyList (Private); + ProcessDispatchNotifyList (Private); } } } diff --git a/MdeModulePkg/Core/Pei/PeiMain.h b/MdeModulePkg/Core/Pei/PeiMain.h index b103215d81f7..322e7cd84524 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.h +++ b/MdeModulePkg/Core/Pei/PeiMain.h @@ -66,37 +66,60 @@ typedef union { } PEI_PPI_LIST_POINTERS; /// -/// PPI database structure which contains two link: PpiList and NotifyList. PpiList -/// is in head of PpiListPtrs array and notify is in end of PpiListPtrs. +/// Number of PEI_PPI_LIST_POINTERS to grow by each time we run out of room /// +#define PPI_GROWTH_STEP 64 +#define CALLBACK_NOTIFY_GROWTH_STEP 32 +#define DISPATCH_NOTIFY_GROWTH_STEP 8 + typedef struct { + UINTN CurrentCount; + UINTN MaxCount; + UINTN LastDispatchedCount; /// - /// index of end of PpiList link list. + /// MaxCount number of entries. /// - INTN PpiListEnd; + PEI_PPI_LIST_POINTERS *PpiPtrs; +} PEI_PPI_LIST; + +typedef struct { + UINTN CurrentCount; + UINTN MaxCount; /// - /// index of end of notify link list. + /// MaxCount number of entries. /// - INTN NotifyListEnd; + PEI_PPI_LIST_POINTERS *NotifyPtrs; +} PEI_CALLBACK_NOTIFY_LIST; + +typedef struct { + UINTN CurrentCount; + UINTN MaxCount; + UINTN LastDispatchedCount; /// - /// index of the dispatched notify list. + /// MaxCount number of entries. /// - INTN DispatchListEnd; + PEI_PPI_LIST_POINTERS *NotifyPtrs; +} PEI_DISPATCH_NOTIFY_LIST; + +/// +/// PPI database structure which contains three links: +/// PpiList, CallbackNotifyList and DispatchNotifyList. +/// +typedef struct { /// - /// index of last installed Ppi description in PpiList link list. + /// PPI List. /// - INTN LastDispatchedInstall; + PEI_PPI_LIST PpiList; /// - /// index of last dispatched notify in Notify link list. + /// Notify List at dispatch level. /// - INTN LastDispatchedNotify; + PEI_CALLBACK_NOTIFY_LIST CallbackNotifyList; /// - /// Ppi database has the PcdPeiCoreMaxPpiSupported number of entries. + /// Notify List at callback level. /// - PEI_PPI_LIST_POINTERS *PpiListPtrs; + PEI_DISPATCH_NOTIFY_LIST DispatchNotifyList; } PEI_PPI_DATABASE; - // // PEI_CORE_FV_HANDE.PeimState // Do not change these values as there is code doing math to change states. @@ -555,13 +578,13 @@ PeiNotifyPpi ( **/ VOID -ProcessNotifyList ( +ProcessDispatchNotifyList ( IN PEI_CORE_INSTANCE *PrivateData ); /** - Dispatch notifications. + Process notifications. @param PrivateData PeiCore's private data structure @param NotifyType Type of notify to fire. @@ -572,7 +595,7 @@ ProcessNotifyList ( **/ VOID -DispatchNotify ( +ProcessNotify ( IN PEI_CORE_INSTANCE *PrivateData, IN UINTN NotifyType, IN INTN InstallStartIndex, diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf b/MdeModulePkg/Core/Pei/PeiMain.inf index dd41fe41bc89..140c4444b107 100644 --- a/MdeModulePkg/Core/Pei/PeiMain.inf +++ b/MdeModulePkg/Core/Pei/PeiMain.inf @@ -104,7 +104,6 @@ [Ppis] gEfiSecHobDataPpiGuid ## SOMETIMES_CONSUMES [Pcd] - gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPpiSupported ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreImageLoaderSearchTeSectionFirst ## CONSUMES gEfiMdeModulePkgTokenSpaceGuid.PcdFrameworkCompatibilitySupport ## CONSUMES diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c index 4869bf18f005..4da80a8222bc 100644 --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c +++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c @@ -190,7 +190,15 @@ PeiCore ( if (OldCoreData->CurrentFvFileHandles != NULL) { OldCoreData->CurrentFvFileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->CurrentFvFileHandles + OldCoreData->HeapOffset); } - OldCoreData->PpiData.PpiListPtrs = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.PpiListPtrs + OldCoreData->HeapOffset); + if (OldCoreData->PpiData.PpiList.PpiPtrs != NULL) { + OldCoreData->PpiData.PpiList.PpiPtrs = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.PpiList.PpiPtrs + OldCoreData->HeapOffset); + } + if (OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs != NULL) { + OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs + OldCoreData->HeapOffset); + } + if (OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs != NULL) { + OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs + OldCoreData->HeapOffset); + } OldCoreData->Fv = (PEI_CORE_FV_HANDLE *) ((UINT8 *) OldCoreData->Fv + OldCoreData->HeapOffset); for (Index = 0; Index < OldCoreData->FvCount; Index ++) { if (OldCoreData->Fv[Index].PeimState != NULL) { @@ -210,7 +218,15 @@ PeiCore ( if (OldCoreData->CurrentFvFileHandles != NULL) { OldCoreData->CurrentFvFileHandles = (EFI_PEI_FILE_HANDLE *) ((UINT8 *) OldCoreData->CurrentFvFileHandles - OldCoreData->HeapOffset); } - OldCoreData->PpiData.PpiListPtrs = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.PpiListPtrs - OldCoreData->HeapOffset); + if (OldCoreData->PpiData.PpiList.PpiPtrs != NULL) { + OldCoreData->PpiData.PpiList.PpiPtrs = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.PpiList.PpiPtrs - OldCoreData->HeapOffset); + } + if (OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs != NULL) { + OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.CallbackNotifyList.NotifyPtrs - OldCoreData->HeapOffset); + } + if (OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs != NULL) { + OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs = (PEI_PPI_LIST_POINTERS *) ((UINT8 *) OldCoreData->PpiData.DispatchNotifyList.NotifyPtrs - OldCoreData->HeapOffset); + } OldCoreData->Fv = (PEI_CORE_FV_HANDLE *) ((UINT8 *) OldCoreData->Fv - OldCoreData->HeapOffset); for (Index = 0; Index < OldCoreData->FvCount; Index ++) { if (OldCoreData->Fv[Index].PeimState != NULL) { @@ -337,14 +353,6 @@ PeiCore ( // Initialize PEI Core Services // InitializeMemoryServices (&PrivateData, SecCoreData, OldCoreData); - if (OldCoreData == NULL) { - // - // Initialize PEI Core Private Data Buffer - // - PrivateData.PpiData.PpiListPtrs = AllocateZeroPool (sizeof (PEI_PPI_LIST_POINTERS) * PcdGet32 (PcdPeiCoreMaxPpiSupported)); - ASSERT (PrivateData.PpiData.PpiListPtrs != NULL); - } - InitializePpiServices (&PrivateData, OldCoreData); // // Update performance measurements @@ -414,7 +422,7 @@ PeiCore ( // // Process the Notify list and dispatch any notifies for the Memory Discovered PPI // - ProcessNotifyList (&PrivateData); + ProcessDispatchNotifyList (&PrivateData); PERF_INMODULE_END ("DisMem"); } diff --git a/MdeModulePkg/Core/Pei/Ppi/Ppi.c b/MdeModulePkg/Core/Pei/Ppi/Ppi.c index 6f03858b8a94..c33dfdf8aa5f 100644 --- a/MdeModulePkg/Core/Pei/Ppi/Ppi.c +++ b/MdeModulePkg/Core/Pei/Ppi/Ppi.c @@ -16,28 +16,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. /** - Initialize PPI services. - - @param PrivateData Pointer to the PEI Core data. - @param OldCoreData Pointer to old PEI Core data. - NULL if being run in non-permament memory mode. - -**/ -VOID -InitializePpiServices ( - IN PEI_CORE_INSTANCE *PrivateData, - IN PEI_CORE_INSTANCE *OldCoreData - ) -{ - if (OldCoreData == NULL) { - PrivateData->PpiData.NotifyListEnd = PcdGet32 (PcdPeiCoreMaxPpiSupported)-1; - PrivateData->PpiData.DispatchListEnd = PcdGet32 (PcdPeiCoreMaxPpiSupported)-1; - PrivateData->PpiData.LastDispatchedNotify = PcdGet32 (PcdPeiCoreMaxPpiSupported)-1; - } -} - -/** - Migrate Pointer from the temporary memory to PEI installed memory. @param Pointer Pointer to the Pointer needs to be converted. @@ -192,14 +170,37 @@ ConvertPpiPointers ( { UINT8 Index; - for (Index = 0; Index < PcdGet32 (PcdPeiCoreMaxPpiSupported); Index++) { - if (Index < PrivateData->PpiData.PpiListEnd || Index > PrivateData->PpiData.NotifyListEnd) { - ConvertSinglePpiPointer ( - SecCoreData, - PrivateData, - &PrivateData->PpiData.PpiListPtrs[Index] - ); - } + // + // Convert normal PPIs. + // + for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) { + ConvertSinglePpiPointer ( + SecCoreData, + PrivateData, + &PrivateData->PpiData.PpiList.PpiPtrs[Index] + ); + } + + // + // Convert Callback Notification PPIs. + // + for (Index = 0; Index < PrivateData->PpiData.CallbackNotifyList.CurrentCount; Index++) { + ConvertSinglePpiPointer ( + SecCoreData, + PrivateData, + &PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index] + ); + } + + // + // Convert Dispatch Notification PPIs. + // + for (Index = 0; Index < PrivateData->PpiData.DispatchNotifyList.CurrentCount; Index++) { + ConvertSinglePpiPointer ( + SecCoreData, + PrivateData, + &PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index] + ); } } @@ -228,10 +229,11 @@ InternalPeiInstallPpi ( IN BOOLEAN Single ) { - PEI_CORE_INSTANCE *PrivateData; - INTN Index; - INTN LastCallbackInstall; - + PEI_CORE_INSTANCE *PrivateData; + PEI_PPI_LIST *PpiListPointer; + UINTN Index; + UINTN LastCount; + VOID *TempPtr; if (PpiList == NULL) { return EFI_INVALID_PARAMETER; @@ -239,8 +241,9 @@ InternalPeiInstallPpi ( PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices); - Index = PrivateData->PpiData.PpiListEnd; - LastCallbackInstall = Index; + PpiListPointer = &PrivateData->PpiData.PpiList; + Index = PpiListPointer->CurrentCount; + LastCount = Index; // // This is loop installs all PPI descriptors in the PpiList. It is terminated @@ -250,27 +253,37 @@ InternalPeiInstallPpi ( for (;;) { // - // Since PpiData is used for NotifyList and PpiList, max resource - // is reached if the Install reaches the NotifyList - // PcdPeiCoreMaxPpiSupported can be set to a larger value in DSC to satisfy more PPI requirement. - // - if (Index == PrivateData->PpiData.NotifyListEnd + 1) { - return EFI_OUT_OF_RESOURCES; - } - // // Check if it is a valid PPI. // If not, rollback list to exclude all in this list. // Try to indicate which item failed. // if ((PpiList->Flags & EFI_PEI_PPI_DESCRIPTOR_PPI) == 0) { - PrivateData->PpiData.PpiListEnd = LastCallbackInstall; + PpiListPointer->CurrentCount = LastCount; DEBUG((EFI_D_ERROR, "ERROR -> InstallPpi: %g %p\n", PpiList->Guid, PpiList->Ppi)); return EFI_INVALID_PARAMETER; } + if (Index >= PpiListPointer->MaxCount) { + // + // Run out of room, grow the buffer. + // + TempPtr = AllocateZeroPool ( + sizeof (PEI_PPI_LIST_POINTERS) * (PpiListPointer->MaxCount + PPI_GROWTH_STEP) + ); + ASSERT (TempPtr != NULL); + CopyMem ( + TempPtr, + PpiListPointer->PpiPtrs, + sizeof (PEI_PPI_LIST_POINTERS) * PpiListPointer->MaxCount + ); + PpiListPointer->PpiPtrs = TempPtr; + PpiListPointer->MaxCount = PpiListPointer->MaxCount + PPI_GROWTH_STEP; + } + DEBUG((EFI_D_INFO, "Install PPI: %g\n", PpiList->Guid)); - PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR*) PpiList; - PrivateData->PpiData.PpiListEnd++; + PpiListPointer->PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *) PpiList; + Index++; + PpiListPointer->CurrentCount++; if (Single) { // @@ -284,23 +297,24 @@ InternalPeiInstallPpi ( // break; } + // + // Go to the next descriptor. + // PpiList++; - Index++; } // - // Dispatch any callback level notifies for newly installed PPIs. + // Process any callback level notifies for newly installed PPIs. // - DispatchNotify ( + ProcessNotify ( PrivateData, EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, - LastCallbackInstall, - PrivateData->PpiData.PpiListEnd, - PrivateData->PpiData.DispatchListEnd, - PrivateData->PpiData.NotifyListEnd + LastCount, + PpiListPointer->CurrentCount, + 0, + PrivateData->PpiData.CallbackNotifyList.CurrentCount ); - return EFI_SUCCESS; } @@ -355,7 +369,7 @@ PeiReInstallPpi ( ) { PEI_CORE_INSTANCE *PrivateData; - INTN Index; + UINTN Index; if ((OldPpi == NULL) || (NewPpi == NULL)) { @@ -372,35 +386,33 @@ PeiReInstallPpi ( // Find the old PPI instance in the database. If we can not find it, // return the EFI_NOT_FOUND error. // - for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) { - if (OldPpi == PrivateData->PpiData.PpiListPtrs[Index].Ppi) { + for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) { + if (OldPpi == PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi) { break; } } - if (Index == PrivateData->PpiData.PpiListEnd) { + if (Index == PrivateData->PpiData.PpiList.CurrentCount) { return EFI_NOT_FOUND; } // - // Remove the old PPI from the database, add the new one. + // Replace the old PPI with the new one. // DEBUG((EFI_D_INFO, "Reinstall PPI: %g\n", NewPpi->Guid)); - ASSERT (Index < (INTN)(PcdGet32 (PcdPeiCoreMaxPpiSupported))); - PrivateData->PpiData.PpiListPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *) NewPpi; + PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi = (EFI_PEI_PPI_DESCRIPTOR *) NewPpi; // - // Dispatch any callback level notifies for the newly installed PPI. + // Process any callback level notifies for the newly installed PPI. // - DispatchNotify ( + ProcessNotify ( PrivateData, EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, Index, Index+1, - PrivateData->PpiData.DispatchListEnd, - PrivateData->PpiData.NotifyListEnd + 0, + PrivateData->PpiData.CallbackNotifyList.CurrentCount ); - return EFI_SUCCESS; } @@ -430,10 +442,10 @@ PeiLocatePpi ( IN OUT VOID **Ppi ) { - PEI_CORE_INSTANCE *PrivateData; - INTN Index; - EFI_GUID *CheckGuid; - EFI_PEI_PPI_DESCRIPTOR *TempPtr; + PEI_CORE_INSTANCE *PrivateData; + UINTN Index; + EFI_GUID *CheckGuid; + EFI_PEI_PPI_DESCRIPTOR *TempPtr; PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices); @@ -441,8 +453,8 @@ PeiLocatePpi ( // // Search the data base for the matching instance of the GUIDed PPI. // - for (Index = 0; Index < PrivateData->PpiData.PpiListEnd; Index++) { - TempPtr = PrivateData->PpiData.PpiListPtrs[Index].Ppi; + for (Index = 0; Index < PrivateData->PpiData.PpiList.CurrentCount; Index++) { + TempPtr = PrivateData->PpiData.PpiList.PpiPtrs[Index].Ppi; CheckGuid = TempPtr->Guid; // @@ -498,15 +510,14 @@ InternalPeiNotifyPpi ( IN BOOLEAN Single ) { - PEI_CORE_INSTANCE *PrivateData; - INTN Index; - INTN NotifyIndex; - INTN LastCallbackNotify; - EFI_PEI_NOTIFY_DESCRIPTOR *NotifyPtr; - UINTN NotifyDispatchCount; - - - NotifyDispatchCount = 0; + PEI_CORE_INSTANCE *PrivateData; + PEI_CALLBACK_NOTIFY_LIST *CallbackNotifyListPointer; + UINTN CallbackNotifyIndex; + UINTN LastCallbackNotifyCount; + PEI_DISPATCH_NOTIFY_LIST *DispatchNotifyListPointer; + UINTN DispatchNotifyIndex; + UINTN LastDispatchNotifyCount; + VOID *TempPtr; if (NotifyList == NULL) { return EFI_INVALID_PARAMETER; @@ -514,8 +525,13 @@ InternalPeiNotifyPpi ( PrivateData = PEI_CORE_INSTANCE_FROM_PS_THIS(PeiServices); - Index = PrivateData->PpiData.NotifyListEnd; - LastCallbackNotify = Index; + CallbackNotifyListPointer = &PrivateData->PpiData.CallbackNotifyList; + CallbackNotifyIndex = CallbackNotifyListPointer->CurrentCount; + LastCallbackNotifyCount = CallbackNotifyIndex; + + DispatchNotifyListPointer = &PrivateData->PpiData.DispatchNotifyList; + DispatchNotifyIndex = DispatchNotifyListPointer->CurrentCount; + LastDispatchNotifyCount = DispatchNotifyIndex; // // This is loop installs all Notify descriptors in the NotifyList. It is @@ -525,31 +541,59 @@ InternalPeiNotifyPpi ( for (;;) { // - // Since PpiData is used for NotifyList and InstallList, max resource - // is reached if the Install reaches the PpiList - // PcdPeiCoreMaxPpiSupported can be set to a larger value in DSC to satisfy more Notify PPIs requirement. - // - 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 // if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_TYPES) == 0) { - PrivateData->PpiData.NotifyListEnd = LastCallbackNotify; - DEBUG((EFI_D_ERROR, "ERROR -> InstallNotify: %g %p\n", NotifyList->Guid, NotifyList->Notify)); + CallbackNotifyListPointer->CurrentCount = LastCallbackNotifyCount; + DispatchNotifyListPointer->CurrentCount = LastDispatchNotifyCount; + DEBUG((DEBUG_ERROR, "ERROR -> NotifyPpi: %g %p\n", NotifyList->Guid, NotifyList->Notify)); return EFI_INVALID_PARAMETER; } - if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH) != 0) { - NotifyDispatchCount ++; + if ((NotifyList->Flags & EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) != 0) { + if (CallbackNotifyIndex >= CallbackNotifyListPointer->MaxCount) { + // + // Run out of room, grow the buffer. + // + TempPtr = AllocateZeroPool ( + sizeof (PEI_PPI_LIST_POINTERS) * (CallbackNotifyListPointer->MaxCount + CALLBACK_NOTIFY_GROWTH_STEP) + ); + ASSERT (TempPtr != NULL); + CopyMem ( + TempPtr, + CallbackNotifyListPointer->NotifyPtrs, + sizeof (PEI_PPI_LIST_POINTERS) * CallbackNotifyListPointer->MaxCount + ); + CallbackNotifyListPointer->NotifyPtrs = TempPtr; + CallbackNotifyListPointer->MaxCount = CallbackNotifyListPointer->MaxCount + CALLBACK_NOTIFY_GROWTH_STEP; + } + CallbackNotifyListPointer->NotifyPtrs[CallbackNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *) NotifyList; + CallbackNotifyIndex++; + CallbackNotifyListPointer->CurrentCount++; + } else { + if (DispatchNotifyIndex >= DispatchNotifyListPointer->MaxCount) { + // + // Run out of room, grow the buffer. + // + TempPtr = AllocateZeroPool ( + sizeof (PEI_PPI_LIST_POINTERS) * (DispatchNotifyListPointer->MaxCount + DISPATCH_NOTIFY_GROWTH_STEP) + ); + ASSERT (TempPtr != NULL); + CopyMem ( + TempPtr, + DispatchNotifyListPointer->NotifyPtrs, + sizeof (PEI_PPI_LIST_POINTERS) * DispatchNotifyListPointer->MaxCount + ); + DispatchNotifyListPointer->NotifyPtrs = TempPtr; + DispatchNotifyListPointer->MaxCount = DispatchNotifyListPointer->MaxCount + DISPATCH_NOTIFY_GROWTH_STEP; + } + DispatchNotifyListPointer->NotifyPtrs[DispatchNotifyIndex].Notify = (EFI_PEI_NOTIFY_DESCRIPTOR *) NotifyList; + DispatchNotifyIndex++; + DispatchNotifyListPointer->CurrentCount++; } - 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 (Single) { // // Only single entry in the NotifyList. @@ -563,41 +607,21 @@ InternalPeiNotifyPpi ( break; } // - // Go the next descriptor. Remember the NotifyList moves down. + // Go to the next descriptor. // NotifyList++; - Index--; - } - - // - // If there is Dispatch Notify PPI installed put them on the bottom - // - if (NotifyDispatchCount > 0) { - 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--; - } - } - - LastCallbackNotify -= NotifyDispatchCount; } // - // Dispatch any callback level notifies for all previously installed PPIs. + // Process any callback level notifies for all previously installed PPIs. // - DispatchNotify ( + ProcessNotify ( PrivateData, EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK, 0, - PrivateData->PpiData.PpiListEnd, - LastCallbackNotify, - PrivateData->PpiData.NotifyListEnd + PrivateData->PpiData.PpiList.CurrentCount, + LastCallbackNotifyCount, + CallbackNotifyListPointer->CurrentCount ); return EFI_SUCCESS; @@ -627,7 +651,6 @@ PeiNotifyPpi ( return InternalPeiNotifyPpi (PeiServices, NotifyList, FALSE); } - /** Process the Notify List at dispatch level. @@ -636,55 +659,56 @@ PeiNotifyPpi ( **/ VOID -ProcessNotifyList ( +ProcessDispatchNotifyList ( IN PEI_CORE_INSTANCE *PrivateData ) { - INTN TempValue; + UINTN 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 - // DispatchListEnd (with NotifyPpi) so we have to iterate until the same. + // Use "while" instead of "if" since ProcessNotify can modify + // DispatchNotifyList.CurrentCount (with NotifyPpi) so we have + // to iterate until the same. // - while (PrivateData->PpiData.LastDispatchedNotify != PrivateData->PpiData.DispatchListEnd) { - TempValue = PrivateData->PpiData.DispatchListEnd; - DispatchNotify ( + while (PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount != PrivateData->PpiData.DispatchNotifyList.CurrentCount) { + TempValue = PrivateData->PpiData.DispatchNotifyList.CurrentCount; + ProcessNotify ( PrivateData, EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH, 0, - PrivateData->PpiData.LastDispatchedInstall, - PrivateData->PpiData.LastDispatchedNotify, - PrivateData->PpiData.DispatchListEnd + PrivateData->PpiData.PpiList.LastDispatchedCount, + PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount, + PrivateData->PpiData.DispatchNotifyList.CurrentCount ); - PrivateData->PpiData.LastDispatchedNotify = TempValue; + PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount = 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 - // PpiListEnd (with InstallPpi) so we have to iterate until the same. + // Use "while" instead of "if" since ProcessNotify can modify + // PpiList.CurrentCount (with InstallPpi) so we have to iterate + // until the same. // - while (PrivateData->PpiData.LastDispatchedInstall != PrivateData->PpiData.PpiListEnd) { - TempValue = PrivateData->PpiData.PpiListEnd; - DispatchNotify ( + while (PrivateData->PpiData.PpiList.LastDispatchedCount != PrivateData->PpiData.PpiList.CurrentCount) { + TempValue = PrivateData->PpiData.PpiList.CurrentCount; + ProcessNotify ( PrivateData, EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH, - PrivateData->PpiData.LastDispatchedInstall, - PrivateData->PpiData.PpiListEnd, - PcdGet32 (PcdPeiCoreMaxPpiSupported)-1, - PrivateData->PpiData.DispatchListEnd + PrivateData->PpiData.PpiList.LastDispatchedCount, + PrivateData->PpiData.PpiList.CurrentCount, + 0, + PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount ); - PrivateData->PpiData.LastDispatchedInstall = TempValue; + PrivateData->PpiData.PpiList.LastDispatchedCount = TempValue; } - if (PrivateData->PpiData.LastDispatchedNotify == PrivateData->PpiData.DispatchListEnd) { + if (PrivateData->PpiData.DispatchNotifyList.LastDispatchedCount == PrivateData->PpiData.DispatchNotifyList.CurrentCount) { break; } } @@ -693,7 +717,7 @@ ProcessNotifyList ( /** - Dispatch notifications. + Process notifications. @param PrivateData PeiCore's private data structure @param NotifyType Type of notify to fire. @@ -704,7 +728,7 @@ ProcessNotifyList ( **/ VOID -DispatchNotify ( +ProcessNotify ( IN PEI_CORE_INSTANCE *PrivateData, IN UINTN NotifyType, IN INTN InstallStartIndex, @@ -713,22 +737,23 @@ DispatchNotify ( IN INTN NotifyStopIndex ) { - INTN Index1; - INTN Index2; - EFI_GUID *SearchGuid; - EFI_GUID *CheckGuid; - EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor; - - // - // Remember that Installs moves up and Notifies moves down. - // - for (Index1 = NotifyStartIndex; Index1 > NotifyStopIndex; Index1--) { - NotifyDescriptor = PrivateData->PpiData.PpiListPtrs[Index1].Notify; + INTN Index1; + INTN Index2; + EFI_GUID *SearchGuid; + EFI_GUID *CheckGuid; + EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDescriptor; + + for (Index1 = NotifyStartIndex; Index1 < NotifyStopIndex; Index1++) { + if (NotifyType == EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK) { + NotifyDescriptor = PrivateData->PpiData.CallbackNotifyList.NotifyPtrs[Index1].Notify; + } else { + NotifyDescriptor = PrivateData->PpiData.DispatchNotifyList.NotifyPtrs[Index1].Notify; + } CheckGuid = NotifyDescriptor->Guid; for (Index2 = InstallStartIndex; Index2 < InstallStopIndex; Index2++) { - SearchGuid = PrivateData->PpiData.PpiListPtrs[Index2].Ppi->Guid; + SearchGuid = PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi->Guid; // // Don't use CompareGuid function here for performance reasons. // Instead we compare the GUID as INT32 at a time and branch @@ -745,7 +770,7 @@ DispatchNotify ( NotifyDescriptor->Notify ( (EFI_PEI_SERVICES **) GetPeiServicesTablePointer (), NotifyDescriptor, - (PrivateData->PpiData.PpiListPtrs[Index2].Ppi)->Ppi + (PrivateData->PpiData.PpiList.PpiPtrs[Index2].Ppi)->Ppi ); } } -- 2.7.0.windows.1