Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add debug level prefix for advanced logger memory message entries - Driver implementation #525

Merged
3 changes: 2 additions & 1 deletion AdvLoggerPkg/AdvLoggerPkg.ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@
LOGTELEMETRY,
DEBUGAGENT,
POSTMEM,
MMARM
MMARM,
BLKIO
]
},

Expand Down
54 changes: 28 additions & 26 deletions AdvLoggerPkg/Application/DecodeUefiLog/DecodeUefiLog.py
Original file line number Diff line number Diff line change
Expand Up @@ -260,9 +260,9 @@ class AdvLogParser ():
ADVANCED_LOGGER_PHASE_SMM = 9
ADVANCED_LOGGER_PHASE_TFA = 10
ADVANCED_LOGGER_PHASE_CNT = 11
PHASE_STRING_LIST = ["[UNSPECIFIED] ", "[SEC] ", "[PEI] ", "[PEI64] ",
"[DXE] ", "[RUNTIME] ", "[MM_CORE] ", "[MM] ",
"[SMM_CORE] ", "[SMM] ", "[TFA] "]
PHASE_STRING_LIST = ["[UNSPECIFIED]", "[SEC]", "[PEI]", "[PEI64]",
"[DXE]", "[RUNTIME]", "[MM_CORE]", "[MM]",
"[SMM_CORE]", "[SMM]", "[TFA]"]

# Debug levels from MU_BASECORE\MdePkg\Include\Library\DebugLib.h
# //
Expand Down Expand Up @@ -293,27 +293,27 @@ class AdvLogParser ():
# #define DEBUG_ERROR 0x80000000 // Error

debug_levels_dict = {
liqiqiii marked this conversation as resolved.
Show resolved Hide resolved
0x00000001: "[DEBUG_INIT]",
liqiqiii marked this conversation as resolved.
Show resolved Hide resolved
0x00000002: "[DEBUG_WARN]",
0x00000004: "[DEBUG_LOAD]",
0x00000008: "[DEBUG_FS]",
0x00000010: "[DEBUG_POOL]",
0x00000020: "[DEBUG_PAGE]",
0x00000040: "[DEBUG_INFO]",
0x00000080: "[DEBUG_DISPATCH]",
0x00000100: "[DEBUG_VARIABLE]",
0x00000200: "[DEBUG_SMI]",
0x00000400: "[DEBUG_BM]",
0x00001000: "[DEBUG_BLKIO]",
0x00004000: "[DEBUG_NET]",
0x00010000: "[DEBUG_UNDI]",
0x00020000: "[DEBUG_LOADFILE]",
0x00080000: "[DEBUG_EVENT]",
0x00100000: "[DEBUG_GCD]",
0x00200000: "[DEBUG_CACHE]",
0x00400000: "[DEBUG_VERBOSE]",
0x00800000: "[DEBUG_MANAGEABILITY]",
0x80000000: "[DEBUG_ERROR]"
0x00000001: "[INIT]",
0x00000002: "[WARN]",
0x00000004: "[LOAD]",
0x00000008: "[FS]",
0x00000010: "[POOL]",
0x00000020: "[PAGE]",
0x00000040: "[INFO]",
0x00000080: "[DISPATCH]",
0x00000100: "[VARIABLE]",
0x00000200: "[SMI]",
0x00000400: "[BM]",
0x00001000: "[BLKIO]",
0x00004000: "[NET]",
0x00010000: "[UNDI]",
0x00020000: "[LOADFILE]",
0x00080000: "[EVENT]",
0x00100000: "[GCD]",
0x00200000: "[CACHE]",
0x00400000: "[VERBOSE]",
0x00800000: "[MANAGEABILITY]",
0x80000000: "[ERROR]"
}

#
Expand Down Expand Up @@ -713,15 +713,17 @@ def _GetPhaseString(self, Phase):
elif Phase <= self.ADVANCED_LOGGER_PHASE_UNSPECIFIED:
PhaseString = ""
else:
PhaseString = self.PHASE_STRING_LIST[Phase]
# Add an extra space for readability
PhaseString = self.PHASE_STRING_LIST[Phase] + ' '
return PhaseString

