From: "gaoliming via groups.io" <gaoliming=byosoft.com.cn@groups.io>
To: "'Kun Qin'" <kuqin12@gmail.com>, <devel@edk2.groups.io>
Cc: "'Jian J Wang'" <jian.j.wang@intel.com>,
"'Dandan Bi'" <dandan.bi@intel.com>,
"'Debkumar De'" <debkumar.de@intel.com>,
"'Catharine West'" <catharine.west@intel.com>,
"'Mike Turner'" <mikeyt@pobox.com>
Subject: [edk2-devel] 回复: [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch
Date: Tue, 25 Jul 2023 10:17:16 +0800 [thread overview]
Message-ID: <01b901d9be9e$21a964c0$64fc2e40$@byosoft.com.cn> (raw)
In-Reply-To: <20230720210729.774-4-kuqin12@gmail.com>
Kun:
I add my comments below.
> -----邮件原件-----
> 发件人: Kun Qin <kuqin12@gmail.com>
> 发送时间: 2023年7月21日 5:07
> 收件人: devel@edk2.groups.io
> 抄送: Jian J Wang <jian.j.wang@intel.com>; Dandan Bi
> <dandan.bi@intel.com>; Liming Gao <gaoliming@byosoft.com.cn>;
> Debkumar De <debkumar.de@intel.com>; Catharine West
> <catharine.west@intel.com>; Mike Turner <mikeyt@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.wang@intel.com>
> Cc: Dandan Bi <dandan.bi@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Debkumar De <debkumar.de@intel.com>
> Cc: Catharine West <catharine.west@intel.com>
>
> Co-authored-by: Mike Turner <mikeyt@pobox.com>
> Signed-off-by: Kun Qin <kuqin12@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/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2023-07-25 2:17 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-07-20 21:07 [edk2-devel] [PATCH v1 0/4] Implement Delayed Dispatch per PI v1.8 Kun Qin
2023-07-20 21:07 ` [edk2-devel] [PATCH v1 1/4] MdePkg: DelayedDispatch: Correct PPI descriptions Kun Qin
2023-07-20 21:07 ` [edk2-devel] [PATCH v1 2/4] MdePkg: DelayedDispatch: Added WaitOnEvent interface Kun Qin
2023-07-25 2:13 ` [edk2-devel] 回复: " gaoliming via groups.io
2023-07-20 21:07 ` [edk2-devel] [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch Kun Qin
2023-07-25 2:17 ` gaoliming via groups.io [this message]
2023-08-01 4:15 ` [edk2-devel] 回复: " Kun Qin
2023-08-02 5:15 ` 回复: " gaoliming via groups.io
2023-10-04 14:54 ` Kun Qin
2023-10-07 5:13 ` 回复: " gaoliming via groups.io
2023-10-10 0:21 ` Kun Qin
2023-07-20 21:07 ` [edk2-devel] [PATCH v1 4/4] MdeModulePkg: PeiMain: Updated dispatcher for " Kun Qin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='01b901d9be9e$21a964c0$64fc2e40$@byosoft.com.cn' \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox