public inbox for devel@edk2.groups.io
 help / color / mirror / Atom feed
From: "Joey Gouly" <joey.gouly@arm.com>
To: <devel@edk2.groups.io>
Cc: <joey.gouly@arm.com>, <sami.mujawar@arm.com>, <ray.ni@intel.com>,
	<zhichao.gao@intel.com>, <nd@arm.com>
Subject: [PATCH v2 4/5] ShellPkg: add dot file generator functions
Date: Thu, 16 Sep 2021 15:46:04 +0100	[thread overview]
Message-ID: <20210916144605.42071-5-joey.gouly@arm.com> (raw)
In-Reply-To: <20210916144605.42071-1-joey.gouly@arm.com>

From: Marc Moisson-Franckhauser <marc.moisson-franckhauser@arm.com>

Bugzilla: 3378 (https://bugzilla.tianocore.org/show_bug.cgi?id=3378)

These can be used to generate dot files, that can be used to visualise
graphs in tables, such as PPTT.

Signed-off-by: Joey Gouly <joey.gouly@arm.com>
---
 ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf |   4 +-
 ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.h                  | 101 +++++++
 ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.c                  | 283 ++++++++++++++++++++
 3 files changed, 387 insertions(+), 1 deletion(-)

diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
index 63fc5a1281a894841dac704484c3d4f9481edb46..ffe4979b3ac5d0120bcf678cf7823afac6674e4f 100644
--- a/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/UefiShellAcpiViewCommandLib.inf
@@ -1,7 +1,7 @@
 ##  @file
 # Provides Shell 'acpiview' command functions
 #
-# Copyright (c) 2016 - 2020, Arm Limited. All rights reserved.<BR>
+# Copyright (c) 2016 - 2021, Arm Limited. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -27,6 +27,8 @@ [Sources.common]
   AcpiView.h
   AcpiViewConfig.c
   AcpiViewConfig.h
+  DotGenerator.c
+  DotGenerator.h
   Parsers/Aest/AestParser.c
   Parsers/Bgrt/BgrtParser.c
   Parsers/Dbg2/Dbg2Parser.c
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.h b/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e196eee75417c0a422023c00b043441076ac599
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.h
@@ -0,0 +1,101 @@
+/** @file
+  Header file for Dot File Generation
+
+  Copyright (c) 2021, Arm Limited. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#ifndef DOT_GENERATOR_H_
+#define DOT_GENERATOR_H_
+
+#include <Protocol/Shell.h>
+
+#define DOT_COLOR_MASK            0b111
+// Flags for color of arrow or node.
+#define DOT_COLOR_BLACK           0b000 // default
+#define DOT_COLOR_GRAY            0b001
+#define DOT_COLOR_BLUE            0b010
+#define DOT_COLOR_YELLOW          0b011
+#define DOT_COLOR_RED             0b100
+
+#define DOT_ARROW_TYPE_MASK       0b1000
+// Flags for style of arrow.
+#define DOT_ARROW_FULL            0b0000 // default
+#define DOT_ARROW_DOTTED          0b1000
+
+// Flag for reversing how the nodes will be ranked and displayed.
+#define DOT_ARROW_RANK_REVERSE    0b10000
+
+#define DOT_BOX_TYPE_MASK         0b1100000
+// Flag for shape of box
+#define DOT_BOX_SQUARE            0b0000000 // default
+#define DOT_BOX_DIAMOND           0b0100000
+
+// Flag for adding the node's ID to the end of the label.
+#define DOT_BOX_ADD_ID_TO_LABEL   0b10000000
+
+// Valid flags for DotAddNode.
+#define DOT_BOX_FLAGS_MASK        (DOT_COLOR_MASK |\
+                                   DOT_BOX_TYPE_MASK |\
+                                   DOT_BOX_ADD_ID_TO_LABEL)
+// Valid flags for DotAddLink.
+#define DOT_ARROW_FLAGS_MASK      (DOT_COLOR_MASK |\
+                                   DOT_ARROW_TYPE_MASK |\
+                                   DOT_ARROW_RANK_REVERSE)
+
+
+/**
+  Opens a new dot file and writes a dot directional graph.
+
+  @param [in] FileName    Null terminated unicode string.
+**/
+SHELL_FILE_HANDLE
+DotOpenNewFile (
+  IN CHAR16* FileName
+  );
+
+/**
+  Writes a dot graph footer and closes the dot file.
+
+  @param [in] DotFileHandle  The handle of the dot file.
+**/
+VOID
+DotCloseFile (
+  SHELL_FILE_HANDLE DotFileHandle
+  );
+
+/**
+  Writes a line in the previously opened dot file describing a
+  new node.
+
+  @param [in] DotFileHandle  The handle of the dot file.
+  @param [in] Id             A unique identifier for the node.
+  @param [in] Flags          Flags describing the node's characteristics.
+  @param [in] Label          Label to be shown on the graph node.
+**/
+VOID
+DotAddNode (
+  SHELL_FILE_HANDLE DotFileHandle,
+  IN UINT32         Id,
+  IN UINT16         Flags,
+  IN CONST CHAR16*  Label
+  );
+
+/**
+  Writes a line in the previously opened dot file describing a
+  new link between two nodes.
+
+  @param [in] DotFileHandle  The handle of the dot file.
+  @param [in] IdSource       An identifier for the source node of the link.
+  @param [in] IdTarget       An identifier for the target node of the link.
+  @param [in] Flags          Flags describing the node's characteristics.
+**/
+VOID
+DotAddLink (
+  SHELL_FILE_HANDLE DotFileHandle,
+  IN UINT32 IdSource,
+  IN UINT32 IdTarget,
+  IN UINT16 Flags
+  );
+
+#endif // DOT_GENERATOR_H_
diff --git a/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.c b/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.c
new file mode 100644
index 0000000000000000000000000000000000000000..e19b17537ca85babca5cda38025ae95701ff794f
--- /dev/null
+++ b/ShellPkg/Library/UefiShellAcpiViewCommandLib/DotGenerator.c
@@ -0,0 +1,283 @@
+/** @file
+  Dot File Generator
+
+  Copyright (c) 2021, Arm Limited. All rights reserved.
+  SPDX-License-Identifier: BSD-2-Clause-Patent
+**/
+
+#include <Library/BaseLib.h>
+#include <Library/UefiLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PrintLib.h>
+#include "DotGenerator.h"
+#include "AcpiView.h"
+
+#define MAX_DOT_BUFFER_SIZE   128
+
+/**
+  Writes a Null terminated ASCII string to the dot file handle.
+
+  @param [in] DotFileHandle  The handle of the dot file.
+  @param [in] String         Null terminated ascii string.
+**/
+STATIC
+VOID
+DotWriteFile (
+  SHELL_FILE_HANDLE DotFileHandle,
+  IN CHAR8* String
+  )
+{
+  UINTN TransferBytes;
+  EFI_STATUS Status;
+
+  if (DotFileHandle == NULL) {
+    Print (L"ERROR: Failed to write to dot file\n");
+    ASSERT (0);
+    return;
+  }
+
+  TransferBytes = AsciiStrLen (String);
+  Status = ShellWriteFile (
+    DotFileHandle,
+    &TransferBytes,
+    String
+    );
+  ASSERT_EFI_ERROR (Status);
+  ASSERT (AsciiStrLen (String) == TransferBytes);
+}
+
+/**
+  Writes a new parameter to a previously started parameter list.
+
+  @param [in] DotFileHandle  The handle of the dot file.
+  @param [in] Name           Null terminated string of the parameter's name.
+  @param [in] Value          Null terminated string of the parameter's value.
+  @param [in] Quoted         True if value needs to be quoted.
+**/
+STATIC
+VOID
+DotAddParameter (
+  SHELL_FILE_HANDLE DotFileHandle,
+  IN CHAR16*  Name,
+  IN CHAR16*  Value,
+  IN BOOLEAN  Quoted
+  )
+{
+  CHAR8 StringBuffer[MAX_DOT_BUFFER_SIZE];
+
+  ASSERT(DotFileHandle != NULL);
+
+  if (Quoted) {
+    AsciiSPrint (
+      StringBuffer,
+      sizeof (StringBuffer),
+      "[%s=\"%s\"]",
+      Name,
+      Value
+      );
+  } else {
+    AsciiSPrint (
+      StringBuffer,
+      sizeof (StringBuffer),
+      "[%s=%s]",
+      Name,
+      Value
+      );
+  }
+
+  DotWriteFile (DotFileHandle, StringBuffer);
+}
+
+/**
+  Writes the color argument of nodes or links according to flags.
+
+  @param [in] DotFileHandle  The handle of the dot file.
+  @param [in] Flags          Flags describing the color (one of DOT_COLOR_...)
+**/
+STATIC
+VOID
+WriteColor (
+  SHELL_FILE_HANDLE DotFileHandle,
+  IN UINT16 Flags
+  )
+{
+  ASSERT(DotFileHandle != NULL);
+
+  switch (Flags & DOT_COLOR_MASK) {
+    case DOT_COLOR_GRAY:
+      DotAddParameter (DotFileHandle, L"color", L"gray", FALSE);
+      break;
+    case DOT_COLOR_YELLOW:
+      DotAddParameter (DotFileHandle, L"color", L"yellow", FALSE);
+      break;
+    case DOT_COLOR_BLUE:
+      DotAddParameter (DotFileHandle, L"color", L"blue", FALSE);
+      break;
+    case DOT_COLOR_RED:
+      DotAddParameter (DotFileHandle, L"color", L"red", FALSE);
+      break;
+    case DOT_COLOR_BLACK:
+    default:
+      DotAddParameter (DotFileHandle, L"color", L"black", FALSE);
+      break;
+  }
+}
+
+/**
+  Opens a new dot file and writes a dot directional graph.
+
+  @param [in] FileName    Null terminated unicode string.
+**/
+SHELL_FILE_HANDLE
+DotOpenNewFile (
+  IN CHAR16* FileName
+  )
+{
+  SHELL_FILE_HANDLE DotFileHandle;
+  EFI_STATUS Status;
+
+  Status = ShellOpenFileByName (
+             FileName,
+             &DotFileHandle,
+             EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
+             0
+             );
+  if (EFI_ERROR (Status)) {
+    Print (L"ERROR: Couldn't open dot file");
+    return NULL;//Status;
+  }
+  Print (L"Creating DOT Graph in : %s... ", FileName);
+  DotWriteFile (DotFileHandle, "digraph {\n\trankdir=BT\n");
+  return DotFileHandle;
+}
+
+/**
+  Writes a dot graph footer and closes the dot file.
+
+  @param [in] DotFileHandle  The handle of the dot file.
+**/
+VOID
+DotCloseFile (
+  SHELL_FILE_HANDLE DotFileHandle
+  )
+{
+  ASSERT(DotFileHandle != NULL);
+
+  DotWriteFile (DotFileHandle, "}\n");
+  ShellCloseFile (&DotFileHandle);
+  Print (L"Done.\n");
+}
+
+/**
+  Writes a line in the previously opened dot file describing a
+  new node.
+
+  @param [in] DotFileHandle  The handle of the dot file.
+  @param [in] Id             A unique identifier for the node.
+  @param [in] Flags          Flags describing the node's characteristics.
+  @param [in] Label          Label to be shown on the graph node.
+**/
+VOID
+DotAddNode (
+  SHELL_FILE_HANDLE DotFileHandle,
+  IN UINT32         Id,
+  IN UINT16         Flags,
+  IN CONST CHAR16*  Label
+  )
+{
+  CHAR8  LineBuffer[64];
+  CHAR16 LabelBuffer[MAX_DOT_BUFFER_SIZE];
+
+  ASSERT ((Flags & ~DOT_BOX_FLAGS_MASK) == 0);
+  ASSERT(DotFileHandle != NULL);
+
+  AsciiSPrint (
+    LineBuffer,
+    sizeof (LineBuffer),
+    "\tx%x",
+    Id
+    );
+  DotWriteFile (DotFileHandle, LineBuffer);
+
+  switch (Flags & DOT_BOX_TYPE_MASK) {
+    case DOT_BOX_DIAMOND:
+      DotAddParameter (DotFileHandle, L"shape", L"diamond", FALSE);
+      break;
+    case DOT_BOX_SQUARE:
+    default:
+      DotAddParameter (DotFileHandle, L"shape", L"box", FALSE);
+      break;
+  }
+
+  if (Label != NULL) {
+    if ((Flags & DOT_BOX_ADD_ID_TO_LABEL) != 0) {
+      UnicodeSPrint (
+        LabelBuffer,
+        sizeof (LabelBuffer),
+        L"%s\\n0x%x",
+        Label,
+        Id
+        );
+    } else {
+      UnicodeSPrint (
+        LabelBuffer,
+        sizeof (LabelBuffer),
+        L"%s",
+        Label
+        );
+    }
+    DotAddParameter (DotFileHandle, L"label", LabelBuffer, TRUE);
+  }
+
+  WriteColor (DotFileHandle, Flags);
+  DotWriteFile (DotFileHandle, "\n");
+}
+
+/**
+  Writes a line in the previously opened dot file describing a
+  new link between two nodes.
+
+  @param [in] DotFileHandle  The handle of the dot file.
+  @param [in] IdSource       An identifier for the source node of the link.
+  @param [in] IdTarget       An identifier for the target node of the link.
+  @param [in] Flags          Flags describing the node's characteristics.
+**/
+VOID
+DotAddLink (
+  SHELL_FILE_HANDLE DotFileHandle,
+  IN UINT32 IdSource,
+  IN UINT32 IdTarget,
+  IN UINT16 Flags
+  )
+{
+  CHAR8 LineBuffer[64];
+
+  ASSERT(DotFileHandle != NULL);
+  ASSERT ((Flags & ~DOT_ARROW_FLAGS_MASK) == 0);
+
+  AsciiSPrint (
+    LineBuffer,
+    sizeof (LineBuffer),
+    "\tx%x -> x%x",
+    IdSource,
+    IdTarget
+    );
+  DotWriteFile (DotFileHandle, LineBuffer);
+
+  if ((Flags & DOT_ARROW_RANK_REVERSE) != 0) {
+    DotAddParameter (DotFileHandle, L"dir", L"back", FALSE);
+  }
+
+  switch (Flags & DOT_ARROW_TYPE_MASK) {
+    case DOT_ARROW_DOTTED:
+      DotAddParameter (DotFileHandle, L"style", L"dotted", FALSE);
+      break;
+    case DOT_ARROW_FULL:
+    default:
+      DotAddParameter (DotFileHandle, L"style", L"solid", FALSE);
+      break;
+  }
+
+  WriteColor (DotFileHandle, Flags);
+  DotWriteFile (DotFileHandle, "\n");
+}
-- 
Guid("CE165669-3EF3-493F-B85D-6190EE5B9759")


  parent reply	other threads:[~2021-09-16 14:46 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-09-16 14:46 [PATCH v2 0/5] Dot graph generator for PPTT Joey Gouly
2021-09-16 14:46 ` [PATCH v2 1/5] ShellPkg: Replace 'Trace' parameter with 'ParseFlags' Joey Gouly
2021-11-09  5:46   ` Gao, Zhichao
2021-09-16 14:46 ` [PATCH v2 2/5] ShellPkg: add a helper function for getting a new file name Joey Gouly
2021-09-16 14:46 ` [PATCH v2 3/5] ShellPkg: add a Graph option to the Parser Flags Joey Gouly
2021-09-16 14:46 ` Joey Gouly [this message]
2021-09-16 14:46 ` [PATCH v2 5/5] ShellPkg: add PPTT dot file genration Joey Gouly

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=20210916144605.42071-5-joey.gouly@arm.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