REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3737 Apply uncrustify changes to .c/.h files in the DynamicTablesPkg package Cc: Andrew Fish <afish@apple.com> Cc: Leif Lindholm <leif@nuviainc.com> Cc: Michael D Kinney <michael.d.kinney@intel.com> Signed-off-by: Michael Kubacki <michael.kubacki@microsoft.com> Reviewed-by: Sami Mujawar <sami.mujawar@arm.com>
		
			
				
	
	
		
			563 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			563 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   AML Print Function.
 | |
| 
 | |
|   Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>
 | |
|   Copyright (c) 2019 - 2021, Arm Limited. All rights reserved.<BR>
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| **/
 | |
| 
 | |
| #include <AmlNodeDefines.h>
 | |
| #include <AmlDbgPrint/AmlDbgPrint.h>
 | |
| 
 | |
| #include <AmlCoreInterface.h>
 | |
| #include <String/AmlString.h>
 | |
| #include <Tree/AmlNode.h>
 | |
| #include <Tree/AmlTreeTraversal.h>
 | |
| 
 | |
| #if !defined (MDEPKG_NDEBUG)
 | |
| 
 | |
| /** String table representing AML Data types as defined by EAML_NODE_DATA_TYPE.
 | |
| */
 | |
| CONST CHAR8  *NodeDataTypeStrTbl[] = {
 | |
|   "EAmlNodeDataTypeNone",
 | |
|   "EAmlNodeDataTypeReserved1",
 | |
|   "EAmlNodeDataTypeReserved2",
 | |
|   "EAmlNodeDataTypeReserved3",
 | |
|   "EAmlNodeDataTypeReserved4",
 | |
|   "EAmlNodeDataTypeReserved5",
 | |
|   "EAmlNodeDataTypeNameString",
 | |
|   "EAmlNodeDataTypeString",
 | |
|   "EAmlNodeDataTypeUInt",
 | |
|   "EAmlNodeDataTypeRaw",
 | |
|   "EAmlNodeDataTypeResourceData",
 | |
|   "EAmlNodeDataTypeFieldPkgLen",
 | |
|   "EAmlNodeDataTypeMax"
 | |
| };
 | |
| 
 | |
| /** String table representing AML Node types as defined by EAML_NODE_TYPE.
 | |
| */
 | |
| CONST CHAR8  *NodeTypeStrTbl[] = {
 | |
|   "EAmlNodeUnknown",
 | |
|   "EAmlNodeRoot",
 | |
|   "EAmlNodeObject",
 | |
|   "EAmlNodeData",
 | |
|   "EAmlNodeMax"
 | |
| };
 | |
| 
 | |
