Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 22 additions & 4 deletions AdvLoggerPkg/Application/DecodeUefiLog/DecodeUefiLog.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,10 @@ class AdvLogParser ():
# EFI_TIME Time; // Uefi Time Field
# UINT32 HwPrintLevel; // Logging level to be printed at hw port
# UINT32 Reserved3; //
# EFI_PHYSICAL_ADDRESS NewLoggerInfoAddress; // If non-zero, this field holds the address of new logger info (added in later V5 revision, may not be present in older logs)
# } ADVANCED_LOGGER_INFO;
V5_LOGGER_INFO_SIZE = 80
V5_LOGGER_INFO_SIZE_WITH_NEW_ADDRESS = 88
V5_LOGGER_INFO_VERSION = 5

# ---------------------------------------------------------------------- #
Expand Down Expand Up @@ -458,14 +460,24 @@ def _InitializeLoggerInfo(self, InFile, StartLine):

elif Version == self.V5_LOGGER_INFO_VERSION:
InFile.read(4) # skip over rest of reserved section
Size = self.V5_LOGGER_INFO_SIZE
# V5 can be either 80 bytes or 88 bytes (minor version 1 update with NewLoggerInfoAddress)
BaseAddress = 0
LoggerInfo["LogBufferOffset"] = struct.unpack("=I", InFile.read(4))[0]
Size = LoggerInfo["LogBufferOffset"]

# Determine if this has the NewLoggerInfoAddress field based on structure size
if Size == self.V5_LOGGER_INFO_SIZE:
HasNewLoggerInfoAddress = False
elif Size == self.V5_LOGGER_INFO_SIZE_WITH_NEW_ADDRESS:
HasNewLoggerInfoAddress = True
else:
raise Exception('Error initializing logger info. Unexpected V5 structure size: %d' % Size)

# we no longer have this field in the struct but for compatibility can calculate it
# to be used
LoggerInfo["LogBuffer"] = Size
# this is only used to calculate LogCurrent as an offset, but V5 uses
# LogCurrentOffset already, so we do this just to share the common code
BaseAddress = 0
LoggerInfo["LogBufferOffset"] = struct.unpack("=I", InFile.read(4))[0]
InFile.read(4) # skip over reserved4 field
LoggerInfo["LogCurrentOffset"] = struct.unpack("=I", InFile.read(4))[0]
# we don't have this field anymore, but to share the common code we
Expand Down Expand Up @@ -499,10 +511,16 @@ def _InitializeLoggerInfo(self, InFile, StartLine):
InFile.read(4)
InFile.read(4)

# Read NewLoggerInfoAddress if present (88-byte V5 format)
if HasNewLoggerInfoAddress:
LoggerInfo["NewLoggerInfoAddress"] = struct.unpack("=Q", InFile.read(8))[0]
else:
LoggerInfo["NewLoggerInfoAddress"] = 0

self._Compute_Basetime(LoggerInfo)

if InFile.tell() != (Size):
raise Exception('Error initializing logger info. AmountRead: %d' % InFile.tell())
raise Exception('Error initializing logger info. AmountRead: %d, Expected: %d' % (InFile.tell(), Size))

else:
raise Exception('Error initializing logger info. Unsupported version: 0x%X' % LoggerInfo["Version"])
Expand Down
64 changes: 42 additions & 22 deletions AdvLoggerPkg/Include/AdvancedLoggerInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,24 @@
#ifndef __ADVANCED_LOGGER_INTERNAL_H__
#define __ADVANCED_LOGGER_INTERNAL_H__

#define ADVANCED_LOGGER_SIGNATURE SIGNATURE_32('A','L','O','G')
#define ADVANCED_LOGGER_HW_LVL_VER 5
#define ADVANCED_LOGGER_SIGNATURE SIGNATURE_32('A','L','O','G')

//
// Advanced Logger Hardware Port Level Support Version
//
// Writing to hardware port based on message DebugLevel is supported
// (AdvancedLoggerHdwPortWrite()).
//
#define ADVANCED_LOGGER_HW_LVL_VER 5

//
// Advanced Logger Message structure versions
//
// Version 1: Original structure (ADVANCED_LOGGER_MESSAGE_ENTRY)
// Version 2: New backward incompatible V2 structure (ADVANCED_LOGGER_MESSAGE_ENTRY_V2
//
#define ADVANCED_LOGGER_MSG_MAJ_VER 2
#define ADVANCED_LOGGER_MSG_MIN_VER 0
#define ADVANCED_LOGGER_MSG_MIN_VER 1

