diff options
author | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
---|---|---|
committer | raywu <raywu0301@gmail.com> | 2018-06-15 00:00:50 +0800 |
commit | b7c51c9cf4864df6aabb99a1ae843becd577237c (patch) | |
tree | eebe9b0d0ca03062955223097e57da84dd618b9a /EDK/Foundation/Library/EfiCommonLib/ReportStatusCode.c | |
download | zprj-master.tar.xz |
Diffstat (limited to 'EDK/Foundation/Library/EfiCommonLib/ReportStatusCode.c')
-rw-r--r-- | EDK/Foundation/Library/EfiCommonLib/ReportStatusCode.c | 333 |
1 files changed, 333 insertions, 0 deletions
diff --git a/EDK/Foundation/Library/EfiCommonLib/ReportStatusCode.c b/EDK/Foundation/Library/EfiCommonLib/ReportStatusCode.c new file mode 100644 index 0000000..8214d00 --- /dev/null +++ b/EDK/Foundation/Library/EfiCommonLib/ReportStatusCode.c @@ -0,0 +1,333 @@ +/*++ + +Copyright (c) 2004, Intel Corporation +All rights reserved. This program and the accompanying materials +are licensed and made available under the terms and conditions of the BSD License +which accompanies this distribution. The full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +Module Name: + + ReportStatusCode.c + +Abstract: + + Worker functions for ReportStatusCode + +--*/ + +#include "TianoCommon.h" +#include "EfiCommonLib.h" +#include EFI_GUID_DEFINITION (StatusCodeCallerId) +#include EFI_GUID_DEFINITION (StatusCodeDataTypeId) + + +VOID * +EfiConstructStatusCodeData ( + IN UINT16 DataSize, + IN EFI_GUID *TypeGuid, + IN OUT EFI_STATUS_CODE_DATA *Data + ) +/*++ + +Routine Description: + + Construct stanader header for optional data passed into ReportStatusCode + +Arguments: + + DataSize - Size of optional data. Does not include EFI_STATUS_CODE_DATA header + TypeGuid - GUID to place in EFI_STATUS_CODE_DATA + Data - Buffer to use. + +Returns: + + Return pointer to Data buffer pointing past the end of EFI_STATUS_CODE_DATA + +--*/ +{ + Data->HeaderSize = sizeof (EFI_STATUS_CODE_DATA); + Data->Size = (UINT16)(DataSize - sizeof (EFI_STATUS_CODE_DATA)); + EfiCommonLibCopyMem (&Data->Type, TypeGuid, sizeof (EFI_GUID)); + + return (VOID *)(Data + 1); +} + +EFI_STATUS +EfiDebugVPrintWorker ( + IN UINTN ErrorLevel, + IN CHAR8 *Format, + IN VA_LIST Marker, + IN UINTN BufferSize, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Worker function for DEBUG(). If Error Logging hub is loaded log ASSERT + information. If Error Logging hub is not loaded do nothing. + + We use UINT64 buffers due to IPF alignment concerns. + +Arguments: + + ErrorLevel - If error level is set do the debug print. + + Format - String to use for the print, followed by Print arguments. + + Marker - VarArgs + + BufferSize - Size of Buffer. + + Buffer - Caller allocated buffer, contains ReportStatusCode extended data + +Returns: + + Status code + + EFI_BUFFER_TOO_SMALL - Format too big to fit in buffer + + EFI_SUCCESS - Successfully printed + +--*/ +{ + UINTN Index; + UINTN FormatStrLen; + UINT64 *Ptr; + EFI_DEBUG_INFO *EfiDebug; + + + // + // Build the type specific EFI_STATUS_CODE_DATA in order + // + + // + // Fill in EFI_STATUS_CODE_DATA to Buffer. + // + EfiDebug = (EFI_DEBUG_INFO *)EfiConstructStatusCodeData ( + (UINT16)BufferSize, + &gEfiStatusCodeDataTypeDebugGuid, + Buffer + ); + + // + // Then EFI_DEBUG_INFO + // + EfiDebug->ErrorLevel = (UINT32)ErrorLevel; + + // + // 256 byte mini Var Arg stack. That is followed by the format string. + // + for (Index = 0, Ptr = (UINT64 *)(EfiDebug + 1); Index < 12; Index++, Ptr++) { + *Ptr = VA_ARG (Marker, UINT64); + } + + // + // Place Ascii Format string at the end + // + FormatStrLen = EfiAsciiStrLen (Format) + 1; + if (FormatStrLen > EFI_STATUS_CODE_DATA_MAX_SIZE) { + // + // Format too big to fit in our buffer, so do nothing. + // + return EFI_BUFFER_TOO_SMALL; + } else { + EfiCommonLibCopyMem (Ptr, Format, FormatStrLen); + } + + return EFI_SUCCESS; +} + + + +EFI_STATUS +EfiDebugAssertWorker ( + IN CHAR8 *Filename, + IN INTN LineNumber, + IN CHAR8 *Description, + IN UINTN BufferSize, + IN OUT VOID *Buffer + ) +/*++ + +Routine Description: + + Worker function for ASSERT (). If Error Logging hub is loaded log ASSERT + information. If Error Logging hub is not loaded DEADLOOP (). + + We use UINT64 buffers due to IPF alignment concerns. + +Arguments: + + Filename - File name of failing routine. + + LineNumber - Line number of failing ASSERT(). + + Description - Description, usually the assertion, + + BufferSize - Size of Buffer. + + Buffer - Caller allocated buffer, contains ReportStatusCode extendecd data + +Returns: + + Status code + + EFI_BUFFER_TOO_SMALL - Buffer not large enough + + EFI_SUCCESS - Function successfully done. + +--*/ +{ + EFI_DEBUG_ASSERT_DATA *AssertData; + UINTN TotalSize; + CHAR8 *EndOfStr; + + // + // Make sure it will all fit in the passed in buffer + // + TotalSize = sizeof (EFI_STATUS_CODE_DATA) + sizeof (EFI_DEBUG_ASSERT_DATA); + TotalSize += EfiAsciiStrLen (Filename) + EfiAsciiStrLen (Description); + if (TotalSize > BufferSize) { + return EFI_BUFFER_TOO_SMALL; + } + + // + // Fill in EFI_STATUS_CODE_DATA + // + AssertData = (EFI_DEBUG_ASSERT_DATA *) + EfiConstructStatusCodeData ( + (UINT16)(TotalSize - sizeof (EFI_STATUS_CODE_DATA)), + &gEfiStatusCodeDataTypeAssertGuid, + Buffer + ); + + // + // Fill in EFI_DEBUG_ASSERT_DATA + // + AssertData->LineNumber = (UINT32)LineNumber; + + // + // Copy Ascii FileName including NULL. + // + EndOfStr = EfiAsciiStrCpy ((CHAR8 *)(AssertData + 1), Filename); + + // + // Copy Ascii Description + // + EfiAsciiStrCpy (EndOfStr, Description); + return EFI_SUCCESS; +} + + + +BOOLEAN +ReportStatusCodeExtractAssertInfo ( + IN EFI_STATUS_CODE_TYPE CodeType, + IN EFI_STATUS_CODE_VALUE Value, + IN EFI_STATUS_CODE_DATA *Data, + OUT CHAR8 **Filename, + OUT CHAR8 **Description, + OUT UINT32 *LineNumber + ) +/*++ + +Routine Description: + + Extract assert information from status code data. + +Arguments: + + CodeType - Code type + Value - Code value + Data - Optional data associated with this status code. + Filename - Filename extracted from Data + Description - Description extracted from Data + LineNumber - Line number extracted from Data + +Returns: + + TRUE - Successfully extracted + + FALSE - Extraction failed + +--*/ +{ + EFI_DEBUG_ASSERT_DATA *AssertData; + + if (((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE) && + ((CodeType & EFI_STATUS_CODE_SEVERITY_MASK) == EFI_ERROR_UNRECOVERED)) { + // + // Assume if we have an uncontained unrecoverable error that the data hub + // may not work. So we will print out data here. If we had an IPMI controller, + // or error log we could wack the hardware here. + // + if ((Value & EFI_STATUS_CODE_OPERATION_MASK) == EFI_SW_EC_ILLEGAL_SOFTWARE_STATE && (Data != NULL)) { + // + // ASSERT (Expresion) - + // ExtendedData == FileName + // Instance == Line Nuber + // NULL == String of Expresion + // + AssertData = (EFI_DEBUG_ASSERT_DATA *)(Data + 1); + *Filename = (CHAR8 *)(AssertData + 1); + *Description = *Filename + EfiAsciiStrLen (*Filename) + 1; + *LineNumber = AssertData->LineNumber; + return TRUE; + } + } + return FALSE; +} + + +BOOLEAN +ReportStatusCodeExtractDebugInfo ( + IN EFI_STATUS_CODE_DATA *Data, + OUT UINT32 *ErrorLevel, + OUT VA_LIST *Marker, + OUT CHAR8 **Format + ) +/*++ + +Routine Description: + + Extract debug information from status code data. + +Arguments: + + Data - Optional data associated with status code. + ErrorLevel - Error level extracted from Data + Marker - VA_LIST extracted from Data + Format - Format string extracted from Data + +Returns: + + TRUE - Successfully extracted + + FALSE - Extraction failed + +--*/ +{ + EFI_DEBUG_INFO *DebugInfo; + + if ((Data == NULL) || (!EfiCompareGuid (&Data->Type, &gEfiStatusCodeDataTypeDebugGuid))) { + return FALSE; + } + + DebugInfo = (EFI_DEBUG_INFO *)(Data + 1); + + *ErrorLevel = DebugInfo->ErrorLevel; + + // + // The first 12 * UINTN bytes of the string are really an + // arguement stack to support varargs on the Format string. + // + *Marker = (VA_LIST) (DebugInfo + 1); + *Format = (CHAR8 *)(((UINT64 *)*Marker) + 12); + + return TRUE; +} |