MdeModulePkg: Add ResetUtility library class and BASE instance

The library class that provides services to generate a GUID specific
reset, parse the GUID from a GUID specific reset, and build the
ResetData buffer for any type of reset that requires extra data.

Cc: Liming Gao <liming.gao@intel.com>
Reviewed-by: Ruiyu Ni <ruiyu.ni@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
Contributed-under: TianoCore Contribution Agreement 1.1
Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com>
Signed-off-by: Ruiyu Ni <ruiyu.ni@intel.com>
This commit is contained in:
Michael D Kinney 2017-09-01 16:16:50 +08:00 committed by Ruiyu Ni
parent ce3cd892c8
commit e12ceb40ce
5 changed files with 376 additions and 0 deletions

View File

@ -0,0 +1,110 @@
/** @file
This header describes various helper functions for resetting the system.
Copyright (c) 2017 Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 Microsoft 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 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 _RESET_UTILITY_LIB_H_
#define _RESET_UTILITY_LIB_H_
/**
This is a shorthand helper function to reset with a subtype so that
the caller doesn't have to bother with a function that has half a dozen
parameters.
This will generate a reset with status EFI_SUCCESS, a NULL string, and
no custom data. The subtype will be formatted in such a way that it can be
picked up by notification registrations and custom handlers.
NOTE: This call will fail if the architectural ResetSystem underpinnings
are not initialized. For DXE, you can add gEfiResetArchProtocolGuid
to your DEPEX.
@param[in] ResetSubtype GUID pointer for the reset subtype to be used.
**/
VOID
EFIAPI
ResetPlatformSpecificGuid (
IN CONST GUID *ResetSubtype
);
/**
This function examines the DataSize and ResetData parameters passed to
to ResetSystem() and detemrines if the ResetData contains a Null-terminated
Unicode string followed by a GUID specific subtype. If the GUID specific
subtype is present, then a pointer to the GUID value in ResetData is returned.
@param[in] DataSize The size, in bytes, of ResetData.
@param[in] ResetData Pointer to the data buffer passed into ResetSystem().
@retval Pointer Pointer to the GUID value in ResetData.
@retval NULL ResetData is NULL.
@retval NULL ResetData does not start with a Null-terminated
Unicode string.
@retval NULL A Null-terminated Unicode string is present, but there
are less than sizeof (GUID) bytes after the string.
@retval NULL No subtype is found.
**/
GUID *
EFIAPI
GetResetPlatformSpecificGuid (
IN UINTN DataSize,
IN CONST VOID *ResetData
);
/**
This is a helper function that creates the reset data buffer that can be
passed into ResetSystem().
The reset data buffer is returned in ResetData and contains ResetString
followed by the ResetSubtype GUID followed by the ExtraData.
NOTE: Strings are internally limited by MAX_UINT16.
@param[in, out] ResetDataSize On input, the size of the ResetData buffer. On
output, either the total number of bytes
copied, or the required buffer size.
@param[in, out] ResetData A pointer to the buffer in which to place the
final structure.
@param[in] ResetSubtype Pointer to the GUID specific subtype. This
parameter is optional and may be NULL.
@param[in] ResetString Pointer to a Null-terminated Unicode string
that describes the reset. This parameter is
optional and may be NULL.
@param[in] ExtraDataSize The size, in bytes, of ExtraData buffer.
@param[in] ExtraData Pointer to a buffer of extra data. This
parameter is optional and may be NULL.
@retval RETURN_SUCCESS ResetDataSize and ResetData are updated.
@retval RETURN_INVALID_PARAMETER ResetDataSize is NULL.
@retval RETURN_INVALID_PARAMETER ResetData is NULL.
@retval RETURN_INVALID_PARAMETER ExtraData was provided without a
ResetSubtype. This is not supported by the
UEFI spec.
@retval RETURN_BUFFER_TOO_SMALL An insufficient buffer was provided.
ResetDataSize is updated with minimum size
required.
**/
RETURN_STATUS
EFIAPI
BuildResetData (
IN OUT UINTN *ResetDataSize,
IN OUT VOID *ResetData,
IN CONST GUID *ResetSubtype OPTIONAL,
IN CONST CHAR16 *ResetString OPTIONAL,
IN UINTN ExtraDataSize OPTIONAL,
IN CONST VOID *ExtraData OPTIONAL
);
#endif // _RESET_UTILITY_LIB_H_

View File

@ -0,0 +1,220 @@
/** @file
This contains the business logic for the module-specific Reset Helper functions.
Copyright (c) 2017 Intel Corporation. All rights reserved.<BR>
Copyright (c) 2016 Microsoft 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 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.
**/
#include <Uefi.h>
#include <Library/BaseLib.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/ResetSystemLib.h>
typedef struct {
CHAR16 NullTerminator;
GUID ResetSubtype;
} RESET_UTILITY_GUID_SPECIFIC_RESET_DATA;
/**
This is a shorthand helper function to reset with a subtype so that
the caller doesn't have to bother with a function that has half a dozen
parameters.
This will generate a reset with status EFI_SUCCESS, a NULL string, and
no custom data. The subtype will be formatted in such a way that it can be
picked up by notification registrations and custom handlers.
NOTE: This call will fail if the architectural ResetSystem underpinnings
are not initialized. For DXE, you can add gEfiResetArchProtocolGuid
to your DEPEX.
@param[in] ResetSubtype GUID pointer for the reset subtype to be used.
**/
VOID
EFIAPI
ResetPlatformSpecificGuid (
IN CONST GUID *ResetSubtype
)
{
RESET_UTILITY_GUID_SPECIFIC_RESET_DATA ResetData;
ResetData.NullTerminator = CHAR_NULL;
CopyGuid (&ResetData.ResetSubtype, ResetSubtype);
ResetPlatformSpecific (sizeof (ResetData), &ResetData);
}
/**
This function examines the DataSize and ResetData parameters passed to
to ResetSystem() and detemrines if the ResetData contains a Null-terminated
Unicode string followed by a GUID specific subtype. If the GUID specific
subtype is present, then a pointer to the GUID value in ResetData is returned.
@param[in] DataSize The size, in bytes, of ResetData.
@param[in] ResetData Pointer to the data buffer passed into ResetSystem().
@retval Pointer Pointer to the GUID value in ResetData.
@retval NULL ResetData is NULL.
@retval NULL ResetData does not start with a Null-terminated
Unicode string.
@retval NULL A Null-terminated Unicode string is present, but there
are less than sizeof (GUID) bytes after the string.
@retval NULL No subtype is found.
**/
GUID *
EFIAPI
GetResetPlatformSpecificGuid (
IN UINTN DataSize,
IN CONST VOID *ResetData
)
{
UINTN ResetDataStringSize;
GUID *ResetSubtypeGuid;
//
// Make sure parameters are valid
//
if ((ResetData == NULL) || (DataSize < sizeof (GUID))) {
return NULL;
}
//
// Determine the number of bytes in the Null-terminated Unicode string
// at the beginning of ResetData including the Null terminator.
//
ResetDataStringSize = StrnSizeS (ResetData, (DataSize / sizeof (CHAR16)));
//
// Now, assuming that we have enough data for a GUID after the string, the
// GUID should be immediately after the string itself.
//
if ((ResetDataStringSize < DataSize) && (DataSize - ResetDataStringSize) >= sizeof (GUID)) {
ResetSubtypeGuid = (GUID *)((UINT8 *)ResetData + ResetDataStringSize);
DEBUG ((DEBUG_VERBOSE, __FUNCTION__" - Detected reset subtype %g...\n", ResetSubtypeGuid));
return ResetSubtypeGuid;
}
return NULL;
}
/**
This is a helper function that creates the reset data buffer that can be
passed into ResetSystem().
The reset data buffer is returned in ResetData and contains ResetString
followed by the ResetSubtype GUID followed by the ExtraData.
NOTE: Strings are internally limited by MAX_UINT16.
@param[in, out] ResetDataSize On input, the size of the ResetData buffer. On
output, either the total number of bytes
copied, or the required buffer size.
@param[in, out] ResetData A pointer to the buffer in which to place the
final structure.
@param[in] ResetSubtype Pointer to the GUID specific subtype. This
parameter is optional and may be NULL.
@param[in] ResetString Pointer to a Null-terminated Unicode string
that describes the reset. This parameter is
optional and may be NULL.
@param[in] ExtraDataSize The size, in bytes, of ExtraData buffer.
@param[in] ExtraData Pointer to a buffer of extra data. This
parameter is optional and may be NULL.
@retval RETURN_SUCCESS ResetDataSize and ResetData are updated.
@retval RETURN_INVALID_PARAMETER ResetDataSize is NULL.
@retval RETURN_INVALID_PARAMETER ResetData is NULL.
@retval RETURN_INVALID_PARAMETER ExtraData was provided without a
ResetSubtype. This is not supported by the
UEFI spec.
@retval RETURN_BUFFER_TOO_SMALL An insufficient buffer was provided.
ResetDataSize is updated with minimum size
required.
**/
RETURN_STATUS
EFIAPI
BuildResetData (
IN OUT UINTN *ResetDataSize,
IN OUT VOID *ResetData,
IN CONST GUID *ResetSubtype OPTIONAL,
IN CONST CHAR16 *ResetString OPTIONAL,
IN UINTN ExtraDataSize OPTIONAL,
IN CONST VOID *ExtraData OPTIONAL
)
{
UINTN ResetStringSize;
UINTN ResetDataBufferSize;
UINT8 *Data;
//
// If the size return pointer is NULL.
//
if (ResetDataSize == NULL) {
return RETURN_INVALID_PARAMETER;
}
//
// If extra data is indicated, but pointer is NULL.
//
if (ExtraDataSize > 0 && ExtraData == NULL) {
return RETURN_INVALID_PARAMETER;
}
//
// If extra data is indicated, but no subtype GUID is supplied.
//
if (ResetSubtype == NULL && ExtraDataSize > 0) {
return RETURN_INVALID_PARAMETER;
}
//
// Determine the final string.
//
if (ResetString == NULL) {
ResetString = L""; // Use an empty string.
}
//
// Calculate the total buffer required for ResetData.
//
ResetStringSize = StrnSizeS (ResetString, MAX_UINT16);
ResetDataBufferSize = ResetStringSize + ExtraDataSize;
if (ResetSubtype != NULL) {
ResetDataBufferSize += sizeof (GUID);
}
//
// At this point, if the buffer isn't large enough (or if
// the buffer is NULL) we cannot proceed.
//
if (*ResetDataSize < ResetDataBufferSize) {
*ResetDataSize = ResetDataBufferSize;
return RETURN_BUFFER_TOO_SMALL;
}
*ResetDataSize = ResetDataBufferSize;
if (ResetData == NULL) {
return RETURN_INVALID_PARAMETER;
}
//
// Fill in ResetData with ResetString, the ResetSubtype GUID, and extra data
//
Data = (UINT8 *)ResetData;
CopyMem (Data, ResetString, ResetStringSize);
Data += ResetStringSize;
if (ResetSubtype != NULL) {
CopyMem (Data, ResetSubtype, sizeof (GUID));
Data += sizeof (GUID);
}
if (ExtraDataSize > 0) {
CopyMem (Data, ExtraData, ExtraDataSize);
}
return RETURN_SUCCESS;
}