#
# Get the formatted debug level string
#
def _GetDebugLevelString(self, DebugLevel):
if DebugLevel in list(self.debug_levels_dict.keys()):
DebugLevelString = self.debug_levels_dict[DebugLevel]
# Add an extra space for readability
DebugLevelString = self.debug_levels_dict[DebugLevel] + ' '
else:
DebugLevelString = ""
return DebugLevelString
Expand Down
150 changes: 122 additions & 28 deletions AdvLoggerPkg/Library/AdvancedLoggerAccessLib/AdvancedLoggerAccessLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,23 +27,55 @@ STATIC EFI_PHYSICAL_ADDRESS mLowAddress = 0;
STATIC EFI_PHYSICAL_ADDRESS mHighAddress = 0;
STATIC UINT16 mMaxMessageSize = ADVANCED_LOGGER_MAX_MESSAGE_SIZE;
CONST CHAR8 *AdvMsgEntryPrefix[ADVANCED_LOGGER_PHASE_CNT] = {
"[UNSPECIFIED] ",
"[SEC] ",
"[PEI] ",
"[PEI64] ",
"[DXE] ",
"[RUNTIME] ",
"[MM_CORE] ",
"[MM] ",
"[SMM_CORE] ",
"[SMM] ",
"[TFA] ",
"[UNSPECIFIED]",
"[SEC]",
"[PEI]",
"[PEI64]",
"[DXE]",
"[RUNTIME]",
"[MM_CORE]",
"[MM]",
"[SMM_CORE]",
"[SMM]",
"[TFA]",
};

#define ADV_TIME_STAMP_FORMAT "%2.2d:%2.2d:%2.2d.%3.3d : "
#define ADV_TIME_STAMP_RESULT "hh:mm:ss:ttt : "
#define ADV_PHASE_ERR_FORMAT "[%04X] "
#define ADV_PHASE_MAX_SIZE 32
// Define a structure to hold debug level information
typedef struct {
CONST CHAR8 *Name;
UINT32 Value;
} DEBUG_LEVEL;

// Create an array of DebugLevel structures
DEBUG_LEVEL DebugLevels[] = {
{ "[INIT]", 0x00000001 },
{ "[WARN]", 0x00000002 },
{ "[LOAD]", 0x00000004 },
{ "[FS]", 0x00000008 },
{ "[POOL]", 0x00000010 },
{ "[PAGE]", 0x00000020 },
{ "[INFO]", 0x00000040 },
{ "[DISPATCH]", 0x00000080 },
{ "[VARIABLE]", 0x00000100 },
{ "[SMI]", 0x00000200 },
{ "[BM]", 0x00000400 },
{ "[BLKIO]", 0x00001000 },
{ "[NET]", 0x00004000 },
{ "[UNDI]", 0x00010000 },
{ "[LOADFILE]", 0x00020000 },
{ "[EVENT]", 0x00080000 },
{ "[GCD]", 0x00100000 },
{ "[CACHE]", 0x00200000 },
{ "[VERBOSE]", 0x00400000 },
{ "[MANAGEABILITY]", 0x00800000 },
{ "[ERROR]", 0x80000000 }
};

#define ADV_LOG_TIME_STAMP_FORMAT "%2.2d:%2.2d:%2.2d.%3.3d : "
#define ADV_LOG_TIME_STAMP_RESULT "hh:mm:ss:ttt : "
#define ADV_LOG_PHASE_ERR_FORMAT "[%04X] "
#define ADV_LOG_PHASE_MAX_SIZE 32
#define ADV_LOG_DEBUG_LEVEL_MAX_SIZE 32

/**

Expand Down Expand Up @@ -88,21 +120,19 @@ FormatTimeStamp (
TimeStampLen = AsciiSPrint (
MessageBuffer,
MessageBufferSize,
ADV_TIME_STAMP_FORMAT,
ADV_LOG_TIME_STAMP_FORMAT,
Hours,
Minutes,
Seconds,
Milliseconds
);

ASSERT (TimeStampLen == AsciiStrLen (ADV_TIME_STAMP_RESULT));
ASSERT (TimeStampLen == AsciiStrLen (ADV_LOG_TIME_STAMP_RESULT));

return (UINT16)TimeStampLen;
}

/**
FormatPhasePrefix

Adds a phase indicator to the message being returned. If phase is recognized and specified,
returns the phase prefix in from the AdvMsgEntryPrefix, otherwise raw phase value is returned.

Expand All @@ -128,14 +158,64 @@ FormatPhasePrefix (
} else if (Phase < ADVANCED_LOGGER_PHASE_CNT) {
// Normal message we recognize
PhaseStringLen = AsciiSPrint (MessageBuffer, MessageBufferSize, AdvMsgEntryPrefix[Phase]);
// Verify string length and add an extra space for readability
if (PhaseStringLen < MessageBufferSize - 1) {
MessageBuffer[PhaseStringLen] = ' ';
MessageBuffer[PhaseStringLen + 1] = '\0';
PhaseStringLen++;
}
} else {
// Unrecognized phase, just print the raw value
PhaseStringLen = AsciiSPrint (MessageBuffer, MessageBufferSize, ADV_PHASE_ERR_FORMAT, Phase);
PhaseStringLen = AsciiSPrint (MessageBuffer, MessageBufferSize, ADV_LOG_PHASE_ERR_FORMAT, Phase);
}

return (UINT16)PhaseStringLen;
}

/**
Adds a debug level indicator to the message being returned. If debug level is recognized and specified,
returns the debug_level prefix in from the AdvMsgEntryPrefix, otherwise raw debug level value is returned.

@param MessageBuffer
@param MessageBufferSize
@param DebugLevel

@retval Number of characters printed
*/
STATIC
UINT16
liqiqiii marked this conversation as resolved.
Show resolved Hide resolved
FormatDebugLevelPrefix (
IN CHAR8 *MessageBuffer,
IN UINTN MessageBufferSize,
IN UINT32 DebugLevel
)
{
if ((MessageBuffer == NULL) || (MessageBufferSize == 0)) {
return 0;
}

UINTN DebugLevelStringLen;
UINTN Index;

// Print the debug flags
for (Index = 0; Index < ARRAY_SIZE (DebugLevels); Index++) {
if ((DebugLevel & DebugLevels[Index].Value) == DebugLevels[Index].Value) {
DebugLevelStringLen = AsciiSPrint (MessageBuffer, MessageBufferSize, DebugLevels[Index].Name);
// Verify string length and add an extra space for readability
if (DebugLevelStringLen < MessageBufferSize - 1) {
MessageBuffer[DebugLevelStringLen] = ' ';
MessageBuffer[DebugLevelStringLen + 1] = '\0';
DebugLevelStringLen++;
}

liqiqiii marked this conversation as resolved.
Show resolved Hide resolved
return (UINT16)DebugLevelStringLen;
}
}

// If this is not a known debug level, just don't print it out and return 0
return 0;
}

