* [edk2-devel] [PATCH v1 0/4] Implement Delayed Dispatch per PI v1.8
@ 2023-07-20 21:07 Kun Qin
2023-07-20 21:07 ` [edk2-devel] [PATCH v1 1/4] MdePkg: DelayedDispatch: Correct PPI descriptions Kun Qin
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Kun Qin @ 2023-07-20 21:07 UTC (permalink / raw)
To: devel
Cc: Michael D Kinney, Liming Gao, Zhiguang Liu, Jian J Wang,
Dandan Bi, Debkumar De, Catharine West
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4496
PI spec v1.8 has introduced some corrections and a new interface for
delayed dispatch for the PPI.
This patch series has ported the implementation from Project MU.
Patch branch: https://github.com/kuqin12/edk2/tree/Delayed_Dispatch_V2
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Dandan Bi <dandan.bi@intel.com>
Cc: Debkumar De <debkumar.de@intel.com>
Cc: Catharine West <catharine.west@intel.com>
Kun Qin (4):
MdePkg: DelayedDispatch: Correct PPI descriptions
MdePkg: DelayedDispatch: Added WaitOnEvent interface
MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch
MdeModulePkg: PeiMain: Updated dispatcher for delayed dispatch
MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c | 358 +++++++++++++++++++-
MdeModulePkg/Core/Pei/PeiMain/PeiMain.c | 3 +
MdeModulePkg/Core/Pei/PeiMain.h | 76 +++++
MdeModulePkg/Core/Pei/PeiMain.inf | 7 +
MdeModulePkg/MdeModulePkg.dec | 15 +
MdePkg/Include/Ppi/DelayedDispatch.h | 39 ++-
6 files changed, 489 insertions(+), 9 deletions(-)
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107111): https://edk2.groups.io/g/devel/message/107111
Mute This Topic: https://groups.io/mt/100264775/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 12+ messages in thread
* [edk2-devel] [PATCH v1 1/4] MdePkg: DelayedDispatch: Correct PPI descriptions
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 ` Kun Qin
2023-07-20 21:07 ` [edk2-devel] [PATCH v1 2/4] MdePkg: DelayedDispatch: Added WaitOnEvent interface Kun Qin
` (2 subsequent siblings)
3 siblings, 0 replies; 12+ messages in thread
From: Kun Qin @ 2023-07-20 21:07 UTC (permalink / raw)
To: devel; +Cc: Michael D Kinney, Liming Gao, Zhiguang Liu, Mike Turner
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4496
PI spec defined the `Register` function input argument `Delay` as output.
However, this parameter should be used to define the minmal time delay
the callback should fire. Thus it should be an input parameter.
This change fixed the argument type.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Co-authored-by: Mike Turner <mikeyt@pobox.com>
Signed-off-by: Kun Qin <kuqin12@gmail.com>
---
MdePkg/Include/Ppi/DelayedDispatch.h | 15 ++++++++-------
1 file changed, 8 insertions(+), 7 deletions(-)
diff --git a/MdePkg/Include/Ppi/DelayedDispatch.h b/MdePkg/Include/Ppi/DelayedDispatch.h
index f9b4fed30fb0..098d57758551 100644
--- a/MdePkg/Include/Ppi/DelayedDispatch.h
+++ b/MdePkg/Include/Ppi/DelayedDispatch.h
@@ -4,6 +4,7 @@
Provide timed event service in PEI
Copyright (c) 2020, American Megatrends International LLC. All rights reserved.
+ Copyright (c) Microsoft Corporation.
SPDX-License-Identifier: BSD-2-Clause-Patent
**/
@@ -15,7 +16,7 @@
///
#define EFI_DELAYED_DISPATCH_PPI_GUID \
{ \
- 0x869c711d, 0x649c, 0x44fe, { 0x8b, 0x9e, 0x2c, 0xbb, 0x29, 0x11, 0xc3, 0xe6} } \
+ 0x869c711d, 0x649c, 0x44fe, { 0x8b, 0x9e, 0x2c, 0xbb, 0x29, 0x11, 0xc3, 0xe6} \
}
/**
@@ -46,10 +47,10 @@ 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 This Pointer to the EFI_DELAYED_DISPATCH_PPI instance
- @param Function Function to call back
- @param Context Context data
- @param Delay Delay interval
+ @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] Delay Delay interval
@retval EFI_SUCCESS Function successfully loaded
@retval EFI_INVALID_PARAMETER One of the Arguments is not supported
@@ -61,8 +62,8 @@ EFI_STATUS
(EFIAPI *EFI_DELAYED_DISPATCH_REGISTER)(
IN EFI_DELAYED_DISPATCH_PPI *This,
IN EFI_DELAYED_DISPATCH_FUNCTION Function,
- IN UINT64 Context,
- OUT UINT32 Delay
+ IN UINT64 Context,
+ IN UINT32 Delay
);
///
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107112): https://edk2.groups.io/g/devel/message/107112
Mute This Topic: https://groups.io/mt/100264776/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [edk2-devel] [PATCH v1 2/4] MdePkg: DelayedDispatch: Added WaitOnEvent interface
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 ` 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-20 21:07 ` [edk2-devel] [PATCH v1 4/4] MdeModulePkg: PeiMain: Updated dispatcher for " Kun Qin
3 siblings, 1 reply; 12+ messages in thread
From: Kun Qin @ 2023-07-20 21:07 UTC (permalink / raw)
To: devel; +Cc: Michael D Kinney, Liming Gao, Zhiguang Liu, Mike Turner
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4496
This change adds a new interface for the delayed dispatch PPI. This
new addition allows functional components relying on delayed dispatch
callbacks to be managed/dispatched with definitive order.
The full defintion has been added into PI spec.
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Zhiguang Liu <zhiguang.liu@intel.com>
Co-authored-by: Mike Turner <mikeyt@pobox.com>
Signed-off-by: Kun Qin <kuqin12@gmail.com>
---
MdePkg/Include/Ppi/DelayedDispatch.h | 24 +++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/MdePkg/Include/Ppi/DelayedDispatch.h b/MdePkg/Include/Ppi/DelayedDispatch.h
index 098d57758551..253cafd46d28 100644
--- a/MdePkg/Include/Ppi/DelayedDispatch.h
+++ b/MdePkg/Include/Ppi/DelayedDispatch.h
@@ -50,6 +50,7 @@ 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
@@ -63,9 +64,29 @@ EFI_STATUS
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.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_DELAYED_DISPATCH_WAIT_ON_EVENT)(
+ IN EFI_DELAYED_DISPATCH_PPI *This,
+ IN EFI_GUID *UniqueId
+ );
+
///
/// This PPI is a pointer to the Delayed Dispatch Service.
/// This service will be published by the Pei Foundation. The PEI Foundation
@@ -73,7 +94,8 @@ EFI_STATUS
/// execution.
///
struct _EFI_DELAYED_DISPATCH_PPI {
- EFI_DELAYED_DISPATCH_REGISTER Register;
+ EFI_DELAYED_DISPATCH_REGISTER Register;
+ EFI_DELAYED_DISPATCH_WAIT_ON_EVENT WaitOnEvent;
};
extern EFI_GUID gEfiPeiDelayedDispatchPpiGuid;
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107113): https://edk2.groups.io/g/devel/message/107113
Mute This Topic: https://groups.io/mt/100264777/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [edk2-devel] [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch
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-20 21:07 ` Kun Qin
2023-07-25 2:17 ` [edk2-devel] 回复: " gaoliming via groups.io
2023-07-20 21:07 ` [edk2-devel] [PATCH v1 4/4] MdeModulePkg: PeiMain: Updated dispatcher for " Kun Qin
3 siblings, 1 reply; 12+ messages in thread
From: Kun Qin @ 2023-07-20 21:07 UTC (permalink / raw)
To: devel
Cc: Jian J Wang, Dandan Bi, Liming Gao, Debkumar De, Catharine West,
Mike Turner
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.
+
+ @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
+ gEfiEndOfPeiSignalPpiGuid ## CONSUMES
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdPeiCoreMaxPeiStackSize ## CONSUMES
@@ -112,6 +116,9 @@ [Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdShadowPeimOnBoot ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdInitValueInTempStack ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMigrateTemporaryRamFirmwareVolumes ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchMaxDelayUs ## CONSUMES
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchCompletionTimeoutUs ## 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}}
+
#
# GUID defined in UniversalPayload
#
@@ -991,6 +994,18 @@ [PcdsFixedAtBuild]
# @ValidList 0x80000006 | 0x03058002
gEfiMdeModulePkgTokenSpaceGuid.PcdErrorCodeSetVariable|0x03058002|UINT32|0x30001040
+ ## Delayed Dispatch Maximum Delay in us (microseconds)
+ # Maximum delay for any particular delay request - 5 seconds
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchMaxDelayUs|5000000|UINT32|0x3000104A
+
+ ## Delayed Dispatch timeout in us (microseconds)
+ # Maximum delay when waiting for completion (ie EndOfPei) - 10 seconds
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchCompletionTimeoutUs|10000000|UINT32|0x3000104B
+
+ ## Delayed Dispatch Max Entries
+ # Maximum number of delayed dispatch entries
+ gEfiMdeModulePkgTokenSpaceGuid.PcdDelayedDispatchMaxEntries|8|UINT32|0x3000104C
+
## 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 (#107114): https://edk2.groups.io/g/devel/message/107114
Mute This Topic: https://groups.io/mt/100264778/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [edk2-devel] [PATCH v1 4/4] MdeModulePkg: PeiMain: Updated dispatcher for delayed dispatch
2023-07-20 21:07 [edk2-devel] [PATCH v1 0/4] Implement Delayed Dispatch per PI v1.8 Kun Qin
` (2 preceding siblings ...)
2023-07-20 21:07 ` [edk2-devel] [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch Kun Qin
@ 2023-07-20 21:07 ` Kun Qin
3 siblings, 0 replies; 12+ messages in thread
From: Kun Qin @ 2023-07-20 21:07 UTC (permalink / raw)
To: devel
Cc: Jian J Wang, Liming Gao, Dandan Bi, Debkumar De, Catharine West,
Mike Turner
REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4496
This change adds a check for PEI dispatcher to continue dispatching when
there are still pending delayed dispatch requests, to be compatible with
newly integrated Delayed Dispatcher PPI interface.
Cc: Jian J Wang <jian.j.wang@intel.com>
Cc: Liming Gao <gaoliming@byosoft.com.cn>
Cc: Dandan Bi <dandan.bi@intel.com>
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 | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
index 50e59bdbe732..6eb807500e5e 100644
--- a/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
+++ b/MdeModulePkg/Core/Pei/Dispatcher/Dispatcher.c
@@ -2000,7 +2000,10 @@ PeiDispatcher (
// pass. If we did not dispatch a PEIM/FV there is no point in trying again
// as it will fail the next time too (nothing has changed).
//
- } while (Private->PeimNeedingDispatch && Private->PeimDispatchOnThisPass);
+ // Also continue dispatch loop if there are outstanding delay-
+ // dispatch registrations still running.
+ } while ((Private->PeimNeedingDispatch && Private->PeimDispatchOnThisPass) ||
+ (Private->DelayedDispatchTable->Count > 0));
}
/**
--
2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107115): https://edk2.groups.io/g/devel/message/107115
Mute This Topic: https://groups.io/mt/100264779/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [edk2-devel] 回复: [PATCH v1 2/4] MdePkg: DelayedDispatch: Added WaitOnEvent interface
2023-07-20 21:07 ` [edk2-devel] [PATCH v1 2/4] MdePkg: DelayedDispatch: Added WaitOnEvent interface Kun Qin
@ 2023-07-25 2:13 ` gaoliming via groups.io
0 siblings, 0 replies; 12+ messages in thread
From: gaoliming via groups.io @ 2023-07-25 2:13 UTC (permalink / raw)
To: 'Kun Qin', devel
Cc: 'Michael D Kinney', 'Zhiguang Liu',
'Mike Turner'
Kun:
This change is introduced in PI spec 1.8. Please update DelayedDispatch.h
file header with correct PI version.
Thanks
Liming
> -----邮件原件-----
> 发件人: Kun Qin <kuqin12@gmail.com>
> 发送时间: 2023年7月21日 5:07
> 收件人: devel@edk2.groups.io
> 抄送: Michael D Kinney <michael.d.kinney@intel.com>; Liming Gao
> <gaoliming@byosoft.com.cn>; Zhiguang Liu <zhiguang.liu@intel.com>; Mike
> Turner <mikeyt@pobox.com>
> 主题: [PATCH v1 2/4] MdePkg: DelayedDispatch: Added WaitOnEvent
> interface
>
> REF: https://bugzilla.tianocore.org/show_bug.cgi?id=4496
>
> This change adds a new interface for the delayed dispatch PPI. This
> new addition allows functional components relying on delayed dispatch
> callbacks to be managed/dispatched with definitive order.
>
> The full defintion has been added into PI spec.
>
> Cc: Michael D Kinney <michael.d.kinney@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Cc: Zhiguang Liu <zhiguang.liu@intel.com>
>
> Co-authored-by: Mike Turner <mikeyt@pobox.com>
> Signed-off-by: Kun Qin <kuqin12@gmail.com>
> ---
> MdePkg/Include/Ppi/DelayedDispatch.h | 24 +++++++++++++++++++-
> 1 file changed, 23 insertions(+), 1 deletion(-)
>
> diff --git a/MdePkg/Include/Ppi/DelayedDispatch.h
> b/MdePkg/Include/Ppi/DelayedDispatch.h
> index 098d57758551..253cafd46d28 100644
> --- a/MdePkg/Include/Ppi/DelayedDispatch.h
> +++ b/MdePkg/Include/Ppi/DelayedDispatch.h
> @@ -50,6 +50,7 @@ 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
>
> @@ -63,9 +64,29 @@ EFI_STATUS
> 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.
>
> +
>
> +**/
>
> +typedef
>
> +EFI_STATUS
>
> +(EFIAPI *EFI_DELAYED_DISPATCH_WAIT_ON_EVENT)(
>
> + IN EFI_DELAYED_DISPATCH_PPI *This,
>
> + IN EFI_GUID *UniqueId
>
> + );
>
> +
>
> ///
>
> /// This PPI is a pointer to the Delayed Dispatch Service.
>
> /// This service will be published by the Pei Foundation. The PEI
Foundation
>
> @@ -73,7 +94,8 @@ EFI_STATUS
> /// execution.
>
> ///
>
> struct _EFI_DELAYED_DISPATCH_PPI {
>
> - EFI_DELAYED_DISPATCH_REGISTER Register;
>
> + EFI_DELAYED_DISPATCH_REGISTER Register;
>
> + EFI_DELAYED_DISPATCH_WAIT_ON_EVENT WaitOnEvent;
>
> };
>
>
>
> extern EFI_GUID gEfiPeiDelayedDispatchPpiGuid;
>
> --
> 2.41.0.windows.2
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#107213): https://edk2.groups.io/g/devel/message/107213
Mute This Topic: https://groups.io/mt/100343032/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 12+ messages in thread
* [edk2-devel] 回复: [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch
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
2023-08-01 4:15 ` Kun Qin
0 siblings, 1 reply; 12+ messages in thread
From: gaoliming via groups.io @ 2023-07-25 2:17 UTC (permalink / raw)
To: 'Kun Qin', devel
Cc: 'Jian J Wang', 'Dandan Bi', 'Debkumar De',
'Catharine West', 'Mike Turner'
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]
-=-=-=-=-=-=-=-=-=-=-=-
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [edk2-devel] 回复: [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch
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
0 siblings, 1 reply; 12+ messages in thread
From: Kun Qin @ 2023-08-01 4:15 UTC (permalink / raw)
To: devel, gaoliming
Cc: 'Jian J Wang', 'Dandan Bi', 'Debkumar De',
'Catharine West', 'Mike Turner'
[-- Attachment #1: Type: text/plain, Size: 28612 bytes --]
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>
>> 发送时间: 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 (#107417): https://edk2.groups.io/g/devel/message/107417
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]
-=-=-=-=-=-=-=-=-=-=-=-
[-- Attachment #2: Type: text/html, Size: 30145 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* 回复: [edk2-devel] 回复: [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch
2023-08-01 4:15 ` Kun Qin
@ 2023-08-02 5:15 ` gaoliming via groups.io
2023-10-04 14:54 ` Kun Qin
0 siblings, 1 reply; 12+ messages in thread
From: gaoliming via groups.io @ 2023-08-02 5:15 UTC (permalink / raw)
To: devel, kuqin12
Cc: 'Jian J Wang', 'Dandan Bi', 'Debkumar De',
'Catharine West', 'Mike Turner'
[-- Attachment #1: Type: text/plain, Size: 28441 bytes --]
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> 代表 Kun Qin
发送时间: 2023年8月1日 12:16
收件人: 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,
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 <mailto:kuqin12@gmail.com> <kuqin12@gmail.com>
发送时间: 2023年7月21日 5:07
收件人: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
抄送: Jian J Wang <mailto:jian.j.wang@intel.com> <jian.j.wang@intel.com>; Dandan Bi
<mailto:dandan.bi@intel.com> <dandan.bi@intel.com>; Liming Gao <mailto:gaoliming@byosoft.com.cn> <gaoliming@byosoft.com.cn>;
Debkumar De <mailto:debkumar.de@intel.com> <debkumar.de@intel.com>; Catharine West
<mailto:catharine.west@intel.com> <catharine.west@intel.com>; Mike Turner <mailto:mikeyt@pobox.com> <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 <mailto:jian.j.wang@intel.com> <jian.j.wang@intel.com>
Cc: Dandan Bi <mailto:dandan.bi@intel.com> <dandan.bi@intel.com>
Cc: Liming Gao <mailto:gaoliming@byosoft.com.cn> <gaoliming@byosoft.com.cn>
Cc: Debkumar De <mailto:debkumar.de@intel.com> <debkumar.de@intel.com>
Cc: Catharine West <mailto:catharine.west@intel.com> <catharine.west@intel.com>
Co-authored-by: Mike Turner <mailto:mikeyt@pobox.com> <mikeyt@pobox.com>
Signed-off-by: Kun Qin <mailto:kuqin12@gmail.com> <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 (#107447): https://edk2.groups.io/g/devel/message/107447
Mute This Topic: https://groups.io/mt/100499790/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: 98091 bytes --]
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: 回复: [edk2-devel] 回复: [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch
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
0 siblings, 1 reply; 12+ messages in thread
From: Kun Qin @ 2023-10-04 14:54 UTC (permalink / raw)
To: devel, gaoliming
Cc: 'Jian J Wang', 'Dandan Bi', 'Debkumar De',
'Catharine West', 'Mike Turner'
[-- Attachment #1: Type: text/plain, Size: 37646 bytes --]
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> *代表 *Kun Qin
> *发送时间:*2023年8月1日12:16
> *收件人:*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,
>
> 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 (#109321): https://edk2.groups.io/g/devel/message/109321
Mute This Topic: https://groups.io/mt/100499790/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: 118238 bytes --]
^ permalink raw reply [flat|nested] 12+ messages in thread
* 回复: 回复: [edk2-devel] 回复: [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch
2023-10-04 14:54 ` Kun Qin
@ 2023-10-07 5:13 ` gaoliming via groups.io
2023-10-10 0:21 ` Kun Qin
0 siblings, 1 reply; 12+ messages in thread
From: gaoliming via groups.io @ 2023-10-07 5:13 UTC (permalink / raw)
To: devel, kuqin12
Cc: 'Jian J Wang', 'Dandan Bi', 'Debkumar De',
'Catharine West', 'Mike Turner'
[-- Attachment #1: Type: text/plain, Size: 29981 bytes --]
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 <mailto:devel@edk2.groups.io> <mailto:devel@edk2.groups.io> <devel@edk2.groups.io> 代表 Kun Qin
发送时间: 2023年8月1日 12:16
收件人: devel@edk2.groups.io <mailto:devel@edk2.groups.io> ; gaoliming@byosoft.com.cn <mailto:gaoliming@byosoft.com.cn>
抄送: 'Jian J Wang' <mailto:jian.j.wang@intel.com> <jian.j.wang@intel.com>; 'Dandan Bi' <mailto:dandan.bi@intel.com> <dandan.bi@intel.com>; 'Debkumar De' <mailto:debkumar.de@intel.com> <debkumar.de@intel.com>; 'Catharine West' <mailto:catharine.west@intel.com> <catharine.west@intel.com>; 'Mike Turner' <mailto:mikeyt@pobox.com> <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 <mailto:kuqin12@gmail.com> <kuqin12@gmail.com>
发送时间: 2023年7月21日 5:07
收件人: devel@edk2.groups.io <mailto:devel@edk2.groups.io>
抄送: Jian J Wang <mailto:jian.j.wang@intel.com> <jian.j.wang@intel.com>; Dandan Bi
<mailto:dandan.bi@intel.com> <dandan.bi@intel.com>; Liming Gao <mailto:gaoliming@byosoft.com.cn> <gaoliming@byosoft.com.cn>;
Debkumar De <mailto:debkumar.de@intel.com> <debkumar.de@intel.com>; Catharine West
<mailto:catharine.west@intel.com> <catharine.west@intel.com>; Mike Turner <mailto:mikeyt@pobox.com> <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 <mailto:jian.j.wang@intel.com> <jian.j.wang@intel.com>
Cc: Dandan Bi <mailto:dandan.bi@intel.com> <dandan.bi@intel.com>
Cc: Liming Gao <mailto:gaoliming@byosoft.com.cn> <gaoliming@byosoft.com.cn>
Cc: Debkumar De <mailto:debkumar.de@intel.com> <debkumar.de@intel.com>
Cc: Catharine West <mailto:catharine.west@intel.com> <catharine.west@intel.com>
Co-authored-by: Mike Turner <mailto:mikeyt@pobox.com> <mikeyt@pobox.com>
Signed-off-by: Kun Qin <mailto:kuqin12@gmail.com> <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 (#109379): https://edk2.groups.io/g/devel/message/109379
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: 110721 bytes --]
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: 回复: 回复: [edk2-devel] 回复: [PATCH v1 3/4] MdeModulePkg: PeiMain: Introduce implementation of delayed dispatch
2023-10-07 5:13 ` 回复: " gaoliming via groups.io
@ 2023-10-10 0:21 ` Kun Qin
0 siblings, 0 replies; 12+ messages in thread
From: Kun Qin @ 2023-10-10 0:21 UTC (permalink / raw)
To: devel, gaoliming
Cc: 'Jian J Wang', 'Dandan Bi', 'Debkumar De',
'Catharine West', 'Mike Turner'
[-- 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 --]
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2023-10-10 0:21 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
2023-07-20 21:07 ` [edk2-devel] [PATCH v1 4/4] MdeModulePkg: PeiMain: Updated dispatcher for " Kun Qin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox