MdeModulePkg/ResetSystem: Implement ResetNotification protocol

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
Ruiyu Ni 2017-06-15 16:31:56 +08:00
parent 34861f4323
commit cf6da55693
4 changed files with 161 additions and 16 deletions

View File

@ -1,5 +1,5 @@
/** @file
Reset Architectural Protocol implementation
Reset Architectural and Reset Notification protocols implementation.
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
@ -15,6 +15,121 @@
#include "ResetSystem.h"
/**
Register a notification function to be called when ResetSystem() is called.
The RegisterResetNotify() function registers a notification function that is called when
ResetSystem()is called and prior to completing the reset of the platform.
The registered functions must not perform a platform reset themselves. These
notifications are intended only for the notification of components which may need some
special-purpose maintenance prior to the platform resetting.
The list of registered reset notification functions are processed if ResetSystem()is called
before ExitBootServices(). The list of registered reset notification functions is ignored if
ResetSystem()is called after ExitBootServices().
@param[in] This A pointer to the EFI_RESET_NOTIFICATION_PROTOCOL instance.
@param[in] ResetFunction Points to the function to be called when a ResetSystem() is executed.
@retval EFI_SUCCESS The reset notification function was successfully registered.
@retval EFI_INVALID_PARAMETER ResetFunction is NULL.
@retval EFI_OUT_OF_RESOURCES There are not enough resources available to register the reset notification function.
@retval EFI_ALREADY_STARTED The reset notification function specified by ResetFunction has already been registered.
**/
EFI_STATUS
EFIAPI
RegisterResetNotify (
IN EFI_RESET_NOTIFICATION_PROTOCOL *This,
IN EFI_RESET_SYSTEM ResetFunction
)
{
RESET_NOTIFICATION_INSTANCE *Instance;
LIST_ENTRY *Link;
RESET_NOTIFY_ENTRY *Entry;
if (ResetFunction == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = RESET_NOTIFICATION_INSTANCE_FROM_THIS (This);
for ( Link = GetFirstNode (&Instance->ResetNotifies)
; !IsNull (&Instance->ResetNotifies, Link)
; Link = GetNextNode (&Instance->ResetNotifies, Link)
) {
Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
if (Entry->ResetNotify == ResetFunction) {
return EFI_ALREADY_STARTED;
}
}
ASSERT (IsNull (&Instance->ResetNotifies, Link));
Entry = AllocatePool (sizeof (*Entry));
if (Entry == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Entry->Signature = RESET_NOTIFY_ENTRY_SIGNATURE;
Entry->ResetNotify = ResetFunction;
InsertTailList (&Instance->ResetNotifies, &Entry->Link);
return EFI_SUCCESS;
}
/**
Unregister a notification function.
The UnregisterResetNotify() function removes the previously registered
notification using RegisterResetNotify().
@param[in] This A pointer to the EFI_RESET_NOTIFICATION_PROTOCOL instance.
@param[in] ResetFunction The pointer to the ResetFunction being unregistered.
@retval EFI_SUCCESS The reset notification function was unregistered.
@retval EFI_INVALID_PARAMETER ResetFunction is NULL.
@retval EFI_INVALID_PARAMETER The reset notification function specified by ResetFunction was not previously
registered using RegisterResetNotify().
**/
EFI_STATUS
EFIAPI
UnregisterResetNotify (
IN EFI_RESET_NOTIFICATION_PROTOCOL *This,
IN EFI_RESET_SYSTEM ResetFunction
)
{
RESET_NOTIFICATION_INSTANCE *Instance;
LIST_ENTRY *Link;
RESET_NOTIFY_ENTRY *Entry;
if (ResetFunction == NULL) {
return EFI_INVALID_PARAMETER;
}
Instance = RESET_NOTIFICATION_INSTANCE_FROM_THIS (This);
for ( Link = GetFirstNode (&Instance->ResetNotifies)
; !IsNull (&Instance->ResetNotifies, Link)
; Link = GetNextNode (&Instance->ResetNotifies, Link)
) {
Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
if (Entry->ResetNotify == ResetFunction) {
RemoveEntryList (&Entry->Link);
FreePool (Entry);
return EFI_SUCCESS;
}
}
return EFI_INVALID_PARAMETER;
}
RESET_NOTIFICATION_INSTANCE mResetNotification = {
RESET_NOTIFICATION_INSTANCE_SIGNATURE,
{
RegisterResetNotify,
UnregisterResetNotify
},
INITIALIZE_LIST_HEAD_VARIABLE (mResetNotification.ResetNotifies)
};
/**
The driver's entry point.
@ -53,8 +168,8 @@ InitializeResetSystem (
Handle = NULL;
Status = gBS->InstallMultipleProtocolInterfaces (
&Handle,
&gEfiResetArchProtocolGuid,
NULL,
&gEfiResetArchProtocolGuid, NULL,
&gEfiResetNotificationProtocolGuid, &mResetNotification.ResetNotification,
NULL
);
ASSERT_EFI_ERROR (Status);
@ -102,15 +217,27 @@ ResetSystem (
IN VOID *ResetData OPTIONAL
)
{
EFI_STATUS Status;
UINTN Size;
UINTN CapsuleDataPtr;
EFI_STATUS Status;
UINTN Size;
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 ()) {
for ( Link = GetFirstNode (&mResetNotification.ResetNotifies)
; !IsNull (&mResetNotification.ResetNotifies, Link)
; Link = GetNextNode (&mResetNotification.ResetNotifies, Link)
) {
Entry = RESET_NOTIFY_ENTRY_FROM_LINK (Link);
Entry->ResetNotify (ResetType, ResetStatus, DataSize, ResetData);
}
}
switch (ResetType) {
case EfiResetWarm:

View File

@ -1,6 +1,6 @@
/** @file
Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
@ -19,6 +19,7 @@
#include <PiDxe.h>
#include <Protocol/Reset.h>
#include <Protocol/ResetNotification.h>
#include <Guid/CapsuleVendor.h>
#include <Library/BaseLib.h>
@ -31,6 +32,24 @@
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/ResetSystemLib.h>
#include <Library/ReportStatusCodeLib.h>
#include <Library/MemoryAllocationLib.h>
typedef struct {
UINT32 Signature;
LIST_ENTRY Link;
EFI_RESET_SYSTEM ResetNotify;
} RESET_NOTIFY_ENTRY;
#define RESET_NOTIFY_ENTRY_SIGNATURE SIGNATURE_32('r', 's', 't', 'n')
#define RESET_NOTIFY_ENTRY_FROM_LINK(a) CR (a, RESET_NOTIFY_ENTRY, Link, RESET_NOTIFY_ENTRY_SIGNATURE)
typedef struct {
UINT32 Signature;
EFI_RESET_NOTIFICATION_PROTOCOL ResetNotification;
LIST_ENTRY ResetNotifies;
} RESET_NOTIFICATION_INSTANCE;
#define RESET_NOTIFICATION_INSTANCE_SIGNATURE SIGNATURE_32('r', 's', 't', 'i')
#define RESET_NOTIFICATION_INSTANCE_FROM_THIS(a) \
CR (a, RESET_NOTIFICATION_INSTANCE, ResetNotification, RESET_NOTIFICATION_INSTANCE_SIGNATURE)
/**
The driver's entry point.

View File

@ -1,7 +1,7 @@
## @file
# This driver implements Reset Architectural Protocol.
# This driver implements Reset Architectural and Reset Notification protocols.
#
# Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials are
# licensed and made available under the terms and conditions of the BSD License
@ -48,7 +48,7 @@
DebugLib
BaseLib
ReportStatusCodeLib
MemoryAllocationLib
[Guids]
gEfiCapsuleVendorGuid ## SOMETIMES_CONSUMES ## Variable:L"CapsuleUpdateData"
@ -56,6 +56,7 @@
[Protocols]
gEfiResetArchProtocolGuid ## PRODUCES
gEfiResetNotificationProtocolGuid ## PRODUCES
[Depex]

View File

@ -1,9 +1,7 @@
// /** @file
// This driver implements Reset Architectural Protocol.
// This driver implements Reset Architectural and Reset Notification protocols.
//
// This driver implements Reset Architectural Protocol.
//
// Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.<BR>
// Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<BR>
//
// This program and the accompanying materials are
// licensed and made available under the terms and conditions of the BSD License
@ -16,7 +14,7 @@
// **/
#string STR_MODULE_ABSTRACT #language en-US "Implements Reset Architectural Protocol"
#string STR_MODULE_ABSTRACT #language en-US "Implements Reset Architectural and Reset Notification protocols"
#string STR_MODULE_DESCRIPTION #language en-US "This driver implements Reset Architectural Protocol."
#string STR_MODULE_DESCRIPTION #language en-US "This driver implements Reset Architectural and Reset Notification protocols."