From: "Kun Qin" <kuqin12@gmail.com>
To: devel@edk2.groups.io, gaoliming@byosoft.com.cn
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: Re: 回复: 回复: [edk2-devel] 回复: [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch
Date: Mon, 9 Oct 2023 17:21:35 -0700 [thread overview]
Message-ID: <15fe8a75-26ac-4507-ae64-5f08c2641cd0@gmail.com> (raw)
In-Reply-To: <080201d9f8dd$09132210$1b396630$@byosoft.com.cn>
[-- Attachment #1: Type: text/plain, Size: 42529 bytes --]
Hi Liming,
I updated this patch to use macro definition and incorporated other
changes as you suggested in v2. Could you please review when you have a
chance?
Any input is appreciated.
Regards,
Kun
On 10/6/2023 10:13 PM, gaoliming via groups.io wrote:
>
> Kun:
>
> For this usage, this PCD is not required. We can update the code
> logic to avoid new PCD. You can set the default PPI number for current
> usage. If so, PPI number will not be increased.
>
> Thanks
>
> Liming
>
> *发件人:*devel@edk2.groups.io <devel@edk2.groups.io> *代表 *Kun Qin
> *发送时间:*2023年10月4日22:54
> *收件人:*devel@edk2.groups.io; gaoliming@byosoft.com.cn
> *抄送:*'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>
> *主题:*Re: 回复: [edk2-devel] 回复: [PATCH v1 3/4] MdeModulePkg: PeiMain:
> Introduce implementation of delayed dispatch
>
> Hi Liming,
>
> Sorry for the delayed response on this patch. I went on leave while
> collecting opinions regarding your feedback.
>
> The concern we have for increasing the entry number during boot time
> is that this PPI is designed to be available at pre-mem phase. The
> practical usage would be a small number of platforms just needing an
> additional one or two slots, which we think this is ideal for a build
> time PCD. Could you please let us know how you think?
>
> Thanks,
> Kun
>
> On 8/1/2023 10:15 PM, gaoliming via groups.io wrote:
>
> Kun:
>
> PcdDelayedDispatchMaxEntries is not required. The required Entry
> number can be increased at boot time. You can see MaxFvCount in
> PrivateData that is increased by FV_GROWTH_STEP
>
> Thanks
>
> Liming
>
> *发件人:*devel@edk2.groups.io <devel@edk2.groups.io>
> <mailto:devel@edk2.groups.io> *代表 *Kun Qin
> *发送时间:*2023年8月1日12:16
> *收件人:*devel@edk2.groups.io; gaoliming@byosoft.com.cn
> *抄送:*'Jian J Wang' <jian.j.wang@intel.com>
> <mailto:jian.j.wang@intel.com>; 'Dandan Bi' <dandan.bi@intel.com>
> <mailto:dandan.bi@intel.com>; 'Debkumar De'
> <debkumar.de@intel.com> <mailto:debkumar.de@intel.com>; 'Catharine
> West' <catharine.west@intel.com>
> <mailto:catharine.west@intel.com>; 'Mike Turner'
> <mikeyt@pobox.com> <mailto:mikeyt@pobox.com>
> *主题:*Re: [edk2-devel] 回复: [PATCH v1 3/4] MdeModulePkg: PeiMain:
> Introduce implementation of delayed dispatch
>
> Hi Liming,
>
> Thanks for the feedback.
>
> Per your feedback (I suggest to define MACRO in PeiCore for them.
> If there is real usage model, new PCD can be introduced later.) on
> the following new PCDs:
>
> gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchMaxDelayUs
> gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchCompletionTimeoutUs
> gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchMaxEntries
>
> Given this feature has been used internally at Project MU for a
> while, I
> collected some feedback from the consumer platforms:
>
> - Delayed dispatch is a feature that can be used for power up
> sequence, and
> thus the value of maximum entries in this case can depend on the
> number of PCI
> devices on the platform, and thus hardcoding the value as a macro
> definition will
> limit the usage and we might come to update it very soon.
>
> - There is already usage on our platforms that would override the
> timeout PCDs
> to based on the firmware builds. For example, on a test build, we
> might register extra
> entries to the PPI and thus extend the completion timeout.
>
> I agree with your comments on other fronts. Please let me know if
> you have further
> concerns regarding the PCDs above. I can send out an updated
> version after your input
> on those.
>
> Thanks,
> Kun
>
> On 7/24/2023 7:17 PM, gaoliming via groups.io wrote:
>
> Kun:
>
> I add my comments below.
>
> -----邮件原件-----
>
> 发件人: Kun Qin <kuqin12@gmail.com> <mailto:kuqin12@gmail.com>
>
> 发送时间: 2023年7月21日5:07
>
> 收件人: devel@edk2.groups.io
>
> 抄送: Jian J Wang <jian.j.wang@intel.com>
> <mailto:jian.j.wang@intel.com>; Dandan Bi
>
> <dandan.bi@intel.com> <mailto:dandan.bi@intel.com>; Liming
> Gao <gaoliming@byosoft.com.cn>
> <mailto:gaoliming@byosoft.com.cn>;
>
> Debkumar De <debkumar.de@intel.com>
> <mailto:debkumar.de@intel.com>; Catharine West
>
> <catharine.west@intel.com>
> <mailto:catharine.west@intel.com>; Mike Turner
> <mikeyt@pobox.com> <mailto: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>
> <mailto:jian.j.wang@intel.com>
>
> Cc: Dandan Bi <dandan.bi@intel.com>
> <mailto:dandan.bi@intel.com>
>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> <mailto:gaoliming@byosoft.com.cn>
>
> Cc: Debkumar De <debkumar.de@intel.com>
> <mailto:debkumar.de@intel.com>
>
> Cc: Catharine West <catharine.west@intel.com>
> <mailto:catharine.west@intel.com>
>
> Co-authored-by: Mike Turner <mikeyt@pobox.com>
> <mailto:mikeyt@pobox.com>
>
> Signed-off-by: Kun Qin <kuqin12@gmail.com>
> <mailto: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 (#109471): https://edk2.groups.io/g/devel/message/109471
Mute This Topic: https://groups.io/mt/101812406/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
[-- Attachment #2: Type: text/html, Size: 126114 bytes --]
next prev parent reply other threads:[~2023-10-10 0:21 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 ` [edk2-devel] 回复: " gaoliming via groups.io
2023-08-01 4:15 ` 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 [this message]
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=15fe8a75-26ac-4507-ae64-5f08c2641cd0@gmail.com \
--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