Merged PR 2124207: Adding hardware error record support into core

Adding report status code handler that collects certain errors and store on the flash for MS WHEA process.

Related work items: #16620999, #17798962, #17798979, #18167784
This commit is contained in:
Kun Qin 2018-10-02 21:25:00 +00:00 коммит произвёл Bret Barkelew
Родитель 063c57a491
Коммит 326963f3ba
20 изменённых файлов: 5945 добавлений и 0 удалений

Просмотреть файл

@ -0,0 +1,110 @@
/** @file -- MsWheaEarlyStorageLib.h
This header defines APIs to utilize special memory for MsWheaReport during early stage.
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#ifndef __MS_WHEA_EARLY_STORAGE_LIB__
#define __MS_WHEA_EARLY_STORAGE_LIB__
#include <Uefi/UefiBaseType.h>
#define EARLY_STORAGE_DEFAULT_VALUE 0xFF
/**
This routine returns the maximum number of bytes that can be stored in the PEI event store.
@retval Count The maximum number of bytes that can be stored in the MS WHEA store.
**/
UINT8
EFIAPI
MsWheaEarlyStorageGetMaxSize (
VOID
);
/**
This routine reads the specified data region from the MS WHEA store.
@param[in] Ptr The pointer to hold intended read data
@param[in] Size The size of intended read data
@param[in] Offset The offset of read data, starting from
MS_WHEA_EARLY_STORAGE_OFFSET
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
EFI_STATUS
EFIAPI
MsWheaEarlyStorageRead (
VOID *Ptr,
UINT8 Size,
UINT8 Offset
);
/**
This routine writes the specified data region from the MS WHEA store.
@param[in] Ptr The pointer to hold intended written data
@param[in] Size The size of intended written data
@param[in] Offset The offset of written data, starting from
MS_WHEA_EARLY_STORAGE_OFFSET
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
EFI_STATUS
EFIAPI
MsWheaEarlyStorageWrite (
VOID *Ptr,
UINT8 Size,
UINT8 Offset
);
/**
This routine clears the specified data region from the MS WHEA store to PcdMsWheaEarlyStorageDefaultValue.
@param[in] Size The size of intended clear data
@param[in] Offset The offset of clear data, starting from
MS_WHEA_EARLY_STORAGE_OFFSET
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
EFI_STATUS
EFIAPI
MsWheaEarlyStorageClear (
UINT8 Size,
UINT8 Offset
);
#endif // __MS_WHEA_EARLY_STORAGE_LIB__

Просмотреть файл

@ -0,0 +1,128 @@
/** @file -- MsWheaErrorStatus.h
This header file defines MsWheaReport expected/applied header components.
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#ifndef __MS_WHEA_ERROR_STATUS__
#define __MS_WHEA_ERROR_STATUS__
#include <Guid/Cper.h>
#include <Pi/PiStatusCode.h>
#define MS_WHEA_ERROR_SIGNATURE SIGNATURE_32('W', 'H', 'E', 'A')
/**
Accepted phase values
**/
#define MS_WHEA_PHASE_PEI 0x00
#define MS_WHEA_PHASE_DXE 0x01
#define MS_WHEA_PHASE_DXE_RUNTIME 0x02
/**
Accepted revision values
**/
#define MS_WHEA_REV_0 0x0000
#define MS_WHEA_REV_1 0x0001
#define MS_WHEA_REV_WILDCARD 0x7FFF
#define MS_WHEA_ERROR_EARLY_STORAGE_STORE_FULL \
0xAFAFAFAF
/**
Microsoft WHEA accepted error status type, other types will be ignored
**/
#define MS_WHEA_ERROR_STATUS_TYPE (EFI_ERROR_MAJOR | EFI_ERROR_CODE)
typedef UINT16 MS_WHEA_REV;
typedef UINT16 MS_WHEA_ERROR_PHASE;
/**
Minimal information reported for reported status codes under fatal severity (Rev0 and above).
Note: All the upcoming Early Storage entry should start with the following parameters
Rev: Revision used for parser to identify supplied payload format.
Phase: Phase of boot process reporting module, will be filled at the backend.
ErrorStatusCode: Reported Status Code Value upon calling ReportStatusCode*
**/
typedef struct MS_WHEA_EARLY_STORAGE_ENTRY_V0_T_DEF {
MS_WHEA_REV Rev;
MS_WHEA_ERROR_PHASE Phase;
UINT32 ErrorStatusCode;
} MS_WHEA_EARLY_STORAGE_ENTRY_V0, MS_WHEA_EARLY_STORAGE_ENTRY_COMMON;
/**
Minimal information reported for reported status codes under Rev 1 and fatal severity
Rev: Revision used for parser to identify supplied payload format.
Phase: Phase of boot process reporting module, will be filled at the backend.
ErrorStatusCode: Reported Status Code Value upon calling ReportStatusCode*
CriticalInfo: Critical information to be filled by caller
ReporterID: ReporterID to be filled by caller to reporter identification purpose
**/
typedef struct MS_WHEA_EARLY_STORAGE_ENTRY_V1_T_DEF {
MS_WHEA_REV Rev;
MS_WHEA_ERROR_PHASE Phase;
UINT32 ErrorStatusCode;
UINT64 CriticalInfo;
UINT64 ReporterID;
} MS_WHEA_EARLY_STORAGE_ENTRY_V1;
/**
Microsoft WHEA error list entry header, to be included as error header when using
ReportStatusCodeWithExtendedData.
Signature: 'WHEA', indocator of WHEA compliance
Rev: Revision used for parser to identify supplied payload format.
Phase: Phase of boot process reporting module, will be filled at the backend.
ErrorStatusCode: Reported Status Code Value upon calling ReportStatusCode*
CriticalInfo: Critical information to be filled by caller, Ignored for Rev: 0 and wildcard
ReporterID: ReporterID to be filled by caller to reporter identification purpose, ignored for
Rev: 0 and wildcard
**/
typedef struct MS_WHEA_ERROR_HDR_T_DEF {
UINT32 Signature;
MS_WHEA_REV Rev;
MS_WHEA_ERROR_PHASE Phase;
UINT32 ErrorSeverity;
UINT32 Reserved;
UINT64 CriticalInfo;
UINT64 ReporterID;
} MS_WHEA_ERROR_HDR;
#endif // __MS_WHEA_ERROR_STATUS__

Просмотреть файл

