X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FResetSystemRuntimeDxe%2FResetSystem.c;h=fed527fac2dbca7f9dfd1e50fbe82b90c504cbcc;hb=99a6529e1ed38606bb5330895cba64cc98aa3e26;hp=b8e3ea460de220f15b0e58f2eb3a35f8392998ad;hpb=cf6da5569307cb3033465d2207e17f438f6e7655;p=mirror_edk2.git diff --git a/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystem.c b/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystem.c index b8e3ea460d..fed527fac2 100644 --- a/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystem.c +++ b/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystem.c @@ -15,6 +15,11 @@ #include "ResetSystem.h" +// +// The current ResetSystem() notification recursion depth +// +UINTN mResetNotifyDepth = 0; + /** Register a notification function to be called when ResetSystem() is called. @@ -130,6 +135,24 @@ RESET_NOTIFICATION_INSTANCE mResetNotification = { INITIALIZE_LIST_HEAD_VARIABLE (mResetNotification.ResetNotifies) }; +RESET_NOTIFICATION_INSTANCE mPlatformSpecificResetFilter = { + RESET_NOTIFICATION_INSTANCE_SIGNATURE, + { + RegisterResetNotify, + UnregisterResetNotify + }, + INITIALIZE_LIST_HEAD_VARIABLE (mPlatformSpecificResetFilter.ResetNotifies) +}; + +RESET_NOTIFICATION_INSTANCE mPlatformSpecificResetHandler = { + RESET_NOTIFICATION_INSTANCE_SIGNATURE, + { + RegisterResetNotify, + UnregisterResetNotify + }, + INITIALIZE_LIST_HEAD_VARIABLE (mPlatformSpecificResetHandler.ResetNotifies) +}; + /** The driver's entry point. @@ -170,6 +193,8 @@ InitializeResetSystem ( &Handle, &gEfiResetArchProtocolGuid, NULL, &gEfiResetNotificationProtocolGuid, &mResetNotification.ResetNotification, + &gEdkiiPlatformSpecificResetFilterProtocolGuid, &mPlatformSpecificResetFilter.ResetNotification, + &gEdkiiPlatformSpecificResetHandlerProtocolGuid, &mPlatformSpecificResetHandler.ResetNotification, NULL ); ASSERT_EFI_ERROR (Status); @@ -207,6 +232,9 @@ DoS3 ( valid if ResetStatus is something other than EFI_SUCCESS unless the ResetType is EfiResetPlatformSpecific where a minimum amount of ResetData is always required. + For a ResetType of EfiResetPlatformSpecific the data buffer + also starts with a Null-terminated string that is followed + by an EFI_GUID that describes the specific type of reset to perform. **/ VOID EFIAPI @@ -222,13 +250,44 @@ ResetSystem ( UINTN CapsuleDataPtr; LIST_ENTRY *Link; RESET_NOTIFY_ENTRY *Entry; - + + // + // Above the maximum recursion depth, so do the smallest amount of + // work to perform a cold reset. + // + if (mResetNotifyDepth >= MAX_RESET_NOTIFY_DEPTH) { + ResetCold (); + ASSERT (FALSE); + return; + } + // - // Indicate reset system runtime service is called. + // Only do REPORT_STATUS_CODE() on first call to ResetSystem() // - REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_RESET_SYSTEM)); + if (mResetNotifyDepth == 0) { + // + // Indicate reset system runtime service is called. + // + REPORT_STATUS_CODE (EFI_PROGRESS_CODE, (EFI_SOFTWARE_EFI_RUNTIME_SERVICE | EFI_SW_RS_PC_RESET_SYSTEM)); + } - if (!EfiAtRuntime ()) { + mResetNotifyDepth++; + if (!EfiAtRuntime () && mResetNotifyDepth < MAX_RESET_NOTIFY_DEPTH) { + // + // Call reset notification functions registered through the + // EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PROTOCOL. + // + for ( Link = GetFirstNode (&mPlatformSpecificResetFilter.ResetNotifies) + ; !IsNull (&mPlatformSpecificResetFilter.ResetNotifies, Link) + ; Link = GetNextNode (&mPlatformSpecificResetFilter.ResetNotifies, Link) + ) { + Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link); + Entry->ResetNotify (ResetType, ResetStatus, DataSize, ResetData); + } + // + // Call reset notification functions registered through the + // EFI_RESET_NOTIFICATION_PROTOCOL. + // for ( Link = GetFirstNode (&mResetNotification.ResetNotifies) ; !IsNull (&mResetNotification.ResetNotifies, Link) ; Link = GetNextNode (&mResetNotification.ResetNotifies, Link) @@ -236,6 +295,17 @@ ResetSystem ( Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link); Entry->ResetNotify (ResetType, ResetStatus, DataSize, ResetData); } + // + // call reset notification functions registered through the + // EDKII_PLATFORM_SPECIFIC_RESET_HANDLER_PROTOCOL. + // + for ( Link = GetFirstNode (&mPlatformSpecificResetHandler.ResetNotifies) + ; !IsNull (&mPlatformSpecificResetHandler.ResetNotifies, Link) + ; Link = GetNextNode (&mPlatformSpecificResetHandler.ResetNotifies, Link) + ) { + Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link); + Entry->ResetNotify (ResetType, ResetStatus, DataSize, ResetData); + } } switch (ResetType) {