#define ADVANCED_LOGGER_VERSION ADVANCED_LOGGER_HW_LVL_VER

Expand All @@ -31,6 +45,11 @@
#define ADVANCED_LOGGER_PHASE_TFA 10
#define ADVANCED_LOGGER_PHASE_CNT 11

//
// The maximum depth to follow when traversing chains of advanced logger info structures
//
#define ADVANCED_LOGGER_MAX_LOGGER_CHAIN_DEPTH 3

//
// These Pcds are used to carve out a PEI memory buffer from the temporary RAM.
//
Expand All @@ -46,25 +65,26 @@
#pragma pack (push, 1)

typedef volatile struct {
UINT32 Signature; // Signature 'ALOG'
UINT16 Version; // Current Version
UINT16 Reserved[3]; // Reserved for future
UINT32 LogBufferOffset; // Offset from LoggerInfo to start of log, expected to be the size of this structure 8 byte aligned
UINT32 Reserved4;
UINT32 LogCurrentOffset; // Offset from LoggerInfo to where to store next log entry.
UINT32 DiscardedSize; // Number of bytes of messages missed
UINT32 LogBufferSize; // Size of allocated buffer
BOOLEAN InPermanentRAM; // Log in permanent RAM
BOOLEAN AtRuntime; // After ExitBootServices
BOOLEAN GoneVirtual; // After VirtualAddressChange
BOOLEAN HdwPortInitialized; // HdwPort initialized
BOOLEAN HdwPortDisabled; // HdwPort is Disabled
BOOLEAN Reserved2[3]; //
UINT64 TimerFrequency; // Ticks per second for log timing
UINT64 TicksAtTime; // Ticks when Time Acquired
EFI_TIME Time; // Uefi Time Field
UINT32 HwPrintLevel; // Logging level to be printed at hw port
UINT32 Reserved3; //
UINT32 Signature; // Signature 'ALOG'
UINT16 Version; // Current Version
UINT16 Reserved[3]; // Reserved for future
UINT32 LogBufferOffset; // Offset from LoggerInfo to start of log, expected to be the size of this structure 8 byte aligned
UINT32 Reserved4;
UINT32 LogCurrentOffset; // Offset from LoggerInfo to where to store next log entry.
UINT32 DiscardedSize; // Number of bytes of messages missed
UINT32 LogBufferSize; // Size of allocated buffer
BOOLEAN InPermanentRAM; // Log in permanent RAM
BOOLEAN AtRuntime; // After ExitBootServices
BOOLEAN GoneVirtual; // After VirtualAddressChange
BOOLEAN HdwPortInitialized; // HdwPort initialized
BOOLEAN HdwPortDisabled; // HdwPort is Disabled
BOOLEAN Reserved2[3]; //
UINT64 TimerFrequency; // Ticks per second for log timing
UINT64 TicksAtTime; // Ticks when Time Acquired
EFI_TIME Time; // Uefi Time Field
UINT32 HwPrintLevel; // Logging level to be printed at hw port
UINT32 Reserved3; //
EFI_PHYSICAL_ADDRESS NewLoggerInfoAddress; // If non-zero, this field holds the address of new logger info that should be used
Comment thread
makubacki marked this conversation as resolved.
} ADVANCED_LOGGER_INFO;

typedef struct {
Expand Down
81 changes: 81 additions & 0 deletions AdvLoggerPkg/Library/AdvLoggerMmAccessLib/AdvLoggerMmAccessLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,69 @@ STATIC EFI_PHYSICAL_ADDRESS mMaxAddress = 0;
STATIC UINTN mLoggerTransferSize = 0;
extern UINTN mVariableBufferPayloadSize;

/**
Follow the logger info redirection chain and update the provided logger info pointer.

@param[in,out] LoggerInfo Pointer to a logger info pointer to update.
@param[out] MaxAddress Optional pointer to update with the max address of the current logger.
@param[out] BufferSize Optional pointer to update with the buffer size of the current logger.

@retval TRUE A new logger was found and LoggerInfo was updated to the new address.
@retval FALSE A new logger was not found and no modification was made to LoggerInfo.
**/
STATIC
BOOLEAN
AdvancedLoggerCheckForNewerLogger (
IN OUT ADVANCED_LOGGER_INFO **LoggerInfo,
OUT EFI_PHYSICAL_ADDRESS *MaxAddress OPTIONAL,
OUT UINT32 *BufferSize OPTIONAL
)
{
ADVANCED_LOGGER_INFO *CurrentLoggerInfo;
ADVANCED_LOGGER_INFO *NextLoggerInfo;
UINTN Depth;

if ((LoggerInfo == NULL) || (*LoggerInfo == NULL)) {
return FALSE;
}

CurrentLoggerInfo = *LoggerInfo;
Depth = 0;

// Follow the chain to find the current logger
while ((CurrentLoggerInfo->NewLoggerInfoAddress != 0) && (Depth < ADVANCED_LOGGER_MAX_LOGGER_CHAIN_DEPTH)) {
NextLoggerInfo = ALI_FROM_PA (CurrentLoggerInfo->NewLoggerInfoAddress);

if (NextLoggerInfo->Signature != ADVANCED_LOGGER_SIGNATURE) {
return FALSE;
}

CurrentLoggerInfo = NextLoggerInfo;
Depth++;
}

if (Depth >= ADVANCED_LOGGER_MAX_LOGGER_CHAIN_DEPTH) {
return FALSE;
}

// Update if we found a newer logger
if (CurrentLoggerInfo != *LoggerInfo) {
*LoggerInfo = CurrentLoggerInfo;

if (MaxAddress != NULL) {
*MaxAddress = LOG_MAX_ADDRESS (CurrentLoggerInfo);
}

if (BufferSize != NULL) {
*BufferSize = CurrentLoggerInfo->LogBufferSize;
}

return TRUE;
}

return FALSE;
}

/**
CheckAddress

Expand Down Expand Up @@ -112,6 +175,12 @@ AdvLoggerAccessInit (
mMaxAddress = LOG_MAX_ADDRESS (mLoggerInfo);
}

if ((mLoggerInfo != NULL) && !FeaturePcdGet (PcdAdvancedLoggerFixedInRAM)) {
if (AdvancedLoggerCheckForNewerLogger (&mLoggerInfo, &mMaxAddress, &mBufferSize)) {
DEBUG ((DEBUG_INFO, "%a: Logger buffer migrated. LoggerInfo=%p\n", __FUNCTION__, mLoggerInfo));
}
}

//
// If mLoggerInfo is NULL at this point, there is no Advanced Logger.
//
Expand Down Expand Up @@ -194,6 +263,12 @@ AdvLoggerAccessGetVariable (
UINT8 *LogBufferEnd;
UINTN LogBufferSize;

if ((mLoggerInfo != NULL) && !mLoggerInfo->AtRuntime && !FeaturePcdGet (PcdAdvancedLoggerFixedInRAM)) {
if (AdvancedLoggerCheckForNewerLogger (&mLoggerInfo, &mMaxAddress, &mBufferSize)) {
DEBUG ((DEBUG_INFO, "%a: Logger buffer migrated during access. LoggerInfo=%p\n", __FUNCTION__, mLoggerInfo));
}
}

if ((!ValidateInfoBlock ()) || (mLoggerTransferSize == 0)) {
return EFI_UNSUPPORTED;
}
Expand Down Expand Up @@ -260,6 +335,12 @@ AdvLoggerAccessAtRuntime (
VOID
)
{
if ((mLoggerInfo != NULL) && !FeaturePcdGet (PcdAdvancedLoggerFixedInRAM)) {
if (AdvancedLoggerCheckForNewerLogger (&mLoggerInfo, &mMaxAddress, &mBufferSize)) {
DEBUG ((DEBUG_INFO, "%a: Logger buffer migrated at ExitBootServices. LoggerInfo=%p\n", __FUNCTION__, mLoggerInfo));
}
}

if (mLoggerInfo != NULL) {
mLoggerInfo->AtRuntime = TRUE;
}
Expand Down
79 changes: 79 additions & 0 deletions AdvLoggerPkg/Library/AdvLoggerSmmAccessLib/AdvLoggerSmmAccessLib.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,69 @@ STATIC EFI_PHYSICAL_ADDRESS mMaxAddress = 0;
STATIC UINTN mLoggerTransferSize = 0;
extern UINTN mVariableBufferPayloadSize;

/**
Follow the logger info redirection chain and update the provided logger info pointer.

@param[in,out] LoggerInfo Pointer to a logger info pointer to update.
@param[out] MaxAddress Optional pointer to update with the max address of the current logger.
@param[out] BufferSize Optional pointer to update with the buffer size of the current logger.

@retval TRUE A new logger was found and LoggerInfo was updated to the new address.
@retval FALSE A new logger was not found and no modification was made to LoggerInfo.
**/
STATIC
BOOLEAN
AdvancedLoggerCheckForNewerLogger (
IN OUT ADVANCED_LOGGER_INFO **LoggerInfo,
OUT EFI_PHYSICAL_ADDRESS *MaxAddress OPTIONAL,
OUT UINT32 *BufferSize OPTIONAL
)
{
ADVANCED_LOGGER_INFO *CurrentLoggerInfo;
ADVANCED_LOGGER_INFO *NextLoggerInfo;
UINTN Depth;

if ((LoggerInfo == NULL) || (*LoggerInfo == NULL)) {
return FALSE;
}

CurrentLoggerInfo = *LoggerInfo;
Depth = 0;

// Follow the chain to find the current logger
while ((CurrentLoggerInfo->NewLoggerInfoAddress != 0) && (Depth < ADVANCED_LOGGER_MAX_LOGGER_CHAIN_DEPTH)) {
NextLoggerInfo = ALI_FROM_PA (CurrentLoggerInfo->NewLoggerInfoAddress);

if (NextLoggerInfo->Signature != ADVANCED_LOGGER_SIGNATURE) {
return FALSE;
}

CurrentLoggerInfo = NextLoggerInfo;
Depth++;
}

if (Depth >= ADVANCED_LOGGER_MAX_LOGGER_CHAIN_DEPTH) {
return FALSE;
}

// Update if we found a newer logger
if (CurrentLoggerInfo != *LoggerInfo) {
*LoggerInfo = CurrentLoggerInfo;

if (MaxAddress != NULL) {
*MaxAddress = LOG_MAX_ADDRESS (CurrentLoggerInfo);
}

if (BufferSize != NULL) {
*BufferSize = CurrentLoggerInfo->LogBufferSize;
}

return TRUE;
}

return FALSE;
}

/**
CheckAddress

Expand Down Expand Up @@ -127,6 +190,10 @@ AdvLoggerAccessInit (
mLoggerInfo = LOGGER_INFO_FROM_PROTOCOL (LoggerProtocol);
if (mLoggerInfo != NULL) {
mMaxAddress = LOG_MAX_ADDRESS (mLoggerInfo);

if (AdvancedLoggerCheckForNewerLogger (&mLoggerInfo, &mMaxAddress, &mBufferSize)) {
DEBUG ((DEBUG_INFO, "%a: Logger buffer migrated. LoggerInfo=%p\n", __FUNCTION__, mLoggerInfo));
}
}

if (!ValidateInfoBlock ()) {
Expand Down Expand Up @@ -194,6 +261,12 @@ AdvLoggerAccessGetVariable (
UINT8 *LogBufferEnd;
UINTN LogBufferSize;

if ((mLoggerInfo != NULL) && !mLoggerInfo->AtRuntime) {
if (AdvancedLoggerCheckForNewerLogger (&mLoggerInfo, &mMaxAddress, &mBufferSize)) {
DEBUG ((DEBUG_INFO, "%a: Logger buffer migrated during access. LoggerInfo=%p\n", __FUNCTION__, mLoggerInfo));
}
}

if ((!ValidateInfoBlock ()) || (mLoggerTransferSize == 0)) {
return EFI_UNSUPPORTED;
}
Expand Down Expand Up @@ -260,6 +333,12 @@ AdvLoggerAccessAtRuntime (
VOID
)
{
if (mLoggerInfo != NULL) {
if (AdvancedLoggerCheckForNewerLogger (&mLoggerInfo, &mMaxAddress, &mBufferSize)) {
DEBUG ((DEBUG_INFO, "%a: Logger buffer migrated at ExitBootServices. LoggerInfo=%p\n", __FUNCTION__, mLoggerInfo));
}
}

if (mLoggerInfo != NULL) {
mLoggerInfo->AtRuntime = TRUE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,7 @@
[Pcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdMaxVariableSize

[FeaturePcd]
gAdvLoggerPkgTokenSpaceGuid.PcdAdvancedLoggerFixedInRAM

[Depex]
Loading