@ -0,0 +1,311 @@
/** @file -- MsWheaEarlyStorageLib.c
This header defines APIs to utilize special memory for MsWheaReport during
early stage.
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include <Library/DebugLib.h>
#include <Library/IoLib.h>
#include <Library/PcdLib.h>
#include <Library/MsWheaEarlyStorageLib.h>
#define PCAT_RTC_LO_ADDRESS_PORT 0x70
#define PCAT_RTC_LO_DATA_PORT 0x71
#define PCAT_RTC_HI_ADDRESS_PORT 0x72
#define PCAT_RTC_HI_DATA_PORT 0x73
#define MS_WHEA_EARLY_STORAGE_OFFSET 0x40
/**
This routine has the highest previlege to read any byte(s) on the CMOS
@param[in] Ptr The pointer to hold read data
@param[in] Size The size of intended read data
@param[in] Offset The offset of read data, starting from the beginning of CMOS
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
STATIC
EFI_STATUS
__MsWheaCMOSRawRead (
VOID *Ptr,
UINT8 Size,
UINT8 Offset
)
{
UINT8 mIndex;
UINT8 i;
UINT8 *mBuf;
EFI_STATUS Status;
mBuf = Ptr;
if ((mBuf == NULL) ||
(Size == 0) ||
((UINT8)(PcdGet32(PcdMsWheaReportPcatCapacity) - Size) < Offset)) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
for (i = 0; i < Size; i++) {
mIndex = Offset + i;
if ((mIndex >= 0) && (mIndex <= 127)) {
IoWrite8(PCAT_RTC_LO_ADDRESS_PORT, mIndex);
mBuf[i] = IoRead8(PCAT_RTC_LO_DATA_PORT);
}
else {
IoWrite8(PCAT_RTC_HI_ADDRESS_PORT, mIndex);
mBuf[i] = IoRead8(PCAT_RTC_HI_DATA_PORT);
}
}
Status = EFI_SUCCESS;
Cleanup:
return Status;
}
/**
This routine has the highest previlege to write any byte(s) on the CMOS
@param[in] Ptr The pointer to hold intended written data
@param[in] Size The size of intended written data
@param[in] Offset The offset of written data, starting from the beginning of CMOS
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
STATIC
EFI_STATUS
__MsWheaCMOSRawWrite (
VOID *Ptr,
UINT8 Size,
UINT8 Offset
)
{
UINT8 mIndex;
UINT8 i;
UINT8 *mBuf;
EFI_STATUS Status;
mBuf = Ptr;
if ((mBuf == NULL) ||
(Size == 0) ||
((UINT8)(PcdGet32(PcdMsWheaReportPcatCapacity) - Size) < Offset)) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
for (i = 0; i < Size; i++) {
mIndex = Offset + i;
if ((mIndex >= 0) && (mIndex <= 127)) {
IoWrite8(PCAT_RTC_LO_ADDRESS_PORT, mIndex);
IoWrite8(PCAT_RTC_LO_DATA_PORT, mBuf[i]);
}
else {
IoWrite8(PCAT_RTC_HI_ADDRESS_PORT, mIndex);
IoWrite8(PCAT_RTC_HI_DATA_PORT, mBuf[i]);
}
}
Status = EFI_SUCCESS;
Cleanup:
return Status;
}
/**
This routine has the highest previlege to 'clear' any byte(s) on the CMOS
@param[in] Size The size of intended clear region
@param[in] Offset The offset of clear data, starting from the beginning of CMOS
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
STATIC
EFI_STATUS
__MsWheaCMOSRawClear (
UINT8 Size,
UINT8 Offset
)
{
UINT8 mIndex;
UINT8 i;
EFI_STATUS Status;
if ((Size == 0) ||
((UINT8)(PcdGet32(PcdMsWheaReportPcatCapacity) - Size) < Offset)) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
for (i = 0; i < Size; i++) {
mIndex = Offset + i;
if ((mIndex >= 0) && (mIndex <= 127)) {
IoWrite8(PCAT_RTC_LO_ADDRESS_PORT, mIndex);
IoWrite8(PCAT_RTC_LO_DATA_PORT, PcdGet8(PcdMsWheaEarlyStorageDefaultValue));
}
else {
IoWrite8(PCAT_RTC_HI_ADDRESS_PORT, mIndex);
IoWrite8(PCAT_RTC_HI_DATA_PORT, PcdGet8(PcdMsWheaEarlyStorageDefaultValue));
}
}
Status = EFI_SUCCESS;
Cleanup:
return Status;
}
/**
This routine clears all bytes in Data region
**/
STATIC
VOID
MsWheaCMOSStoreClearAll (
VOID
)
{
__MsWheaCMOSRawClear(MsWheaEarlyStorageGetMaxSize(), MS_WHEA_EARLY_STORAGE_OFFSET);
}
/**
This routine returns the maximum number of bytes that can be stored in the PEI event store.
@retval Count The maximum number of bytes that can be stored in the MS WHEA store.
**/
UINT8
EFIAPI
MsWheaEarlyStorageGetMaxSize (
VOID
)
{
return (UINT8)((PcdGet32(PcdMsWheaReportPcatCapacity) - (MS_WHEA_EARLY_STORAGE_OFFSET)) & 0xFF);
}
/**
This routine reads the specified data region from the MS WHEA store.
@param[in] Ptr The pointer to hold intended read data
@param[in] Size The size of intended read data
@param[in] Offset The offset of read data, starting from
MS_WHEA_EARLY_STORAGE_OFFSET
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
EFI_STATUS
EFIAPI
MsWheaEarlyStorageRead (
VOID *Ptr,
UINT8 Size,
UINT8 Offset
)
{
EFI_STATUS Status;
if (Offset >= MsWheaEarlyStorageGetMaxSize()) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
Status = __MsWheaCMOSRawRead(Ptr, Size, MS_WHEA_EARLY_STORAGE_OFFSET + Offset);
Cleanup:
return Status;
}
/**
This routine writes the specified data region from the MS WHEA store.
@param[in] Ptr The pointer to hold intended written data
@param[in] Size The size of intended written data
@param[in] Offset The offset of written data, starting from
MS_WHEA_EARLY_STORAGE_OFFSET
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
EFI_STATUS
EFIAPI
MsWheaEarlyStorageWrite (
VOID *Ptr,
UINT8 Size,
UINT8 Offset
)
{
EFI_STATUS Status;
if (Offset >= MsWheaEarlyStorageGetMaxSize()) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
Status = __MsWheaCMOSRawWrite(Ptr, Size, MS_WHEA_EARLY_STORAGE_OFFSET + Offset);
Cleanup:
return Status;
}
/**
This routine clears the specified data region from the MS WHEA store to PcdMsWheaEarlyStorageDefaultValue.
@param[in] Size The size of intended clear data
@param[in] Offset The offset of clear data, starting from
MS_WHEA_EARLY_STORAGE_OFFSET
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
EFI_STATUS
EFIAPI
MsWheaEarlyStorageClear (
UINT8 Size,
UINT8 Offset
)
{
EFI_STATUS Status;
if (Offset >= MsWheaEarlyStorageGetMaxSize()) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
Status = __MsWheaCMOSRawClear(Size, MS_WHEA_EARLY_STORAGE_OFFSET + Offset);
Cleanup:
return Status;
}

Просмотреть файл

@ -0,0 +1,64 @@
## @file -- MsWheaEarlyStorageLib.inf
#
# This header defines APIs to utilize special memory for MsWheaReport during
# early stage.
#
# Copyright (c) 2018, Microsoft Corporation
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = MsWheaEarlyStorageLib
FILE_GUID = E3E9F981-545E-4AF1-ACFA-44578AB7D159
MODULE_TYPE = BASE
VERSION_STRING = 1.0
LIBRARY_CLASS = MsWheaEarlyStorageLib
#
# The following information is for reference only and not required by the
# build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
MsWheaEarlyStorageLib.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
MsWheaPkg/MsWheaPkg.dec
[LibraryClasses]
BaseLib
DebugLib
IoLib
PcdLib
[Protocols]
[Pcd]
gMsWheaPkgTokenSpaceGuid.PcdMsWheaEarlyStorageDefaultValue
gMsWheaPkgTokenSpaceGuid.PcdMsWheaReportPcatCapacity
[Guids]

53
MsWheaPkg/MsWheaPkg.dec Normal file
Просмотреть файл

@ -0,0 +1,53 @@
## @file
# Package declaration file for Microsoft WHEA Package
#
# Copyright (c) 2018, Microsoft Corporation
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
[Defines]
DEC_SPECIFICATION = 0x00010017
PACKAGE_NAME = MsWheaPkg
PACKAGE_VERSION = 0.1
PACKAGE_GUID = B34D6A40-334D-4596-836E-ECCD0409CD2D
[Guids]
gMsWheaPkgTokenSpaceGuid = { 0x9b859fdb, 0xcae9, 0x44f8, { 0x80, 0x86, 0xbb, 0xc0, 0xb2, 0x69, 0x3a, 0x1d } }
gMsWheaReportServiceGuid = { 0x8efebc4a, 0x5222, 0x409c, { 0xa5, 0x9f, 0x6f, 0x06, 0xdd, 0xb7, 0x96, 0x78 } }
[Includes]
Include
[Protocols]
[Ppis]
[LibraryClasses]
MsWheaEarlyStorageLib|Include/Library/MsWheaEarlyStorageLib.h
[PcdsFeatureFlag]
gMsWheaPkgTokenSpaceGuid.PcdMsWheaReportTestEnable|FALSE|BOOLEAN|0x00000001
[PcdsFixedAtBuild]
gMsWheaPkgTokenSpaceGuid.PcdMsWheaReportPcatCapacity|0x00000100|UINT32|0x00000002
gMsWheaPkgTokenSpaceGuid.PcdMsWheaEarlyStorageDefaultValue|0xFF|UINT8|0x00000003

141
MsWheaPkg/MsWheaPkg.dsc Normal file
Просмотреть файл

@ -0,0 +1,141 @@
## @file
# Microsoft Whea Package, routing ReportStatusCode here to store as Hardware
# Error Record.
#
# Copyright (c) 2018, Microsoft Corporation
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
################################################################################
[Defines]
PLATFORM_NAME = MsWheaPkg
PLATFORM_GUID = EB995458-4F79-49F8-8F1F-977B581701D5
PLATFORM_VERSION = 0.1
DSC_SPECIFICATION = 0x00010005
OUTPUT_DIRECTORY = Build/MsWheaPkg
SUPPORTED_ARCHITECTURES = IA32|X64
BUILD_TARGETS = DEBUG|RELEASE
SKUID_IDENTIFIER = DEFAULT
################################################################################
#
# Library Class section - list of all Library Classes needed by this Platform.
#
################################################################################
[LibraryClasses]
#
# Entry Point Libraries
#
UefiDriverEntryPoint|MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
#
# Common Libraries
#
BaseLib|MdePkg/Library/BaseLib/BaseLib.inf
BaseMemoryLib|MdePkg/Library/BaseMemoryLib/BaseMemoryLib.inf
##MSCHANGE Begin
!if $(TARGET) == DEBUG
#if debug is enabled provide StackCookie support lib so that we can link to /GS exports
RngLib|MdePkg/Library/BaseRngLib/BaseRngLib.inf
NULL|MdePkg/Library/BaseBinSecurityLibRng/BaseBinSecurityLibRng.inf
!endif
##MSCHANGE End
UefiLib|MdePkg/Library/UefiLib/UefiLib.inf
PrintLib|MdePkg/Library/BasePrintLib/BasePrintLib.inf
PcdLib|MdePkg/Library/BasePcdLibNull/BasePcdLibNull.inf
MemoryAllocationLib|MdePkg/Library/UefiMemoryAllocationLib/UefiMemoryAllocationLib.inf
UefiBootServicesTableLib|MdePkg/Library/UefiBootServicesTableLib/UefiBootServicesTableLib.inf
UefiRuntimeServicesTableLib|MdePkg/Library/UefiRuntimeServicesTableLib/UefiRuntimeServicesTableLib.inf
DebugLib|MdePkg/Library/BaseDebugLibNull/BaseDebugLibNull.inf
DebugPrintErrorLevelLib|MdePkg/Library/BaseDebugPrintErrorLevelLib/BaseDebugPrintErrorLevelLib.inf
DevicePathLib|MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/DxeReportStatusCodeLib/DxeReportStatusCodeLib.inf
OemHookStatusCodeLib|MdeModulePkg/Library/OemHookStatusCodeLibNull/OemHookStatusCodeLibNull.inf
HobLib|MdePkg/Library/DxeHobLib/DxeHobLib.inf
SerialPortLib|MdePkg/Library/BaseSerialPortLibNull/BaseSerialPortLibNull.inf
IoLib|MdePkg/Library/BaseIoLibIntrinsic/BaseIoLibIntrinsic.inf
MsWheaEarlyStorageLib|MsWheaPkg/Library/MsWheaEarlyStorageLib/MsWheaEarlyStorageLib.inf
# UNIT TEST APPLICATION RELATED
[LibraryClasses.X64.UEFI_APPLICATION]
UnitTestLib|MsUnitTestPkg/Library/UnitTestLib/UnitTestLib.inf
UnitTestAssertLib|MsUnitTestPkg/Library/UnitTestAssertLib/UnitTestAssertLib.inf
UnitTestLogLib|MsUnitTestPkg/Library/UnitTestLogLib/UnitTestLogLib.inf
UnitTestPersistenceLib|MsUnitTestPkg/Library/UnitTestPersistenceLibNull/UnitTestPersistenceLibNull.inf
UnitTestBootUsbLib|MsUnitTestPkg/Library/UnitTestBootUsbClassLib/UnitTestBootUsbClassLib.inf
UnitTestResultReportLib|MsUnitTestPkg/Library/UnitTestResultReportPlainTextOutputLib/UnitTestResultReportLib.inf
UefiBootManagerLib|MdeModulePkg/Library/UefiBootManagerLib/UefiBootManagerLib.inf
#TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf
PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf
Performance2Lib|MdePkg/Library/BasePerformance2LibNull/BasePerformance2LibNull.inf
PeCoffGetEntryPointLib|MdePkg/Library/BasePeCoffGetEntryPointLib/BasePeCoffGetEntryPointLib.inf
DxeServicesTableLib|MdePkg/Library/DxeServicesTableLib/DxeServicesTableLib.inf
DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf
HiiLib|MdeModulePkg/Library/UefiHiiLib/UefiHiiLib.inf
SortLib|MdeModulePkg/Library/UefiSortLib/UefiSortLib.inf
UefiHiiServicesLib|MdeModulePkg/Library/UefiHiiServicesLib/UefiHiiServicesLib.inf
ShellLib|ShellPkg/Library/UefiShellLib/UefiShellLib.inf
FileHandleLib|MdePkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf
UefiApplicationEntryPoint|MdePkg/Library/UefiApplicationEntryPoint/UefiApplicationEntryPoint.inf
[LibraryClasses.common.PEIM]
PeimEntryPoint|MdePkg/Library/PeimEntryPoint/PeimEntryPoint.inf
PeiServicesLib|MdePkg/Library/PeiServicesLib/PeiServicesLib.inf
PeiServicesTablePointerLib|MdePkg/Library/PeiServicesTablePointerLib/PeiServicesTablePointerLib.inf
HobLib|MdePkg/Library/PeiHobLib/PeiHobLib.inf
MemoryAllocationLib|MdePkg/Library/PeiMemoryAllocationLib/PeiMemoryAllocationLib.inf
ReportStatusCodeLib|MdeModulePkg/Library/PeiReportStatusCodeLib/PeiReportStatusCodeLib.inf
[PcdsFixedAtBuild]
# Enabled support for HwErrRec and increased the size of HwErrRec region on flash
gEfiMdePkgTokenSpaceGuid.PcdHardwareErrorRecordLevel|1
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize|0x00001000
# This is copied from MdePkg.dec for self reference
# gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize|0x400
################################################################################
#
# Components section - list of all Components needed by this Platform.
#
################################################################################
[Components]
MsWheaPkg/Library/MsWheaEarlyStorageLib/MsWheaEarlyStorageLib.inf
[Components.IA32]
MsWheaPkg/MsWheaReport/Pei/MsWheaReportPei.inf {
<LibraryClasses>
DebugLib|MdePkg/Library/BaseDebugLibSerialPort/BaseDebugLibSerialPort.inf
}
[Components.X64]
MsWheaPkg/MsWheaReport/Dxe/MsWheaReportDxe.inf
# UNIT TEST APPLICATION RELATED
MsWheaPkg/UnitTests/MsWheaReportUnitTestApp/MsWheaReportUnitTestApp.inf
[BuildOptions]
*_*_*_CC_FLAGS = -D DISABLE_NEW_DEPRECATED_INTERFACES

Просмотреть файл

@ -0,0 +1,451 @@
/** @file -- MsWheaReportDxe.c
This Dxe driver will produce a RSC listener that listens to reported status codes.
Certains errors will be stored to flash upon reproting, under gEfiHardwareErrorVariableGuid
with VarName "HwErrRecXXXX", where "XXXX" are hexadecimal digits;
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/HobLib.h>
#include <Library/PcdLib.h>
#include <Library/ReportStatusCodeLib.h>
#include <Protocol/ReportStatusCodeHandler.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiRuntimeServicesTableLib.h>
#include "MsWheaReportCommon.h"
#include "MsWheaReportHER.h"
#include "MsWheaEarlyStorageMgr.h"
#include "MsWheaReportList.h"
STATIC EFI_RSC_HANDLER_PROTOCOL *mRscHandlerProtocol = NULL;
STATIC EFI_EVENT mWriteArchAvailEvent = NULL;
STATIC EFI_EVENT mVarArchAvailEvent = NULL;
STATIC EFI_EVENT mExitBootServicesEvent = NULL;
STATIC BOOLEAN mWriteArchAvailable = FALSE;
STATIC BOOLEAN mVarArchAvailable = FALSE;
STATIC BOOLEAN mExitBootHasOccurred = FALSE;
STATIC LIST_ENTRY mMsWheaEntryList;
/**
Handler function that validates input arguments, and store on flash/CMOS for OS to process.
Note: It is the reporter's responsibility to make sure the format of each blob is compliant
with specifications. Malformed data will fail the entire reporting.
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@param[in] PayloadPtr The pointer to reported error block payload, the content will be copied
@param[in] PayloadSize The size of reported error block payload
@retval EFI_SUCCESS Operation is successful
@retval EFI_ACCESS_DENIED Exit boot has locked the report function
@retval EFI_OUT_OF_RESOURCES List cannot make the space for requested error block payload
@retval EFI_INVALID_PARAMETER Null pointer or zero length payload detected
**/
STATIC
EFI_STATUS
MsWheaReportHandlerDxe(
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN VOID *PayloadPtr,
IN UINT32 PayloadSize
)
{
EFI_STATUS Status;
DEBUG((DEBUG_INFO, __FUNCTION__ ": enter...\n"));
if (mExitBootHasOccurred != FALSE) {
// This function is locked due to Exit Boot has occurred
Status = EFI_ACCESS_DENIED;
goto Cleanup;
}
// Input argument sanity check
if ((PayloadPtr == NULL) ||
(PayloadSize == 0) ||
(MsWheaEntryMD == NULL)) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
if ((mWriteArchAvailable != FALSE) && (mVarArchAvailable != FALSE)) {
// Variable service is ready, store to HwErrRecXXXX
Status = MsWheaReportHERAdd(MsWheaEntryMD, PayloadPtr, PayloadSize);
}
else {
// Add to linked list, similar to hob list
Status = MsWheaAddReportEvent(&mMsWheaEntryList, MsWheaEntryMD, PayloadPtr, PayloadSize);
}
Cleanup:
return Status;
}
/**
Added module phase information and route reported status code value and extended data to ReportHwErrRecRouter
for further processing.
@param[in] CodeType Indicates the type of status code being reported.
@param[in] Value Describes the current status of a hardware or software entity. This
includes information about the class and subclass that is used to
classify the entity as well as an operation.
@param[in] Instance The enumeration of a hardware or software entity within the system.
Valid instance numbers start with 1.
@param[in] CallerId This optional parameter may be used to identify the caller. This
parameter allows the status code driver to apply different rules to
different callers.
@param[in] Data This optional parameter may be used to pass additional data.
@retval EFI_SUCCESS Operation is successful
@retval Others Any other error that rises from Variable Services, Boot Services,
Runtime Services, etc.
**/
STATIC
EFI_STATUS
MsWheaRscHandlerDxe (
IN EFI_STATUS_CODE_TYPE CodeType,
IN EFI_STATUS_CODE_VALUE Value,
IN UINT32 Instance,
IN EFI_GUID *CallerId,
IN EFI_STATUS_CODE_DATA *Data OPTIONAL
)
{
MS_WHEA_ERROR_PHASE CurrentPhase;
if ((mWriteArchAvailable != FALSE) && (mVarArchAvailable != FALSE)) {
CurrentPhase = MS_WHEA_PHASE_DXE_RUNTIME;
}
else {
CurrentPhase = MS_WHEA_PHASE_DXE;
}
return ReportHwErrRecRouter(CodeType,
Value,
Instance,
CallerId,
Data,
CurrentPhase,
MsWheaReportHandlerDxe);
}
/**
This routine processes the reported errors during PEI phase through hob list
@retval EFI_SUCCESS Operation is successful
@retval Others See MsWheaReportHandlerDxe function for more details
**/
STATIC
EFI_STATUS
MsWheaProcHob (
VOID
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT16 EntrySize = 0;
VOID *GuidHob = NULL;
VOID *MsWheaReportEntry = NULL;
MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD = NULL;
DEBUG((DEBUG_INFO, __FUNCTION__ ": enter...\n"));
GuidHob = GetFirstGuidHob(&gMsWheaReportServiceGuid);
if (GuidHob == NULL) {
// This means no reported errors during Pei phase, job done!
Status = EFI_SUCCESS;
goto Cleanup;
}
while (GuidHob != NULL) {
MsWheaReportEntry = GET_GUID_HOB_DATA(GuidHob);
EntrySize = GET_GUID_HOB_DATA_SIZE(GuidHob);
MsWheaEntryMD = (MS_WHEA_ERROR_ENTRY_MD *) MsWheaReportEntry;
if ((EntrySize != 0) && (EntrySize >= MsWheaEntryMD->PayloadSize)) {
// Report this entry
Status = MsWheaReportHandlerDxe(MsWheaEntryMD,
MsWheaEntryMD + 1,
MsWheaEntryMD->PayloadSize - sizeof(MS_WHEA_ERROR_ENTRY_MD));
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Hob entry process failed %r\n", Status));
}
}
else {
DEBUG((DEBUG_ERROR, __FUNCTION__": Bad entry: EntrySize: %08X, PayloadSize: %08X\n",
EntrySize,
MsWheaEntryMD->PayloadSize));
}
GuidHob = GetNextGuidHob(&gMsWheaReportServiceGuid, GET_NEXT_HOB(GuidHob));
}
Cleanup:
DEBUG((DEBUG_INFO, __FUNCTION__ ": exit...%r\n", Status));
return Status;
}
/**
This routine processes the reported errors during Dxe phase through linked list
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null head entry pointer detected
@retval Others See MsWheaReportHandlerDxe function for more details
**/
STATIC
EFI_STATUS
MsWheaProcList (
VOID
)
{
EFI_STATUS Status = EFI_SUCCESS;
VOID *MsWheaReportEntry = NULL;
MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD = NULL;
MS_WHEA_LIST_ENTRY *MsWheaListEntry = NULL;
LIST_ENTRY *HeadList = NULL;
DEBUG((DEBUG_INFO, __FUNCTION__ ": enter...\n"));
while (IsListEmpty(&mMsWheaEntryList) == FALSE) {
HeadList = GetFirstNode(&mMsWheaEntryList);
MsWheaListEntry = CR(HeadList, MS_WHEA_LIST_ENTRY, Link, MS_WHEA_LIST_ENTRY_SIGNATURE);
if (MsWheaListEntry->PayloadPtr != NULL) {
MsWheaReportEntry = MsWheaListEntry->PayloadPtr;
MsWheaEntryMD = (MS_WHEA_ERROR_ENTRY_MD *) MsWheaReportEntry;
Status = MsWheaReportHandlerDxe(MsWheaEntryMD,
MsWheaEntryMD + 1,
MsWheaEntryMD->PayloadSize - sizeof(MS_WHEA_ERROR_ENTRY_MD));
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Linked list entry process failed %r\n", Status));
}
}
MsWheaDeleteReportEvent(&mMsWheaEntryList);
}
DEBUG((DEBUG_INFO, __FUNCTION__ ": exit...\n"));
return Status;
}
/**
Process all previously reported status errors during PEI/early Dxe/previous boots
@retval EFI_SUCCESS Operation is successful
@retval Others See each individual function for more details
**/
STATIC
EFI_STATUS
MsWheaProcessPrevError (
VOID
)
{
EFI_STATUS Status;
Status = MsWheaESProcess(MsWheaReportHandlerDxe);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": CMOS entries process failed %r\n", Status));
}
Status = MsWheaProcHob();
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Hob entries process failed %r\n", Status));
}
Status = MsWheaProcList();
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": List entries process failed %r\n", Status));
}
return Status;
}
/**
Callback of exit boot event. This will unregister RSC handler in this module.
**/
STATIC
VOID
MsWheaReportDxeExitBoot (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status;
DEBUG((DEBUG_INFO, __FUNCTION__ ": enter...\n"));
if (mExitBootHasOccurred != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Been here already...\n"));
Status = EFI_ACCESS_DENIED;
}
else {
mExitBootHasOccurred = TRUE;
Status = mRscHandlerProtocol->Unregister(MsWheaRscHandlerDxe);
DEBUG((DEBUG_INFO, __FUNCTION__ ": Protocol unregister result %r\n", Status));
}
DEBUG((DEBUG_INFO, __FUNCTION__ ": exit...%r\n", Status));
}
/**
Register Exit Boot callback and process previous errors when variable service is ready
@param[in] Event Event whose notification function is being invoked.
@param[in] Context The pointer to the notification function's context, which is
implementation-dependent.
**/
STATIC
VOID
MsWheaArchCallback (
IN EFI_EVENT Event,
IN VOID *Context
)
{
EFI_STATUS Status = EFI_SUCCESS;
if ((Event == mWriteArchAvailEvent) && (mWriteArchAvailable == FALSE)) {
mWriteArchAvailable = TRUE;
}
else if ((Event == mVarArchAvailEvent) && (mVarArchAvailable == FALSE)) {
mVarArchAvailable = TRUE;
}
else {
// Unrecognized event or all available already, do nothing
goto Cleanup;
}
if ((mVarArchAvailable == FALSE) || (mWriteArchAvailable == FALSE)) {
// Some protocol(s) not ready
goto Cleanup;
}
// register for the exit boot event
Status = gBS->CreateEventEx(EVT_NOTIFY_SIGNAL,
TPL_NOTIFY,
MsWheaReportDxeExitBoot,
NULL,
&gEfiEventExitBootServicesGuid,
&mExitBootServicesEvent);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ " failed to register of MsWhea report exit boot (%r)\n", Status));
goto Cleanup;
}
// collect all reported events during PEI and pre-DXE Runtime
Status = MsWheaProcessPrevError();
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ " processing hob list failed (%r)\n", Status));
}
if (PcdGetBool(PcdMsWheaReportTestEnable) != FALSE) {
MsWheaInSituTest(MS_WHEA_PHASE_DXE_RUNTIME);
}
Cleanup:
return;
}
/**
Register Write Archetecture and Variable Archetecture callbacks
@param[in] Event Event whose notification function is being invoked.
@param[in] Context The pointer to the notification function's context, which is
implementation-dependent.
**/
STATIC
VOID
MsWheaRegisterCallbacks (
VOID
)
{
VOID *Registration; // Just a dummy, not used
// register for Write Archetecture Protocol Callback
mWriteArchAvailEvent = EfiCreateProtocolNotifyEvent(&gEfiVariableWriteArchProtocolGuid,
TPL_CALLBACK,
MsWheaArchCallback,
NULL,
&Registration);
// register for Variable Archetecture Protocol Callback
mVarArchAvailEvent = EfiCreateProtocolNotifyEvent(&gEfiVariableArchProtocolGuid,
TPL_CALLBACK,
MsWheaArchCallback,
NULL,
&Registration);
}
/**
Entry to MsWheaReportDxe, register RSC handler and callback functions
@param[in] ImageHandle The image handle.
@param[in] SystemTable The system table.
@retval Status From internal routine or boot object, should not fail
**/
EFI_STATUS
EFIAPI
MsWheaReportDxeEntry (
IN EFI_HANDLE ImageHandle,
IN EFI_SYSTEM_TABLE *SystemTable
)
{
EFI_STATUS Status = EFI_SUCCESS;
DEBUG((DEBUG_INFO, __FUNCTION__ ": enter...\n"));
// init linked list, all fields should be 0
InitializeListHead(&mMsWheaEntryList);
// locate the RSC protocol
Status = gBS->LocateProtocol(&gEfiRscHandlerProtocolGuid, NULL, (VOID**)&mRscHandlerProtocol);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ " failed to register MsWhea report RSC handler (%r)\n", Status));
goto Cleanup;
}
// register for the RSC callback handler
Status = mRscHandlerProtocol->Register(MsWheaRscHandlerDxe, TPL_HIGH_LEVEL);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ " failed to register MsWhea report RSC handler (%r)\n", Status));
goto Cleanup;
}
if (PcdGetBool(PcdMsWheaReportTestEnable) != FALSE) {
MsWheaInSituTest(MS_WHEA_PHASE_DXE);
}
MsWheaRegisterCallbacks();
Cleanup:
DEBUG((DEBUG_INFO, __FUNCTION__ ": exit (%r)\n", Status));
return Status;
}

