Kun: I add my comments below. > -----邮件原件----- > 发件人: Kun Qin <kuqi...@gmail.com> > 发送时间: 2023年7月21日 5:07 > 收件人: devel@edk2.groups.io > 抄送: Jian J Wang <jian.j.w...@intel.com>; Dandan Bi > <dandan...@intel.com>; Liming Gao <gaolim...@byosoft.com.cn>; > Debkumar De <debkumar...@intel.com>; Catharine West > <catharine.w...@intel.com>; Mike Turner <mik...@pobox.com> > 主题: [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of > delayed dispatch > > REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4496 > > This change adds the implementation that fits the needs and description > of PI spec defined Delayed Dispatch PPI in Pei Core. > > The PPI would allow minimal delay for registered callbacks. As well as > allowing other functions to wait for GUIDed delayed dispatch callbacks. > > Cc: Jian J Wang <jian.j.w...@intel.com> > Cc: Dandan Bi <dandan...@intel.com> > Cc: Liming Gao <gaolim...@byosoft.com.cn> > Cc: Debkumar De <debkumar...@intel.com> > Cc: Catharine West <catharine.w...@intel.com> > > Co-authored-by: Mike Turner <mik...@pobox.com> > Signed-off-by: Kun Qin <kuqi...@gmail.com> > --- > MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 353 > ++++++++++++++++++++ > MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 3 + > MdeModulePkg/Core/Pei/PeiMain.h | 76 +++++ > MdeModulePkg/Core/Pei/PeiMain.inf | 7 + > MdeModulePkg/MdeModulePkg.dec | 15 + > 5 files changed, 454 insertions(+) > > diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > index 5f32ebb560ae..50e59bdbe732 100644 > --- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > +++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c > @@ -3,12 +3,339 @@ > > > Copyright (c) 2006 - 2019, Intel Corporation. All rights reserved.<BR> > > (C) Copyright 2016 Hewlett Packard Enterprise Development LP<BR> > > +Copyright (c) Microsoft Corporation. > > SPDX-License-Identifier: BSD-2-Clause-Patent > > > > **/ > > > > #include "PeiMain.h" > > > > +/** > > + DelayedDispatchDispatcher > > + > > + ayed Dispach cycle (ie one pass) through each entry, calling functions > when their > > + e has expired. When UniqueId is specified, if there are any of the > specified entries > > + the dispatch queue during dispatch, repeat the DelayedDispatch cycle. > > + > [Liming] Above comments are incomplete. Please update.
> + @param DelayedDispatchTable Pointer to dispatch table > > + @param OPTIONAL UniqueId used to insure particular > time is met. > > + > > + @return BOOLEAN > > +**/ > > +BOOLEAN > > +DelayedDispatchDispatcher ( > > + IN DELAYED_DISPATCH_TABLE *DelayedDispatchTable, > > + IN EFI_GUID *UniqueId OPTIONAL > > + ); > > + > > +/** > > + DelayedDispatch End of PEI callback function. Insure that all of the > delayed dispatch > > + entries are complete before exiting PEI. > > + > > + @param[in] PeiServices - Pointer to PEI Services Table. > > + @param[in] NotifyDesc - Pointer to the descriptor for the Notification > event that > > + caused this function to execute. > > + @param[in] Ppi - Pointer to the PPI data associated with this > function. > > + > > + @retval EFI_STATUS - Always return EFI_SUCCESS > > +**/ > > +EFI_STATUS > > +EFIAPI > > +PeiDelayedDispatchOnEndOfPei ( > > + IN EFI_PEI_SERVICES **PeiServices, > > + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, > > + IN VOID *Ppi > > + ); > > + > > +EFI_DELAYED_DISPATCH_PPI mDelayedDispatchPpi = > { PeiDelayedDispatchRegister, PeiDelayedDispatchWaitOnUniqueId }; > > +EFI_PEI_PPI_DESCRIPTOR mDelayedDispatchDesc = { > > + (EFI_PEI_PPI_DESCRIPTOR_PPI | > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), > > + &gEfiPeiDelayedDispatchPpiGuid, > > + &mDelayedDispatchPpi > > +}; > > + > > +EFI_PEI_NOTIFY_DESCRIPTOR mDelayedDispatchNotifyDesc = { > > + EFI_PEI_PPI_DESCRIPTOR_NOTIFY_CALLBACK | > EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST, > > + &gEfiEndOfPeiSignalPpiGuid, > > + PeiDelayedDispatchOnEndOfPei > > +}; > > + > > +/** > > + Helper function to look up DELAYED_DISPATCH_TABLE published in HOB. > > + > > + @return Pointer to DELAYED_DISPATCH_TABLE from HOB > > +**/ > > +DELAYED_DISPATCH_TABLE * > > +GetDelayedDispatchTable ( > > + VOID > > + ) > > +{ > > + EFI_HOB_GUID_TYPE *GuidHob; > > + > > + GuidHob = GetFirstGuidHob (&gEfiDelayedDispatchTableGuid); > > + if (NULL == GuidHob) { > > + DEBUG ((DEBUG_ERROR, "Delayed Dispatch PPI ERROR - Delayed > Dispatch Hob not available.\n")); > > + ASSERT (FALSE); > > + return NULL; > > + } > > + > > + return (DELAYED_DISPATCH_TABLE *)GET_GUID_HOB_DATA (GuidHob); > > +} > > + > > +/** > > +Register a callback to be called after a minimum delay has occurred. > > + > > +This service is the single member function of the > EFI_DELAYED_DISPATCH_PPI > > + > > + @param[in] This Pointer to the EFI_DELAYED_DISPATCH_PPI > instance > > + @param[in] Function Function to call back > > + @param[in] Context Context data > > + @param[in] UniqueId GUID for this Delayed Dispatch request. > > + @param[in] Delay Delay interval > > + > > + @retval EFI_SUCCESS Function successfully loaded > > + @retval EFI_INVALID_PARAMETER One of the Arguments is not > supported > > + @retval EFI_OUT_OF_RESOURCES No more entries > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +PeiDelayedDispatchRegister ( > > + IN EFI_DELAYED_DISPATCH_PPI *This, > > + IN EFI_DELAYED_DISPATCH_FUNCTION Function, > > + IN UINT64 Context, > > + IN EFI_GUID *UniqueId OPTIONAL, > > + IN UINT32 Delay > > + ) > > +{ > > + DELAYED_DISPATCH_TABLE *DelayedDispatchTable; > > + DELAYED_DISPATCH_ENTRY *Entry; > > + > > + // Check input parameters > > + if ((NULL == Function) || (Delay > FixedPcdGet32 > (PcdDelayedDispatchMaxDelayUs)) || (NULL == This)) { > > + DEBUG ((DEBUG_ERROR, "%a Invalid parameter\n", __func__)); > > + return EFI_INVALID_PARAMETER; > > + } > > + > > + // Get delayed dispatch table > > + DelayedDispatchTable = GetDelayedDispatchTable (); > > + if (NULL == DelayedDispatchTable) { > > + DEBUG ((DEBUG_ERROR, "%a Unable to locate dispatch table\n", > __func__)); > > + return EFI_UNSUPPORTED; > > + } > > + > > + // Check for available entry slots > > + if (DelayedDispatchTable->Count >= FixedPcdGet32 > (PcdDelayedDispatchMaxEntries)) { > > + ASSERT (DelayedDispatchTable->Count < FixedPcdGet32 > (PcdDelayedDispatchMaxEntries)); > > + DEBUG ((DEBUG_ERROR, "%a Too many entries requested\n", > __func__)); > > + return EFI_OUT_OF_RESOURCES; > > + } > > + > > + Entry = > &(DelayedDispatchTable->Entry[DelayedDispatchTable->Count]); > > + Entry->Function = Function; > > + Entry->Context = Context; > > + Entry->DispatchTime = GET_TIME_IN_US () + Delay; > > + if (NULL != UniqueId) { > > + CopyGuid (&Entry->UniqueId, UniqueId); > > + } else { > > + ZeroMem (&Entry->UniqueId, sizeof (EFI_GUID)); > > + } > > + > > + Entry->MicrosecondDelay = Delay; > > + DelayedDispatchTable->Count++; > > + > > + DEBUG ((DEBUG_INFO, "%a Adding dispatch Entry\n", __func__)); > > + DEBUG ((DEBUG_INFO, " Requested Delay = %d\n", Delay)); > > + DEBUG ((DEBUG_INFO, " Trigger Time = %d\n", > Entry->DispatchTime)); > > + DEBUG ((DEBUG_INFO, " Context = 0x%08lx\n", Entry->Context)); > > + DEBUG ((DEBUG_INFO, " Function = %p\n", Entry->Function)); > > + DEBUG ((DEBUG_INFO, " GuidHandle = %g\n", &(Entry->UniqueId))); > > + > > + if (0 == Delay) { > > + // Force early dispatch point > > + DelayedDispatchDispatcher (DelayedDispatchTable, NULL); > > + } > > + > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + DelayedDispatchDispatcher > > + > > + ayed Dispach cycle (ie one pass) through each entry, calling functions > when their > > + e has expired. When UniqueId is specified, if there are any of the > specified entries > > + the dispatch queue during dispatch, repeat the DelayedDispatch cycle. > > + > > + @param DelayedDispatchTable Pointer to dispatch table > > + @param OPTIONAL UniqueId used to insure particular > time is met. > > + > > + @return BOOLEAN > > +**/ > > +BOOLEAN > > +DelayedDispatchDispatcher ( > > + IN DELAYED_DISPATCH_TABLE *DelayedDispatchTable, > > + IN EFI_GUID *UniqueId OPTIONAL > > + ) > > +{ > > + BOOLEAN Dispatched; > > + UINT32 TimeCurrent; > > + UINT32 MaxDispatchTime; > > + UINTN Index1; > > + BOOLEAN UniqueIdPresent; > > + DELAYED_DISPATCH_ENTRY *Entry; > > + > > + Dispatched = FALSE; > > + UniqueIdPresent = TRUE; > > + MaxDispatchTime = GET_TIME_IN_US () + FixedPcdGet32 > (PcdDelayedDispatchCompletionTimeoutUs); > > + while ((DelayedDispatchTable->Count > 0) && (UniqueIdPresent)) { > > + UniqueIdPresent = FALSE; > > + DelayedDispatchTable->DispCount++; > > + > > + // If dispatching is messed up, clear DelayedDispatchTable and exit. > > + TimeCurrent = GET_TIME_IN_US (); > > + if (TimeCurrent > MaxDispatchTime) { > > + DEBUG ((DEBUG_ERROR, "%a - DelayedDispatch Completion > timeout!\n", __func__)); > > + ReportStatusCode ((EFI_ERROR_MAJOR | EFI_ERROR_CODE), > (EFI_SOFTWARE_PEI_CORE | EFI_SW_EC_ABORTED)); > > + ASSERT (FALSE); > > + DelayedDispatchTable->Count = 0; > > + break; > > + } > > + > > + // Check each entry in the table for possible dispatch > > + for (Index1 = 0; Index1 < DelayedDispatchTable->Count;) { > > + Entry = &(DelayedDispatchTable->Entry[Index1]); > > + // If UniqueId is present, insure there is an additional check of the > table. > > + if (NULL != UniqueId) { > > + if (CompareGuid (UniqueId, &Entry->UniqueId)) { > > + UniqueIdPresent = TRUE; > > + } > > + } > > + > > + TimeCurrent = GET_TIME_IN_US (); > > + if (TimeCurrent >= Entry->DispatchTime) { > > + // Time expired, invoked the function > > + DEBUG (( > > + DEBUG_ERROR, > > + "Delayed dispatch entry %d @ %p, Target=%d, Act=%d > Disp=%d\n", > > + Index1, > > + Entry->Function, > > + Entry->DispatchTime, > > + TimeCurrent, > > + DelayedDispatchTable->DispCount > > + )); > > + Dispatched = TRUE; > > + Entry->MicrosecondDelay = 0; > > + Entry->Function ( > > + &Entry->Context, > > + &Entry->MicrosecondDelay > > + ); > > + DEBUG ((DEBUG_ERROR, "Delayed dispatch Function returned > delay=%d\n", Entry->MicrosecondDelay)); > > + if (0 == Entry->MicrosecondDelay) { > > + // NewTime = 0 = delete this entry from the table > > + DelayedDispatchTable->Count--; > > + CopyMem (Entry, Entry+1, sizeof (DELAYED_DISPATCH_ENTRY) > * (DelayedDispatchTable->Count - Index1)); > > + } else { > > + if (Entry->MicrosecondDelay > FixedPcdGet32 > (PcdDelayedDispatchMaxDelayUs)) { > > + DEBUG ((DEBUG_ERROR, "%a Illegal new delay %d > requested\n", __func__, Entry->MicrosecondDelay)); > > + ASSERT (FALSE); > > + Entry->MicrosecondDelay = FixedPcdGet32 > (PcdDelayedDispatchMaxDelayUs); > > + } > > + > > + // NewTime != 0 - update the time from us to Dispatch time > > + Entry->DispatchTime = GET_TIME_IN_US () + > Entry->MicrosecondDelay; > > + Index1++; > > + } > > + } else { > > + Index1++; > > + } > > + } > > + } > > + > > + return Dispatched; > > +} > > + > > +/** > > + Wait on a registered Delayed Dispatch unit that has a UniqueId. > Continue > > + to dispatch all registered delayed dispatch entries until *ALL* entries with > > + UniqueId have completed. > > + > > + @param[in] This The Delayed Dispatch PPI pointer. > > + @param[in] UniqueId UniqueId of delayed dispatch entry. > > + > > + @retval EFI_SUCCESS The operation succeeds. > > + @retval EFI_INVALID_PARAMETER The parameters are invalid. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +PeiDelayedDispatchWaitOnUniqueId ( > > + IN EFI_DELAYED_DISPATCH_PPI *This, > > + IN EFI_GUID *UniqueId > > + ) > > +{ > > + PERF_FUNCTION_BEGIN (); > > + DELAYED_DISPATCH_TABLE *DelayedDispatchTable; > > + > > + // Get delayed dispatch table > > + DelayedDispatchTable = GetDelayedDispatchTable (); > > + if (NULL == DelayedDispatchTable) { > > + PERF_FUNCTION_END (); > > + return EFI_UNSUPPORTED; > > + } > > + > > + if ((NULL == UniqueId) || (IsZeroGuid (UniqueId))) { > > + ASSERT (FALSE); > > + PERF_FUNCTION_END (); > > + return EFI_UNSUPPORTED; > > + } > > + > > + DEBUG ((DEBUG_INFO, "Delayed dispatch on %g. Count=%d, > DispatchCount=%d\n", UniqueId, DelayedDispatchTable->Count, > DelayedDispatchTable->DispCount)); > > + PERF_EVENT_SIGNAL_BEGIN (UniqueId); > > + DelayedDispatchDispatcher (DelayedDispatchTable, UniqueId); > > + PERF_EVENT_SIGNAL_END (UniqueId); > > + > > + PERF_FUNCTION_END (); > > + return EFI_SUCCESS; > > +} > > + > > +/** > > + DelayedDispatch End of PEI callback function. Insure that all of the > delayed dispatch > > + entries are complete before exiting PEI. > > + > > + @param[in] PeiServices - Pointer to PEI Services Table. > > + @param[in] NotifyDesc - Pointer to the descriptor for the Notification > event that > > + caused this function to execute. > > + @param[in] Ppi - Pointer to the PPI data associated with this > function. > > + > > + @retval EFI_STATUS - Always return EFI_SUCCESS > > +**/ > > +EFI_STATUS > > +EFIAPI > > +PeiDelayedDispatchOnEndOfPei ( > > + IN EFI_PEI_SERVICES **PeiServices, > > + IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc, > > + IN VOID *Ppi > > + ) > > +{ > > + DELAYED_DISPATCH_TABLE *DelayedDispatchTable; > > + > > + // Get delayed dispatch table > > + DelayedDispatchTable = GetDelayedDispatchTable (); > > + if (NULL == DelayedDispatchTable) { > > + return EFI_UNSUPPORTED; > > + } > > + > > + PERF_INMODULE_BEGIN ("PerfDelayedDispatchEndOfPei"); > > + while (DelayedDispatchTable->Count > 0) { > > + DelayedDispatchDispatcher (DelayedDispatchTable, NULL); > > + } > > + > > + DEBUG ((DEBUG_ERROR, "%a Count of dispatch cycles is %d\n", __func__, > DelayedDispatchTable->DispCount)); > > + PERF_INMODULE_END ("PerfDelayedDispatchEndOfPei"); > > + > > + return EFI_SUCCESS; > > +} > > + > > /** > > > > Discover all PEIMs and optional Apriori file in one FV. There is at most one > > @@ -1365,12 +1692,31 @@ PeiDispatcher ( > EFI_PEI_FILE_HANDLE SaveCurrentFileHandle; > > EFI_FV_FILE_INFO FvFileInfo; > > PEI_CORE_FV_HANDLE *CoreFvHandle; > > + EFI_HOB_GUID_TYPE *GuidHob; > > + UINT32 TableSize; > > > > PeiServices = (CONST EFI_PEI_SERVICES **)&Private->Ps; > > PeimEntryPoint = NULL; > > PeimFileHandle = NULL; > > EntryPoint = 0; > > > > + if (NULL == Private->DelayedDispatchTable) { > > + GuidHob = GetFirstGuidHob (&gEfiDelayedDispatchTableGuid); > > + if (NULL != GuidHob) { > > + Private->DelayedDispatchTable = (DELAYED_DISPATCH_TABLE > *)(GET_GUID_HOB_DATA (GuidHob)); > > + } else { > > + TableSize = sizeof > (DELAYED_DISPATCH_TABLE) + ((FixedPcdGet32 > (PcdDelayedDispatchMaxEntries) - 1) * sizeof (DELAYED_DISPATCH_ENTRY)); > > + Private->DelayedDispatchTable = BuildGuidHob > (&gEfiDelayedDispatchTableGuid, TableSize); > > + if (NULL != Private->DelayedDispatchTable) { > > + ZeroMem (Private->DelayedDispatchTable, TableSize); > > + Status = PeiServicesInstallPpi (&mDelayedDispatchDesc); > > + ASSERT_EFI_ERROR (Status); > > + Status = PeiServicesNotifyPpi (&mDelayedDispatchNotifyDesc); > > + ASSERT_EFI_ERROR (Status); > > + } > > + } > > + } > > + > > if ((Private->PeiMemoryInstalled) && > > (PcdGetBool (PcdMigrateTemporaryRamFirmwareVolumes) || > > (Private->HobList.HandoffInformationTable->BootMode != > BOOT_ON_S3_RESUME) || > > @@ -1621,6 +1967,13 @@ PeiDispatcher ( > } > > } > > } > > + > > + // Dispatch pending delalyed dispatch requests > > + if (NULL != Private->DelayedDispatchTable) { > > + if (DelayedDispatchDispatcher (Private->DelayedDispatchTable, > NULL)) { > > + ProcessDispatchNotifyList (Private); > > + } > > + } > > } > > > > // > > diff --git a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > index bf1719d7941a..e5643adf7027 100644 > --- a/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > +++ b/MdeModulePkg/Core/Pei/PeiMain/PeiMain.c > @@ -277,6 +277,9 @@ PeiCore ( > OldCoreData->TempFileHandles = (EFI_PEI_FILE_HANDLE > *)((UINT8 *)OldCoreData->TempFileHandles - OldCoreData->HeapOffset); > > } > > > > + // Force relocating the dispatch table > > + OldCoreData->DelayedDispatchTable = NULL; > > + > > // > > // Fixup for PeiService's address > > // > > diff --git a/MdeModulePkg/Core/Pei/PeiMain.h > b/MdeModulePkg/Core/Pei/PeiMain.h > index 556beddad533..3b8bbe7f25a1 100644 > --- a/MdeModulePkg/Core/Pei/PeiMain.h > +++ b/MdeModulePkg/Core/Pei/PeiMain.h > @@ -11,6 +11,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > > > #include <PiPei.h> > > #include <Ppi/DxeIpl.h> > > +#include <Ppi/DelayedDispatch.h> > > +#include <Ppi/EndOfPeiPhase.h> > > #include <Ppi/MemoryDiscovered.h> > > #include <Ppi/StatusCode.h> > > #include <Ppi/Reset.h> > > @@ -41,6 +43,7 @@ SPDX-License-Identifier: BSD-2-Clause-Patent > #include <IndustryStandard/PeImage.h> > > #include <Library/PeiServicesTablePointerLib.h> > > #include <Library/MemoryAllocationLib.h> > > +#include <Library/TimerLib.h> > > #include <Guid/FirmwareFileSystem2.h> > > #include <Guid/FirmwareFileSystem3.h> > > #include <Guid/AprioriFileName.h> > > @@ -207,6 +210,29 @@ EFI_STATUS > > > #define PEI_CORE_HANDLE_SIGNATURE SIGNATURE_32('P','e','i','C') > > > > +#define GET_TIME_IN_US() > ((UINT32)DivU64x32(GetTimeInNanoSecond(GetPerformanceCounter ()), > 1000)) > > + > > +// > > +// Internal structure for delayed dispatch entries. > > +// > > +#pragma pack (push, 1) > > + > > +typedef struct { > > + EFI_GUID UniqueId; > > + UINT64 Context; > > + EFI_DELAYED_DISPATCH_FUNCTION Function; > > + UINT32 DispatchTime; > > + UINT32 MicrosecondDelay; > > +} DELAYED_DISPATCH_ENTRY; > > + > > +typedef struct { > > + UINT32 Count; > > + UINT32 DispCount; > > + DELAYED_DISPATCH_ENTRY Entry[1]; // Actual size based on > PCD PcdDelayedDispatchMaxEntries; > > +} DELAYED_DISPATCH_TABLE; > > + > > +#pragma pack (pop) > > + > > /// > > /// Pei Core private data structure instance > > /// > > @@ -307,6 +333,11 @@ struct _PEI_CORE_INSTANCE { > // Those Memory Range will be migrated into physical memory. > > // > > HOLE_MEMORY_DATA > HoleData[HOLE_MAX_NUMBER]; > > + > > + // > > + // Table of delayed dispatch requests > > + // > > + DELAYED_DISPATCH_TABLE *DelayedDispatchTable; > > }; > > > > /// > > @@ -2038,4 +2069,49 @@ PeiReinitializeFv ( > IN PEI_CORE_INSTANCE *PrivateData > > ); > > > > +/** > > +Register a callback to be called after a minimum delay has occurred. > > + > > +This service is the single member function of the > EFI_DELAYED_DISPATCH_PPI > > + > > + @param[in] This Pointer to the EFI_DELAYED_DISPATCH_PPI > instance > > + @param[in] Function Function to call back > > + @param[in] Context Context data > > + @param[in] UniqueId GUID for this Delayed Dispatch request. > > + @param[in] Delay Delay interval > > + > > + @retval EFI_SUCCESS Function successfully loaded > > + @retval EFI_INVALID_PARAMETER One of the Arguments is not > supported > > + @retval EFI_OUT_OF_RESOURCES No more entries > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +PeiDelayedDispatchRegister ( > > + IN EFI_DELAYED_DISPATCH_PPI *This, > > + IN EFI_DELAYED_DISPATCH_FUNCTION Function, > > + IN UINT64 Context, > > + IN EFI_GUID *UniqueId OPTIONAL, > > + IN UINT32 Delay > > + ); > > + > > +/** > > + Wait on a registered Delayed Dispatch unit that has a UniqueId. > Continue > > + to dispatch all registered delayed dispatch entries until *ALL* entries with > > + UniqueId have completed. > > + > > + @param[in] This The Delayed Dispatch PPI pointer. > > + @param[in] UniqueId UniqueId of delayed dispatch entry. > > + > > + @retval EFI_SUCCESS The operation succeeds. > > + @retval EFI_INVALID_PARAMETER The parameters are invalid. > > + > > +**/ > > +EFI_STATUS > > +EFIAPI > > +PeiDelayedDispatchWaitOnUniqueId ( > > + IN EFI_DELAYED_DISPATCH_PPI *This, > > + IN EFI_GUID *UniqueId > > + ); > > + > > #endif > > diff --git a/MdeModulePkg/Core/Pei/PeiMain.inf > b/MdeModulePkg/Core/Pei/PeiMain.inf > index 0cf357371a16..73738c939ac7 100644 > --- a/MdeModulePkg/Core/Pei/PeiMain.inf > +++ b/MdeModulePkg/Core/Pei/PeiMain.inf > @@ -66,6 +66,7 @@ [LibraryClasses] > PeCoffLib > > PeiServicesTablePointerLib > > PcdLib > > + TimerLib > > > > [Guids] > > gPeiAprioriFileNameGuid ## SOMETIMES_CONSUMES ## File > > @@ -78,6 +79,7 @@ [Guids] > gEfiFirmwareFileSystem3Guid > > gStatusCodeCallbackGuid > > gEdkiiMigratedFvInfoGuid ## > SOMETIMES_PRODUCES ## HOB > > + gEfiDelayedDispatchTableGuid ## > SOMETIMES_PRODUCES ## HOB > > > > [Ppis] > > gEfiPeiStatusCodePpiGuid ## > SOMETIMES_CONSUMES # PeiReportStatusService is not ready if this PPI > doesn't exist > > @@ -100,6 +102,8 @@ [Ppis] > gEfiPeiReset2PpiGuid ## > SOMETIMES_CONSUMES > > gEfiSecHobDataPpiGuid ## > SOMETIMES_CONSUMES > > gEfiPeiCoreFvLocationPpiGuid ## > SOMETIMES_CONSUMES > > + gEfiPeiDelayedDispatchPpiGuid ## > SOMETIMES_CONSUMES > [Liming] Here should PRODUCES. > + gEfiEndOfPeiSignalPpiGuid ## CONSUMES > > > > [Pcd] > > gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize > ## CONSUMES > > @@ -112,6 +116,9 @@ [Pcd] > gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnBoot > ## CONSUMES > > gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack > ## CONSUMES > > > gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolu > mes ## CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchMaxDelayUs > ## CONSUMES > > + > gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchCompletionTimeout > Us ## CONSUMES > > + gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchMaxEntries > ## CONSUMES > > > > # [BootMode] > > # S3_RESUME ## SOMETIMES_CONSUMES > > diff --git a/MdeModulePkg/MdeModulePkg.dec > b/MdeModulePkg/MdeModulePkg.dec > index 0ff058b0a9da..2f4bd2f2b773 100644 > --- a/MdeModulePkg/MdeModulePkg.dec > +++ b/MdeModulePkg/MdeModulePkg.dec > @@ -418,6 +418,9 @@ [Guids] > ## Include/Guid/MigratedFvInfo.h > > gEdkiiMigratedFvInfoGuid = { 0xc1ab12f7, 0x74aa, 0x408d, { 0xa2, 0xf4, > 0xc6, 0xce, 0xfd, 0x17, 0x98, 0x71 } } > > > > + ## Delayed Dispatch table GUID > > + gEfiDelayedDispatchTableGuid = { 0x4b733449, 0x8eff, 0x488c, {0x92, > 0x1a, 0x15, 0x4a, 0xda, 0x25, 0x18, 0x07}} > > + [Liming] This GUID is only used in PeiMain. I suggest to define the global GUID variable in PeiCore for this usage. > > # > > # GUID defined in UniversalPayload > > # > > @@ -991,6 +994,18 @@ [PcdsFixedAtBuild] > # @ValidList 0x80000006 | 0x03058002 > > > gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable|0x03058002|U > INT32|0x30001040 > > > > + ## Delayed Dispatch Maximum Delay in us (microseconds) > > + # Maximum delay for any particular delay request - 5 seconds > > + > gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchMaxDelayUs|500000 > 0|UINT32|0x3000104A > > + > > + ## Delayed Dispatch timeout in us (microseconds) > > + # Maximum delay when waiting for completion (ie EndOfPei) - 10 seconds > > + > gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchCompletionTimeout > Us|10000000|UINT32|0x3000104B > > + > > + ## Delayed Dispatch Max Entries > > + # Maximum number of delayed dispatch entries > > + > gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchMaxEntries|8|UINT3 > 2|0x3000104C > > + [Liming] I suggest to define MACRO in PeiCore for them. If there is real usage model, new PCD can be introduced later. Thanks Liming > > ## Mask to control the NULL address detection in code for different > phases. > > # If enabled, accessing NULL address in UEFI or SMM code can be > caught.<BR><BR> > > # BIT0 - Enable NULL pointer detection for UEFI.<BR> > > -- > 2.41.0.windows.2 -=-=-=-=-=-=-=-=-=-=-=- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#107214): https://edk2.groups.io/g/devel/message/107214 Mute This Topic: https://groups.io/mt/100343108/21656 Group Owner: devel+ow...@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-