public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
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]
-=-=-=-=-=-=-=-=-=-=-=-



  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