Enhance debug log buffer as ring buffer (#699)

This will allow debug log buffer to record logs in ring buffer
if the buffer is full.

Signed-off-by: Aiden Park <aiden.park@intel.com>
This commit is contained in:
Aiden Park 2020-04-30 11:56:39 -07:00 committed by GitHub
parent b884702aca
commit 57bea9118d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 71 additions and 19 deletions

View File

@ -14,26 +14,14 @@
///
extern EFI_GUID gLoaderPlatformDataGuid;
#define DEBUG_LOG_BUFFER_SIGNATURE SIGNATURE_32 ('D', 'L', 'O', 'G')
#define DEBUG_OUTPUT_DEVICE_LOG_BUFFER BIT0
#define DEBUG_OUTPUT_DEVICE_SERIAL_PORT BIT1
#define DEBUG_OUTPUT_DEVICE_CONSOLE BIT2
typedef struct {
UINT32 Signature;
UINT8 HeaderLength;
UINT8 Attribute;
UINT8 Reserved[2];
UINT32 UsedLength;
UINT32 TotalLength;
UINT8 Buffer[0];
} DEBUG_LOG_BUFFER_HEADER;
typedef struct {
UINT8 Revision;
UINT8 Reserved0[3];
DEBUG_LOG_BUFFER_HEADER *DebugLogBuffer;
VOID *DebugLogBuffer;
VOID *ConfigDataPtr;
VOID *ContainerList;
VOID *DmaBufferPtr;

View File

@ -9,6 +9,20 @@
#ifndef __DEBUG_LOG_BUFFER_LIB_H__
#define __DEBUG_LOG_BUFFER_LIB_H__
#define DEBUG_LOG_BUFFER_SIGNATURE SIGNATURE_32 ('D', 'L', 'O', 'G')
#define DEBUG_LOG_BUFFER_ATTRIBUTE_FULL BIT0
typedef struct {
UINT32 Signature;
UINT8 HeaderLength;
UINT8 Attribute;
UINT8 Reserved[2];
UINT32 UsedLength;
UINT32 TotalLength;
UINT8 Buffer[0];
} DEBUG_LOG_BUFFER_HEADER;
/**
Write data from buffer to console buffer.

View File

@ -16,6 +16,7 @@
#include <Library/HobLib.h>
#include <Library/BootloaderCommonLib.h>
#include <Library/SecureBootLib.h>
#include <Library/DebugLogBufferLib.h>
CONST CHAR8 mHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
CONST CHAR8 *mStage[] = { "1A", "1B", "2", "PAYLOAD"};

View File

@ -39,6 +39,7 @@ DebugLogBufferWrite (
)
{
DEBUG_LOG_BUFFER_HEADER *LogBufHdr;
UINTN RemainingBytes;
// This function will be called by DEBUG or ASSERT macro.
// So please DON'T use DEBUG/ASSERT macro inside this function,
@ -48,14 +49,37 @@ DebugLogBufferWrite (
return 0;
}
if (LogBufHdr->Signature != DEBUG_LOG_BUFFER_SIGNATURE) {
return 0;
}
//
// Something wrong in Debug Log Buffer.
// Reset buffer index and continue to record logs.
//
if (LogBufHdr->UsedLength > LogBufHdr->TotalLength) {
LogBufHdr->UsedLength = LogBufHdr->HeaderLength;
}
RemainingBytes = 0;
if (LogBufHdr->UsedLength + NumberOfBytes > LogBufHdr->TotalLength) {
NumberOfBytes = LogBufHdr->TotalLength - LogBufHdr->UsedLength;
RemainingBytes = LogBufHdr->UsedLength + NumberOfBytes - LogBufHdr->TotalLength;
NumberOfBytes = LogBufHdr->TotalLength - LogBufHdr->UsedLength;
}
if (NumberOfBytes > 0) {
CopyMem ((UINT8 *)LogBufHdr + LogBufHdr->UsedLength, Buffer, NumberOfBytes);
CopyMem (&LogBufHdr->Buffer[LogBufHdr->UsedLength - LogBufHdr->HeaderLength], Buffer, NumberOfBytes);
LogBufHdr->UsedLength += (UINT32)NumberOfBytes;
}
return NumberOfBytes;
//
// Handle Ring Buffer
//
if (RemainingBytes > 0) {
CopyMem (&LogBufHdr->Buffer[0], Buffer + NumberOfBytes, RemainingBytes);
LogBufHdr->UsedLength = LogBufHdr->HeaderLength + (UINT32)RemainingBytes;
LogBufHdr->Attribute |= DEBUG_LOG_BUFFER_ATTRIBUTE_FULL;
}
return (NumberOfBytes + RemainingBytes);
}

View File

@ -13,6 +13,7 @@
#include <Library/ConsoleInLib.h>
#include <Library/ConsoleOutLib.h>
#include <Library/BootloaderCommonLib.h>
#include <Library/DebugLogBufferLib.h>
/**
Print the contents of the log buffer
@ -65,6 +66,8 @@ ShellCommandDmesgFunc (
UINTN Index;
UINT8 Buf[1];
BOOLEAN Paged = FALSE;
UINTN Length;
UINTN BufIndex;
for (Index = 1; Index < Argc; Index++) {
if (StrCmp (Argv[Index], L"-h") == 0) {
@ -77,11 +80,27 @@ ShellCommandDmesgFunc (
PageLineCount = 0;
LogBufHdr = (DEBUG_LOG_BUFFER_HEADER *) GetDebugLogBufferPtr ();
for (Index = 0; Index < (LogBufHdr->UsedLength - LogBufHdr->HeaderLength); Index++) {
ConsoleWrite ((UINT8 *)&LogBufHdr->Buffer[Index], 1);
if (LogBufHdr == NULL) {
return EFI_UNSUPPORTED;
}
if (LogBufHdr->UsedLength > LogBufHdr->TotalLength) {
return EFI_LOAD_ERROR;
}
if ((LogBufHdr->Attribute & DEBUG_LOG_BUFFER_ATTRIBUTE_FULL) != 0) {
BufIndex = LogBufHdr->UsedLength - LogBufHdr->HeaderLength;
Length = LogBufHdr->TotalLength - LogBufHdr->HeaderLength;
} else {
BufIndex = 0;
Length = LogBufHdr->UsedLength - LogBufHdr->HeaderLength;
}
for (Index = 0; Index < Length; Index++, BufIndex++) {
ConsoleWrite ((UINT8 *)&LogBufHdr->Buffer[BufIndex % Length], 1);
// Page out the log contents if requested
if (Paged && (LogBufHdr->Buffer[Index] == '\n') && (++PageLineCount == LinesPerPage)) {
if (Paged && (LogBufHdr->Buffer[BufIndex % Length] == '\n') && (++PageLineCount == LinesPerPage)) {
ShellPrint (L"[Press <ESC> to stop, or any other key to continue...]");
ConsoleRead (Buf, 1);
if (Buf[0] == '\x1b') { break; }

View File

@ -552,6 +552,11 @@ SecStartup2 (
CopyMem ((VOID *)NewLogBuf, (VOID *)OldLogBuf, OldLogBuf->UsedLength);
NewLogBuf->TotalLength = PcdGet32 (PcdLogBufferSize);
LdrGlobal->LogBufPtr = NewLogBuf;
//
// No ring buffer manipulation here even if early log buffer was full.
// Simply clear FULL attribute and continue to overwrite logs.
//
NewLogBuf->Attribute &= (UINT8)~(DEBUG_LOG_BUFFER_ATTRIBUTE_FULL);
}
}
}

View File

@ -46,6 +46,7 @@
#include <Library/ElfLib.h>
#include <Library/LinuxLib.h>
#include <Library/ContainerLib.h>
#include <Library/DebugLogBufferLib.h>
#include <Guid/SeedInfoHobGuid.h>
#include <Guid/OsConfigDataHobGuid.h>
#include <Guid/OsBootOptionGuid.h>