Просмотреть файл

@ -0,0 +1,94 @@
## @file -- MsWheaReportDxe.inf
#
# MsWheaReportDxe implements Microsoft WHEA report service for Dxe phase.
#
# Copyright (c) 2018, Microsoft Corporation
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = MsWheaReportDxe
FILE_GUID = 995F045B-0265-46A4-8D21-001211A24A4F
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
ENTRY_POINT = MsWheaReportDxeEntry
#
# The following information is for reference only and not required by the
# build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
../MsWheaReportCommon.h
../MsWheaReportCommon.c
../MsWheaEarlyStorageMgr.c
../MsWheaEarlyStorageMgr.h
MsWheaReportDxe.c
MsWheaReportHER.c
MsWheaReportHER.h
MsWheaReportList.c
MsWheaReportList.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
MsWheaPkg/MsWheaPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
UefiLib
DebugLib
HobLib
MemoryAllocationLib
PcdLib
PrintLib
ReportStatusCodeLib
UefiBootServicesTableLib
UefiDriverEntryPoint
UefiRuntimeServicesTableLib
MsWheaEarlyStorageLib
[Protocols]
gEfiAcpiTableProtocolGuid ## CONSUMES
gEfiRuntimeArchProtocolGuid ## CONSUMES
gEfiRscHandlerProtocolGuid ## CONSUMES
gEfiVariableWriteArchProtocolGuid ## CONSUMES
gEfiVariableArchProtocolGuid ## CONSUMES
[Pcd]
gMsWheaPkgTokenSpaceGuid.PcdMsWheaReportTestEnable
gMsWheaPkgTokenSpaceGuid.PcdMsWheaReportPcatCapacity
gMsWheaPkgTokenSpaceGuid.PcdMsWheaEarlyStorageDefaultValue
[Guids]
gEfiHardwareErrorVariableGuid ## CONSUMES
gEfiEventExitBootServicesGuid ## CONSUMES
gMsWheaReportServiceGuid ## SOMETIMES_CONSUMES
gEfiFirmwareErrorSectionGuid ## SOMETIMES_CONSUMES
gEfiEventNotificationTypeBootGuid ## SOMETIMES_CONSUMES
[Depex]
gEfiRscHandlerProtocolGuid

Просмотреть файл

@ -0,0 +1,298 @@
/** @file -- MsWheaReportHER.c
This source implements backend routines to support storing persistent hardware
error records in UEFI.
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include <Library/UefiRuntimeServicesTableLib.h>
#include <Library/PrintLib.h>
#include "MsWheaReportHER.h"
/**
This routine accepts the pointer to the MS WHEA entry metadata, payload and payload length, allocate and
fill (AnF) in the buffer with supplied information. Then return the pointer of processed buffer.
Note: Caller is responsible for freeing the valid returned buffer!!!
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@param[in] PayloadPtr The pointer to payload
@param[in, out] PayloadSize The pointer to payload length, this will be updated to the totally
allocated/operated size if operation succeeded
@retval NULL if any errors, otherwise filled and allocated buffer will be returned.
**/
STATIC
VOID *
MsWheaAnFBuffer (
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN OUT UINT32 *PayloadSize,
IN CONST VOID *PayloadPtr
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8 *Buffer = NULL;
UINT32 BufferIndex = 0;
UINT32 ErrorPayloadSize = 0;
EFI_COMMON_ERROR_RECORD_HEADER *CperHdr;
EFI_ERROR_SECTION_DESCRIPTOR *CperErrSecDscp;
EFI_FIRMWARE_ERROR_DATA *EfiFirmwareErrorData;
DEBUG((DEBUG_INFO,__FUNCTION__" enter...\n"));
if ((PayloadSize == NULL) ||
(PayloadPtr == NULL) ||
(MsWheaEntryMD == NULL)) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
ErrorPayloadSize = sizeof(EFI_FIRMWARE_ERROR_DATA) + *PayloadSize;
Buffer = AllocateZeroPool(sizeof(EFI_COMMON_ERROR_RECORD_HEADER) +
sizeof(EFI_ERROR_SECTION_DESCRIPTOR) +
ErrorPayloadSize);
if (Buffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Cleanup;
}
// Grab pointers to each header
CperHdr = (EFI_COMMON_ERROR_RECORD_HEADER*)&Buffer[BufferIndex];
BufferIndex += sizeof(EFI_COMMON_ERROR_RECORD_HEADER);
CperErrSecDscp = (EFI_ERROR_SECTION_DESCRIPTOR*)&Buffer[BufferIndex];
BufferIndex += sizeof(EFI_ERROR_SECTION_DESCRIPTOR);
EfiFirmwareErrorData = (EFI_FIRMWARE_ERROR_DATA*)&Buffer[BufferIndex];
BufferIndex += sizeof(EFI_FIRMWARE_ERROR_DATA);
// Fill out error type based headers according to UEFI Spec...
CreateHeadersDefault(CperHdr,
CperErrSecDscp,
EfiFirmwareErrorData,
MsWheaEntryMD,
ErrorPayloadSize);
// Copy payload section
CopyMem(&Buffer[BufferIndex], PayloadPtr, *PayloadSize);
BufferIndex += (*PayloadSize);
// Update PayloadSize as the recorded error has Headers and Payload merged
*PayloadSize = BufferIndex;
Cleanup:
DEBUG((DEBUG_INFO,__FUNCTION__" exit %r...\n", Status));
return (VOID*) Buffer;
}
/**
This routine accepts the pointer to a UINT16 number. It will iterate through each HwErrRecXXXX and stops
after 0xFFFF iterations or spotted a slot that returns EFI_NOT_FOUND.
@param[out] next The pointer to output result holder
@retval EFI_SUCCESS Entry addition is successful.
@retval EFI_INVALID_PARAMETER Input pointer is NULL.
@retval EFI_OUT_OF_RESOURCES No available slot for HwErrRec.
@retval Others See GetVariable for more details
**/
STATIC
EFI_STATUS
MsWheaFindNextAvailableSlot (
OUT UINT16 *next
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT32 Index = 0;
UINTN Size = 0;
CHAR16 VarName[EFI_HW_ERR_REC_VAR_NAME_LEN];
if (next == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
if ((gRT == NULL) || (gRT->GetVariable == NULL)) {
Status = EFI_NOT_READY;
goto Cleanup;
}
for (Index = 0; Index <= MAX_UINT16; Index++) {
Size = 0;
UnicodeSPrint(VarName, sizeof(VarName), L"%s%04X", EFI_HW_ERR_REC_VAR_NAME, (UINT16)(Index & MAX_UINT16));
Status = gRT->GetVariable(VarName,
&gEfiHardwareErrorVariableGuid,
NULL,
&Size,
NULL);
if (Status == EFI_NOT_FOUND) {
break;
}
}
// Translate result corresponds to this specific function
if (Status == EFI_NOT_FOUND) {
*next = (UINT16)(Index & MAX_UINT16);
Status = EFI_SUCCESS;
} else if (Status == EFI_SUCCESS) {
Status = EFI_OUT_OF_RESOURCES;
} else {
// Do Nothing, pass on the error
}
Cleanup:
return Status;
}
/**
Clear all the HwErrRec entries on flash.
@retval EFI_SUCCESS Entry addition is successful.
@retval Others See GetVariable/SetVariable for more details
**/
EFI_STATUS
EFIAPI
MsWheaClearAllEntries (
VOID
)
{
UINT32 Index = 0;
CHAR16 VarName[EFI_HW_ERR_REC_VAR_NAME_LEN];
UINTN Size = 0;
EFI_STATUS Status = EFI_SUCCESS;
DEBUG((DEBUG_ERROR, __FUNCTION__ " enter\n"));
for (Index = 0; Index <= MAX_UINT16; Index++) {
Size = 0;
UnicodeSPrint(VarName, sizeof(VarName), L"%s%04X", EFI_HW_ERR_REC_VAR_NAME, Index);
Status = gRT->GetVariable(VarName,
&gEfiHardwareErrorVariableGuid,
NULL,
&Size,
NULL);
if (Status == EFI_NOT_FOUND) {
// Do nothing
continue;
}
else if (Status != EFI_BUFFER_TOO_SMALL) {
// We have other problems here..
break;
}
Status = gRT->SetVariable(VarName,
&gEfiHardwareErrorVariableGuid,
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_HARDWARE_ERROR_RECORD,
0,
NULL);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ " Clear HwErrRec has an issue...\n"));
break;
}
}
if ((Status == EFI_SUCCESS) || (Status == EFI_NOT_FOUND)) {
Status = EFI_SUCCESS;
}
DEBUG((DEBUG_ERROR, __FUNCTION__ " exit...\n"));
return Status;
}
/**
This routine accepts the pointer to the MS WHEA entry metadata, error specific data payload and its size
then store on the flash as HwErrRec awaiting to be picked up by OS (Refer to UEFI Spec 2.7A)
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@param[in] PayloadPtr The pointer to reported error block payload, the content will be copied
@param[in] PayloadSize The size of reported error block payload
@retval EFI_SUCCESS Entry addition is successful.
@retval EFI_INVALID_PARAMETER Input has NULL pointer as input.
@retval EFI_OUT_OF_RESOURCES Not enough spcae for the requested space.
**/
EFI_STATUS
EFIAPI
MsWheaReportHERAdd (
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN CONST VOID *PayloadPtr,
IN UINT32 PayloadSize
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT16 Index = 0;
VOID *Buffer = NULL;
UINT32 Size = PayloadSize;
CHAR16 VarName[EFI_HW_ERR_REC_VAR_NAME_LEN];
// 1. Find an available variable name for next write
Status = MsWheaFindNextAvailableSlot(&Index);
if (EFI_ERROR(Status)) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Find the next available slot failed (%r)\n", Status));
goto Cleanup;
}
// 2. Fill out headers
Buffer = MsWheaAnFBuffer(MsWheaEntryMD, &Size, PayloadPtr);
if (Buffer == NULL) {
Status = EFI_OUT_OF_RESOURCES;
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Buffer allocate and fill failed (%r)\n", Status));
goto Cleanup;
}
// 3. Save the record to flash
UnicodeSPrint(VarName, sizeof(VarName), L"%s%04X", EFI_HW_ERR_REC_VAR_NAME, Index);
Status = gRT->SetVariable(VarName,
&gEfiHardwareErrorVariableGuid,
EFI_VARIABLE_NON_VOLATILE |
EFI_VARIABLE_BOOTSERVICE_ACCESS |
EFI_VARIABLE_RUNTIME_ACCESS |
EFI_VARIABLE_HARDWARE_ERROR_RECORD,
Size,
Buffer);
if (EFI_ERROR(Status)) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Write size of %d at index %04X errored with (%r)\n", Size, Index, Status));
} else {
DEBUG((DEBUG_INFO, __FUNCTION__ ": Write size of %d at index %04X succeeded\n", Size, Index));
}
Cleanup:
if (Buffer) {
FreePool(Buffer);
}
DEBUG((DEBUG_INFO, __FUNCTION__ ": exit (%r)\n", Status));
return Status;
}

