public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Michael D Kinney" <michael.d.kinney@intel.com>
To: "devel@edk2.groups.io" <devel@edk2.groups.io>,
	"Oram, Isaac W" <isaac.w.oram@intel.com>
Cc: "Wang, Jian J" <jian.j.wang@intel.com>,
	"Gao, Liming" <gaoliming@byosoft.com.cn>,
	"Zimmer, Vincent" <vincent.zimmer@intel.com>,
	"Chiu, Chasel" <chasel.chiu@intel.com>,
	"Kinney, Michael D" <michael.d.kinney@intel.com>
Subject: Re: [edk2-devel][edk2-platforms][RFC PATCH V1 1/1] MdeModulePkg/StatusCodeHandlerSmm: Add debug strings to memory buffering
Date: Tue, 16 May 2023 18:00:49 +0000	[thread overview]
Message-ID: <CO1PR11MB492982642D675614A777B8D3D2799@CO1PR11MB4929.namprd11.prod.outlook.com> (raw)
In-Reply-To: <SA1PR11MB58017C6094E419519A9AB612D0799@SA1PR11MB5801.namprd11.prod.outlook.com>

Hi Isaac,

Multiple status code handlers can be registered.  One for memory and one for serial.

Why would we mix serial into memory one?

Mike

> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Isaac
> Oram
> Sent: Tuesday, May 16, 2023 10:39 AM
> To: devel@edk2.groups.io; Oram, Isaac W <isaac.w.oram@intel.com>
> Cc: Wang, Jian J <jian.j.wang@intel.com>; Gao, Liming
> <gaoliming@byosoft.com.cn>; Zimmer, Vincent <vincent.zimmer@intel.com>;
> Chiu, Chasel <chasel.chiu@intel.com>
> Subject: Re: [edk2-devel][edk2-platforms][RFC PATCH V1 1/1]
> MdeModulePkg/StatusCodeHandlerSmm: Add debug strings to memory
> buffering
> 
> Apologies, this is edk2 scope, not edk2-platforms.
> 
> This is an RFC to see if this kind of feature is widely interesting and if
> someone wants to explore this in depth.
> This is not a complete or mature implementation.  I didn't fully decipher the
> extended data format.
> 
> Regards,
> Isaac
> 
> -----Original Message-----
> From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Isaac
> Oram
> Sent: Tuesday, May 16, 2023 10:35 AM
> To: devel@edk2.groups.io
> Cc: Oram, Isaac W <isaac.w.oram@intel.com>; Wang, Jian J
> <jian.j.wang@intel.com>; Gao, Liming <gaoliming@byosoft.com.cn>
> Subject: [edk2-devel][edk2-platforms][RFC PATCH V1 1/1]
> MdeModulePkg/StatusCodeHandlerSmm: Add debug strings to memory
> buffering
> 
> Extend the MemoryStatusCodeWorker functionality to log the debug strings.
> In the event of an assert, dump the strings to serial port.
> The rationale is that SMI latency is very important.  This provides a means to
> log messages quickly (to memory) and dump them in the event of an assert.
> 
> Cc: Jian J Wang <jian.j.wang@intel.com>
> Cc: Liming Gao <gaoliming@byosoft.com.cn>
> Signed-off-by: Isaac Oram <isaac.w.oram@intel.com>
> ---
>  .../Include/Guid/MemoryStatusCodeRecord.h     |   7 +
>  .../Smm/MemoryStatusCodeWorker.c              | 199 ++++++++++++++++++
>  2 files changed, 206 insertions(+)
> 
> diff --git a/MdeModulePkg/Include/Guid/MemoryStatusCodeRecord.h
> b/MdeModulePkg/Include/Guid/MemoryStatusCodeRecord.h
> index a924c592c9..d37b6304c6 100644
> --- a/MdeModulePkg/Include/Guid/MemoryStatusCodeRecord.h
> +++ b/MdeModulePkg/Include/Guid/MemoryStatusCodeRecord.h
> @@ -10,6 +10,8 @@ SPDX-License-Identifier: BSD-2-Clause-Patent  #ifndef
> __MEMORY_STATUS_CODE_RECORD_H__  #define
> __MEMORY_STATUS_CODE_RECORD_H__
> 
> +#include <Guid/StatusCodeDataTypeDebug.h>
> +
>  ///
>  /// Global ID used to identify GUIDed HOBs that start with a structure of type
> /// MEMORY_STATUSCODE_PACKET_HEADER, followed by an array of
> structures of type @@ -90,6 +92,11 @@ typedef struct {
>    /// the system. Valid instance numbers start with the number 1.
>    ///
>    UINT32                   Instance;
> +
> +  //
> +  // Extra data
> +  //
> +  UINT64                   Data[(MAX_EXTENDED_DATA_SIZE / sizeof (UINT64)) + 1];
>  } MEMORY_STATUSCODE_RECORD;
> 
>  extern EFI_GUID  gMemoryStatusCodeRecordGuid; diff --git
> a/MdeModulePkg/Universal/StatusCodeHandler/Smm/MemoryStatusCodeWo
> rker.c
> b/MdeModulePkg/Universal/StatusCodeHandler/Smm/MemoryStatusCodeW
> orker.c
> index 80c94e4682..c482c4bd9a 100644
> ---
> a/MdeModulePkg/Universal/StatusCodeHandler/Smm/MemoryStatusCodeWo
> rker.c
> +++
> b/MdeModulePkg/Universal/StatusCodeHandler/Smm/MemoryStatusCodeW
> orke
> +++ r.c
> @@ -11,6 +11,141 @@
> 
>  RUNTIME_MEMORY_STATUSCODE_HEADER  *mMmMemoryStatusCodeTable;
> 
> +VOID
> +DumpBufferToSerial (
> +  VOID
> +  );
> +
> +EFI_STATUS
> +EFIAPI
> +DumpRecordToSerial (
> +  IN EFI_STATUS_CODE_TYPE   CodeType,
> +  IN EFI_STATUS_CODE_VALUE  Value,
> +  IN UINT32                 Instance,
> +  IN EFI_GUID               *CallerId,
> +  IN EFI_STATUS_CODE_DATA   *Data OPTIONAL
> +  )
> +{
> +  CHAR8      *Filename;
> +  CHAR8      *Description;
> +  CHAR8      *Format;
> +  CHAR8      Buffer[MAX_EXTENDED_DATA_SIZE + sizeof (UINT64)];
> +  UINT32     ErrorLevel;
> +  UINT32     LineNumber;
> +  UINTN      CharCount;
> +  BASE_LIST  Marker;
> +
> +  Buffer[0] = '\0';
> +
> +  if ((Data != NULL) &&
> +      ReportStatusCodeExtractAssertInfo (CodeType, Value, Data,
> + &Filename, &Description, &LineNumber))  {
> +    //
> +    // Print ASSERT() information into output buffer.
> +    //
> +    CharCount = AsciiSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  "\n\rDXE_ASSERT!: %a (%d): %a\n\r",
> +                  Filename,
> +                  LineNumber,
> +                  Description
> +                  );
> +  } else if ((Data != NULL) &&
> +             ReportStatusCodeExtractDebugInfo (Data, &ErrorLevel,
> + &Marker, &Format))  {
> +    //
> +    // Print DEBUG() information into output buffer.
> +    //
> +    CharCount = AsciiBSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  Format,
> +                  Marker
> +                  );
> +  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) == EFI_ERROR_CODE)
> {
> +    //
> +    // Print ERROR information into output buffer.
> +    //
> +    CharCount = AsciiSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  "ERROR: C%08x:V%08x I%x",
> +                  CodeType,
> +                  Value,
> +                  Instance
> +                  );
> +    ASSERT (CharCount > 0);
> +
> +    if (CallerId != NULL) {
> +      CharCount += AsciiSPrint (
> +                     &Buffer[CharCount],
> +                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
> +                     " %g",
> +                     CallerId
> +                     );
> +    }
> +
> +    if (Data != NULL) {
> +      CharCount += AsciiSPrint (
> +                     &Buffer[CharCount],
> +                     (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
> +                     " %x",
> +                     Data
> +                     );
> +    }
> +
> +    CharCount += AsciiSPrint (
> +                   &Buffer[CharCount],
> +                   (sizeof (Buffer) - (sizeof (Buffer[0]) * CharCount)),
> +                   "\n\r"
> +                   );
> +  } else if ((CodeType & EFI_STATUS_CODE_TYPE_MASK) ==
> EFI_PROGRESS_CODE) {
> +    //
> +    // Print PROGRESS information into output buffer.
> +    //
> +    CharCount = AsciiSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  "PROGRESS CODE: V%08x I%x\n\r",
> +                  Value,
> +                  Instance
> +                  );
> +  } else if ((Data != NULL) &&
> +             CompareGuid (&Data->Type, &gEfiStatusCodeDataTypeStringGuid)
> &&
> +             (((EFI_STATUS_CODE_STRING_DATA *)Data)->StringType ==
> + EfiStringAscii))  {
> +    //
> +    // EFI_STATUS_CODE_STRING_DATA
> +    //
> +    CharCount = AsciiSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  "%a",
> +                  ((EFI_STATUS_CODE_STRING_DATA *)Data)->String.Ascii
> +                  );
> +  } else {
> +    //
> +    // Code type is not defined.
> +    //
> +    CharCount = AsciiSPrint (
> +                  Buffer,
> +                  sizeof (Buffer),
> +                  "Undefined: C%08x:V%08x I%x\n\r",
> +                  CodeType,
> +                  Value,
> +                  Instance
> +                  );
> +  }
> +
> +  //
> +  // Call SerialPort Lib function to do print.
> +  //
> +  SerialPortWrite ((UINT8 *)Buffer, CharCount);
> +
> +  return EFI_SUCCESS;
> +}
> +
>  /**
>    Initialize MM memory status code table as initialization for memory status
> code worker
> 
> @@ -69,6 +204,9 @@ MemoryStatusCodeReportWorker (
>    )
>  {
>    MEMORY_STATUSCODE_RECORD  *Record;
> +  CHAR8                     *Filename;
> +  CHAR8                     *Description;
> +  UINT32                    LineNumber;
> 
>    //
>    // Locate current record buffer.
> @@ -82,6 +220,7 @@ MemoryStatusCodeReportWorker (
>    Record->CodeType = CodeType;
>    Record->Value    = Value;
>    Record->Instance = Instance;
> +  CopyMem (&Record->Data, Data, (Data->HeaderSize + Data->Size));
> 
>    //
>    // If record index equals to max record number, then wrap around record
> index to zero.
> @@ -99,5 +238,65 @@ MemoryStatusCodeReportWorker (
>      mMmMemoryStatusCodeTable->RecordIndex = 0;
>    }
> 
> +  if ((Data != NULL) && ReportStatusCodeExtractAssertInfo (CodeType, Value,
> Data, &Filename, &Description, &LineNumber)) {
> +    // Found an assert, dump the buffer
> +    DumpBufferToSerial ();
> +  }
> +
>    return EFI_SUCCESS;
>  }
> +
> +VOID
> +DumpBufferToSerial (
> +  VOID
> +  )
> +{
> +  MEMORY_STATUSCODE_RECORD  *CurrentRecord;
> +  UINT32                    CurrentIndex;
> +  UINT32                    RecordsToPrint;
> +  CHAR8                     Buffer[MAX_DEBUG_MESSAGE_LENGTH];
> +  UINTN                     CharCount;
> +
> +  CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "Begin dump of SMM
> + debug messages\n");  SerialPortWrite ((UINT8 *)Buffer, CharCount);
> +
> +  //
> +  // Determine number of records to print  //
> +
> +  RecordsToPrint = mMmMemoryStatusCodeTable->NumberOfRecords;
> +
> +  //
> +  // Determine first record in case we rolled over.
> +  //
> +  if (mMmMemoryStatusCodeTable->NumberOfRecords >=
> mMmMemoryStatusCodeTable->MaxRecordsNumber) {
> +    RecordsToPrint = mMmMemoryStatusCodeTable->MaxRecordsNumber;
> +    CurrentIndex = mMmMemoryStatusCodeTable->RecordIndex;
> +  } else {
> +    RecordsToPrint = mMmMemoryStatusCodeTable->NumberOfRecords;
> +    CurrentIndex = 0;
> +  }
> +
> +
> +  //
> +  // Locate first record.
> +  //
> +  CurrentRecord = (MEMORY_STATUSCODE_RECORD
> *)(mMmMemoryStatusCodeTable
> + + 1);  CurrentRecord = &CurrentRecord[CurrentIndex];
> +
> +  //
> +  // Print records
> +  //
> +  while (CurrentIndex < RecordsToPrint) {
> +    DumpRecordToSerial (CurrentRecord->CodeType, CurrentRecord->Value,
> CurrentRecord->Instance, NULL, (EFI_STATUS_CODE_DATA *)CurrentRecord-
> >Data);
> +    CurrentIndex++;
> +    if (CurrentIndex == mMmMemoryStatusCodeTable->MaxRecordsNumber) {
> +      CurrentIndex = 0;
> +    }
> +    CurrentRecord = (MEMORY_STATUSCODE_RECORD
> *)(mMmMemoryStatusCodeTable + 1);
> +    CurrentRecord = &CurrentRecord[CurrentIndex];  }
> +
> +  CharCount = AsciiSPrint (Buffer, sizeof (Buffer), "End dump of SMM
> +debug messages\n");
> +  SerialPortWrite ((UINT8 *)Buffer, CharCount); }
> --
> 2.40.0.windows.1
> 
> 
> 
> 
> 
> 
> 
> 
> 
> 


  reply	other threads:[~2023-05-16 18:01 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1684258196.git.isaac.w.oram@intel.com>
2023-05-16 17:34 ` [edk2-devel][edk2-platforms][RFC PATCH V1 1/1] MdeModulePkg/StatusCodeHandlerSmm: Add debug strings to memory buffering Isaac Oram
     [not found] ` <175FB03665B4DC78.20583@groups.io>
2023-05-16 17:39   ` Isaac Oram
2023-05-16 18:00     ` Michael D Kinney [this message]
2023-05-16 19:11       ` Isaac Oram
2023-05-16 21:41         ` Michael D Kinney

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-list from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=CO1PR11MB492982642D675614A777B8D3D2799@CO1PR11MB4929.namprd11.prod.outlook.com \
    --to=devel@edk2.groups.io \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox