---
MdeModulePkg/Include/Library/ResetUtilityLib.h | 111 +++++++++++
.../Library/ResetUtilityLib/ResetUtility.c | 221
+++++++++++++++++++++
.../Library/ResetUtilityLib/ResetUtilityLib.inf | 43 ++++
MdeModulePkg/MdeModulePkg.dsc | 7 +
4 files changed, 382 insertions(+)
create mode 100644 MdeModulePkg/Include/Library/ResetUtilityLib.h
create mode 100644 MdeModulePkg/Library/ResetUtilityLib/ResetUtility.c
create mode 100644
MdeModulePkg/Library/ResetUtilityLib/ResetUtilityLib.inf
diff --git a/MdeModulePkg/Include/Library/ResetUtilityLib.h
b/MdeModulePkg/Include/Library/ResetUtilityLib.h
new file mode 100644
index 0000000000..94828785e2
--- /dev/null
+++ b/MdeModulePkg/Include/Library/ResetUtilityLib.h
@@ -0,0 +1,111 @@
+/** @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] ResetType Base reset type as defined in UEFI spec.
+ @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_
diff --git a/MdeModulePkg/Library/ResetUtilityLib/ResetUtility.c
b/MdeModulePkg/Library/ResetUtilityLib/ResetUtility.c
new file mode 100644
index 0000000000..5bbe002be0
--- /dev/null
+++ b/MdeModulePkg/Library/ResetUtilityLib/ResetUtility.c
@@ -0,0 +1,221 @@
+/** @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] ResetType Base reset type as defined in UEFI spec.
+ @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 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;
+}
diff --git a/MdeModulePkg/Library/ResetUtilityLib/ResetUtilityLib.inf
b/MdeModulePkg/Library/ResetUtilityLib/ResetUtilityLib.inf
new file mode 100644
index 0000000000..7a403749c5
--- /dev/null
+++ b/MdeModulePkg/Library/ResetUtilityLib/ResetUtilityLib.inf
@@ -0,0 +1,43 @@
+## @file
+# This file contains the Reset Utility functions.
+#
+# The application pops up a menu showing all the boot options
referenced by
+# BootOrder NV variable and user can choose to boot from one of them.
+#
+# 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
+# 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
diff --git a/MdeModulePkg/MdeModulePkg.dsc
b/MdeModulePkg/MdeModulePkg.dsc
index dd7e9d5988..d96bff90b0 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -285,13 +285,16 @@ [Components]
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
@@ -358,6 +361,10 @@ [Components]
MdeModulePkg/Universal/MemoryTest/NullMemoryTestDxe/NullMemoryTestDxe.inf
MdeModulePkg/Universal/Metronome/Metronome.inf
MdeModulePkg/Universal/MonotonicCounterRuntimeDxe/MonotonicCounterRuntimeDxe.inf
+ MdeModulePkg/Universal/ResetSystemPei/ResetSystemPei.inf {
+ <LibraryClasses>
+
ResetSystemLib|MdeModulePkg/Library/BaseResetSystemLibNull/BaseResetSystemLibNull.inf
+ }
MdeModulePkg/Universal/ResetSystemRuntimeDxe/ResetSystemRuntimeDxe.inf
MdeModulePkg/Universal/SmbiosDxe/SmbiosDxe.inf
MdeModulePkg/Universal/SmbiosMeasurementDxe/SmbiosMeasurementDxe.inf