Fix ECC error 8001 reported errors in AmlDbgPrint.
  [8001] Only capital letters are allowed to be used
         for #define declarations.
Signed-off-by: Sami Mujawar <sami.mujawar@arm.com>
Reviewed-by: Alexei Fedorov <Alexei.Fedorov@arm.com>
		
	
		
			
				
	
	
		
			547 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			547 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/** @file
 | 
						|
  AML Print Function.
 | 
						|
 | 
						|
  Copyright (c) 2010 - 2018, Intel Corporation. All rights reserved. <BR>
 | 
						|
  Copyright (c) 2019 - 2020, 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 | %-15s | ",
 | 
						|
    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, "%-36s | ", 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, "%-15s ", AmlGetFieldOpCodeStr (
 | 
						|
                                    ObjectNode->AmlByteEncoding->OpCode,
 | 
						|
                                    0
 | 
						|
                                    )));
 | 
						|
  } else {
 | 
						|
    // Print a string corresponding to the object OpCode/SubOpCode.
 | 
						|
    DEBUG ((DEBUG_INFO, "%-15s | ", 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,
 | 
						|
    "    | %-15s | Signature| Length     | Rev | CSum | OemId  | "
 | 
						|
      "OemTableId       | OemRev   | CreatorId| CreatorRev\n",
 | 
						|
    NodeTypeStrTbl[EAmlNodeRoot]
 | 
						|
    ));
 | 
						|
  DEBUG ((
 | 
						|
    DEBUG_INFO,
 | 
						|
    "    | %-15s | Op   | SubOp| OpName          | MaxI| Attribute  | "
 | 
						|
      "PkgLen | NodeName (opt)\n",
 | 
						|
    NodeTypeStrTbl[EAmlNodeObject]
 | 
						|
    ));
 | 
						|
  DEBUG ((
 | 
						|
    DEBUG_INFO,
 | 
						|
    "    | %-15s | 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
 |