| /** Print Size chars at Buffer address.
 | |
| 
 | |
|   @param  [in]  ErrorLevel    Error level for the DEBUG macro.
 | |
|   @param  [in]  Buffer        Buffer containing the chars.
 | |
|   @param  [in]  Size          Number of chars to print.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgPrintChars (
 | |
|   IN        UINT32  ErrorLevel,
 | |
|   IN  CONST CHAR8   *Buffer,
 | |
|   IN        UINT32  Size
 | |
|   )
 | |
| {
 | |
|   UINT32  i;
 | |
| 
 | |
|   if (Buffer == NULL) {
 | |
|     ASSERT (0);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   for (i = 0; i < Size; i++) {
 | |
|     DEBUG ((ErrorLevel, "%c", Buffer[i]));
 | |
|   }
 | |
| }
 | |
| 
 | |
| /** Print an AML NameSeg.
 | |
|     Don't print trailing underscores ('_').
 | |
| 
 | |
|   @param  [in] Buffer   Buffer containing an AML NameSeg.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgPrintNameSeg (
 | |
|   IN  CONST CHAR8  *Buffer
 | |
|   )
 | |
| {
 | |
|   if (Buffer == NULL) {
 | |
|     ASSERT (0);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "%c", Buffer[0]));
 | |
|   if ((Buffer[1] == AML_NAME_CHAR__)  &&
 | |
|       (Buffer[2] == AML_NAME_CHAR__)  &&
 | |
|       (Buffer[3] == AML_NAME_CHAR__))
 | |
|   {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "%c", Buffer[1]));
 | |
|   if ((Buffer[2] == AML_NAME_CHAR__)  &&
 | |
|       (Buffer[3] == AML_NAME_CHAR__))
 | |
|   {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "%c", Buffer[2]));
 | |
|   if (Buffer[3] == AML_NAME_CHAR__) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "%c", Buffer[3]));
 | |
|   return;
 | |
| }
 | |
| 
 | |
| /** Print an AML NameString.
 | |
| 
 | |
|   @param  [in] Buffer   Buffer containing an AML NameString.
 | |
|   @param  [in] NewLine  Print a newline char at the end of the NameString.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgPrintNameString (
 | |
|   IN  CONST CHAR8    *Buffer,
 | |
|   IN        BOOLEAN  NewLine
 | |
|   )
 | |
| {
 | |
|   UINT8  SegCount;
 | |
|   UINT8  Index;
 | |
| 
 | |
|   if (Buffer == NULL) {
 | |
|     ASSERT (0);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   // Handle Root and Parent(s).
 | |
|   if (*Buffer == AML_ROOT_CHAR) {
 | |
|     Buffer++;
 | |
|     DEBUG ((DEBUG_INFO, "\\"));
 | |
|   } else if (*Buffer == AML_PARENT_PREFIX_CHAR) {
 | |
|     do {
 | |
|       Buffer++;
 | |
|       DEBUG ((DEBUG_INFO, "^"));
 | |
|     } while (*Buffer == AML_PARENT_PREFIX_CHAR);
 | |
|   }
 | |
| 
 | |
|   // Handle SegCount(s).
 | |
|   if (*Buffer == AML_DUAL_NAME_PREFIX) {
 | |
|     Buffer++;
 | |
|     SegCount = 2;
 | |
|   } else if (*Buffer == AML_MULTI_NAME_PREFIX) {
 | |
|     Buffer++;
 | |
|     // For multi name prefix the seg count is in the second byte.
 | |
|     SegCount = *Buffer;
 | |
|     Buffer++;
 | |
|   } else if (AmlIsLeadNameChar (*Buffer)) {
 | |
|     // Only check the first char first to avoid overflow.
 | |
|     // Then the whole NameSeg can be checked.
 | |
|     if (!AmlIsNameSeg (Buffer)) {
 | |
|       ASSERT (0);
 | |
|       return;
 | |
|     }
 | |
| 
 | |
|     SegCount = 1;
 | |
|   } else if (*Buffer == AML_ZERO_OP) {
 | |
|     SegCount = 0;
 | |
|   } else {
 | |
|     // Should not be possible.
 | |
|     ASSERT (0);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (SegCount != 0) {
 | |
|     AMLDBG_PRINT_NAMESEG (Buffer);
 | |
|     Buffer += AML_NAME_SEG_SIZE;
 | |
|     for (Index = 0; Index < SegCount - 1; Index++) {
 | |
|       DEBUG ((DEBUG_INFO, "."));
 | |
|       AMLDBG_PRINT_NAMESEG (Buffer);
 | |
|       Buffer += AML_NAME_SEG_SIZE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (NewLine) {
 | |
|     DEBUG ((DEBUG_INFO, "\n"));
 | |
|   }
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| /** Print the information contained in the header of the Node.
 | |
| 
 | |
|   @param  [in]  Node    Pointer to a node.
 | |
|   @param  [in]  Level   Level of the indentation.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgPrintNodeHeader (
 | |
|   IN  AML_NODE_HEADER  *Node,
 | |
|   IN  UINT8            Level
 | |
|   )
 | |
| {
 | |
|   if (!IS_AML_NODE_VALID (Node)) {
 | |
|     ASSERT (0);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   DEBUG ((
 | |
|     DEBUG_INFO,
 | |
|     "%3d | %-15a | ",
 | |
|     Level,
 | |
|     NodeTypeStrTbl[Node->NodeType]
 | |
|     ));
 | |
| }
 | |
| 
 | |
| /** Print fields of a data node.
 | |
| 
 | |
|   @param  [in]  DataNode  Pointer to a data node.
 | |
|   @param  [in]  Level     Level of the indentation.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgPrintDataNode (
 | |
|   IN  AML_DATA_NODE  *DataNode,
 | |
|   IN  UINT8          Level
 | |
|   )
 | |
| {
 | |
|   UINT32  Idx;
 | |
| 
 | |
|   if (!IS_AML_DATA_NODE (DataNode)) {
 | |
|     ASSERT (0);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   AmlDbgPrintNodeHeader ((AML_NODE_HEADER *)DataNode, Level);
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "%-36a | ", NodeDataTypeStrTbl[DataNode->DataType]));
 | |
|   DEBUG ((DEBUG_INFO, "0x%04x | ", DataNode->Size));
 | |
| 
 | |
|   if ((DataNode->DataType == EAmlNodeDataTypeNameString) ||
 | |
|       (DataNode->DataType == EAmlNodeDataTypeString))
 | |
|   {
 | |
|     AMLDBG_PRINT_CHARS (
 | |
|       DEBUG_INFO,
 | |
|       (CONST CHAR8 *)DataNode->Buffer,
 | |
|       DataNode->Size
 | |
|       );
 | |
|   } else if (DataNode->DataType == EAmlNodeDataTypeUInt) {
 | |
|     switch (DataNode->Size) {
 | |
|       case 1:
 | |
|       {
 | |
|         DEBUG ((DEBUG_INFO, "0x%0x", *((UINT8 *)DataNode->Buffer)));
 | |
|         break;
 | |
|       }
 | |
|       case 2:
 | |
|       {
 | |
|         DEBUG ((DEBUG_INFO, "0x%0x", *((UINT16 *)DataNode->Buffer)));
 | |
|         break;
 | |
|       }
 | |
|       case 4:
 | |
|       {
 | |
|         DEBUG ((DEBUG_INFO, "0x%0lx", *((UINT32 *)DataNode->Buffer)));
 | |
|         break;
 | |
|       }
 | |
|       case 8:
 | |
|       {
 | |
|         DEBUG ((DEBUG_INFO, "0x%0llx", *((UINT64 *)DataNode->Buffer)));
 | |
|         break;
 | |
|       }
 | |
|       default:
 | |
|       {
 | |
|         ASSERT (0);
 | |
|         return;
 | |
|       }
 | |
|     }
 | |
|   } else {
 | |
|     // No specific format.
 | |
|     for (Idx = 0; Idx < DataNode->Size; Idx++) {
 | |
|       DEBUG ((DEBUG_INFO, "%02x ", DataNode->Buffer[Idx]));
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "\n"));
 | |
| }
 | |
| 
 | |
| /** Print fields of an object node.
 | |
| 
 | |
|   @param  [in]  ObjectNode  Pointer to an object node.
 | |
|   @param  [in]  Level       Level of the indentation.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgPrintObjectNode (
 | |
|   IN  AML_OBJECT_NODE  *ObjectNode,
 | |
|   IN  UINT8            Level
 | |
|   )
 | |
| {
 | |
|   if (!IS_AML_OBJECT_NODE (ObjectNode)) {
 | |
|     ASSERT (0);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   AmlDbgPrintNodeHeader ((AML_NODE_HEADER *)ObjectNode, Level);
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "0x%02x | ", ObjectNode->AmlByteEncoding->OpCode));
 | |
|   DEBUG ((DEBUG_INFO, "0x%02x | ", ObjectNode->AmlByteEncoding->SubOpCode));
 | |
| 
 | |
|   // Print a string corresponding to the field object OpCode/SubOpCode.
 | |
|   if (AmlNodeHasAttribute (ObjectNode, AML_IS_FIELD_ELEMENT)) {
 | |
|     DEBUG ((
 | |
|       DEBUG_INFO,
 | |
|       "%-15a ",
 | |
|       AmlGetFieldOpCodeStr (
 | |
|         ObjectNode->AmlByteEncoding->OpCode,
 | |
|         0
 | |
|         )
 | |
|       ));
 | |
|   } else {
 | |
|     // Print a string corresponding to the object OpCode/SubOpCode.
 | |
|     DEBUG ((
 | |
|       DEBUG_INFO,
 | |
|       "%-15a | ",
 | |
|       AmlGetOpCodeStr (
 | |
|         ObjectNode->AmlByteEncoding->OpCode,
 | |
|         ObjectNode->AmlByteEncoding->SubOpCode
 | |
|         )
 | |
|       ));
 | |
|   }
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "%3d | ", ObjectNode->AmlByteEncoding->MaxIndex));
 | |
|   DEBUG ((DEBUG_INFO, "0x%08x | ", ObjectNode->AmlByteEncoding->Attribute));
 | |
|   DEBUG ((DEBUG_INFO, "0x%04x | ", ObjectNode->PkgLen));
 | |
|   if (AmlNodeHasAttribute (ObjectNode, AML_IN_NAMESPACE)) {
 | |
|     AMLDBG_PRINT_NAMESTR (
 | |
|       AmlNodeGetName ((CONST AML_OBJECT_NODE *)ObjectNode),
 | |
|       FALSE
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "\n"));
 | |
| }
 | |
| 
 | |
| /** Print fields of a root node.
 | |
| 
 | |
|   @param  [in]  RootNode  Pointer to a root node.
 | |
|   @param  [in]  Level     Level of the indentation.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgPrintRootNode (
 | |
|   IN  AML_ROOT_NODE  *RootNode,
 | |
|   IN  UINT8          Level
 | |
|   )
 | |
| {
 | |
|   if (!IS_AML_ROOT_NODE (RootNode)) {
 | |
|     ASSERT (0);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   AmlDbgPrintNodeHeader ((AML_NODE_HEADER *)RootNode, Level);
 | |
| 
 | |
|   DEBUG ((DEBUG_INFO, "%8x | ", RootNode->SdtHeader->Signature));
 | |
|   DEBUG ((DEBUG_INFO, "0x%08x | ", RootNode->SdtHeader->Length));
 | |
|   DEBUG ((DEBUG_INFO, "%3d | ", RootNode->SdtHeader->Revision));
 | |
|   DEBUG ((DEBUG_INFO, "0x%02x | ", RootNode->SdtHeader->Checksum));
 | |
|   DEBUG ((
 | |
|     DEBUG_INFO,
 | |
|     "%c%c%c%c%c%c | ",
 | |
|     RootNode->SdtHeader->OemId[0],
 | |
|     RootNode->SdtHeader->OemId[1],
 | |
|     RootNode->SdtHeader->OemId[2],
 | |
|     RootNode->SdtHeader->OemId[3],
 | |
|     RootNode->SdtHeader->OemId[4],
 | |
|     RootNode->SdtHeader->OemId[5]
 | |
|     ));
 | |
|   DEBUG ((DEBUG_INFO, "%-16llx | ", RootNode->SdtHeader->OemTableId));
 | |
|   DEBUG ((DEBUG_INFO, "%8x | ", RootNode->SdtHeader->OemRevision));
 | |
|   DEBUG ((DEBUG_INFO, "%8x | ", RootNode->SdtHeader->CreatorId));
 | |
|   DEBUG ((DEBUG_INFO, "%8x", RootNode->SdtHeader->CreatorRevision));
 | |
|   DEBUG ((DEBUG_INFO, "\n"));
 | |
| }
 | |
| 
 | |
| /** Print a header to help interpreting node information.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgPrintTableHeader (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   DEBUG ((DEBUG_INFO, "Lvl | Node Type       |\n"));
 | |
|   DEBUG ((
 | |
|     DEBUG_INFO,
 | |
|     "    | %-15a | Signature| Length     | Rev | CSum | OemId  | "
 | |
|     "OemTableId       | OemRev   | CreatorId| CreatorRev\n",
 | |
|     NodeTypeStrTbl[EAmlNodeRoot]
 | |
|     ));
 | |
|   DEBUG ((
 | |
|     DEBUG_INFO,
 | |
|     "    | %-15a | Op   | SubOp| OpName          | MaxI| Attribute  | "
 | |
|     "PkgLen | NodeName (opt)\n",
 | |
|     NodeTypeStrTbl[EAmlNodeObject]
 | |
|     ));
 | |
|   DEBUG ((
 | |
|     DEBUG_INFO,
 | |
|     "    | %-15a | Data Type                            | Size   | "
 | |
|     "Buffer\n",
 | |
|     NodeTypeStrTbl[EAmlNodeData]
 | |
|     ));
 | |
|   DEBUG ((
 | |
|     DEBUG_INFO,
 | |
|     "---------------------------------------"
 | |
|     "---------------------------------------\n"
 | |
|     ));
 | |
| }
 | |
| 
 | |
| /** Recursively print the subtree under the Node.
 | |
|     This is an internal function.
 | |
| 
 | |
|   @param  [in]  Node            Pointer to the root of the subtree to print.
 | |
|                                 Can be a root/object/data node.
 | |
|   @param  [in]  Recurse         If TRUE, recurse.
 | |
|   @param  [in]  Level           Level in the tree.
 | |
| **/
 | |