Просмотреть файл

@ -0,0 +1,70 @@
/** @file -- MsWheaReportHER.h
This header defines API that will save supplied payload via HwErrRec.
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#ifndef __MS_WHEA_REPORT_HER__
#define __MS_WHEA_REPORT_HER__
#include "MsWheaReportCommon.h"
/**
Clear all the HwErrRec entries on flash.
@retval EFI_SUCCESS Entry addition is successful.
@retval Others See GetVariable/SetVariable for more details
**/
EFI_STATUS
EFIAPI
MsWheaClearAllEntries (
VOID
);
/**
This routine accepts the pointer to the MS WHEA entry metadata, error specific data payload and its size
then store on the flash as HwErrRec awaiting to be picked up by OS (Refer to UEFI Spec 2.7A)
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@param[in] PayloadPtr The pointer to reported error block payload, the content will be copied
@param[in] PayloadSize The size of reported error block payload
@retval EFI_SUCCESS Entry addition is successful.
@retval EFI_INVALID_PARAMETER Input has NULL pointer as input.
@retval EFI_OUT_OF_RESOURCES Not enough spcae for the requested space.
**/
EFI_STATUS
EFIAPI
MsWheaReportHERAdd (
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN CONST VOID *PayloadPtr,
IN UINT32 PayloadSize
);
#endif // __MS_WHEA_REPORT_HER__

Просмотреть файл

