diff --git a/AdvLoggerPkg/Library/AdvancedLoggerLib/MmCoreArm/AdvancedLoggerLib.c b/AdvLoggerPkg/Library/AdvancedLoggerLib/MmCoreArm/AdvancedLoggerLib.c index dee083f294..0dd806eb7c 100644 --- a/AdvLoggerPkg/Library/AdvancedLoggerLib/MmCoreArm/AdvancedLoggerLib.c +++ b/AdvLoggerPkg/Library/AdvancedLoggerLib/MmCoreArm/AdvancedLoggerLib.c @@ -23,6 +23,55 @@ // cannot presume globals will be available. // +/** + Initialize the AdvancedLogger header at PcdAdvancedLoggerBase if a previous + firmware phase has not already done so. + + On boot flows where StandaloneMM runs before any phase that would normally + lay down the ADVANCED_LOGGER_INFO header (e.g. BL31 -> StMM -> BL33/UEFI), + the buffer signature will be invalid on first entry. This routine performs + a one-time initialization of the header so that subsequent logging calls + have a valid buffer to write into. + + @param[in] LoggerInfo Caller-supplied non-NULL pointer to the fixed buffer. +**/ +STATIC +VOID +InitializeLoggerHeaderIfNeeded ( + IN ADVANCED_LOGGER_INFO *LoggerInfo + ) +{ + UINTN LogBufferSize; + + if (LoggerInfo == NULL) { + return; + } + + if (LoggerInfo->Signature == ADVANCED_LOGGER_SIGNATURE) { + return; + } + + LogBufferSize = EFI_PAGES_TO_SIZE (FixedPcdGet32 (PcdAdvancedLoggerPages)); + + // + // Buffer must be large enough to hold the header plus some payload + // + if (LogBufferSize <= sizeof (ADVANCED_LOGGER_INFO)) { + return; + } + + ZeroMem ((VOID *)LoggerInfo, sizeof (ADVANCED_LOGGER_INFO)); + LoggerInfo->Signature = ADVANCED_LOGGER_SIGNATURE; + LoggerInfo->Version = ADVANCED_LOGGER_INFO_VER; + LoggerInfo->LogBufferSize = (UINT32)(LogBufferSize - sizeof (ADVANCED_LOGGER_INFO)); + LoggerInfo->LogBufferOffset = EXPECTED_LOG_BUFFER_OFFSET (LoggerInfo); + LoggerInfo->LogCurrentOffset = LoggerInfo->LogBufferOffset; + LoggerInfo->HwPrintLevel = FixedPcdGet32 (PcdAdvancedLoggerHdwPortDebugPrintErrorLevel); + AdvancedLoggerHdwPortInitialize (); + LoggerInfo->HdwPortInitialized = TRUE; + LoggerInfo->InPermanentRAM = TRUE; +} + /** The logger Information Block is carved from the Trust Zone at a specific fixed address. @@ -64,6 +113,12 @@ AdvancedLoggerGetLoggerInfo ( return NULL; } + // + // Check if the log has been initialized by a previous entity (e.g. TF-A) + // or a previous log in StMM. If not, initialize. + // + InitializeLoggerHeaderIfNeeded (LoggerInfo); + // // LogBuffer and LogCurrent, and LogBufferSize, could be written // to by untrusted code. Here, we check that the offsets are within the diff --git a/AdvLoggerPkg/Library/AdvancedLoggerLib/PeilessArm/AdvancedLoggerLib.c b/AdvLoggerPkg/Library/AdvancedLoggerLib/PeilessArm/AdvancedLoggerLib.c index fc8b827789..48f2fcff7b 100644 --- a/AdvLoggerPkg/Library/AdvancedLoggerLib/PeilessArm/AdvancedLoggerLib.c +++ b/AdvLoggerPkg/Library/AdvancedLoggerLib/PeilessArm/AdvancedLoggerLib.c @@ -36,7 +36,10 @@ AdvancedLoggerLibConstructor ( LogBufferSize = EFI_PAGES_TO_SIZE (FixedPcdGet64 (PcdAdvancedLoggerPages)); LoggerInfo = ALI_FROM_PA (FixedPcdGet64 (PcdAdvancedLoggerBase)); - if (LoggerInfo != NULL) { + // + // Buffer must be large enough to hold the header plus some payload. + // + if ((LoggerInfo != NULL) && (LogBufferSize > sizeof (ADVANCED_LOGGER_INFO))) { ZeroMem ((VOID *)LoggerInfo, sizeof (ADVANCED_LOGGER_INFO)); LoggerInfo->Signature = ADVANCED_LOGGER_SIGNATURE; LoggerInfo->Version = ADVANCED_LOGGER_INFO_VER; diff --git a/AdvLoggerPkg/Library/DebugAgent/Sec/AdvancedLoggerSecDebugAgent.c b/AdvLoggerPkg/Library/DebugAgent/Sec/AdvancedLoggerSecDebugAgent.c index 9caf5b81d4..011e7fb1e2 100644 --- a/AdvLoggerPkg/Library/DebugAgent/Sec/AdvancedLoggerSecDebugAgent.c +++ b/AdvLoggerPkg/Library/DebugAgent/Sec/AdvancedLoggerSecDebugAgent.c @@ -122,7 +122,10 @@ InitializeDebugAgent ( CarBase = (EFI_PHYSICAL_ADDRESS)FixedPcdGet64 (PcdAdvancedLoggerCarBase); NewLogBuffer = AllocateRamForSEC (CarBase, LogBufferSize); - if (NewLogBuffer != 0ULL) { + // + // Buffer must be large enough to hold the header plus some payload. + // + if ((NewLogBuffer != 0ULL) && (LogBufferSize > sizeof (ADVANCED_LOGGER_INFO))) { LoggerInfo = ALI_FROM_PA (NewLogBuffer); ZeroMem ((VOID *)LoggerInfo, sizeof (ADVANCED_LOGGER_INFO)); LoggerInfo->Signature = ADVANCED_LOGGER_SIGNATURE;