| STATIC
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgPrintTreeInternal (
 | |
|   IN  AML_NODE_HEADER  *Node,
 | |
|   IN  BOOLEAN          Recurse,
 | |
|   IN  UINT8            Level
 | |
|   )
 | |
| {
 | |
|   AML_NODE_HEADER  *ChildNode;
 | |
| 
 | |
|   if (!IS_AML_NODE_VALID (Node)) {
 | |
|     ASSERT (0);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (IS_AML_DATA_NODE (Node)) {
 | |
|     AmlDbgPrintDataNode ((AML_DATA_NODE *)Node, Level);
 | |
|     return;
 | |
|   } else if (IS_AML_OBJECT_NODE (Node)) {
 | |
|     AmlDbgPrintObjectNode ((AML_OBJECT_NODE *)Node, Level);
 | |
|   } else if (IS_AML_ROOT_NODE (Node)) {
 | |
|     AmlDbgPrintRootNode ((AML_ROOT_NODE *)Node, Level);
 | |
|   } else {
 | |
|     // Should not be possible.
 | |
|     ASSERT (0);
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (!Recurse) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   // Get the first child node.
 | |
|   ChildNode = AmlGetNextSibling (Node, NULL);
 | |
|   while (ChildNode != NULL) {
 | |
|     ASSERT (Level < MAX_UINT8);
 | |
|     AmlDbgPrintTreeInternal (ChildNode, Recurse, (UINT8)(Level + 1));
 | |
|     ChildNode = AmlGetNextSibling (Node, ChildNode);
 | |
|   }
 | |
| }
 | |
| 
 | |
| /** Print Node information.
 | |
| 
 | |
|   @param  [in]  Node    Pointer to the Node to print.
 | |
|                         Can be a root/object/data node.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgPrintNode (
 | |
|   IN  AML_NODE_HEADER  *Node
 | |
|   )
 | |
| {
 | |
|   AmlDbgPrintTableHeader ();
 | |
|   AmlDbgPrintTreeInternal (Node, FALSE, 0);
 | |
| }
 | |
| 
 | |
| /** Recursively print the subtree under the Node.
 | |
| 
 | |
|   @param  [in]  Node    Pointer to the root of the subtree to print.
 | |
|                         Can be a root/object/data node.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgPrintTree (
 | |
|   IN  AML_NODE_HEADER  *Node
 | |
|   )
 | |
| {
 | |
|   AmlDbgPrintTableHeader ();
 | |
|   AmlDbgPrintTreeInternal (Node, TRUE, 0);
 | |
| }
 | |
| 
 | |
| /** This function performs a raw data dump of the ACPI table.
 | |
| 
 | |
|   @param  [in]  Ptr     Pointer to the start of the table buffer.
 | |
|   @param  [in]  Length  The length of the buffer.
 | |
| **/
 | |
| VOID
 | |
| EFIAPI
 | |
| AmlDbgDumpRaw (
 | |
|   IN  CONST UINT8   *Ptr,
 | |
|   IN        UINT32  Length
 | |
|   )
 | |
| {
 | |
|   UINT32  ByteCount;
 | |
|   UINT32  PartLineChars;
 | |
|   UINT32  AsciiBufferIndex;
 | |
|   CHAR8   AsciiBuffer[17];
 | |
| 
 | |
|   ByteCount        = 0;
 | |
|   AsciiBufferIndex = 0;
 | |
| 
 | |
|   DEBUG ((DEBUG_VERBOSE, "Address  : 0x%p\n", Ptr));
 | |
|   DEBUG ((DEBUG_VERBOSE, "Length   : %lld", Length));
 | |
| 
 | |
|   while (ByteCount < Length) {
 | |
|     if ((ByteCount & 0x0F) == 0) {
 | |
|       AsciiBuffer[AsciiBufferIndex] = '\0';
 | |
|       DEBUG ((DEBUG_VERBOSE, "  %a\n%08X : ", AsciiBuffer, ByteCount));
 | |
|       AsciiBufferIndex = 0;
 | |
|     } else if ((ByteCount & 0x07) == 0) {
 | |
|       DEBUG ((DEBUG_VERBOSE, "- "));
 | |
|     }
 | |
| 
 | |
|     if ((*Ptr >= ' ') && (*Ptr < 0x7F)) {
 | |
|       AsciiBuffer[AsciiBufferIndex++] = *Ptr;
 | |
|     } else {
 | |
|       AsciiBuffer[AsciiBufferIndex++] = '.';
 | |
|     }
 | |
| 
 | |
|     DEBUG ((DEBUG_VERBOSE, "%02X ", *Ptr++));
 | |
| 
 | |
|     ByteCount++;
 | |
|   }
 | |
| 
 | |
|   // Justify the final line using spaces before printing
 | |
|   // the ASCII data.
 | |
|   PartLineChars = (Length & 0x0F);
 | |
|   if (PartLineChars != 0) {
 | |
|     PartLineChars = 48 - (PartLineChars * 3);
 | |
|     if ((Length & 0x0F) <= 8) {
 | |
|       PartLineChars += 2;
 | |
|     }
 | |
| 
 | |
|     while (PartLineChars > 0) {
 | |
|       DEBUG ((DEBUG_VERBOSE, " "));
 | |
|       PartLineChars--;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   // Print ASCII data for the final line.
 | |
|   AsciiBuffer[AsciiBufferIndex] = '\0';
 | |
|   DEBUG ((DEBUG_VERBOSE, "  %a\n\n", AsciiBuffer));
 | |
| }
 | |
| 
 | |
| #endif // MDEPKG_NDEBUG
 |