@ -0,0 +1,201 @@
/** @file -- MsWheaReportList.c
This source implements common methods to support logging of non-fatal Microsoft
WHEA errors in UEFI.
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include "MsWheaReportList.h"
/**
This function creates a new entry to be added to the linked list
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error linked list
@param[in] PayloadPtr The pointer to payload
@param[in] PayloadSize The pointer to payload length
@retval MS_WHEA_LIST_ENTRY * Pointer to the created list entry.
@retval NULL Null pointer due to invalid parameter or out of resources.
**/
STATIC
MS_WHEA_LIST_ENTRY *
CreateNewEntry (
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN CONST VOID *PayloadPtr,
IN UINT32 PayloadSize
)
{
MS_WHEA_LIST_ENTRY *MsWheaListEntry = NULL;
UINT32 Index = 0;
// Input argument sanity check
if ((PayloadPtr == NULL) ||
(PayloadSize == 0) ||
(MsWheaEntryMD == NULL)) {
goto Cleanup;
}
MsWheaListEntry = AllocateZeroPool(sizeof(MS_WHEA_LIST_ENTRY));
if (MsWheaListEntry == NULL) {
goto Cleanup;
}
MsWheaListEntry->Signature = MS_WHEA_LIST_ENTRY_SIGNATURE;
MsWheaListEntry->PayloadPtr = AllocateZeroPool(PayloadSize + sizeof(MS_WHEA_ERROR_ENTRY_MD));
if (MsWheaListEntry->PayloadPtr == NULL) {
FreePool(MsWheaListEntry);
MsWheaListEntry = NULL;
goto Cleanup;
}
// Copy linked list and payload
Index = 0;
CopyMem(&((UINT8*)MsWheaListEntry->PayloadPtr)[Index], MsWheaEntryMD, sizeof(MS_WHEA_ERROR_ENTRY_MD));
Index += sizeof(MS_WHEA_ERROR_ENTRY_MD);
CopyMem(&((UINT8*)MsWheaListEntry->PayloadPtr)[Index], PayloadPtr, PayloadSize);
Index += PayloadSize;
((MS_WHEA_ERROR_ENTRY_MD*)MsWheaListEntry->PayloadPtr)->PayloadSize = Index;
MsWheaListEntry->PayloadSize = Index;
Cleanup:
return MsWheaListEntry;
}
/**
This routine accepts the MS WHEA linked list and the reported data and data length, then add the data to the
existed list, First In First Out (FIFO)
@param[in] MsWheaLinkedList Supplies a MS WHEA error linked list header.
@param[in] PayloadPtr The pointer to reported error block, the content will be copied.
@param[in] PayloadSize The size of reported error block.
@retval EFI_SUCCESS Entry addition is successful.
@retval EFI_INVALID_PARAMETER Input has NULL pointer as input.
@retval EFI_OUT_OF_RESOURCES Not enough spcae for the requested space.
**/
EFI_STATUS
EFIAPI
MsWheaAddReportEvent(
IN LIST_ENTRY *MsWheaLinkedList,
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN CONST VOID *PayloadPtr,
IN UINT32 PayloadSize
)
{
EFI_STATUS Status;
MS_WHEA_LIST_ENTRY *MsWheaListEntry;
// Caller has to supply valid pointers to linked list and data.
if (MsWheaLinkedList == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
MsWheaListEntry = CreateNewEntry(MsWheaEntryMD, PayloadPtr, PayloadSize);
if (MsWheaListEntry == NULL) {
// This error code may not be true, but something is knowingly wrong
Status = EFI_OUT_OF_RESOURCES;
goto Cleanup;
}
// Added the initialized entry into the linked list
InsertTailList(MsWheaLinkedList, &MsWheaListEntry->Link);
Status = EFI_SUCCESS;
Cleanup:
if (EFI_ERROR(Status)) {
// Clean up the memory remainder, if any errors
if ((MsWheaListEntry != NULL) && (MsWheaListEntry->PayloadPtr != NULL)) {
FreePool(MsWheaListEntry->PayloadPtr);
}
if (MsWheaListEntry != NULL) {
FreePool(MsWheaListEntry);
}
}
return Status;
}
/**
This routine accepts the MS WHEA linked list, remove and free an element from the list
@param[in] MsWheaLinkedList Supplies a MS WHEA linked list header.
@retval EFI_SUCCESS Entry addition is successful.
@retval EFI_INVALID_PARAMETER Input has NULL pointer as input.
**/
EFI_STATUS
EFIAPI
MsWheaDeleteReportEvent(
IN LIST_ENTRY *MsWheaLinkedList
)
{
EFI_STATUS Status;
MS_WHEA_LIST_ENTRY *MsWheaListEntry = NULL;
LIST_ENTRY *HeadList = NULL;
// Caller has to supply valid pointers to linked list.
if (MsWheaLinkedList == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
// linked list needs to have content, if not, it shouldn't be an issue;
if (IsListEmpty(MsWheaLinkedList) != FALSE) {
Status = EFI_SUCCESS;
goto Cleanup;
}
// Retrieve a temporary data holder
HeadList = GetFirstNode(MsWheaLinkedList);
if (HeadList == NULL) {
// Shouldn't happen, since we've checked the linked list has more than one entry...
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
MsWheaListEntry = CR(HeadList, MS_WHEA_LIST_ENTRY, Link, MS_WHEA_LIST_ENTRY_SIGNATURE);
// House keeping for the linked list
RemoveEntryList(HeadList);
if (MsWheaListEntry->PayloadPtr != NULL) {
FreePool(MsWheaListEntry->PayloadPtr);
}
FreePool(MsWheaListEntry);
Status = EFI_SUCCESS;
Cleanup:
return Status;
}

Просмотреть файл

@ -0,0 +1,83 @@
/** @file -- MsWheaReportList.h
This header defines API that will save supplied payload on heap for pre-ExitBoot usage.
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#ifndef __MS_WHEA_REPORT_LIST__
#define __MS_WHEA_REPORT_LIST__
#include "MsWheaReportCommon.h"
#define MS_WHEA_LIST_ENTRY_SIGNATURE MS_WHEA_ERROR_SIGNATURE
// The linked list node to recover necessary information from each error block
typedef struct MS_WHEA_LIST_ENTRY_T_DEF {
UINT32 Signature;
UINT32 PayloadSize;
VOID *PayloadPtr;
LIST_ENTRY Link;
} MS_WHEA_LIST_ENTRY;
/**
This routine accepts the MS WHEA metadata and the reported data and data length, then add the data to the
existed list, First In First Out (FIFO)
@param[in] MsWheaLinkedList Supplies a MS WHEA error linked list header.
@param[in] PayloadPtr The pointer to reported error block, the content will be copied.
@param[in] PayloadSize The size of reported error block.
@retval EFI_SUCCESS Entry addition is successful.
@retval EFI_INVALID_PARAMETER Input has NULL pointer as input.
@retval EFI_OUT_OF_RESOURCES Not enough spcae for the requested space.
**/
EFI_STATUS
EFIAPI
MsWheaAddReportEvent(
IN LIST_ENTRY *MsWheaLinkedList,
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN CONST VOID *PayloadPtr,
IN UINT32 PayloadSize
);
/**
This routine accepts the MS WHEA metadata, remove and free an element from the list
@param[in] MsWheaLinkedList Supplies a MS WHEA linked list header.
@retval EFI_SUCCESS Entry addition is successful.
@retval EFI_INVALID_PARAMETER Input has NULL pointer as input.
**/
EFI_STATUS
EFIAPI
MsWheaDeleteReportEvent(
IN LIST_ENTRY *MsWheaLinkedList
);
#endif // __MS_WHEA_REPORT_LIST__

Просмотреть файл

@ -0,0 +1,801 @@
/** @file -- MsWheaEarlyStorageMgr.c
This source utilizes early storage APIs for MsWheaReport usage.
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include <Uefi/UefiBaseType.h>
#include <Library/MsWheaEarlyStorageLib.h>
#include "MsWheaEarlyStorageMgr.h"
typedef struct _MS_WHEA_EARLY_STORAGE_HEADER {
UINT32 Signature;
UINT8 IsStorageFull;
UINT8 Reserved;
MS_WHEA_ERROR_PHASE FullPhase;
} MS_WHEA_EARLY_STORAGE_HEADER;
#define MS_WHEA_EARLY_STORAGE_SIGNATURE MS_WHEA_ERROR_SIGNATURE
#define MS_WHEA_EARLY_STORAGE_HEADER_SIZE (sizeof(MS_WHEA_EARLY_STORAGE_HEADER))
#define MS_WHEA_EARLY_STORAGE_DATA_OFFSET MS_WHEA_EARLY_STORAGE_HEADER_SIZE
/**
This routine returns the maximum number of bytes that can be stored in the PEI event store.
@retval Count The maximum number of bytes that can be stored in the MS WHEA store.
**/
STATIC
UINT8
MsWheaESGetMaxDataCount (
VOID
)
{
return (UINT8)((MsWheaEarlyStorageGetMaxSize() - (MS_WHEA_EARLY_STORAGE_DATA_OFFSET)) & 0xFF);
}
/**
This routine reads the specified data region from the MS WHEA store.
@param[in] Ptr The pointer to hold intended read data
@param[in] Size The size of intended read data
@param[in] Offset The offset of read data, starting from
Early MS_WHEA_EARLY_STORAGE_DATA_OFFSET
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
STATIC
EFI_STATUS
MsWheaESReadData (
VOID *Ptr,
UINT8 Size,
UINT8 Offset
)
{
EFI_STATUS Status;
if (Offset >= MsWheaESGetMaxDataCount()) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
Status = MsWheaEarlyStorageRead(Ptr, Size, MS_WHEA_EARLY_STORAGE_DATA_OFFSET + Offset);
Cleanup:
return Status;
}
/**
This routine writes the specified data region from the MS WHEA store.
@param[in] Ptr The pointer to hold intended written data
@param[in] Size The size of intended written data
@param[in] Offset The offset of written data, starting from
MS_WHEA_EARLY_STORAGE_DATA_OFFSET
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
STATIC
EFI_STATUS
MsWheaESWriteData (
VOID *Ptr,
UINT8 Size,
UINT8 Offset
)
{
EFI_STATUS Status;
if (Offset >= MsWheaESGetMaxDataCount()) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
Status = MsWheaEarlyStorageWrite(Ptr, Size, MS_WHEA_EARLY_STORAGE_DATA_OFFSET + Offset);
Cleanup:
return Status;
}
/**
This routine clears the specified data region from the MS WHEA store.
@param[in] Size The size of intended clear data
@param[in] Offset The offset of clear data, starting from
Early MS_WHEA_EARLY_STORAGE_DATA_OFFSET
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer or zero or over length request detected
**/
STATIC
EFI_STATUS
MsWheaESClearData (
UINT8 Size,
UINT8 Offset
)
{
EFI_STATUS Status;
if (Offset >= MsWheaESGetMaxDataCount()) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
Status = MsWheaEarlyStorageClear(Size, MS_WHEA_EARLY_STORAGE_DATA_OFFSET + Offset);
Cleanup:
return Status;
}
/**
This routine dumps the contents of the early storage.
**/
VOID
EFIAPI
MsWheaESDump (
VOID
)
{
UINT8 Data;
UINT8 Index;
EFI_STATUS Status;
DEBUG((DEBUG_INFO, "CMOS MS WHEA Store..."));
for (Index = 0; Index < MsWheaEarlyStorageGetMaxSize(); Index ++) {
Status = MsWheaESReadData(&Data, sizeof(Data), Index);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__": Reading Early Storage %d failed %r", Index, Status));
goto Cleanup;
}
if ((Index % 16) == 0) {
DEBUG((DEBUG_INFO, "\n0x%02x: ", Index));
}
DEBUG((DEBUG_INFO, "%02x ", Data));
}
Cleanup:
DEBUG((DEBUG_INFO, "\n"));
return;
}
/**
This routine clears all bytes in Data region
**/
STATIC
VOID
MsWheaESClearAllData (
VOID
)
{
MsWheaESClearData(MsWheaESGetMaxDataCount(), MS_WHEA_EARLY_STORAGE_DATA_OFFSET);
}
/**
This routine reads the Early Storage MS WHEA store header.
@param Header Supplies a pointer that will hold the Early Storage header.
**/
STATIC
VOID
MsWheaESReadHeader (
MS_WHEA_EARLY_STORAGE_HEADER *Header
)
{
if (Header == NULL) {
return;
}
MsWheaEarlyStorageRead(Header, MS_WHEA_EARLY_STORAGE_HEADER_SIZE, 0);
}
/**
This routine writes the passed Early Storage MS WHEA store header.
@param Header Supplies a pointer that holds the target Early Storage header.
**/
STATIC
VOID
MsWheaESWriteHeader (
MS_WHEA_EARLY_STORAGE_HEADER *Header
)
{
if (Header == NULL) {
return;
}
MsWheaEarlyStorageWrite(Header, MS_WHEA_EARLY_STORAGE_HEADER_SIZE, 0);
}
/**
This routine returns a boolean indicating if the MS WHEA store is valid.
@retval TRUE if the MS WHEA store is valid, else FALSE.
**/
STATIC
BOOLEAN
MsWheaESRegionIsValid (
VOID
)
{
MS_WHEA_EARLY_STORAGE_HEADER Header;
MsWheaESReadHeader(&Header);
if (Header.Signature != MS_WHEA_EARLY_STORAGE_SIGNATURE) {
return FALSE;
}
else {
return TRUE;
}
}
/**
This routine finds a contiguous memory that has default value of specified size in data region
from the MS WHEA store.
@param[in] Size The size of intended clear data
@param[out] Offset The pointer to receive returned offset value, starting from
Early MS_WHEA_EARLY_STORAGE_DATA_OFFSET
@retval EFI_SUCCESS Operation is successful
@retval EFI_OUT_OF_RESOURCES Null pointer or zero or over length request detected
**/
STATIC
EFI_STATUS
MsWheaESFindSlot (
IN UINT8 Size,
IN UINT8 *Offset
)
{
UINT16 i = 0;
UINT8 val = 0;
UINT8 ceiling;
UINT8 remainder = Size;
EFI_STATUS Status = EFI_OUT_OF_RESOURCES;
ceiling = MsWheaESGetMaxDataCount();
for (i = 0; i < ceiling; i ++) {
if (remainder == Size) {
*Offset = (UINT8) i;
}
MsWheaESReadData(&val, sizeof(UINT8), (UINT8) i);
if (val != PcdGet8(PcdMsWheaEarlyStorageDefaultValue)) {
remainder = Size;
continue;
}
if (remainder > 0) {
remainder --;
} else {
Status = EFI_SUCCESS;
break;
}
}
return Status;
}
/**
This routine initialized the Early Storage MS WHEA store.
**/
VOID
EFIAPI
MsWheaESInit (
VOID
)
{
MS_WHEA_EARLY_STORAGE_HEADER Header;
MsWheaESReadHeader(&Header);
// Check if the Early Storage has the signature. If it does, the store has already been initialized
// and there's nothing more to do.
if (Header.Signature == MS_WHEA_EARLY_STORAGE_SIGNATURE) {
goto Cleanup;
}
DEBUG((DEBUG_INFO, __FUNCTION__ ": init early storage...\n"));
// Clear the rest of the Early Storage store.
MsWheaESClearAllData();
// Zero all the fields in the
SetMem(&Header, MS_WHEA_EARLY_STORAGE_HEADER_SIZE, 0);
// Sign the header signature.
Header.Signature = MS_WHEA_EARLY_STORAGE_SIGNATURE;
MsWheaESWriteHeader(&Header);
Cleanup:
MsWheaESDump();
return;
}
/**
This routine will extract necessary Rev 0 information from supplied metadata and store onto the next
contiguously available Early Storage data region
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@retval EFI_SUCCESS Operation is successful
@retval Others See MsWheaESFindSlot and MsWheaESWriteData for more details
**/
STATIC
EFI_STATUS
MsWheaESV0InfoStore (
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD
)
{
UINT8 Offset = 0;
EFI_STATUS Status;
MS_WHEA_EARLY_STORAGE_ENTRY_V0 WheaV0;
Status = MsWheaESFindSlot(sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V0), &Offset);
if (EFI_ERROR(Status) != FALSE) {
goto Cleanup;
}
WheaV0.Rev = MsWheaEntryMD->MsWheaErrorHdr.Rev;
WheaV0.Phase = MsWheaEntryMD->MsWheaErrorHdr.Phase;
WheaV0.ErrorStatusCode = MsWheaEntryMD->ErrorStatusCode;
Status = MsWheaESWriteData(&WheaV0, sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V0), Offset);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Clear V0 Early Storage failed at %d %r\n", Offset, Status));
goto Cleanup;
}
Cleanup:
return Status;
}
/**
This routine will extract necessary Rev 1 information from supplied metadata and store onto the next
contiguously available Early Storage data region
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@retval EFI_SUCCESS Operation is successful
@retval Others See MsWheaESFindSlot and MsWheaESWriteData for more
details
**/
STATIC
EFI_STATUS
MsWheaESV1InfoStore (
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD
)
{
UINT8 Offset = 0;
EFI_STATUS Status;
MS_WHEA_EARLY_STORAGE_ENTRY_V1 WheaV1;
Status = MsWheaESFindSlot(sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V1), &Offset);
if (EFI_ERROR(Status) != FALSE) {
goto Cleanup;
}
WheaV1.Rev = MsWheaEntryMD->MsWheaErrorHdr.Rev;
WheaV1.Phase = MsWheaEntryMD->MsWheaErrorHdr.Phase;
WheaV1.ErrorStatusCode = MsWheaEntryMD->ErrorStatusCode;
WheaV1.CriticalInfo = MsWheaEntryMD->MsWheaErrorHdr.CriticalInfo;
WheaV1.ReporterID = MsWheaEntryMD->MsWheaErrorHdr.ReporterID;
Status = MsWheaESWriteData(&WheaV1, sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V1), Offset);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Clear V0 Early Storage failed at %d %r\n", Offset, Status));
goto Cleanup;
}
Cleanup:
return Status;
}
/**
This routine will read Rev 0 information from specified offset on Early Storage data region and fill in the
metadata based on read value
@param[out] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@param[in, out] Offset The pointer to specified offset, will be updated to the end of
processed data upon successful operation
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer detected
@retval Others See MsWheaESFindSlot and MsWheaESReadData for more
details
**/
STATIC
EFI_STATUS
MsWheaESGetV0Info (
OUT MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN OUT UINT8 *Offset
)
{
EFI_STATUS Status;
MS_WHEA_EARLY_STORAGE_ENTRY_V0 WheaV0;
if (MsWheaEntryMD == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
SetMem(&WheaV0, sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V0), 0);
SetMem(MsWheaEntryMD, sizeof(MS_WHEA_ERROR_ENTRY_MD), 0);
Status = MsWheaESReadData(&WheaV0, sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V0), *Offset);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Read V0 Early Storage storage failed at %d %r\n", Offset, Status));
goto Cleanup;
}
MsWheaEntryMD->MsWheaErrorHdr.Signature = MS_WHEA_ERROR_SIGNATURE;
MsWheaEntryMD->MsWheaErrorHdr.Rev = WheaV0.Rev;
MsWheaEntryMD->MsWheaErrorHdr.Phase = WheaV0.Phase;
MsWheaEntryMD->MsWheaErrorHdr.ErrorSeverity = EFI_GENERIC_ERROR_FATAL;
MsWheaEntryMD->ErrorStatusCode = WheaV0.ErrorStatusCode;
MsWheaEntryMD->PayloadSize = sizeof(MS_WHEA_ERROR_ENTRY_MD) + sizeof(MS_WHEA_ERROR_HDR);
Status = MsWheaESClearData(sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V0), *Offset);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Clear V0 Early Storage storage failed at %d %r\n", Offset, Status));
goto Cleanup;
}
*Offset = *Offset + sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V0);
Cleanup:
return Status;
}
/**
This routine will read Rev 1 information from specified offset on Early Storage data region and fill in the
metadata based on read value
@param[out] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@param[in, out] Offset The pointer to specified offset, will be updated to the end of
processed data upon successful operation
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer detected
@retval Others See MsWheaESFindSlot and MsWheaESReadData for more
details
**/
STATIC
EFI_STATUS
MsWheaESGetV1Info (
OUT MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN UINT8 *Offset
)
{
EFI_STATUS Status;
MS_WHEA_EARLY_STORAGE_ENTRY_V1 WheaV1;
if (MsWheaEntryMD == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
SetMem(&WheaV1, sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V1), 0);
SetMem(MsWheaEntryMD, sizeof(MS_WHEA_ERROR_ENTRY_MD), 0);
Status = MsWheaESReadData(&WheaV1, sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V1), *Offset);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Read V1 Early Storage storage failed at %d %r\n", Offset, Status));
goto Cleanup;
}
MsWheaEntryMD->MsWheaErrorHdr.Signature = MS_WHEA_ERROR_SIGNATURE;
MsWheaEntryMD->MsWheaErrorHdr.Rev = WheaV1.Rev;
MsWheaEntryMD->MsWheaErrorHdr.Phase = WheaV1.Phase;
MsWheaEntryMD->MsWheaErrorHdr.ErrorSeverity = EFI_GENERIC_ERROR_FATAL;
MsWheaEntryMD->MsWheaErrorHdr.CriticalInfo = WheaV1.CriticalInfo;
MsWheaEntryMD->MsWheaErrorHdr.ReporterID = WheaV1.ReporterID;
MsWheaEntryMD->ErrorStatusCode = WheaV1.ErrorStatusCode;
MsWheaEntryMD->PayloadSize = sizeof(MS_WHEA_ERROR_ENTRY_MD) + sizeof(MS_WHEA_ERROR_HDR);
Status = MsWheaESClearData(sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V1), *Offset);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Clear V1 Early Storage storage failed at %d %r\n", Offset, Status));
goto Cleanup;
}
*Offset = *Offset + sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_V1);
Cleanup:
return Status;
}
/**
This routine will Set Early Storage header IsStorageFull flag and mark the system stage if the signature is
legit
@param[in] Phase Current envirnment stage by the time of report
@retval EFI_SUCCESS Operation is successful
@retval EFI_NOT_FOUND Early Storage header region is not valid
@retval Others See MsWheaESFindSlot and MsWheaESReadData for more
details
**/
STATIC
EFI_STATUS
MsWheaESSetHeaderFull (
MS_WHEA_ERROR_PHASE Phase
)
{
EFI_STATUS Status;
MS_WHEA_EARLY_STORAGE_HEADER Header;
MsWheaESReadHeader(&Header);
if (Header.Signature != MS_WHEA_EARLY_STORAGE_SIGNATURE) {
Status = EFI_NOT_FOUND;
goto Cleanup;
}
if (Header.IsStorageFull != FALSE) {
Status = EFI_SUCCESS;
goto Cleanup;
}
// Set this field to any non-zero value;
Header.IsStorageFull = PcdGet8(PcdMsWheaEarlyStorageDefaultValue);
Header.FullPhase = Phase;
MsWheaESWriteHeader(&Header);
Status = EFI_SUCCESS;
Cleanup:
return Status;
}
/**
This routine will read Early Storage header and fill out the Metadata if header indicates the Early Storage
is full
@retval EFI_SUCCESS Operation is successful
@retval EFI_NOT_STARTED Metadata is not filled as Early Storage is not full
@retval EFI_INVALID_PARAMETER Null pointer detected
@retval EFI_NOT_FOUND Early Storage header region is not valid
@retval Others See MsWheaESFindSlot and MsWheaESReadData for more
details
**/
STATIC
EFI_STATUS
MsWheaESCheckHeader (
OUT MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD
)
{
EFI_STATUS Status;
MS_WHEA_EARLY_STORAGE_HEADER Header;
MsWheaESReadHeader(&Header);
if (Header.Signature != MS_WHEA_EARLY_STORAGE_SIGNATURE) {
Status = EFI_NOT_FOUND;
goto Cleanup;
}
if (Header.IsStorageFull == FALSE) {
Status = EFI_NOT_STARTED;
goto Cleanup;
}
if (MsWheaEntryMD == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
SetMem(MsWheaEntryMD, sizeof(MS_WHEA_ERROR_ENTRY_MD), 0);
MsWheaEntryMD->MsWheaErrorHdr.Signature = MS_WHEA_ERROR_SIGNATURE;
MsWheaEntryMD->MsWheaErrorHdr.Rev = MS_WHEA_REV_0;
MsWheaEntryMD->MsWheaErrorHdr.Phase = Header.FullPhase;
MsWheaEntryMD->MsWheaErrorHdr.ErrorSeverity = EFI_GENERIC_ERROR_RECOVERABLE;
MsWheaEntryMD->ErrorStatusCode = MS_WHEA_ERROR_EARLY_STORAGE_STORE_FULL;
MsWheaEntryMD->PayloadSize = sizeof(MS_WHEA_ERROR_ENTRY_MD) + sizeof(MS_WHEA_ERROR_HDR);
// Reset the header after processing
SetMem(&Header, MS_WHEA_EARLY_STORAGE_HEADER_SIZE, 0);
Header.Signature = MS_WHEA_EARLY_STORAGE_SIGNATURE;
MsWheaESWriteHeader(&Header);
Cleanup:
return Status;
}
/**
This routine will store data onto Early Storage data region based on supplied MS WHEA metadata
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@retval EFI_SUCCESS Operation is successful
@retval Others See MsWheaESFindSlot and MsWheaESWriteData for more
details
**/
EFI_STATUS
EFIAPI
MsWheaESStoreEntry (
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD
)
{
MS_WHEA_REV Rev = 0;
EFI_STATUS Status = EFI_SUCCESS;
if (MsWheaEntryMD == NULL) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": input pointer cannot be null!\n"));
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
// Make sure the Early Storage is valid.
if (MsWheaESRegionIsValid() == FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": the Early Storage is not valid!\n"));
Status = EFI_NOT_FOUND;
goto Cleanup;
}
Rev = MsWheaEntryMD->MsWheaErrorHdr.Rev;
switch (Rev) {
case MS_WHEA_REV_0:
// Fall through
case MS_WHEA_REV_WILDCARD:
// Store Rev0/Wildcard structure
Status = MsWheaESV0InfoStore(MsWheaEntryMD);
break;
case MS_WHEA_REV_1:
// Store Rev1 structure
Status = MsWheaESV1InfoStore(MsWheaEntryMD);
break;
default:
// Any unsupported revisions are not stored
Status = EFI_UNSUPPORTED;
break;
}
if (Status == EFI_OUT_OF_RESOURCES) {
// Early Storage is full, write the header error section
MsWheaESSetHeaderFull(MsWheaEntryMD->MsWheaErrorHdr.Phase);
}
Cleanup:
return Status;
}
/**
This routine processes the stored errors on Early Storage data region
@param[in] ReportFn Callback function when a MS WHEA metadata is ready to report
@retval EFI_SUCCESS Operation is successful
@retval EFI_INVALID_PARAMETER Null pointer detected
@retval Others See implementation specific functions and MS_WHEA_ERR_REPORT_PS_FN
definition for more details
**/
EFI_STATUS
EFIAPI
MsWheaESProcess (
IN MS_WHEA_ERR_REPORT_PS_FN ReportFn
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT8 Index = 0;
MS_WHEA_REV mRevInfo;
MS_WHEA_ERROR_ENTRY_MD MsWheaEntryMD;
DEBUG((DEBUG_INFO, __FUNCTION__ ": enter...\n"));
if (ReportFn == NULL) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Input fucntion pointer cannot be null!\n"));
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
// Make sure the Early Storage is valid.
if (MsWheaESRegionIsValid() == FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": the Early Storage is not valid!\n"));
Status = EFI_NOT_FOUND;
goto Cleanup;
}
// Check if there is indication of Early Storage full, report it if so
Status = MsWheaESCheckHeader(&MsWheaEntryMD);
if (EFI_ERROR(Status) == FALSE) {
Status = ReportFn(&MsWheaEntryMD, &MsWheaEntryMD.MsWheaErrorHdr, sizeof(MS_WHEA_ERROR_HDR));
}
else {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Early Storage header check status: %r\n", Status));
}
// Go through normal entries
while (Index < (MsWheaESGetMaxDataCount() - sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_COMMON))) {
Status = MsWheaESReadData(&mRevInfo,
sizeof(MS_WHEA_REV),
Index + OFFSET_OF(MS_WHEA_EARLY_STORAGE_ENTRY_COMMON, Rev));
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Early Storage storage read Index %d failed: %r\n", Index, Status));
Index += sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_COMMON);
continue;
}
switch (mRevInfo) {
case MS_WHEA_REV_WILDCARD:
// Fall through
case MS_WHEA_REV_0:
Status = MsWheaESGetV0Info(&MsWheaEntryMD, &Index);
if (EFI_ERROR(Status) == FALSE) {
Status = ReportFn(&MsWheaEntryMD, &MsWheaEntryMD.MsWheaErrorHdr, sizeof(MS_WHEA_ERROR_HDR));
}
else {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": V0 Early Storage storage process failed %r\n", Status));
Index += sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_COMMON);
}
break;
case MS_WHEA_REV_1:
Status = MsWheaESGetV1Info(&MsWheaEntryMD, &Index);
if (EFI_ERROR(Status) == FALSE) {
Status = ReportFn(&MsWheaEntryMD, &MsWheaEntryMD.MsWheaErrorHdr, sizeof(MS_WHEA_ERROR_HDR));
}
else {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": V1 Early Storage storage process failed %r\n", Status));
Index += sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_COMMON);
}
break;
default:
Index += sizeof(MS_WHEA_EARLY_STORAGE_ENTRY_COMMON);
break;
}
}
// This is needed incase there is leftover garbage in default/failed cases
MsWheaESClearAllData();
Cleanup:
DEBUG((DEBUG_INFO, __FUNCTION__ ": exit...\n"));
return Status;
}