View File

@ -0,0 +1,40 @@
## @file
# This file contains the Reset Utility functions.
#
# Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
# Copyright (c) 2016, Microsoft 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
# which 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.
#
##
[Defines]
INF_VERSION = 0x00010017
BASE_NAME = ResetUtilityLib
FILE_GUID = CAFC3CA1-3E32-449F-9B0E-40BA3CB73A12
VERSION_STRING = 1.0
MODULE_TYPE = BASE
LIBRARY_CLASS = ResetUtilityLib
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
ResetUtility.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseLib
DebugLib
BaseMemoryLib
ResetSystemLib

View File

@ -54,6 +54,9 @@
## @libraryclass Defines a set of methods to reset whole system.
ResetSystemLib|Include/Library/ResetSystemLib.h
## @libraryclass Defines a set of helper functions for resetting the system.
ResetUtilityLib|Include/Library/ResetUtilityLib.h
## @libraryclass Defines a set of methods related do S3 mode.
# This library class is no longer used and modules using this library should
# directly locate EFI_PEI_S3_RESUME_PPI defined in PI 1.2 specification.

View File

@ -281,13 +281,16 @@
MdeModulePkg/Library/DxeIpIoLib/DxeIpIoLib.inf
MdeModulePkg/Library/DxeNetLib/DxeNetLib.inf
MdeModulePkg/Library/DxePerformanceLib/DxePerformanceLib.inf
MdeModulePkg/Library/DxeResetSystemLib/DxeResetSystemLib.inf
MdeModulePkg/Library/DxeUdpIoLib/DxeUdpIoLib.inf
MdeModulePkg/Library/DxePrintLibPrint2Protocol/DxePrintLibPrint2Protocol.inf
MdeModulePkg/Library/PeiCrc32GuidedSectionExtractLib/PeiCrc32GuidedSectionExtractLib.inf
MdeModulePkg/Library/PeiPerformanceLib/PeiPerformanceLib.inf
MdeModulePkg/Library/PeiRecoveryLibNull/PeiRecoveryLibNull.inf
MdeModulePkg/Library/PeiResetSystemLib/PeiResetSystemLib.inf
MdeModulePkg/Library/PeiS3LibNull/PeiS3LibNull.inf
MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
MdeModulePkg/Library/ResetUtilityLib/ResetUtilityLib.inf
MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf
MdeModulePkg/Library/DxeSecurityManagementLib/DxeSecurityManagementLib.inf
MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf