diff --git a/MdeModulePkg/Include/Ppi/PlatformSpecificResetFilter.h b/MdeModulePkg/Include/Ppi/PlatformSpecificResetFilter.h new file mode 100644 index 0000000000..0f1432f5f8 --- /dev/null +++ b/MdeModulePkg/Include/Ppi/PlatformSpecificResetFilter.h @@ -0,0 +1,31 @@ +/** @file + This PPI provides services to register a platform specific reset filter + for ResetSystem(). A reset filter evaluates the parameters passed to + ResetSystem() and converts a ResetType of EfiResetPlatformSpecific to a + non-platform specific reset type. The registered filters are processed before + EDKII_PLATFORM_SPECIFIC_RESET_HANDLER_PPI handlers. + + Copyright (c) 2017 Intel Corporation. All rights reserved.
+ This program and the accompanying materials are licensed and made available under + the terms and conditions of the BSD License that accompanies this distribution. + The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PLATFORM_SPECIFIC_RESET_FILTER_PPI_H_ +#define _PLATFORM_SPECIFIC_RESET_FILTER_PPI_H_ + +#include + +#define EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PPI_GUID \ + { 0x8c9f4de3, 0x7b90, 0x47ef, { 0x93, 0x8, 0x28, 0x7c, 0xec, 0xd6, 0x6d, 0xe8 } } + +typedef EFI_RESET_NOTIFICATION_PROTOCOL EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PPI; + +extern EFI_GUID gEdkiiPlatformSpecificResetFilterPpiGuid; + +#endif diff --git a/MdeModulePkg/Include/Ppi/PlatformSpecificResetHandler.h b/MdeModulePkg/Include/Ppi/PlatformSpecificResetHandler.h new file mode 100644 index 0000000000..d5f1350c69 --- /dev/null +++ b/MdeModulePkg/Include/Ppi/PlatformSpecificResetHandler.h @@ -0,0 +1,29 @@ +/** @file + This PPI provides services to register a platform specific handler for + ResetSystem(). The registered handlers are processed after + EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PPI notifications. + + Copyright (c) 2017 Intel Corporation. All rights reserved.
+ This program and the accompanying materials are licensed and made available under + the terms and conditions of the BSD License that accompanies this distribution. + The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PLATFORM_SPECIFIC_RESET_HANDLER_PPI_H_ +#define _PLATFORM_SPECIFIC_RESET_HANDLER_PPI_H_ + +#include + +#define EDKII_PLATFORM_SPECIFIC_RESET_HANDLER_PPI_GUID \ + { 0x75cf14ae, 0x3441, 0x49dc, { 0xaa, 0x10, 0xbb, 0x35, 0xa7, 0xba, 0x8b, 0xab } } + +typedef EFI_RESET_NOTIFICATION_PROTOCOL EDKII_PLATFORM_SPECIFIC_RESET_HANDLER_PPI; + +extern EFI_GUID gEdkiiPlatformSpecificResetHandlerPpiGuid; + +#endif diff --git a/MdeModulePkg/Include/Protocol/PlatformSpecificResetFilter.h b/MdeModulePkg/Include/Protocol/PlatformSpecificResetFilter.h new file mode 100644 index 0000000000..ff5ca48fdd --- /dev/null +++ b/MdeModulePkg/Include/Protocol/PlatformSpecificResetFilter.h @@ -0,0 +1,31 @@ +/** @file + This Protocol provides services to register a platform specific reset filter + for ResetSystem(). A reset filter evaluates the parameters passed to + ResetSystem() and converts a ResetType of EfiResetPlatformSpecific to a + non-platform specific reset type. The registered filters are processed before + the UEFI 2.7 Reset Notifications. + + Copyright (c) 2017 Intel Corporation. All rights reserved.
+ This program and the accompanying materials are licensed and made available under + the terms and conditions of the BSD License that accompanies this distribution. + The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PLATFORM_SPECIFIC_RESET_FILTER_PROTOCOL_H_ +#define _PLATFORM_SPECIFIC_RESET_FILTER_PROTOCOL_H_ + +#include + +#define EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PROTOCOL_GUID \ + { 0x695d7835, 0x8d47, 0x4c11, { 0xab, 0x22, 0xfa, 0x8a, 0xcc, 0xe7, 0xae, 0x7a } } + +typedef EFI_RESET_NOTIFICATION_PROTOCOL EDKII_PLATFORM_SPECIFIC_RESET_FILTER_PROTOCOL; + +extern EFI_GUID gEdkiiPlatformSpecificResetFilterProtocolGuid; + +#endif diff --git a/MdeModulePkg/Include/Protocol/PlatformSpecificResetHandler.h b/MdeModulePkg/Include/Protocol/PlatformSpecificResetHandler.h new file mode 100644 index 0000000000..8a44e860b2 --- /dev/null +++ b/MdeModulePkg/Include/Protocol/PlatformSpecificResetHandler.h @@ -0,0 +1,29 @@ +/** @file + This protocol provides services to register a platform specific handler for + ResetSystem(). The registered handlers are called after the UEFI 2.7 Reset + Notifications are processed + + Copyright (c) 2017 Intel Corporation. All rights reserved.
+ This program and the accompanying materials are licensed and made available under + the terms and conditions of the BSD License that accompanies this distribution. + The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php. + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PLATFORM_SPECIFIC_RESET_HANDLER_PROTOCOL_H_ +#define _PLATFORM_SPECIFIC_RESET_HANDLER_PROTOCOL_H_ + +#include + +#define EDKII_PLATFORM_SPECIFIC_RESET_HANDLER_PROTOCOL_GUID \ + { 0x2df6ba0b, 0x7092, 0x440d, { 0xbd, 0x4, 0xfb, 0x9, 0x1e, 0xc3, 0xf3, 0xc1 } } + +typedef EFI_RESET_NOTIFICATION_PROTOCOL EDKII_PLATFORM_SPECIFIC_RESET_HANDLER_PROTOCOL; + +extern EFI_GUID gEdkiiPlatformSpecificResetHandlerProtocolGuid; + +#endif diff --git a/MdeModulePkg/MdeModulePkg.dec b/MdeModulePkg/MdeModulePkg.dec index 000e59697e..449ad2975b 100644 --- a/MdeModulePkg/MdeModulePkg.dec +++ b/MdeModulePkg/MdeModulePkg.dec @@ -444,6 +444,12 @@ ## Include/Ppi/IoMmu.h gEdkiiIoMmuPpiGuid = { 0x70b0af26, 0xf847, 0x4bb6, { 0xaa, 0xb9, 0xcd, 0xe8, 0x4f, 0xc6, 0x14, 0x31 } } + ## Include/Ppi/PlatformSpecificResetFilter.h + gEdkiiPlatformSpecificResetFilterPpiGuid = { 0x8c9f4de3, 0x7b90, 0x47ef, { 0x93, 0x8, 0x28, 0x7c, 0xec, 0xd6, 0x6d, 0xe8 } } + + ## Include/Ppi/PlatformSpecificResetHandler.h + gEdkiiPlatformSpecificResetHandlerPpiGuid = { 0x75cf14ae, 0x3441, 0x49dc, { 0xaa, 0x10, 0xbb, 0x35, 0xa7, 0xba, 0x8b, 0xab } } + [Protocols] ## Load File protocol provides capability to load and unload EFI image into memory and execute it. # Include/Protocol/LoadPe32Image.h @@ -565,6 +571,10 @@ ## Include/Protocol/SmmMemoryAttribute.h gEdkiiSmmMemoryAttributeProtocolGuid = { 0x69b792ea, 0x39ce, 0x402d, { 0xa2, 0xa6, 0xf7, 0x21, 0xde, 0x35, 0x1d, 0xfe } } + ## Include/Protocol/PlatformSpecificResetFilter.h + gEdkiiPlatformSpecificResetFilterProtocolGuid = { 0x695d7835, 0x8d47, 0x4c11, { 0xab, 0x22, 0xfa, 0x8a, 0xcc, 0xe7, 0xae, 0x7a } } + ## Include/Protocol/PlatformSpecificResetHandler.h + gEdkiiPlatformSpecificResetHandlerProtocolGuid = { 0x2df6ba0b, 0x7092, 0x440d, { 0xbd, 0x4, 0xfb, 0x9, 0x1e, 0xc3, 0xf3, 0xc1 } } # # [Error.gEfiMdeModulePkgTokenSpaceGuid] # 0x80000001 | Invalid value provided. diff --git a/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystem.c b/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystem.c index 75cff37773..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); @@ -225,13 +250,44 @@ ResetSystem ( UINTN CapsuleDataPtr; LIST_ENTRY *Link; RESET_NOTIFY_ENTRY *Entry; - - // - // 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 ()) { + // + // 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; + } + + // + // Only do REPORT_STATUS_CODE() on first call to ResetSystem() + // + 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)); + } + + 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) @@ -239,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) { diff --git a/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystem.h b/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystem.h index 75cdd88896..ea5660274b 100644 --- a/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystem.h +++ b/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystem.h @@ -20,6 +20,8 @@ #include #include +#include +#include #include #include @@ -34,6 +36,11 @@ #include #include +// +// The maximum recurstion depth to ResetSystem() by reset notification handlers +// +#define MAX_RESET_NOTIFY_DEPTH 10 + typedef struct { UINT32 Signature; LIST_ENTRY Link; diff --git a/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf b/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf index 11233757c2..da9e8e118b 100644 --- a/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf +++ b/MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf @@ -55,9 +55,10 @@ [Protocols] - gEfiResetArchProtocolGuid ## PRODUCES - gEfiResetNotificationProtocolGuid ## PRODUCES - + gEfiResetArchProtocolGuid ## PRODUCES + gEfiResetNotificationProtocolGuid ## PRODUCES + gEdkiiPlatformSpecificResetFilterProtocolGuid ## PRODUCES + gEdkiiPlatformSpecificResetHandlerProtocolGuid ## PRODUCES [Depex] TRUE