Просмотреть файл

@ -0,0 +1,74 @@
/** @file -- MsWheaEarlyStorageMgr.h
This header defines APIs to manipulate early storage for MsWheaReport usage.
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#ifndef __MS_WHEA_EARLY_STORAGE_MGR__
#define __MS_WHEA_EARLY_STORAGE_MGR__
#include "MsWheaReportCommon.h"
/**
This routine initialized the Early Storage MS WHEA store.
**/
VOID
EFIAPI
MsWheaESInit (
VOID
);
/**
This routine will store data onto Early Storage data region based on supplied MS WHEA metadata
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@retval EFI_SUCCESS Operation is successful
@retval Others See MsWheaStoreCMOSFindSlot and MsWheaCMOSStoreWriteData for more details
**/
EFI_STATUS
EFIAPI
MsWheaESStoreEntry (
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD
);
/**
This routine processes the stored errors on Early Storage data region
@param[in] ReportFn Callback function when a MS WHEA metadata is ready to report
@retval EFI_SUCCESS Operation is successful
@retval Others See implementation specific functions and MS_WHEA_ERR_REPORT_PS_FN
definition for more details
**/
EFI_STATUS
EFIAPI
MsWheaESProcess (
IN MS_WHEA_ERR_REPORT_PS_FN ReportFn
);
#endif // __MS_WHEA_EARLY_STORAGE_MGR__

Просмотреть файл

@ -0,0 +1,579 @@
/** @file -- MsWheaReportCommon.c
This source implements MsWheaReport helpers shared by both PEI and DXE phases.
The APIs include populating fields in Common Platform Error (CPER) related headers,
fill out timestamp based on CMOS, CMOS information storage, etc. The populated
headers can be used to report Microsoft WHEA to OS via Hardware Error Records (HwErrRec).
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include <Library/ReportStatusCodeLib.h>
#include "MsWheaEarlyStorageMgr.h"
#include "MsWheaReportCommon.h"
#define CPER_HDR_SEC_CNT 0x01
#define MS_WHEA_IN_SITU_TEST_ERROR_CODE 0xA0A0A0A0
#define MS_WHEA_IN_SITU_TEST_ERROR_SIZE 0x40
#define MS_WHEA_IN_SITU_TEST_ERROR_SHORT_SIZE 0x08
#define MS_WHEA_IN_SITU_TEST_ERROR_PATTERN 0xC0
#define MS_WHEA_IN_SITU_TEST_ERROR_PHASE_BSFT 0x03
#define MS_WHEA_IN_SITU_TEST_ERROR_PI_BMSK 0x07
#define MS_WHEA_IN_SITU_TEST_ERROR_PATTERN 0xC0
#define MS_WHEA_IN_SITU_TEST_ERROR_REV_UNSUP 0x66
#define MS_WHEA_IN_SITU_TEST_ERROR_INFO 0x30303030
#define MS_WHEA_IN_SITU_TEST_ERROR_ID 0x50505050
/************************************ Header Section *************************************/
/**
This routine will fill out the CPER header for caller.
Zeroed: Flags, PersistenceInfo;
@param[out] CperHdr Supplies a pointer to CPER header structure
@param[in] PayloadSize Length of entire payload to be included within this entry, refer to
UEFI Spec for more information
@param[in] ErrorSeverity Error severity of this entry
@param[in] ErrorStatusCode Reported Status Code from ReportStatucCode* function
@param[in] RecordIDGuid RecordID for error source identification, default to
gMsWheaReportServiceGuid if NULL
@param[in] NotificationType Notification type GUID of this entry, default to
gEfiEventNotificationTypeBootGuid if NULL
@retval EFI_SUCCESS The operation completed successfully
@retval EFI_INVALID_PARAMETER Any required input pointer is NULL
**/
STATIC
EFI_STATUS
CreateCperHdrDefaultMin (
OUT EFI_COMMON_ERROR_RECORD_HEADER *CperHdr,
IN UINT32 PayloadSize,
IN UINT32 ErrorSeverity,
IN UINT32 ErrorStatusCode,
IN EFI_GUID *RecordIDGuid OPTIONAL,
IN EFI_GUID *NotificationType OPTIONAL
)
{
EFI_STATUS Status = EFI_SUCCESS;
if (CperHdr == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
SetMem(CperHdr, sizeof(EFI_COMMON_ERROR_RECORD_HEADER), 0);
CperHdr->SignatureStart = EFI_ERROR_RECORD_SIGNATURE_START;
CperHdr->Revision = EFI_ERROR_RECORD_REVISION;
CperHdr->SignatureEnd = EFI_ERROR_RECORD_SIGNATURE_END;
CperHdr->SectionCount = CPER_HDR_SEC_CNT;
CperHdr->ErrorSeverity = ErrorSeverity;
CperHdr->ValidationBits = EFI_ERROR_RECORD_HEADER_PLATFORM_ID_VALID;
CperHdr->RecordLength = (UINT32)(sizeof(EFI_COMMON_ERROR_RECORD_HEADER) + sizeof(EFI_ERROR_SECTION_DESCRIPTOR) + PayloadSize);
CperHdr->ValidationBits &= (~EFI_ERROR_RECORD_HEADER_TIME_STAMP_VALID);
CopyGuid(&CperHdr->PlatformID, &gMsWheaReportServiceGuid);
//SetMem(&CperHdr->PartitionID, sizeof(EFI_GUID), 0); // Not used, left zero.
if (RecordIDGuid != NULL) {
CopyGuid(&CperHdr->CreatorID, RecordIDGuid);
}
else {
// Default to MS WHEA Service guid
CopyGuid(&CperHdr->CreatorID, &gMsWheaReportServiceGuid);
}
if (NotificationType) {
CopyGuid(&CperHdr->NotificationType, NotificationType);
}
else {
// Default to Boot Error
CopyGuid(&CperHdr->NotificationType, &gEfiEventNotificationTypeBootGuid);
}
// This is can be modified further
CperHdr->RecordID = ErrorStatusCode;
CperHdr->Flags |= EFI_HW_ERROR_FLAGS_PREVERR;
//CperHdr->PersistenceInfo = 0;// Untouched.
//SetMem(&CperHdr->Resv1, sizeof(CperHdr->Resv1), 0); // Reserved field, should be 0.
Cleanup:
return Status;
}
/**
This routine will fill out the CPER Section Descriptor for caller.
Zeroed: SectionFlags, FruId, FruString;
@param[out] CperErrSecDscp Supplies a pointer to CPER header structure
@param[in] PayloadSize Length of entire payload to be included within this entry, refer to
UEFI Spec for more information
@param[in] ErrorSeverity Error severity of this entry
@param[in] SectionType Section type GUID of this entry, default to
gEfiFirmwareErrorSectionGuid if NULL
@retval EFI_SUCCESS The operation completed successfully
@retval EFI_INVALID_PARAMETER Any required input pointer is NULL
**/
STATIC
EFI_STATUS
CreateCperErrSecDscpDefaultMin (
OUT EFI_ERROR_SECTION_DESCRIPTOR *CperErrSecDscp,
IN UINT32 PayloadSize,
IN UINT32 ErrorSeverity,
IN EFI_GUID *SectionType OPTIONAL
)
{
EFI_STATUS Status = EFI_SUCCESS;
if (CperErrSecDscp == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
SetMem(CperErrSecDscp, sizeof(EFI_ERROR_SECTION_DESCRIPTOR), 0);
CperErrSecDscp->SectionOffset = sizeof(EFI_COMMON_ERROR_RECORD_HEADER) + sizeof(EFI_ERROR_SECTION_DESCRIPTOR);
CperErrSecDscp->SectionLength = (UINT32) PayloadSize;
CperErrSecDscp->Revision = MS_WHEA_SECTION_REVISION;
//CperErrSecDscp->SecValidMask = 0;
//CperErrSecDscp->Resv1 = 0; // Reserved field, should be 0.
//CperErrSecDscp->SectionFlags = 0; // Untouched.
if (SectionType) {
CopyGuid(&CperErrSecDscp->SectionType, SectionType);
}
else {
// Default to Firmware Error
CopyGuid(&CperErrSecDscp->SectionType, &gEfiFirmwareErrorSectionGuid);
}
//SetMem(&CperErrSecDscp->FruId, sizeof(CperErrSecDscp->FruId), 0); // Untouched.
CperErrSecDscp->Severity = ErrorSeverity;
//SetMem(CperErrSecDscp->FruString, sizeof(CperErrSecDscp->FruString), 0); // Untouched.
Cleanup:
return Status;
}
/**
This routine will fill out the Firmware Error Data header structure for caller.
@param[out] EfiFirmwareErrorData Supplies a pointer to Firmware Error Data header structure
@param[in] ErrorStatusCode Reported Status Code from ReportStatucCode* function
@param[in] RecordIDGuid RecordID for error source identification, default to
gMsWheaReportServiceGuid if NULL
@retval EFI_SUCCESS The operation completed successfully
@retval EFI_INVALID_PARAMETER Any required input pointer is NULL
**/
STATIC
EFI_STATUS
CreateFwErrDataDefaultMin (
OUT EFI_FIRMWARE_ERROR_DATA *EfiFirmwareErrorData,
IN UINT32 ErrorStatusCode,
IN EFI_GUID *RecordIDGuid OPTIONAL
)
{
EFI_STATUS Status = EFI_SUCCESS;
if (EfiFirmwareErrorData == NULL) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
SetMem(EfiFirmwareErrorData, sizeof(EFI_FIRMWARE_ERROR_DATA), 0);
EfiFirmwareErrorData->ErrorType = EFI_FIRMWARE_ERROR_TYPE_SOC_TYPE2;
EfiFirmwareErrorData->Revision = EFI_FIRMWARE_ERROR_REVISION;
//SetMem(&EfiFirmwareErrorData->Resv1, sizeof(EfiFirmwareErrorData->Resv1), 0); // Reserved field.
//EfiFirmwareErrorData->RecordId = 0; // Must be set to NULL
if (RecordIDGuid != NULL) {
CopyGuid(&EfiFirmwareErrorData->RecordIdGuid, RecordIDGuid);
}
else {
// Default to MS WHEA Service guid
CopyGuid(&EfiFirmwareErrorData->RecordIdGuid, &gMsWheaReportServiceGuid);
}
Cleanup:
return Status;
}
/**
This routine will populate certain MS WHEA metadata fields based on supplied information
@param[in] Value Reported Status Code from ReportStatucCode* function
@param[in] CurrentPhase Supplies the boot phase the reporting module is in
@param[in] ReportHdr Supplies the pointer to reported MS WHEA header, will be treated as
wildcard if cannot decode signature
@param[in] CallerId Supplies the CallerId, will be populated into CPER table CreatorID
field if supplied, else default to gMsWheaReportServiceGuid
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error metadata
**/
STATIC
VOID
GenMsWheaEntryHeaderHelper (
IN EFI_STATUS_CODE_VALUE Value,
IN MS_WHEA_ERROR_PHASE CurrentPhase,
IN CONST MS_WHEA_ERROR_HDR *ReportHdr OPTIONAL,
IN CONST EFI_GUID *CallerId OPTIONAL,
OUT MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD
)
{
MS_WHEA_REV Rev = 0;
if (MsWheaEntryMD == NULL) {
goto Cleanup;
}
SetMem(MsWheaEntryMD, sizeof(MS_WHEA_ERROR_ENTRY_MD), 0);
// Sanity check first
if ((ReportHdr == NULL) || (ReportHdr->Signature != MS_WHEA_ERROR_SIGNATURE)) {
// Could not understand this payload, wild card and severity set to informational
Rev = MS_WHEA_REV_WILDCARD;
MsWheaEntryMD->MsWheaErrorHdr.ErrorSeverity = EFI_GENERIC_ERROR_INFO;
}
else {
Rev = ReportHdr->Rev;
}
MsWheaEntryMD->ErrorStatusCode = Value;
if (CallerId != NULL) {
CopyGuid(&MsWheaEntryMD->CallerID, CallerId);
}
if (Rev == MS_WHEA_REV_WILDCARD) {
MsWheaEntryMD->MsWheaErrorHdr.Signature = MS_WHEA_ERROR_SIGNATURE;
MsWheaEntryMD->MsWheaErrorHdr.Rev = Rev;
}
else {
CopyMem(&MsWheaEntryMD->MsWheaErrorHdr, ReportHdr, sizeof(MS_WHEA_ERROR_HDR));
}
MsWheaEntryMD->MsWheaErrorHdr.Phase = CurrentPhase;
Cleanup:
return;
}
/**
This routine will fill CPER related headers with certain preset values;
Presets: NotificationType: gEfiEventNotificationTypeBootGuid; SectionType: gEfiFirmwareErrorSectionGuid;
Zeroed: CPER Header: Flags, RecordID; Section Descriptor: SectionFlags, FruId, FruString;
@param[out] CperHdr Supplies a pointer to CPER header structure
@param[out] CperErrSecDscp Supplies a pointer to CPER Section Decsriptor structure
@param[out] EfiFirmwareErrorData Supplies a pointer to Firmware Error Data header structure
@param[in] MsWheaEntryMD Supplies a pointer to reported MS WHEA error metadata
@param[in] PayloadSize Length of entire payload to be included within this entry, refer to
UEFI Spec for more information
@retval EFI_SUCCESS The operation completed successfully
@retval EFI_INVALID_PARAMETER Any required input pointer is NULL
**/
EFI_STATUS
EFIAPI
CreateHeadersDefault (
OUT EFI_COMMON_ERROR_RECORD_HEADER *CperHdr,
OUT EFI_ERROR_SECTION_DESCRIPTOR *CperErrSecDscp,
OUT EFI_FIRMWARE_ERROR_DATA *EfiFirmwareErrorData,
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN UINT32 PayloadSize
)
{
EFI_STATUS Status = EFI_SUCCESS;
if ((CperHdr == NULL) ||
(CperErrSecDscp == NULL) ||
(EfiFirmwareErrorData == NULL) ||
(MsWheaEntryMD == NULL)) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
Status = CreateCperHdrDefaultMin(CperHdr,
PayloadSize,
MsWheaEntryMD->MsWheaErrorHdr.ErrorSeverity,
MsWheaEntryMD->ErrorStatusCode,
&MsWheaEntryMD->CallerID, NULL);
if (EFI_ERROR(Status) != FALSE) {
goto Cleanup;
}
Status = CreateCperErrSecDscpDefaultMin(CperErrSecDscp,
PayloadSize,
MsWheaEntryMD->MsWheaErrorHdr.ErrorSeverity,
NULL);
if (EFI_ERROR(Status) != FALSE) {
goto Cleanup;
}
Status = CreateFwErrDataDefaultMin(EfiFirmwareErrorData,
MsWheaEntryMD->ErrorStatusCode,
&MsWheaEntryMD->CallerID);
if (EFI_ERROR(Status) != FALSE) {
goto Cleanup;
}
Cleanup:
return Status;
}
/************************************ Reporter Section *************************************/
/**
This routine will filter status code based on status type, decode reported extended data , if any,
generate MS WHEA metadata based on decoded information and either 1. pass generated metadata to supplied
callback function for further processing or 2. store onto CMOS if boot phase and error severtiy meets
certain requirements
@param[in] CodeType Indicates the type of status code being reported.
@param[in] Value Describes the current status of a hardware or software entity. This
includes information about the class and subclass that is used to
classify the entity as well as an operation.
@param[in] Instance The enumeration of a hardware or software entity within the system.
Valid instance numbers start with 1.
@param[in] CallerId This optional parameter may be used to identify the caller. This
parameter allows the status code driver to apply different rules to
different callers.
@param[in] Data This optional parameter may be used to pass additional data.
@param[in] CurrentPhase This is passed by the RSC handler by indicating what to do next
(store critical information on the CMOS)
@param[in] ReportFn Function pointer collect input argument and save to HwErrRec for OS
to process
@retval EFI_SUCCESS The operation completed successfully
@retval EFI_INVALID_PARAMETER Any required input pointer is NULL
@retval Others Any other error that rises from Variable Services, Boot Services,
Runtime Services, etc.
**/
EFI_STATUS
EFIAPI
ReportHwErrRecRouter (
IN EFI_STATUS_CODE_TYPE CodeType,
IN EFI_STATUS_CODE_VALUE Value,
IN UINT32 Instance,
IN CONST EFI_GUID *CallerId,
IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL,
IN MS_WHEA_ERROR_PHASE CurrentPhase,
IN MS_WHEA_ERR_REPORT_PS_FN ReportFn
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT32 DataSize;
MS_WHEA_ERROR_ENTRY_MD MsWheaEntryMD;
VOID *TempPtr = NULL;
if (ReportFn == NULL) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": Input fucntion pointer cannot be null!\n"));
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
if ((CodeType & MS_WHEA_ERROR_STATUS_TYPE) != MS_WHEA_ERROR_STATUS_TYPE) {
// Do Nothing for minor errors
Status = EFI_SUCCESS;
goto Cleanup;
}
if ((Data != NULL) && (Data->Size >= sizeof(MS_WHEA_ERROR_HDR))) {
// Skip the EFI_STATUS_CODE_DATA in the beginning
GenMsWheaEntryHeaderHelper(Value,
CurrentPhase,
(MS_WHEA_ERROR_HDR*)(Data + 1),
CallerId,
&MsWheaEntryMD);
}
else {
// This is invoked by ReportStatusCode(), generated error header will be payload
GenMsWheaEntryHeaderHelper(Value,
CurrentPhase,
NULL,
CallerId,
&MsWheaEntryMD);
}
if ((MsWheaEntryMD.MsWheaErrorHdr.ErrorSeverity == EFI_GENERIC_ERROR_FATAL) &&
((CurrentPhase == MS_WHEA_PHASE_DXE) || (CurrentPhase == MS_WHEA_PHASE_PEI))) {
Status = MsWheaESStoreEntry(&MsWheaEntryMD);
goto Cleanup;
}
if (Data == NULL) {
// Wildcard report without extended data
DataSize = sizeof(MS_WHEA_ERROR_HDR);
TempPtr = AllocatePool(DataSize);
if (TempPtr == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Cleanup;
}
CopyMem(TempPtr, &MsWheaEntryMD.MsWheaErrorHdr, DataSize);
}
else if ((Data->Size < sizeof(MS_WHEA_ERROR_HDR)) ||
(((MS_WHEA_ERROR_HDR*)(Data + 1))->Signature != MS_WHEA_ERROR_SIGNATURE)) {
// Wildcard report without formatted header
DataSize = sizeof(MS_WHEA_ERROR_HDR) + Data->Size;
TempPtr = AllocatePool(DataSize);
if (TempPtr == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Cleanup;
}
CopyMem(TempPtr, &MsWheaEntryMD.MsWheaErrorHdr, sizeof(MS_WHEA_ERROR_HDR));
CopyMem(&((UINT8*)TempPtr)[sizeof(MS_WHEA_ERROR_HDR)], Data + 1, Data->Size);
}
else {
// Well-formatted data
DataSize = Data->Size;
TempPtr = AllocatePool(DataSize);
if (TempPtr == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Cleanup;
}
CopyMem(TempPtr, Data + 1, Data->Size);
// Overwrite the header since reporter might alter the data fields such as Phase
CopyMem(TempPtr, &MsWheaEntryMD.MsWheaErrorHdr, sizeof(MS_WHEA_ERROR_HDR));
}
Status = ReportFn(&MsWheaEntryMD, TempPtr, DataSize);
Cleanup:
if (TempPtr != NULL) {
FreePool(TempPtr);
}
return Status;
}
/************************************ Test Section *************************************/
/**
This routine will create a few ReportStatusCode calls to test the implementation of backend service.
1. This function should be invoked after evaluating gMsWheaPkgTokenSpaceGuid.PcdMsWheaReportTestEnable;
2. Only the modules creating backend services should use this function;
@param[out] CurrentPhase Supplies the boot phase the reporting module is in
**/
VOID
EFIAPI
MsWheaInSituTest(
IN MS_WHEA_ERROR_PHASE CurrentPhase
)
{
UINT8 Data[sizeof(MS_WHEA_ERROR_HDR) + MS_WHEA_IN_SITU_TEST_ERROR_SIZE];
UINT32 Size = sizeof(MS_WHEA_ERROR_HDR) + MS_WHEA_IN_SITU_TEST_ERROR_SIZE;
MS_WHEA_ERROR_HDR *mMsWheaErrHdr;
UINT8 TestIndex;
DEBUG((DEBUG_INFO, __FUNCTION__ ": enter...\n"));
SetMem(Data, sizeof(MS_WHEA_ERROR_HDR), 0);
mMsWheaErrHdr = (MS_WHEA_ERROR_HDR*)Data;
mMsWheaErrHdr->Signature = MS_WHEA_ERROR_SIGNATURE;
mMsWheaErrHdr->CriticalInfo = MS_WHEA_IN_SITU_TEST_ERROR_INFO;
mMsWheaErrHdr->ReporterID = MS_WHEA_IN_SITU_TEST_ERROR_ID;
mMsWheaErrHdr->ErrorSeverity = EFI_GENERIC_ERROR_FATAL;
DEBUG((DEBUG_INFO, __FUNCTION__ ": Fatal error report rev 0...\n"));
TestIndex = 0;
SetMem((mMsWheaErrHdr + 1),
MS_WHEA_IN_SITU_TEST_ERROR_SIZE,
(UINT8)(MS_WHEA_IN_SITU_TEST_ERROR_PATTERN |
((CurrentPhase<<MS_WHEA_IN_SITU_TEST_ERROR_PHASE_BSFT) + TestIndex)));
mMsWheaErrHdr->Rev = MS_WHEA_REV_0;
ReportStatusCodeWithExtendedData((EFI_ERROR_MAJOR|EFI_ERROR_CODE),
MS_WHEA_IN_SITU_TEST_ERROR_CODE,
Data,
Size);
DEBUG((DEBUG_INFO, __FUNCTION__ ": Fatal error report rev 1...\n"));
TestIndex ++;
SetMem((mMsWheaErrHdr + 1),
MS_WHEA_IN_SITU_TEST_ERROR_SIZE,
(UINT8)(MS_WHEA_IN_SITU_TEST_ERROR_PATTERN |
((CurrentPhase<<MS_WHEA_IN_SITU_TEST_ERROR_PHASE_BSFT) + TestIndex)));
mMsWheaErrHdr->Rev = MS_WHEA_REV_1;
ReportStatusCodeWithExtendedData((EFI_ERROR_MAJOR|EFI_ERROR_CODE),
MS_WHEA_IN_SITU_TEST_ERROR_CODE,
Data,
Size);
DEBUG((DEBUG_INFO, __FUNCTION__ ": Fatal error report unsupported rev...\n"));
TestIndex ++;
SetMem((mMsWheaErrHdr + 1),
MS_WHEA_IN_SITU_TEST_ERROR_SIZE,
(UINT8)(MS_WHEA_IN_SITU_TEST_ERROR_PATTERN |
((CurrentPhase<<MS_WHEA_IN_SITU_TEST_ERROR_PHASE_BSFT) + TestIndex)));
mMsWheaErrHdr->Rev = MS_WHEA_IN_SITU_TEST_ERROR_REV_UNSUP;
ReportStatusCodeWithExtendedData((EFI_ERROR_MAJOR|EFI_ERROR_CODE),
MS_WHEA_IN_SITU_TEST_ERROR_CODE,
Data,
Size);
DEBUG((DEBUG_INFO, __FUNCTION__ ": Non-fatal error report unsupported rev...\n"));
TestIndex ++;
SetMem((mMsWheaErrHdr + 1),
MS_WHEA_IN_SITU_TEST_ERROR_SIZE,
(UINT8)(MS_WHEA_IN_SITU_TEST_ERROR_PATTERN |
((CurrentPhase<<MS_WHEA_IN_SITU_TEST_ERROR_PHASE_BSFT) + TestIndex)));
mMsWheaErrHdr->ErrorSeverity = EFI_GENERIC_ERROR_RECOVERABLE;
ReportStatusCodeWithExtendedData((EFI_ERROR_MAJOR|EFI_ERROR_CODE),
MS_WHEA_IN_SITU_TEST_ERROR_CODE,
Data,
Size);
DEBUG((DEBUG_INFO, __FUNCTION__ ": Non-fatal error report rev wildcard...\n"));
TestIndex ++;
SetMem((mMsWheaErrHdr + 1),
MS_WHEA_IN_SITU_TEST_ERROR_SIZE,
(UINT8)(MS_WHEA_IN_SITU_TEST_ERROR_PATTERN |
((CurrentPhase<<MS_WHEA_IN_SITU_TEST_ERROR_PHASE_BSFT) + TestIndex)));
ReportStatusCodeWithExtendedData((EFI_ERROR_MAJOR|EFI_ERROR_CODE),
MS_WHEA_IN_SITU_TEST_ERROR_CODE,
(mMsWheaErrHdr + 1),
MS_WHEA_IN_SITU_TEST_ERROR_SIZE);
DEBUG((DEBUG_INFO, __FUNCTION__ ": Non-fatal error report rev short payload...\n"));
TestIndex ++;
SetMem((mMsWheaErrHdr + 1),
MS_WHEA_IN_SITU_TEST_ERROR_SHORT_SIZE,
(UINT8)(MS_WHEA_IN_SITU_TEST_ERROR_PATTERN |
((CurrentPhase<<MS_WHEA_IN_SITU_TEST_ERROR_PHASE_BSFT) + TestIndex)));
ReportStatusCodeWithExtendedData((EFI_ERROR_MAJOR|EFI_ERROR_CODE),
MS_WHEA_IN_SITU_TEST_ERROR_CODE,
(mMsWheaErrHdr + 1),
MS_WHEA_IN_SITU_TEST_ERROR_SHORT_SIZE);
DEBUG((DEBUG_INFO, __FUNCTION__ ": Non-fatal error report rev short...\n"));
TestIndex ++;
ReportStatusCode((EFI_ERROR_MAJOR|EFI_ERROR_CODE),
MS_WHEA_IN_SITU_TEST_ERROR_CODE);
DEBUG((DEBUG_INFO, __FUNCTION__ ": exit...\n"));
}

Просмотреть файл