/**
Get Next Message Block.

Expand Down Expand Up @@ -286,8 +366,11 @@ AdvancedLoggerAccessLibGetNextFormattedLine (
UINT16 TargetLen;
UINT16 PhaseStringLen;
UINT16 CurrPhaseStringLen;
CHAR8 TimeStampString[] = { ADV_TIME_STAMP_RESULT };
CHAR8 PhaseString[ADV_PHASE_MAX_SIZE] = { 0 };
UINT16 DebugLevelStringLen;
UINT16 CurrDebugLevelStringLen;
CHAR8 TimeStampString[] = { ADV_LOG_TIME_STAMP_RESULT };
CHAR8 PhaseString[ADV_LOG_PHASE_MAX_SIZE] = { 0 };
CHAR8 DebugLevelString[ADV_LOG_DEBUG_LEVEL_MAX_SIZE] = { 0 };

if (LineEntry == NULL) {
return EFI_INVALID_PARAMETER;
Expand All @@ -298,7 +381,7 @@ AdvancedLoggerAccessLibGetNextFormattedLine (
// reuse the previous LineBuffer
//
if (LineEntry->Message == NULL) {
LineBuffer = AllocatePool (mMaxMessageSize + sizeof (TimeStampString) + ADV_PHASE_MAX_SIZE);
LineBuffer = AllocatePool (mMaxMessageSize + sizeof (TimeStampString) + ADV_LOG_PHASE_MAX_SIZE);
if (LineBuffer == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Expand All @@ -314,15 +397,18 @@ AdvancedLoggerAccessLibGetNextFormattedLine (
// GetNextLine.

// In case this is a restart of the same Message, initialize the time stamp and prefix.
PhaseStringLen = 0;
PhaseStringLen = 0;
DebugLevelStringLen = 0;
if (LineEntry->BlockEntry.Message != NULL) {
FormatTimeStamp (TimeStampString, sizeof (TimeStampString), LineEntry->BlockEntry.TimeStamp);
CopyMem (LineBuffer, TimeStampString, sizeof (TimeStampString) - sizeof (CHAR8));
PhaseStringLen = FormatPhasePrefix (PhaseString, sizeof (PhaseString), LineEntry->BlockEntry.Phase);
CopyMem (LineBuffer + sizeof (TimeStampString) - sizeof (CHAR8), PhaseString, PhaseStringLen);
DebugLevelStringLen = FormatDebugLevelPrefix (DebugLevelString, sizeof (DebugLevelString), LineEntry->BlockEntry.DebugLevel);
CopyMem (LineBuffer + sizeof (TimeStampString) + PhaseStringLen - sizeof (CHAR8), DebugLevelString, DebugLevelStringLen);
}

TargetPtr = &LineBuffer[sizeof (TimeStampString) - sizeof (CHAR8) + PhaseStringLen];
TargetPtr = &LineBuffer[sizeof (TimeStampString) - sizeof (CHAR8) + PhaseStringLen + DebugLevelStringLen];
TargetLen = 0;
Status = EFI_SUCCESS;

Expand Down Expand Up @@ -380,17 +466,25 @@ AdvancedLoggerAccessLibGetNextFormattedLine (
CopyMem (LineBuffer, TimeStampString, sizeof (TimeStampString) - sizeof (CHAR8));
CurrPhaseStringLen = FormatPhasePrefix (PhaseString, sizeof (PhaseString), LineEntry->BlockEntry.Phase);
if (PhaseStringLen != CurrPhaseStringLen) {
// Adjust the TargetPtr to point to the end of the PhaseString
// Update the PhaseStringLen
PhaseStringLen = CurrPhaseStringLen;
TargetPtr = &LineBuffer[sizeof (TimeStampString) - sizeof (CHAR8) + PhaseStringLen];
}

CopyMem (LineBuffer + sizeof (TimeStampString) - sizeof (CHAR8), PhaseString, PhaseStringLen);

CurrDebugLevelStringLen = FormatDebugLevelPrefix (DebugLevelString, sizeof (DebugLevelString), LineEntry->BlockEntry.DebugLevel);
if (DebugLevelStringLen != CurrDebugLevelStringLen) {
// Adjust the TargetPtr to point to the end of the DebugLevelString
DebugLevelStringLen = CurrDebugLevelStringLen;
TargetPtr = &LineBuffer[sizeof (TimeStampString) - sizeof (CHAR8) + PhaseStringLen + DebugLevelStringLen];
}

CopyMem (LineBuffer + sizeof (TimeStampString) - sizeof (CHAR8) + PhaseStringLen, DebugLevelString, DebugLevelStringLen);
}
} while (!EFI_ERROR (Status));

if (!EFI_ERROR (Status)) {
LineEntry->MessageLen = TargetLen + sizeof (TimeStampString) - sizeof (CHAR8) + PhaseStringLen;
LineEntry->MessageLen = TargetLen + sizeof (TimeStampString) - sizeof (CHAR8) + PhaseStringLen + DebugLevelStringLen;
LineEntry->TimeStamp = LineEntry->BlockEntry.TimeStamp;
LineEntry->DebugLevel = LineEntry->BlockEntry.DebugLevel;
LineEntry->Phase = LineEntry->BlockEntry.Phase;
Expand Down
Loading