@ -0,0 +1,169 @@
/** @file -- MsWheaReportCommon.h
This header defines MsWheaReport related helper functions.
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#ifndef __MS_WHEA_REPORT_COMMON__
#define __MS_WHEA_REPORT_COMMON__
#include <Guid/Cper.h>
#include <Protocol/AcpiTable.h>
#include <Library/DebugLib.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
#include <MsWheaErrorStatus.h>
/************************************ Definition Section *************************************/
/**
Definition wrapper to unify all bert/hwerrrec related specification versioning
**/
#define EFI_FIRMWARE_ERROR_REVISION 0x0002 // Set Firmware Error Record Revision to 2 as per UEFI Spec 2.7A
#define MS_WHEA_SECTION_REVISION 0x0100 // Set Section Descriptor Revision to 1.0 as per UEFI Spec 2.7A
#define EFI_HW_ERR_REC_VAR_NAME L"HwErrRec"
#define EFI_HW_ERR_REC_VAR_NAME_LEN 16 // Buffer length covers at least "HwErrRec####\0"
/**
MS WHEA error entry metadata:
MsWheaErrorHdr: MS WHEA error header, either from payload or self-generated if wildcard.
PayloadSize: Payload size of this error, when used for hob/linked list operation, including a MS WHEA
metadata and a well formatted payload (starting with a MS_WHEA_ERROR_HDR, followed by raw
payload).
ErrorStatusCode: Reported Status Code value from ReportStatusCode*
CallerID: Caller ID for identification purpose
**/
typedef struct MS_WHEA_ERROR_ENTRY_MD_T_DEF {
MS_WHEA_ERROR_HDR MsWheaErrorHdr;
UINT32 PayloadSize;
UINT32 ErrorStatusCode;
EFI_GUID CallerID;
} MS_WHEA_ERROR_ENTRY_MD;
/**
This routine accepts the Common Platform Error Record header and Section
Descriptor and correspthen store on the flash as HwErrRec awaiting to be picked up by OS
(Refer to UEFI Spec 2.7A)
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@param[in] PayloadPtr The pointer to reported error block, the content will be copied
@param[in] PayloadSize The size of a well formatted payload (starting with a
MS_WHEA_ERROR_HDR, followed by raw payload)
@retval EFI_SUCCESS Entry addition is successful.
@retval EFI_INVALID_PARAMETER Input has NULL pointer as input.
@retval EFI_OUT_OF_RESOURCES Not enough spcae for the requested space.
**/
typedef
EFI_STATUS
(EFIAPI *MS_WHEA_ERR_REPORT_PS_FN) (
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN VOID *PayloadPtr,
IN UINT32 PayloadSize
);
/************************************ Function Section *************************************/
/**
This routine will fill CPER related headers with certain preset values;
Presets: NotificationType: gEfiEventNotificationTypeBootGuid; SectionType: gEfiFirmwareErrorSectionGuid;
Zeroed: CPER Header: Flags, RecordID; Section Descriptor: SectionFlags, FruId, FruString;
@param[out] CperHdr Supplies a pointer to CPER header structure
@param[out] CperErrSecDscp Supplies a pointer to CPER Section Decsriptor structure
@param[out] EfiFirmwareErrorData Supplies a pointer to Firmware Error Data header structure
@param[in] MsWheaEntryMD Supplies a pointer to reported MS WHEA error metadata
@param[in] PayloadSize Length of entire payload to be included within this entry, refer to
UEFI Spec for more information
@retval EFI_SUCCESS The operation completed successfully
@retval EFI_INVALID_PARAMETER Any required input pointer is NULL
**/
EFI_STATUS
EFIAPI
CreateHeadersDefault (
OUT EFI_COMMON_ERROR_RECORD_HEADER *CperHdr,
OUT EFI_ERROR_SECTION_DESCRIPTOR *CperErrSecDscp,
OUT EFI_FIRMWARE_ERROR_DATA *EfiFirmwareErrorData,
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN UINT32 PayloadSize
);
/**
This routine will filter status code based on status type, decode reported extended data , if any,
generate MS WHEA metadata based on decoded information and either 1. pass generated metadata to supplied
callback function for further processing or 2. store onto CMOS if boot phase and error severtiy meets
certain requirements
@param[in] CodeType Indicates the type of status code being reported.
@param[in] Value Describes the current status of a hardware or software entity. This
includes information about the class and subclass that is used to
classify the entity as well as an operation.
@param[in] Instance The enumeration of a hardware or software entity within the system.
Valid instance numbers start with 1.
@param[in] CallerId This optional parameter may be used to identify the caller. This
parameter allows the status code driver to apply different rules to
different callers.
@param[in] Data This optional parameter may be used to pass additional data.
@param[in] CurrentPhase This is passed by the RSC handler by indicating what to do next
(store critical information on the CMOS)
@param[in] ReportFn Function pointer collect input argument and save to HwErrRec for OS
to process
@retval EFI_SUCCESS The operation completed successfully
@retval EFI_INVALID_PARAMETER Any required input pointer is NULL
@retval Others Any other error that rises from Variable Services, Boot Services,
Runtime Services, etc.
**/
EFI_STATUS
EFIAPI
ReportHwErrRecRouter (
IN EFI_STATUS_CODE_TYPE CodeType,
IN EFI_STATUS_CODE_VALUE Value,
IN UINT32 Instance,
IN CONST EFI_GUID *CallerId,
IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL,
IN MS_WHEA_ERROR_PHASE CurrentPhase,
IN MS_WHEA_ERR_REPORT_PS_FN ReportFn
);
/**
This routine will create a few ReportStatusCode calls to test the implementation of backend service.
1. This function should be invoked after evaluating gMsWheaPkgTokenSpaceGuid.PcdMsWheaReportTestEnable;
2. Only the modules creating backend services should use this function;
@param[out] CurrentPhase Supplies the boot phase the reporting module is in
**/
VOID
EFIAPI
MsWheaInSituTest(
IN MS_WHEA_ERROR_PHASE CurrentPhase
);
#endif //__MS_WHEA_REPORT_COMMON__

Просмотреть файл

@ -0,0 +1,188 @@
/** @file -- MsWheaReportPei.c
This Pei module will produce a RSC listener that listens to reported status codes.
Certains errors will be collected and added to Hob List and waiting to be collected
and/or stored during Dxe phase;
Copyright (c) 2018, Microsoft Corporation
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
**/
#include <Library/PeiServicesLib.h>
#include <Guid/VariableFormat.h>
#include <Library/PcdLib.h>
#include <Library/HobLib.h>
#include <Library/ReportStatusCodeLib.h>
#include <Ppi/ReportStatusCodeHandler.h>
#include "MsWheaEarlyStorageMgr.h"
#include "MsWheaReportCommon.h"
/**
Handler function that validates input arguments, and create a hob list entry for this input for later process.
@param[in] MsWheaEntryMD The pointer to reported MS WHEA error metadata
@param[in] PayloadPtr The pointer to reported error block payload, the content will be copied
@param[in] PayloadSize The size of reported error block payload
@retval EFI_SUCCESS Operation is successful
@retval EFI_OUT_OF_RESOURCES List cannot make the space for requested error block payload
@retval EFI_INVALID_PARAMETER Null pointer or zero length payload detected or length and header
length field exceeds variable limit
**/
STATIC
EFI_STATUS
MsWheaReportHandlerPei(
IN MS_WHEA_ERROR_ENTRY_MD *MsWheaEntryMD,
IN VOID *PayloadPtr,
IN UINT32 PayloadSize
)
{
EFI_STATUS Status = EFI_SUCCESS;
UINT32 Index;
UINT32 Size;
VOID *MsWheaReportEntry = NULL;
if ((PayloadPtr == NULL) ||
(PayloadSize == 0) ||
(MsWheaEntryMD == NULL) ||
((PayloadSize +
sizeof(EFI_COMMON_ERROR_RECORD_HEADER) +
sizeof(EFI_ERROR_SECTION_DESCRIPTOR) +
sizeof(AUTHENTICATED_VARIABLE_HEADER) +
EFI_HW_ERR_REC_VAR_NAME_LEN * sizeof(CHAR16)) >
PcdGet32 (PcdMaxHardwareErrorVariableSize)) ) {
Status = EFI_INVALID_PARAMETER;
goto Cleanup;
}
// Add this block to the list
Size = sizeof(MS_WHEA_ERROR_ENTRY_MD) + PayloadSize;
MsWheaReportEntry = BuildGuidHob(&gMsWheaReportServiceGuid, Size);
if (MsWheaReportEntry == NULL) {
Status = EFI_OUT_OF_RESOURCES;
goto Cleanup;
}
ZeroMem(MsWheaReportEntry, Size);
Index = 0;
CopyMem(&((UINT8*)MsWheaReportEntry)[Index], MsWheaEntryMD, sizeof(MS_WHEA_ERROR_ENTRY_MD));
Index = sizeof(MS_WHEA_ERROR_ENTRY_MD);
CopyMem(&((UINT8*)MsWheaReportEntry)[Index], PayloadPtr, PayloadSize);
((MS_WHEA_ERROR_ENTRY_MD*)MsWheaReportEntry)->PayloadSize = Size;
Cleanup:
return Status;
}
/**
Added module phase information and route reported status code value and extended data to ReportHwErrRecRouter
for further processing.
@param[in] PeiServices Pointer to PEI services table.
@param[in] CodeType Indicates the type of status code being reported.
@param[in] Value Describes the current status of a hardware or software entity. This
includes information about the class and subclass that is used to
classify the entity as well as an operation.
@param[in] Instance The enumeration of a hardware or software entity within the system.
Valid instance numbers start with 1.
@param[in] CallerId This optional parameter may be used to identify the caller. This
parameter allows the status code driver to apply different rules to
different callers.
@param[in] Data This optional parameter may be used to pass additional data.
@retval EFI_SUCCESS Operation is successful
@retval Others Any other error that rises from Variable Services, Boot Services,
Runtime Services, etc.
**/
STATIC
EFI_STATUS
MsWheaRscHandlerPei (
IN CONST EFI_PEI_SERVICES** PeiServices,
IN EFI_STATUS_CODE_TYPE CodeType,
IN EFI_STATUS_CODE_VALUE Value,
IN UINT32 Instance,
IN CONST EFI_GUID *CallerId,
IN CONST EFI_STATUS_CODE_DATA *Data OPTIONAL
)
{
return ReportHwErrRecRouter(CodeType,
Value,
Instance,
CallerId,
Data,
MS_WHEA_PHASE_PEI,
MsWheaReportHandlerPei);
}
/**
Entry to MsWheaReportPei.
@param FileHandle The image handle.
@param PeiServices The PEI services table.
@retval Status From internal routine or boot object, should not fail
**/
EFI_STATUS
EFIAPI
MsWheaReportPeiEntry (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status = EFI_SUCCESS;
EFI_PEI_RSC_HANDLER_PPI *RscHandlerPpi;
DEBUG((DEBUG_INFO, __FUNCTION__ ": enter...\n"));
// Insert signature and clear the space, if not already clear
MsWheaESInit();
Status = PeiServicesLocatePpi(&gEfiPeiRscHandlerPpiGuid,
0,
NULL,
(VOID**)&RscHandlerPpi);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": failed to locate PEI RSC Handler PPI (%r)\n", Status));
goto Cleanup;
}
Status = RscHandlerPpi->Register(MsWheaRscHandlerPei);
if (EFI_ERROR(Status) != FALSE) {
DEBUG((DEBUG_ERROR, __FUNCTION__ ": failed to register PEI RSC Handler PPI (%r)\n", Status));
}
if (PcdGetBool(PcdMsWheaReportTestEnable) != FALSE) {
MsWheaInSituTest(MS_WHEA_PHASE_PEI);
}
Cleanup:
DEBUG((DEBUG_INFO, __FUNCTION__ ": exit (%r)\n", Status));
return Status;
}

Просмотреть файл

@ -0,0 +1,85 @@
## @file -- MsWheaReportPei.inf
#
# MsWheaReportPei implements Microsoft WHEA report service for PEI phase.
#
# Copyright (c) 2018, Microsoft Corporation
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = MsWheaReportPei
FILE_GUID = 57A2921A-7BC2-43C5-AA5D-064EDCBB992F
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
ENTRY_POINT = MsWheaReportPeiEntry
#
# The following information is for reference only and not required by the
# build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
../MsWheaReportCommon.h
../MsWheaReportCommon.c
../MsWheaEarlyStorageMgr.c
../MsWheaEarlyStorageMgr.h
MsWheaReportPei.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
MsWheaPkg/MsWheaPkg.dec
[LibraryClasses]
BaseLib
BaseMemoryLib
DebugLib
HobLib
IoLib
MemoryAllocationLib
PcdLib
ReportStatusCodeLib
PeimEntryPoint
PeiServicesLib
MsWheaEarlyStorageLib
[Protocols]
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize
gMsWheaPkgTokenSpaceGuid.PcdMsWheaReportTestEnable
gMsWheaPkgTokenSpaceGuid.PcdMsWheaReportPcatCapacity
gMsWheaPkgTokenSpaceGuid.PcdMsWheaEarlyStorageDefaultValue
[Ppis]
gEfiPeiRscHandlerPpiGuid ## CONSUMES
[Guids]
gMsWheaReportServiceGuid ## SOMETIMES_CONSUMES
gEfiFirmwareErrorSectionGuid ## SOMETIMES_CONSUMES
gEfiEventNotificationTypeBootGuid ## SOMETIMES_CONSUMES
[Depex]
gEfiPeiRscHandlerPpiGuid

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -0,0 +1,80 @@
## @file MsWheaReportUnitTestApp.inf
#
# Tests for MS WHEA report tests with various payloads and error severities.
##
# Copyright (c) 2018, Microsoft Corporation
#
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# 1. Redistributions of source code must retain the above copyright notice,
# this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
# IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
# OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = MsWheaReportUnitTestApp
FILE_GUID = 75C3E1C3-40EE-4CC2-AF40-5ADE47870D86
VERSION_STRING = 1.0
MODULE_TYPE = UEFI_APPLICATION
ENTRY_POINT = MsWheaReportUnitTestAppEntryPoint
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
MsWheaReportUnitTestApp.c
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
MsUnitTestPkg/MsUnitTestPkg.dec
MsWheaPkg/MsWheaPkg.dec
ShellPkg/ShellPkg.dec
[LibraryClasses]
DebugLib
UefiApplicationEntryPoint
UefiBootServicesTableLib
UnitTestLib
UnitTestLogLib
UnitTestPersistenceLib
UnitTestAssertLib
PrintLib
ReportStatusCodeLib
MemoryAllocationLib
BaseLib
ShellLib
PcdLib
UefiLib
[Protocols]
[Guids]
gEfiEventNotificationTypeBootGuid ## CONSUMES
gEfiFirmwareErrorSectionGuid ## CONSUMES
gEfiHardwareErrorVariableGuid ## CONSUMES
gMsWheaReportServiceGuid ## CONSUMES
[FixedPcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdHwErrStorageSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxHardwareErrorVariableSize ## CONSUMES
gEfiMdeModulePkgTokenSpaceGuid.PcdFlashNvStorageVariableSize ## CONSUMES