]> git.proxmox.com Git - mirror_edk2.git/commitdiff
ShellPkg: Add "dp" command library to ShellPkg.
authorjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 4 Mar 2013 22:02:59 +0000 (22:02 +0000)
committerjcarsey <jcarsey@6f19259b-4bc3-4df7-8a09-765794883524>
Mon, 4 Mar 2013 22:02:59 +0000 (22:02 +0000)
This command is only included in the build with command line option "-D INCLUDE_DP".  The user must also update the DSC with appropriate library instances that match the platform for the build to succeed.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Jaben Carsey <jaben.carsey@intel.com>
Reviewed-by: Erik Bjorge <erik.c.bjorge@intel.com>
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@14160 6f19259b-4bc3-4df7-8a09-765794883524

14 files changed:
ShellPkg/Library/UefiDpLib/Dp.c [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/Dp.h [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/DpInternal.h [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/DpProfile.c [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/DpTrace.c [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/DpUtilities.c [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/Literals.c [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/Literals.h [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/UefiDpLib.c [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/UefiDpLib.h [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/UefiDpLib.inf [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/UefiDpLib.uni [new file with mode: 0644]
ShellPkg/Library/UefiDpLib/readme.txt [new file with mode: 0644]
ShellPkg/ShellPkg.dsc

diff --git a/ShellPkg/Library/UefiDpLib/Dp.c b/ShellPkg/Library/UefiDpLib/Dp.c
new file mode 100644 (file)
index 0000000..b5a6e7a
--- /dev/null
@@ -0,0 +1,310 @@
+/** @file\r
+  Shell command for Displaying Performance Metrics.\r
+\r
+  The Dp command reads performance data and presents it in several\r
+  different formats depending upon the needs of the user.  Both\r
+  Trace and Measured Profiling information is processed and presented.\r
+\r
+  Dp uses the "PerformanceLib" to read the measurement records.\r
+  The "TimerLib" provides information about the timer, such as frequency,\r
+  beginning, and ending counter values.\r
+  Measurement records contain identifying information (Handle, Token, Module)\r
+  and start and end time values.\r
+  Dp uses this information to group records in different ways.  It also uses\r
+  timer information to calculate elapsed time for each measurement.\r
\r
+  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#include "UefiDpLib.h"\r
+#include <Guid/GlobalVariable.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/HandleParsingLib.h>\r
+#include <Library/DevicePathLib.h>\r
+\r
+#include <Library/ShellLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <Guid/Performance.h>\r
+\r
+#include <PerformanceTokens.h>\r
+#include "Dp.h"\r
+#include "Literals.h"\r
+#include "DpInternal.h"\r
+\r
+//\r
+/// Module-Global Variables\r
+///@{\r
+CHAR16           mGaugeString[DP_GAUGE_STRING_LENGTH + 1];\r
+CHAR16           mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];\r
+UINT64           mInterestThreshold;\r
+BOOLEAN          mShowId = FALSE;\r
+\r
+PERF_SUMMARY_DATA SummaryData = { 0 };    ///< Create the SummaryData structure and init. to ZERO.\r
+\r
+/// Timer Specific Information.\r
+TIMER_INFO TimerInfo;\r
+\r
+/// Items for which to gather cumulative statistics.\r
+PERF_CUM_DATA CumData[] = {\r
+  PERF_INIT_CUM_DATA (LOAD_IMAGE_TOK),\r
+  PERF_INIT_CUM_DATA (START_IMAGE_TOK),\r
+  PERF_INIT_CUM_DATA (DRIVERBINDING_START_TOK),\r
+  PERF_INIT_CUM_DATA (DRIVERBINDING_SUPPORT_TOK)\r
+};\r
+\r
+/// Number of items for which we are gathering cumulative statistics.\r
+UINT32 const      NumCum = sizeof(CumData) / sizeof(PERF_CUM_DATA);\r
+\r
+STATIC CONST SHELL_PARAM_ITEM ParamList[] = {\r
+  {L"-v", TypeFlag},   // -v   Verbose Mode\r
+  {L"-A", TypeFlag},   // -A   All, Cooked\r
+  {L"-R", TypeFlag},   // -R   RAW All\r
+  {L"-s", TypeFlag},   // -s   Summary\r
+#if PROFILING_IMPLEMENTED\r
+  {L"-P", TypeFlag},   // -P   Dump Profile Data\r
+  {L"-T", TypeFlag},   // -T   Dump Trace Data\r
+#endif // PROFILING_IMPLEMENTED\r
+  {L"-x", TypeFlag},   // -x   eXclude Cumulative Items\r
+  {L"-i", TypeFlag},   // -i   Display Identifier\r
+  {L"-n", TypeValue},  // -n # Number of records to display for A and R\r
+  {L"-t", TypeValue},  // -t # Threshold of interest\r
+  {NULL, TypeMax}\r
+  };\r
+\r
+///@}\r
+\r
+/**\r
+   Display the trailing Verbose information.\r
+**/\r
+VOID\r
+DumpStatistics( void )\r
+{\r
+  EFI_STRING                StringPtr;\r
+  EFI_STRING                StringPtrUnknown;\r
+  StringPtr        = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_STATISTICS), NULL);\r
+  StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
+              (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMTRACE), gDpHiiHandle,      SummaryData.NumTrace);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMINCOMPLETE), gDpHiiHandle, SummaryData.NumIncomplete);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPHASES), gDpHiiHandle,     SummaryData.NumSummary);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMHANDLES), gDpHiiHandle,    SummaryData.NumHandles, SummaryData.NumTrace - SummaryData.NumHandles);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPEIMS), gDpHiiHandle,      SummaryData.NumPEIMs);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMGLOBALS), gDpHiiHandle,    SummaryData.NumGlobal);\r
+#if PROFILING_IMPLEMENTED\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_STATS_NUMPROFILE), gDpHiiHandle,    SummaryData.NumProfile);\r
+#endif // PROFILING_IMPLEMENTED\r
+  SHELL_FREE_NON_NULL (StringPtr);\r
+  SHELL_FREE_NON_NULL (StringPtrUnknown);\r
+}\r
+\r
+/** \r
+  Dump performance data.\r
+  \r
+  @param[in]  ImageHandle     The image handle.\r
+  @param[in]  SystemTable     The system table.\r
+  \r
+  @retval EFI_SUCCESS            Command completed successfully.\r
+  @retval EFI_INVALID_PARAMETER  Command usage error.\r
+  @retval value                  Unknown error.\r
+  \r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ShellCommandRunDp (\r
+  IN EFI_HANDLE               ImageHandle,\r
+  IN EFI_SYSTEM_TABLE         *SystemTable\r
+  )\r
+{\r
+  LIST_ENTRY                *ParamPackage;\r
+  CONST CHAR16              *CmdLineArg;\r
+  EFI_STATUS                Status;\r
+\r
+  UINT64                    Freq;\r
+  UINT64                    Ticker;\r
+  UINTN                     Number2Display;\r
+\r
+  EFI_STRING                StringPtr   = NULL;\r
+  BOOLEAN                   SummaryMode = FALSE;\r
+  BOOLEAN                   VerboseMode = FALSE;\r
+  BOOLEAN                   AllMode     = FALSE;\r
+  BOOLEAN                   RawMode     = FALSE;\r
+  BOOLEAN                   TraceMode   = FALSE;\r
+  BOOLEAN                   ProfileMode = FALSE;\r
+  BOOLEAN                   ExcludeMode = FALSE;\r
+\r
+  // Get DP's entry time as soon as possible.\r
+  // This is used as the Shell-Phase end time.\r
+  //\r
+  Ticker  = GetPerformanceCounter ();\r
+\r
+  //\r
+  // initialize the shell lib (we must be in non-auto-init...)\r
+  //\r
+  Status = ShellInitialize();\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
+  Status = CommandInit();\r
+  ASSERT_EFI_ERROR(Status);\r
+\r
+  //\r
+  // Process Command Line arguments\r
+  //\r
+  Status = ShellCommandLineParse (ParamList, &ParamPackage, NULL, TRUE);\r
+  if (EFI_ERROR(Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_INVALID_ARG), gDpHiiHandle);\r
+    return SHELL_INVALID_PARAMETER;\r
+  }\r
+\r
+  //\r
+  // Boolean options\r
+  //\r
+  VerboseMode = ShellCommandLineGetFlag (ParamPackage, L"-v");\r
+  SummaryMode = (BOOLEAN) (ShellCommandLineGetFlag (ParamPackage, L"-S") || ShellCommandLineGetFlag (ParamPackage, L"-s"));\r
+  AllMode     = ShellCommandLineGetFlag (ParamPackage, L"-A");\r
+  RawMode     = ShellCommandLineGetFlag (ParamPackage, L"-R");\r
+#if PROFILING_IMPLEMENTED\r
+  TraceMode   = ShellCommandLineGetFlag (ParamPackage, L"-T");\r
+  ProfileMode = ShellCommandLineGetFlag (ParamPackage, L"-P");\r
+#endif  // PROFILING_IMPLEMENTED\r
+  ExcludeMode = ShellCommandLineGetFlag (ParamPackage, L"-x");\r
+  mShowId     = ShellCommandLineGetFlag (ParamPackage, L"-i");\r
+\r
+  // Options with Values\r
+  CmdLineArg  = ShellCommandLineGetValue (ParamPackage, L"-n");\r
+  if (CmdLineArg == NULL) {\r
+    Number2Display = DEFAULT_DISPLAYCOUNT;\r
+  } else {\r
+    Number2Display = StrDecimalToUintn(CmdLineArg);\r
+    if (Number2Display == 0) {\r
+      Number2Display = MAXIMUM_DISPLAYCOUNT;\r
+    }\r
+  }\r
+\r
+  CmdLineArg  = ShellCommandLineGetValue (ParamPackage, L"-t");\r
+  if (CmdLineArg == NULL) {\r
+    mInterestThreshold = DEFAULT_THRESHOLD;  // 1ms := 1,000 us\r
+  } else {\r
+    mInterestThreshold = StrDecimalToUint64(CmdLineArg);\r
+  }\r
+\r
+  // Handle Flag combinations and default behaviors\r
+  // If both TraceMode and ProfileMode are FALSE, set them both to TRUE\r
+  if ((! TraceMode) && (! ProfileMode)) {\r
+    TraceMode   = TRUE;\r
+#if PROFILING_IMPLEMENTED\r
+    ProfileMode = TRUE;\r
+#endif  // PROFILING_IMPLEMENTED\r
+  }\r
+\r
+  //\r
+  // Timer specific processing\r
+  //\r
+  // Get the Performance counter characteristics:\r
+  //          Freq = Frequency in Hz\r
+  //    StartCount = Value loaded into the counter when it starts counting\r
+  //      EndCount = Value counter counts to before it needs to be reset\r
+  //\r
+  Freq = GetPerformanceCounterProperties (&TimerInfo.StartCount, &TimerInfo.EndCount);\r
+\r
+  // Convert the Frequency from Hz to KHz\r
+  TimerInfo.Frequency = (UINT32)DivU64x32 (Freq, 1000);\r
+\r
+  // Determine in which direction the performance counter counts.\r
+  TimerInfo.CountUp = (BOOLEAN) (TimerInfo.EndCount >= TimerInfo.StartCount);\r
+\r
+  //\r
+  // Print header\r
+  //\r
+  // print DP's build version\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_BUILD_REVISION), gDpHiiHandle, DP_MAJOR_VERSION, DP_MINOR_VERSION);\r
+\r
+  // print performance timer characteristics\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_KHZ), gDpHiiHandle, TimerInfo.Frequency);\r
+\r
+  if (VerboseMode && !RawMode) {\r
+    StringPtr = HiiGetString (gDpHiiHandle,\r
+                  (EFI_STRING_ID) (TimerInfo.CountUp ? STRING_TOKEN (STR_DP_UP) : STRING_TOKEN (STR_DP_DOWN)), NULL);\r
+    ASSERT (StringPtr != NULL);\r
+    // Print Timer count range and direction\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TIMER_PROPERTIES), gDpHiiHandle,\r
+                StringPtr,\r
+                TimerInfo.StartCount,\r
+                TimerInfo.EndCount\r
+                );\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_VERBOSE_THRESHOLD), gDpHiiHandle, mInterestThreshold);\r
+  }\r
+\r
+/****************************************************************************\r
+****            Print Sections based on command line options\r
+****\r
+****  Option modes have the following priority:\r
+****    v Verbose     --  Valid in combination with any other options\r
+****    t Threshold   --  Modifies All, Raw, and Cooked output\r
+****                      Default is 0 for All and Raw mode\r
+****                      Default is DEFAULT_THRESHOLD for "Cooked" mode\r
+****    n Number2Display  Used by All and Raw mode.  Otherwise ignored.\r
+****    A All         --  R and S options are ignored\r
+****    R Raw         --  S option is ignored\r
+****    s Summary     --  Modifies "Cooked" output only\r
+****    Cooked (Default)\r
+****\r
+****  The All, Raw, and Cooked modes are modified by the Trace and Profile\r
+****  options.\r
+****    !T && !P  := (0) Default, Both are displayed\r
+****     T && !P  := (1) Only Trace records are displayed\r
+****    !T &&  P  := (2) Only Profile records are displayed\r
+****     T &&  P  := (3) Same as Default, both are displayed\r
+****************************************************************************/\r
+  GatherStatistics();\r
+  if (AllMode) {\r
+    if (TraceMode) {\r
+      DumpAllTrace( Number2Display, ExcludeMode);\r
+    }\r
+    if (ProfileMode) {\r
+      DumpAllProfile( Number2Display, ExcludeMode);\r
+    }\r
+  } else if (RawMode) {\r
+    if (TraceMode) {\r
+      DumpRawTrace( Number2Display, ExcludeMode);\r
+    }\r
+    if (ProfileMode) {\r
+      DumpRawProfile( Number2Display, ExcludeMode);\r
+    }\r
+  } else {\r
+    //------------- Begin Cooked Mode Processing\r
+    if (TraceMode) {\r
+      ProcessPhases ( Ticker );\r
+      if ( ! SummaryMode) {\r
+        Status = ProcessHandles ( ExcludeMode);\r
+        if ( ! EFI_ERROR( Status)) {\r
+          ProcessPeims ();\r
+          ProcessGlobal ();\r
+          ProcessCumulative ();\r
+        }\r
+      }\r
+    }\r
+    if (ProfileMode) {\r
+      DumpAllProfile( Number2Display, ExcludeMode);\r
+    }\r
+  } //------------- End of Cooked Mode Processing\r
+  if ( VerboseMode || SummaryMode) {\r
+    DumpStatistics();\r
+  }\r
+\r
+  SHELL_FREE_NON_NULL (StringPtr);\r
+\r
+  return SHELL_SUCCESS;\r
+}\r
diff --git a/ShellPkg/Library/UefiDpLib/Dp.h b/ShellPkg/Library/UefiDpLib/Dp.h
new file mode 100644 (file)
index 0000000..72e2c3b
--- /dev/null
@@ -0,0 +1,98 @@
+/** @file\r
+  Common declarations for the Dp Performance Reporting Utility.\r
+\r
+  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#ifndef _EFI_APP_DP_H_\r
+#define _EFI_APP_DP_H_\r
+\r
+#include <Library/ShellLib.h>\r
+#include <ShellBase.h>\r
+\r
+#define DP_MAJOR_VERSION        2\r
+#define DP_MINOR_VERSION        4\r
+\r
+/**\r
+  * The value assigned to DP_DEBUG controls which debug output\r
+  * is generated.  Set it to ZERO to disable.\r
+**/\r
+#define DP_DEBUG                0\r
+\r
+/**\r
+  * Set to 1 once Profiling has been implemented in order to enable\r
+  * profiling related options and report output.\r
+**/\r
+#define PROFILING_IMPLEMENTED   0\r
+\r
+#define DEFAULT_THRESHOLD       1000    ///< One millisecond.\r
+#define DEFAULT_DISPLAYCOUNT    50\r
+#define MAXIMUM_DISPLAYCOUNT    999999  ///< Arbitrary maximum reasonable number.\r
+\r
+#define PERF_MAXDUR             0xFFFFFFFFFFFFFFFFULL\r
+\r
+/// Determine whether  0 <= C < L.  If L == 0, return true regardless of C.\r
+#define WITHIN_LIMIT( C, L)   ( ((L) == 0) || ((C) < (L)) )\r
+\r
+/// Structure for storing Timer specific information.\r
+typedef struct {\r
+  UINT64    StartCount;   ///< Value timer is initialized with.\r
+  UINT64    EndCount;     ///< Value timer has just before it wraps.\r
+  UINT32    Frequency;    ///< Timer count frequency in KHz.\r
+  BOOLEAN   CountUp;      ///< TRUE if the counter counts up.\r
+} TIMER_INFO;\r
+\r
+/** Initialize one PERF_CUM_DATA structure instance for token t.\r
+  *\r
+  * This parameterized macro takes a single argument, t, which is expected\r
+  * to resolve to a pointer to an ASCII string literal.  This parameter may\r
+  * take any one of the following forms:\r
+  *   - PERF_INIT_CUM_DATA("Token")         A string literal\r
+  *   - PERF_INIT_CUM_DATA(pointer)         A pointer -- CHAR8 *pointer;\r
+  *   - PERF_INIT_CUM_DATA(array)           Address of an array -- CHAR8 array[N];\r
+**/\r
+#define PERF_INIT_CUM_DATA(t)   { 0ULL, PERF_MAXDUR, 0ULL, (t), 0U }\r
+\r
+typedef struct {\r
+  UINT64  Duration;     ///< Cumulative duration for this item.\r
+  UINT64  MinDur;       ///< Smallest duration encountered.\r
+  UINT64  MaxDur;       ///< Largest duration encountered.\r
+  CHAR8   *Name;        ///< ASCII name of this item.\r
+  UINT32  Count;        ///< Total number of measurements accumulated.\r
+} PERF_CUM_DATA;\r
+\r
+typedef struct {\r
+  UINT32                NumTrace;         ///< Number of recorded TRACE performance measurements.\r
+  UINT32                NumProfile;       ///< Number of recorded PROFILE performance measurements.\r
+  UINT32                NumIncomplete;    ///< Number of measurements with no END value.\r
+  UINT32                NumSummary;       ///< Number of summary section measurements.\r
+  UINT32                NumHandles;       ///< Number of measurements with handles.\r
+  UINT32                NumPEIMs;         ///< Number of measurements of PEIMs.\r
+  UINT32                NumGlobal;        ///< Number of measurements with END value and NULL handle.\r
+} PERF_SUMMARY_DATA;\r
+\r
+typedef struct {\r
+  CONST VOID            *Handle;\r
+  CONST CHAR8           *Token;           ///< Measured token string name.\r
+  CONST CHAR8           *Module;          ///< Module string name.\r
+  UINT64                StartTimeStamp;   ///< Start time point.\r
+  UINT64                EndTimeStamp;     ///< End time point.\r
+  UINT32                Identifier;       ///< Identifier.\r
+} MEASUREMENT_RECORD;\r
+\r
+typedef struct {\r
+  CHAR8                 *Name;            ///< Measured token string name.\r
+  UINT64                CumulativeTime;   ///< Accumulated Elapsed Time.\r
+  UINT64                MinTime;          ///< Minimum Elapsed Time.\r
+  UINT64                MaxTime;          ///< Maximum Elapsed Time.\r
+  UINT32                Count;            ///< Number of measurements accumulated.\r
+} PROFILE_RECORD;\r
+\r
+#endif  // _EFI_APP_DP_H_\r
diff --git a/ShellPkg/Library/UefiDpLib/DpInternal.h b/ShellPkg/Library/UefiDpLib/DpInternal.h
new file mode 100644 (file)
index 0000000..c7d9a59
--- /dev/null
@@ -0,0 +1,340 @@
+/** @file\r
+  Declarations of objects defined internally to the Dp Application.\r
+\r
+  Declarations of data and functions which are private to the Dp application.\r
+  This file should never be referenced by anything other than components of the\r
+  Dp application.  In addition to global data, function declarations for\r
+  DpUtilities.c, DpTrace.c, and DpProfile.c are included here.\r
+\r
+  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+#ifndef _DP_INTELNAL_H_\r
+#define _DP_INTELNAL_H_\r
+\r
+#define DP_GAUGE_STRING_LENGTH   36\r
+\r
+//\r
+/// Module-Global Variables\r
+///@{\r
+extern EFI_HII_HANDLE     gDpHiiHandle;\r
+extern CHAR16             mGaugeString[DP_GAUGE_STRING_LENGTH + 1];\r
+extern CHAR16             mUnicodeToken[DXE_PERFORMANCE_STRING_SIZE];\r
+extern UINT64             mInterestThreshold;\r
+extern BOOLEAN            mShowId;\r
+\r
+extern PERF_SUMMARY_DATA  SummaryData;    ///< Create the SummaryData structure and init. to ZERO.\r
+\r
+/// Timer Specific Information.\r
+extern TIMER_INFO         TimerInfo;\r
+\r
+/// Items for which to gather cumulative statistics.\r
+extern PERF_CUM_DATA      CumData[];\r
+\r
+/// Number of items for which we are gathering cumulative statistics.\r
+extern UINT32 const       NumCum;\r
+\r
+///@}\r
+\r
+/** \r
+  Calculate an event's duration in timer ticks.\r
+  \r
+  Given the count direction and the event's start and end timer values,\r
+  calculate the duration of the event in timer ticks.  Information for\r
+  the current measurement is pointed to by the parameter.\r
+  \r
+  If the measurement's start time is 1, it indicates that the developer\r
+  is indicating that the measurement began at the release of reset.\r
+  The start time is adjusted to the timer's starting count before performing\r
+  the elapsed time calculation.\r
+  \r
+  The calculated duration, in ticks, is the absolute difference between\r
+  the measurement's ending and starting counts.\r
+  \r
+  @param Measurement   Pointer to a MEASUREMENT_RECORD structure containing\r
+                       data for the current measurement.\r
+  \r
+  @return              The 64-bit duration of the event.\r
+**/\r
+UINT64\r
+GetDuration (\r
+  IN OUT MEASUREMENT_RECORD *Measurement\r
+  );\r
+\r
+/** \r
+  Determine whether the Measurement record is for an EFI Phase.\r
+  \r
+  The Token and Module members of the measurement record are checked.\r
+  Module must be empty and Token must be one of SEC, PEI, DXE, BDS, or SHELL.\r
+  \r
+  @param[in]  Measurement A pointer to the Measurement record to test.\r
+  \r
+  @retval     TRUE        The measurement record is for an EFI Phase.\r
+  @retval     FALSE       The measurement record is NOT for an EFI Phase.\r
+**/\r
+BOOLEAN\r
+IsPhase(\r
+  IN MEASUREMENT_RECORD *Measurement\r
+  );\r
+\r
+/** \r
+  Get the file name portion of the Pdb File Name.\r
+  \r
+  The portion of the Pdb File Name between the last backslash and\r
+  either a following period or the end of the string is converted\r
+  to Unicode and copied into UnicodeBuffer.  The name is truncated,\r
+  if necessary, to ensure that UnicodeBuffer is not overrun.\r
+  \r
+  @param[in]  PdbFileName     Pdb file name.\r
+  @param[out] UnicodeBuffer   The resultant Unicode File Name.\r
+  \r
+**/\r
+VOID\r
+GetShortPdbFileName (\r
+  IN  CHAR8     *PdbFileName,\r
+  OUT CHAR16    *UnicodeBuffer\r
+  );\r
+\r
+/** \r
+  Get a human readable name for an image handle.\r
+  The following methods will be tried orderly:\r
+    1. Image PDB\r
+    2. ComponentName2 protocol\r
+    3. FFS UI section\r
+    4. Image GUID\r
+    5. Image DevicePath\r
+    6. Unknown Driver Name\r
+  \r
+  @param[in]    Handle\r
+  \r
+  @post   The resulting Unicode name string is stored in the\r
+          mGaugeString global array.\r
+  \r
+**/\r
+VOID\r
+GetNameFromHandle (\r
+  IN EFI_HANDLE Handle\r
+  );\r
+\r
+/** \r
+  Calculate the Duration in microseconds.\r
+  \r
+  Duration is multiplied by 1000, instead of Frequency being divided by 1000 or\r
+  multiplying the result by 1000, in order to maintain precision.  Since Duration is\r
+  a 64-bit value, multiplying it by 1000 is unlikely to produce an overflow.\r
+  \r
+  The time is calculated as (Duration * 1000) / Timer_Frequency.\r
+  \r
+  @param[in]  Duration   The event duration in timer ticks.\r
+  \r
+  @return     A 64-bit value which is the Elapsed time in microseconds.\r
+**/\r
+UINT64\r
+DurationInMicroSeconds (\r
+  IN UINT64 Duration\r
+  );\r
+\r
+/** \r
+  Get index of Measurement Record's match in the CumData array.\r
+  \r
+  If the Measurement's Token value matches a Token in one of the CumData\r
+  records, the index of the matching record is returned.  The returned\r
+  index is a signed value so that negative values can indicate that\r
+  the Measurement didn't match any entry in the CumData array.\r
+  \r
+  @param[in]  Measurement A pointer to a Measurement Record to match against the CumData array.\r
+  \r
+  @retval     <0    Token is not in the CumData array.\r
+  @retval     >=0   Return value is the index into CumData where Token is found.\r
+**/\r
+INTN\r
+GetCumulativeItem(\r
+  IN MEASUREMENT_RECORD *Measurement\r
+  );\r
+\r
+/** \r
+  Collect verbose statistics about the logged performance measurements.\r
+  \r
+  General Summary information for all Trace measurements is gathered and\r
+  stored within the SummaryData structure.  This information is both\r
+  used internally by subsequent reporting functions, and displayed\r
+  at the end of verbose reports.\r
+  \r
+  @pre  The SummaryData and CumData structures must be initialized\r
+        prior to calling this function.\r
+  \r
+  @post The SummaryData and CumData structures contain statistics for the\r
+        current performance logs.\r
+**/\r
+VOID\r
+GatherStatistics(\r
+  VOID\r
+  );\r
+\r
+/** \r
+  Gather and print ALL Trace Records.\r
+  \r
+  Displays all "interesting" Trace measurements in order.<BR>\r
+  The number of records displayed is controlled by:\r
+     - records with a duration less than mInterestThreshold microseconds are not displayed.\r
+     - No more than Limit records are displayed.  A Limit of zero will not limit the output.\r
+     - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
+       displayed.\r
+  \r
+  @pre    The mInterestThreshold global variable is set to the shortest duration to be printed.\r
+           The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.\r
+           They must not be in use by a calling function.\r
+  \r
+  @param[in]    Limit       The number of records to print.  Zero is ALL.\r
+  @param[in]    ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
+  \r
+**/\r
+VOID\r
+DumpAllTrace(\r
+  IN UINTN             Limit,\r
+  IN BOOLEAN           ExcludeFlag\r
+  );\r
+\r
+/** \r
+  Gather and print Raw Trace Records.\r
+  \r
+  All Trace measurements with a duration greater than or equal to\r
+  mInterestThreshold are printed without interpretation.\r
+  \r
+  The number of records displayed is controlled by:\r
+     - records with a duration less than mInterestThreshold microseconds are not displayed.\r
+     - No more than Limit records are displayed.  A Limit of zero will not limit the output.\r
+     - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
+       displayed.\r
+  \r
+  @pre    The mInterestThreshold global variable is set to the shortest duration to be printed.\r
+  \r
+  @param[in]    Limit       The number of records to print.  Zero is ALL.\r
+  @param[in]    ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
+  \r
+**/\r
+VOID\r
+DumpRawTrace(\r
+  IN UINTN          Limit,\r
+  IN BOOLEAN        ExcludeFlag\r
+  );\r
+\r
+/** \r
+  Gather and print Major Phase metrics.\r
+  \r
+  @param[in]    Ticker      The timer value for the END of Shell phase\r
+  \r
+**/\r
+VOID\r
+ProcessPhases(\r
+  IN UINT64 Ticker\r
+  );\r
+\r
+\r
+/** \r
+  Gather and print Handle data.\r
+  \r
+  @param[in]    ExcludeFlag   TRUE to exclude individual Cumulative items from display.\r
+  \r
+  @return       Status from a call to gBS->LocateHandle().\r
+**/\r
+EFI_STATUS\r
+ProcessHandles(\r
+  IN BOOLEAN ExcludeFlag\r
+  );\r
+\r
+\r
+/** \r
+  Gather and print PEIM data.\r
+  \r
+  Only prints complete PEIM records\r
+  \r
+**/\r
+VOID\r
+ProcessPeims(\r
+  VOID\r
+  );\r
+\r
+/** \r
+  Gather and print global data.\r
+  \r
+  Strips out incomplete or "Execution Phase" records\r
+  Only prints records where Handle is NULL\r
+  Increment TIndex for every record, even skipped ones, so that we have an\r
+  indication of every measurement record taken.\r
+  \r
+**/\r
+VOID\r
+ProcessGlobal(\r
+  VOID\r
+  );\r
+\r
+/** \r
+  Gather and print cumulative data.\r
+  \r
+  Traverse the measurement records and:<BR>\r
+  For each record with a Token listed in the CumData array:<BR>\r
+     - Update the instance count and the total, minimum, and maximum durations.\r
+  Finally, print the gathered cumulative statistics.\r
+  \r
+**/\r
+VOID\r
+ProcessCumulative(\r
+  VOID\r
+  );\r
+\r
+/** \r
+  Gather and print ALL Profiling Records.\r
+  \r
+  Displays all "interesting" Profile measurements in order.\r
+  The number of records displayed is controlled by:\r
+     - records with a duration less than mInterestThreshold microseconds are not displayed.\r
+     - No more than Limit records are displayed.  A Limit of zero will not limit the output.\r
+     - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
+       displayed.\r
+  \r
+  @pre    The mInterestThreshold global variable is set to the shortest duration to be printed.\r
+           The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.\r
+           They must not be in use by a calling function.\r
+  \r
+  @param[in]    Limit         The number of records to print.  Zero is ALL.\r
+  @param[in]    ExcludeFlag   TRUE to exclude individual Cumulative items from display.\r
+  \r
+**/\r
+VOID\r
+DumpAllProfile(\r
+  IN UINTN          Limit,\r
+  IN BOOLEAN        ExcludeFlag\r
+  );\r
+\r
+/** \r
+  Gather and print Raw Profile Records.\r
+  \r
+  All Profile measurements with a duration greater than or equal to\r
+  mInterestThreshold are printed without interpretation.\r
+  \r
+  The number of records displayed is controlled by:\r
+     - records with a duration less than mInterestThreshold microseconds are not displayed.\r
+     - No more than Limit records are displayed.  A Limit of zero will not limit the output.\r
+     - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
+       displayed.\r
+  \r
+  @pre    The mInterestThreshold global variable is set to the shortest duration to be printed.\r
+  \r
+  @param[in]    Limit         The number of records to print.  Zero is ALL.\r
+  @param[in]    ExcludeFlag   TRUE to exclude individual Cumulative items from display.\r
+  \r
+**/\r
+VOID\r
+DumpRawProfile(\r
+  IN UINTN          Limit,\r
+  IN BOOLEAN        ExcludeFlag\r
+  );\r
+\r
+#endif\r
diff --git a/ShellPkg/Library/UefiDpLib/DpProfile.c b/ShellPkg/Library/UefiDpLib/DpProfile.c
new file mode 100644 (file)
index 0000000..6458398
--- /dev/null
@@ -0,0 +1,101 @@
+/** @file\r
+  Measured Profiling reporting for the Dp utility.\r
+\r
+  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/PerformanceLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#include <Guid/Performance.h>\r
+\r
+#include "Dp.h"\r
+#include "Literals.h"\r
+#include "DpInternal.h"\r
+\r
+/** \r
+  Gather and print ALL Profiling Records.\r
+  \r
+  Displays all "interesting" Profile measurements in order.\r
+  The number of records displayed is controlled by:\r
+     - records with a duration less than mInterestThreshold microseconds are not displayed.\r
+     - No more than Limit records are displayed.  A Limit of zero will not limit the output.\r
+     - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
+       displayed.\r
+  \r
+  @pre    The mInterestThreshold global variable is set to the shortest duration to be printed.\r
+           The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.\r
+           They must not be in use by a calling function.\r
+  \r
+  @param[in]    Limit         The number of records to print.  Zero is ALL.\r
+  @param[in]    ExcludeFlag   TRUE to exclude individual Cumulative items from display.\r
+  \r
+**/\r
+VOID\r
+DumpAllProfile(\r
+  IN UINTN      Limit,\r
+  IN BOOLEAN    ExcludeFlag\r
+  )\r
+{\r
+  EFI_STRING    StringPtr;\r
+  EFI_STRING    StringPtrUnknown;\r
+\r
+  StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);   \r
+  StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PROFILE), NULL);\r
+\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle, \r
+              (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
+  FreePool (StringPtr);\r
+  FreePool (StringPtrUnknown);\r
+}\r
+\r
+/** \r
+  Gather and print Raw Profile Records.\r
+  \r
+  All Profile measurements with a duration greater than or equal to\r
+  mInterestThreshold are printed without interpretation.\r
+  \r
+  The number of records displayed is controlled by:\r
+     - records with a duration less than mInterestThreshold microseconds are not displayed.\r
+     - No more than Limit records are displayed.  A Limit of zero will not limit the output.\r
+     - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
+       displayed.\r
+  \r
+  @pre    The mInterestThreshold global variable is set to the shortest duration to be printed.\r
+  \r
+  @param[in]    Limit         The number of records to print.  Zero is ALL.\r
+  @param[in]    ExcludeFlag   TRUE to exclude individual Cumulative items from display.\r
+  \r
+**/\r
+VOID\r
+DumpRawProfile(\r
+  IN UINTN      Limit,\r
+  IN BOOLEAN    ExcludeFlag\r
+  )\r
+{\r
+  EFI_STRING    StringPtr;\r
+  EFI_STRING    StringPtrUnknown;\r
+\r
+  StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
+  StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWPROFILE), NULL);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle, \r
+              (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
+  FreePool (StringPtr);\r
+  FreePool (StringPtrUnknown);\r
+}\r
diff --git a/ShellPkg/Library/UefiDpLib/DpTrace.c b/ShellPkg/Library/UefiDpLib/DpTrace.c
new file mode 100644 (file)
index 0000000..de1d45a
--- /dev/null
@@ -0,0 +1,828 @@
+/** @file\r
+  Trace reporting for the Dp utility.\r
+\r
+  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/PerformanceLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/PcdLib.h>\r
+\r
+#include <Guid/Performance.h>\r
+\r
+#include "Dp.h"\r
+#include "Literals.h"\r
+#include "DpInternal.h"\r
+\r
+/** \r
+  Collect verbose statistics about the logged performance measurements.\r
+  \r
+  General Summary information for all Trace measurements is gathered and\r
+  stored within the SummaryData structure.  This information is both\r
+  used internally by subsequent reporting functions, and displayed\r
+  at the end of verbose reports.\r
+  \r
+  @pre  The SummaryData and CumData structures must be initialized\r
+        prior to calling this function.\r
+  \r
+  @post The SummaryData and CumData structures contain statistics for the\r
+        current performance logs.\r
+**/\r
+VOID\r
+GatherStatistics(\r
+  VOID\r
+)\r
+{\r
+  MEASUREMENT_RECORD        Measurement;\r
+  UINT64                    Duration;\r
+  UINTN                     LogEntryKey;\r
+  INTN                      TIndex;\r
+\r
+  LogEntryKey = 0;\r
+  while ((LogEntryKey = GetPerformanceMeasurementEx (\r
+                        LogEntryKey,\r
+                        &Measurement.Handle,\r
+                        &Measurement.Token,\r
+                        &Measurement.Module,\r
+                        &Measurement.StartTimeStamp,\r
+                        &Measurement.EndTimeStamp,\r
+                        &Measurement.Identifier)) != 0)\r
+  {\r
+    ++SummaryData.NumTrace;           // Count the number of TRACE Measurement records\r
+    if (Measurement.EndTimeStamp == 0) {\r
+      ++SummaryData.NumIncomplete;    // Count the incomplete records\r
+      continue;\r
+    }\r
+\r
+    if (Measurement.Handle != NULL) {\r
+      ++SummaryData.NumHandles;       // Count the number of measurements with non-NULL handles\r
+    }\r
+\r
+    if (IsPhase( &Measurement)) {\r
+      ++SummaryData.NumSummary;       // Count the number of major phases\r
+    }\r
+    else {  // !IsPhase(...\r
+      if(Measurement.Handle == NULL) {\r
+        ++SummaryData.NumGlobal;\r
+      }\r
+    }\r
+\r
+    if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {\r
+      ++SummaryData.NumPEIMs;         // Count PEIM measurements\r
+    }\r
+\r
+    Duration = GetDuration (&Measurement);\r
+    TIndex = GetCumulativeItem (&Measurement);\r
+    if (TIndex >= 0) {\r
+      CumData[TIndex].Duration += Duration;\r
+      CumData[TIndex].Count++;\r
+      if ( Duration < CumData[TIndex].MinDur ) {\r
+        CumData[TIndex].MinDur = Duration;\r
+      }\r
+      if ( Duration > CumData[TIndex].MaxDur ) {\r
+        CumData[TIndex].MaxDur = Duration;\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+/** \r
+  Gather and print ALL Trace Records.\r
+  \r
+  Displays all "interesting" Trace measurements in order.<BR>\r
+  The number of records displayed is controlled by:\r
+     - records with a duration less than mInterestThreshold microseconds are not displayed.\r
+     - No more than Limit records are displayed.  A Limit of zero will not limit the output.\r
+     - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
+       displayed.\r
+  \r
+  @pre    The mInterestThreshold global variable is set to the shortest duration to be printed.\r
+           The mGaugeString and mUnicodeToken global arrays are used for temporary string storage.\r
+           They must not be in use by a calling function.\r
+  \r
+  @param[in]    Limit       The number of records to print.  Zero is ALL.\r
+  @param[in]    ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
+  \r
+**/\r
+VOID\r
+DumpAllTrace(\r
+  IN UINTN             Limit,\r
+  IN BOOLEAN           ExcludeFlag\r
+  )\r
+{\r
+  MEASUREMENT_RECORD        Measurement;\r
+  UINT64                    ElapsedTime;\r
+  UINT64                    Duration;\r
+  CHAR16                    *IncFlag;\r
+  UINTN                     LogEntryKey;\r
+  UINTN                     Count;\r
+  UINTN                     Index;\r
+  UINTN                     TIndex;\r
+\r
+  EFI_HANDLE                *HandleBuffer;\r
+  UINTN                     Size;\r
+  EFI_HANDLE                TempHandle;\r
+  EFI_STATUS                Status;\r
+  EFI_STRING                StringPtrUnknown;\r
+\r
+  StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);\r
+  IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_ALL), NULL);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
+              (IncFlag == NULL) ? StringPtrUnknown : IncFlag);\r
+  FreePool (StringPtrUnknown);\r
+\r
+  // Get Handle information\r
+  //\r
+  Size = 0;\r
+  HandleBuffer = &TempHandle;\r
+  Status  = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    HandleBuffer = AllocatePool (Size);\r
+    ASSERT (HandleBuffer != NULL);\r
+    if (HandleBuffer == NULL) {\r
+      return;\r
+    }\r
+    Status  = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), gDpHiiHandle, Status);\r
+  }\r
+  else {\r
+    // We have successfully populated the HandleBuffer\r
+    // Display ALL Measurement Records\r
+    //    Up to Limit lines displayed\r
+    //    Display only records with Elapsed times >= mInterestThreshold\r
+    //    Display driver names in Module field for records with Handles.\r
+    //\r
+    if (mShowId) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR2), gDpHiiHandle);\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_DASHES2), gDpHiiHandle);\r
+    } else {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_HEADR), gDpHiiHandle);\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
+    }\r
+\r
+    LogEntryKey = 0;\r
+    Count = 0;\r
+    Index = 0;\r
+    while ( WITHIN_LIMIT(Count, Limit) &&\r
+            ((LogEntryKey = GetPerformanceMeasurementEx (\r
+                            LogEntryKey,\r
+                            &Measurement.Handle,\r
+                            &Measurement.Token,\r
+                            &Measurement.Module,\r
+                            &Measurement.StartTimeStamp,\r
+                            &Measurement.EndTimeStamp,\r
+                            &Measurement.Identifier)) != 0)\r
+          )\r
+    {\r
+      ++Index;    // Count every record.  First record is 1.\r
+      ElapsedTime = 0;\r
+      SHELL_FREE_NON_NULL (IncFlag);\r
+      if (Measurement.EndTimeStamp != 0) {\r
+        Duration = GetDuration (&Measurement);\r
+        ElapsedTime = DurationInMicroSeconds ( Duration );\r
+        IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_COMPLETE), NULL);\r
+      }\r
+      else {\r
+        IncFlag = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_INCOMPLETE), NULL);  // Mark incomplete records\r
+      }\r
+      if (((Measurement.EndTimeStamp != 0) && (ElapsedTime < mInterestThreshold)) ||\r
+          ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
+         ) {      // Ignore "uninteresting" or excluded records\r
+        continue;\r
+      }\r
+      ++Count;    // Count the number of records printed\r
+\r
+      // If Handle is non-zero, see if we can determine a name for the driver\r
+      AsciiStrToUnicodeStr (Measurement.Module, mGaugeString); // Use Module by default\r
+      AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);\r
+      if (Measurement.Handle != NULL) {\r
+        // See if the Handle is in the HandleBuffer\r
+        for (TIndex = 0; TIndex < (Size / sizeof(HandleBuffer[0])); TIndex++) {\r
+          if (Measurement.Handle == HandleBuffer[TIndex]) {\r
+            GetNameFromHandle (HandleBuffer[TIndex]);\r
+            break;\r
+          }\r
+        }\r
+      }\r
+\r
+      if (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) == 0) {\r
+        UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", Measurement.Handle);\r
+      }\r
+\r
+      // Ensure that the argument strings are not too long.\r
+      mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
+      mUnicodeToken[13] = 0;\r
+\r
+      if (mShowId) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS2), gDpHiiHandle,\r
+          Index,      // 1 based, Which measurement record is being printed\r
+          IncFlag,\r
+          Measurement.Handle,\r
+          mGaugeString,\r
+          mUnicodeToken,\r
+          ElapsedTime,\r
+          Measurement.Identifier\r
+        );\r
+      } else {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_ALL_VARS), gDpHiiHandle,\r
+          Index,      // 1 based, Which measurement record is being printed\r
+          IncFlag,\r
+          Measurement.Handle,\r
+          mGaugeString,\r
+          mUnicodeToken,\r
+          ElapsedTime\r
+        );\r
+      }\r
+    }\r
+  }\r
+  if (HandleBuffer != &TempHandle) {\r
+    FreePool (HandleBuffer);\r
+  }\r
+  SHELL_FREE_NON_NULL (IncFlag);\r
+}\r
+\r
+/** \r
+  Gather and print Raw Trace Records.\r
+  \r
+  All Trace measurements with a duration greater than or equal to\r
+  mInterestThreshold are printed without interpretation.\r
+  \r
+  The number of records displayed is controlled by:\r
+     - records with a duration less than mInterestThreshold microseconds are not displayed.\r
+     - No more than Limit records are displayed.  A Limit of zero will not limit the output.\r
+     - If the ExcludeFlag is TRUE, records matching entries in the CumData array are not\r
+       displayed.\r
+  \r
+  @pre    The mInterestThreshold global variable is set to the shortest duration to be printed.\r
+  \r
+  @param[in]    Limit       The number of records to print.  Zero is ALL.\r
+  @param[in]    ExcludeFlag TRUE to exclude individual Cumulative items from display.\r
+  \r
+**/\r
+VOID\r
+DumpRawTrace(\r
+  IN UINTN          Limit,\r
+  IN BOOLEAN        ExcludeFlag\r
+  )\r
+{\r
+  MEASUREMENT_RECORD        Measurement;\r
+  UINT64                    ElapsedTime;\r
+  UINT64                    Duration;\r
+  UINTN                     LogEntryKey;\r
+  UINTN                     Count;\r
+  UINTN                     Index;\r
+\r
+  EFI_STRING    StringPtr;\r
+  EFI_STRING    StringPtrUnknown;\r
+\r
+  StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);  \r
+  StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_RAWTRACE), NULL);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
+              (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
+  FreePool (StringPtr);\r
+  FreePool (StringPtrUnknown);\r
+\r
+  if (mShowId) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR2), gDpHiiHandle);\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES2), gDpHiiHandle);\r
+  } else {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_HEADR), gDpHiiHandle);\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_DASHES), gDpHiiHandle);\r
+  }\r
+\r
+  LogEntryKey = 0;\r
+  Count = 0;\r
+  Index = 0;\r
+  while ( WITHIN_LIMIT(Count, Limit) &&\r
+          ((LogEntryKey = GetPerformanceMeasurementEx (\r
+                          LogEntryKey,\r
+                          &Measurement.Handle,\r
+                          &Measurement.Token,\r
+                          &Measurement.Module,\r
+                          &Measurement.StartTimeStamp,\r
+                          &Measurement.EndTimeStamp,\r
+                          &Measurement.Identifier)) != 0)\r
+        )\r
+  {\r
+    ++Index;    // Count every record.  First record is 1.\r
+    ElapsedTime = 0;\r
+    if (Measurement.EndTimeStamp != 0) {\r
+      Duration = GetDuration (&Measurement);\r
+      ElapsedTime = DurationInMicroSeconds ( Duration );\r
+    }\r
+    if ((ElapsedTime < mInterestThreshold)                 ||\r
+        ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
+        ) { // Ignore "uninteresting" or Excluded records\r
+      continue;\r
+    }\r
+    ++Count;    // Count the number of records printed\r
+\r
+    if (mShowId) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS2), gDpHiiHandle,\r
+        Index,      // 1 based, Which measurement record is being printed\r
+        Measurement.Handle,\r
+        Measurement.StartTimeStamp,\r
+        Measurement.EndTimeStamp,\r
+        Measurement.Token,\r
+        Measurement.Module,\r
+        Measurement.Identifier\r
+      );\r
+    } else {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_RAW_VARS), gDpHiiHandle,\r
+        Index,      // 1 based, Which measurement record is being printed\r
+        Measurement.Handle,\r
+        Measurement.StartTimeStamp,\r
+        Measurement.EndTimeStamp,\r
+        Measurement.Token,\r
+        Measurement.Module\r
+      );\r
+    }\r
+  }\r
+}\r
+\r
+/** \r
+  Gather and print Major Phase metrics.\r
+  \r
+  @param[in]    Ticker      The timer value for the END of Shell phase\r
+  \r
+**/\r
+VOID\r
+ProcessPhases(\r
+  IN UINT64            Ticker\r
+  )\r
+{\r
+  MEASUREMENT_RECORD        Measurement;\r
+  UINT64                    BdsTimeoutValue;\r
+  UINT64                    SecTime;\r
+  UINT64                    PeiTime;\r
+  UINT64                    DxeTime;\r
+  UINT64                    BdsTime;\r
+  UINT64                    ShellTime;\r
+  UINT64                    ElapsedTime;\r
+  UINT64                    Duration;\r
+  UINT64                    Total;\r
+  EFI_STRING                StringPtr;\r
+  UINTN                     LogEntryKey;\r
+  EFI_STRING                StringPtrUnknown;\r
+\r
+  BdsTimeoutValue = 0;\r
+  SecTime         = 0;\r
+  PeiTime         = 0;\r
+  DxeTime         = 0;\r
+  BdsTime         = 0;\r
+  ShellTime       = 0;   \r
+  //\r
+  // Get Execution Phase Statistics\r
+  //\r
+  StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);   \r
+  StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PHASES), NULL);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
+              (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
+  FreePool (StringPtr);\r
+  FreePool (StringPtrUnknown);\r
+\r
+  LogEntryKey = 0;\r
+  while ((LogEntryKey = GetPerformanceMeasurementEx (\r
+                          LogEntryKey,\r
+                          &Measurement.Handle,\r
+                          &Measurement.Token,\r
+                          &Measurement.Module,\r
+                          &Measurement.StartTimeStamp,\r
+                          &Measurement.EndTimeStamp,\r
+                          &Measurement.Identifier)) != 0)\r
+  {\r
+    if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {\r
+      Measurement.EndTimeStamp = Ticker;\r
+    }\r
+    if (Measurement.EndTimeStamp == 0) { // Skip "incomplete" records\r
+      continue;\r
+    }\r
+    Duration = GetDuration (&Measurement);\r
+    if (   Measurement.Handle != NULL\r
+        && (AsciiStrnCmp (Measurement.Token, ALit_BdsTO, PERF_TOKEN_LENGTH) == 0)\r
+       )\r
+    {\r
+      BdsTimeoutValue = Duration;\r
+    } else if (AsciiStrnCmp (Measurement.Token, ALit_SEC, PERF_TOKEN_LENGTH) == 0) {\r
+      SecTime     = Duration;\r
+    } else if (AsciiStrnCmp (Measurement.Token, ALit_PEI, PERF_TOKEN_LENGTH) == 0) {\r
+      PeiTime     = Duration;\r
+    } else if (AsciiStrnCmp (Measurement.Token, ALit_DXE, PERF_TOKEN_LENGTH) == 0) {\r
+      DxeTime      = Duration;\r
+    } else if (AsciiStrnCmp (Measurement.Token, ALit_BDS, PERF_TOKEN_LENGTH) == 0) {\r
+      BdsTime      = Duration;\r
+    } else if (AsciiStrnCmp (Measurement.Token, ALit_SHELL, PERF_TOKEN_LENGTH) == 0) {\r
+      ShellTime    = Duration;\r
+    }\r
+  }\r
+\r
+  Total = 0;\r
+\r
+  // print SEC phase duration time\r
+  //\r
+  if (SecTime > 0) {\r
+    ElapsedTime = DurationInMicroSeconds ( SecTime );     // Calculate elapsed time in microseconds\r
+    Total += DivU64x32 (ElapsedTime, 1000);   // Accumulate time in milliseconds\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SEC_PHASE), gDpHiiHandle, ElapsedTime);\r
+  }\r
+\r
+  // print PEI phase duration time\r
+  //\r
+  if (PeiTime > 0) {\r
+    ElapsedTime = DivU64x32 (\r
+                    PeiTime,\r
+                    (UINT32)TimerInfo.Frequency\r
+                    );\r
+    Total += ElapsedTime;\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_PEI, ElapsedTime);\r
+  }\r
+\r
+  // print DXE phase duration time\r
+  //\r
+  if (DxeTime > 0) {\r
+    ElapsedTime = DivU64x32 (\r
+                    DxeTime,\r
+                    (UINT32)TimerInfo.Frequency\r
+                    );\r
+    Total += ElapsedTime;\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_DXE, ElapsedTime);\r
+  }\r
+\r
+  // print BDS phase duration time\r
+  //\r
+  if (BdsTime > 0) {\r
+    ElapsedTime = DivU64x32 (\r
+                    BdsTime,\r
+                    (UINT32)TimerInfo.Frequency\r
+                    );\r
+    Total += ElapsedTime;\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_BDS, ElapsedTime);\r
+  }\r
+\r
+  if (BdsTimeoutValue > 0) {\r
+    ElapsedTime = DivU64x32 (\r
+                    BdsTimeoutValue,\r
+                    (UINT32)TimerInfo.Frequency\r
+                    );\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_BDSTO), gDpHiiHandle, ALit_BdsTO, ElapsedTime);\r
+  }\r
+\r
+  // print SHELL phase duration time\r
+  //\r
+  if (ShellTime > 0) {\r
+    ElapsedTime = DivU64x32 (\r
+                    ShellTime,\r
+                    (UINT32)TimerInfo.Frequency\r
+                    );\r
+    Total += ElapsedTime;\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PHASE_DURATION), gDpHiiHandle, ALit_SHELL, ElapsedTime);\r
+  }\r
+\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_TOTAL_DURATION), gDpHiiHandle, Total);\r
+}\r
+\r
+/** \r
+  Gather and print Handle data.\r
+  \r
+  @param[in]    ExcludeFlag   TRUE to exclude individual Cumulative items from display.\r
+  \r
+  @return       Status from a call to gBS->LocateHandle().\r
+**/\r
+EFI_STATUS\r
+ProcessHandles(\r
+  IN BOOLEAN      ExcludeFlag\r
+  )\r
+{\r
+  MEASUREMENT_RECORD        Measurement;\r
+  UINT64                    ElapsedTime;\r
+  UINT64                    Duration;\r
+  EFI_HANDLE                *HandleBuffer;\r
+  EFI_STRING                StringPtr;\r
+  UINTN                     Index;\r
+  UINTN                     LogEntryKey;\r
+  UINTN                     Count;\r
+  UINTN                     Size;\r
+  EFI_HANDLE                TempHandle;\r
+  EFI_STATUS                Status;\r
+  EFI_STRING                StringPtrUnknown;\r
+\r
+  StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);  \r
+  StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_DRIVERS), NULL);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
+              (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
+  FreePool (StringPtr);\r
+  FreePool (StringPtrUnknown);\r
+\r
+  Size = 0;\r
+  HandleBuffer = &TempHandle;\r
+  Status  = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, &TempHandle);\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    HandleBuffer = AllocatePool (Size);\r
+    ASSERT (HandleBuffer != NULL);\r
+    if (HandleBuffer == NULL) {\r
+      return Status;\r
+    }\r
+    Status  = gBS->LocateHandle (AllHandles, NULL, NULL, &Size, HandleBuffer);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLES_ERROR), gDpHiiHandle, Status);\r
+  }\r
+  else {\r
+#if DP_DEBUG == 2\r
+    Print (L"There are %,d Handles defined.\n", (Size / sizeof(HandleBuffer[0])));\r
+#endif\r
+\r
+    if (mShowId) {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION2), gDpHiiHandle);\r
+    } else {\r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_SECTION), gDpHiiHandle);\r
+    }\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
+\r
+    LogEntryKey = 0;\r
+    Count   = 0;\r
+    while ((LogEntryKey = GetPerformanceMeasurementEx (\r
+                            LogEntryKey,\r
+                            &Measurement.Handle,\r
+                            &Measurement.Token,\r
+                            &Measurement.Module,\r
+                            &Measurement.StartTimeStamp,\r
+                            &Measurement.EndTimeStamp,\r
+                            &Measurement.Identifier)) != 0)\r
+    {\r
+      Count++;\r
+      Duration = GetDuration (&Measurement);\r
+      ElapsedTime = DurationInMicroSeconds ( Duration );\r
+      if ((ElapsedTime < mInterestThreshold)                 ||\r
+          (Measurement.EndTimeStamp == 0)                    ||\r
+          (Measurement.Handle == NULL)                       ||\r
+          ((ExcludeFlag) && (GetCumulativeItem(&Measurement) >= 0))\r
+         ) { // Ignore "uninteresting" or excluded records\r
+        continue;\r
+      }\r
+      mGaugeString[0] = 0;    // Empty driver name by default\r
+      AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);\r
+      // See if the Handle is in the HandleBuffer\r
+      for (Index = 0; Index < (Size / sizeof(HandleBuffer[0])); Index++) {\r
+        if (Measurement.Handle == HandleBuffer[Index]) {\r
+          GetNameFromHandle (HandleBuffer[Index]); // Name is put into mGaugeString\r
+          break;\r
+        }\r
+      }\r
+      // Ensure that the argument strings are not too long.\r
+      mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
+      mUnicodeToken[11] = 0;\r
+      if (mGaugeString[0] != 0) {\r
+        // Display the record if it has a valid handle.\r
+        if (mShowId) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_VARS2), gDpHiiHandle,\r
+            Count,      // 1 based, Which measurement record is being printed\r
+            Index + 1,  // 1 based, Which handle is being printed\r
+            mGaugeString,\r
+            mUnicodeToken,\r
+            ElapsedTime,\r
+            Measurement.Identifier\r
+          );\r
+        } else {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_HANDLE_VARS), gDpHiiHandle,\r
+            Count,      // 1 based, Which measurement record is being printed\r
+            Index + 1,  // 1 based, Which handle is being printed\r
+            mGaugeString,\r
+            mUnicodeToken,\r
+            ElapsedTime\r
+          );\r
+        }\r
+      }\r
+    }\r
+  }\r
+  if (HandleBuffer != &TempHandle) {\r
+    FreePool (HandleBuffer);\r
+  }\r
+  return Status;\r
+}\r
+\r
+/** \r
+  Gather and print PEIM data.\r
+  \r
+  Only prints complete PEIM records\r
+  \r
+**/\r
+VOID\r
+ProcessPeims(\r
+  VOID\r
+)\r
+{\r
+  MEASUREMENT_RECORD        Measurement;\r
+  UINT64                    Duration;\r
+  UINT64                    ElapsedTime;\r
+  EFI_STRING                StringPtr;\r
+  UINTN                     LogEntryKey;\r
+  UINTN                     TIndex;\r
+  EFI_STRING                StringPtrUnknown;\r
+\r
+  StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);  \r
+  StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_PEIMS), NULL);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
+              (StringPtr == NULL) ? StringPtrUnknown : StringPtr);\r
+  FreePool (StringPtr);\r
+  FreePool (StringPtrUnknown);\r
+\r
+  if (mShowId) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION2), gDpHiiHandle);\r
+  } else {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_SECTION), gDpHiiHandle);\r
+  }\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
+  TIndex  = 0;\r
+  LogEntryKey = 0;\r
+  while ((LogEntryKey = GetPerformanceMeasurementEx (\r
+                          LogEntryKey,\r
+                          &Measurement.Handle,\r
+                          &Measurement.Token,\r
+                          &Measurement.Module,\r
+                          &Measurement.StartTimeStamp,\r
+                          &Measurement.EndTimeStamp,\r
+                          &Measurement.Identifier)) != 0)\r
+  {\r
+    TIndex++;\r
+    if ((Measurement.EndTimeStamp == 0) ||\r
+        (AsciiStrnCmp (Measurement.Token, ALit_PEIM, PERF_TOKEN_LENGTH) != 0)\r
+       ) {\r
+      continue;\r
+    }\r
+\r
+    Duration = GetDuration (&Measurement);\r
+    ElapsedTime = DurationInMicroSeconds ( Duration );  // Calculate elapsed time in microseconds\r
+    if (ElapsedTime >= mInterestThreshold) {\r
+      // PEIM FILE Handle is the start address of its FFS file that contains its file guid.\r
+      if (mShowId) {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS2), gDpHiiHandle,\r
+              TIndex,   // 1 based, Which measurement record is being printed\r
+              Measurement.Handle,  // base address\r
+              Measurement.Handle,  // file guid\r
+              ElapsedTime,\r
+              Measurement.Identifier\r
+        );\r
+      } else {\r
+        ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_PEIM_VARS), gDpHiiHandle,\r
+              TIndex,   // 1 based, Which measurement record is being printed\r
+              Measurement.Handle,  // base address\r
+              Measurement.Handle,  // file guid\r
+              ElapsedTime\r
+        );\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+/** \r
+  Gather and print global data.\r
+  \r
+  Strips out incomplete or "Execution Phase" records\r
+  Only prints records where Handle is NULL\r
+  Increment TIndex for every record, even skipped ones, so that we have an\r
+  indication of every measurement record taken.\r
+  \r
+**/\r
+VOID\r
+ProcessGlobal(\r
+  VOID\r
+)\r
+{\r
+  MEASUREMENT_RECORD        Measurement;\r
+  UINT64                    Duration;\r
+  UINT64                    ElapsedTime;\r
+  EFI_STRING                StringPtr;\r
+  UINTN                     LogEntryKey;\r
+  UINTN                     Index;        // Index, or number, of the measurement record being processed\r
+  EFI_STRING                StringPtrUnknown;\r
+\r
+  StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);  \r
+  StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_GENERAL), NULL);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
+              (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
+  FreePool (StringPtr);\r
+  FreePool (StringPtrUnknown);\r
+\r
+  if (mShowId) {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION2), gDpHiiHandle);\r
+  } else {\r
+    ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_SECTION), gDpHiiHandle);\r
+  }\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
+\r
+  Index = 1;\r
+  LogEntryKey = 0;\r
+\r
+  while ((LogEntryKey = GetPerformanceMeasurementEx (\r
+                          LogEntryKey,\r
+                          &Measurement.Handle,\r
+                          &Measurement.Token,\r
+                          &Measurement.Module,\r
+                          &Measurement.StartTimeStamp,\r
+                          &Measurement.EndTimeStamp,\r
+                          &Measurement.Identifier)) != 0)\r
+  {\r
+    AsciiStrToUnicodeStr (Measurement.Module, mGaugeString);\r
+    AsciiStrToUnicodeStr (Measurement.Token, mUnicodeToken);\r
+    mGaugeString[25] = 0;\r
+    mUnicodeToken[31] = 0;\r
+    if ( ! ( IsPhase( &Measurement)  ||\r
+        (Measurement.Handle != NULL)      ||\r
+        (Measurement.EndTimeStamp == 0)\r
+        ))\r
+    {\r
+      Duration = GetDuration (&Measurement);\r
+      ElapsedTime = DurationInMicroSeconds ( Duration );\r
+      if (ElapsedTime >= mInterestThreshold) {\r
+        if (mShowId) {\r
+          ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS2), gDpHiiHandle,\r
+            Index,\r
+            mGaugeString,\r
+            mUnicodeToken,\r
+            ElapsedTime,\r
+            Measurement.Identifier\r
+            );\r
+        } else {\r
+           ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_GLOBAL_VARS), gDpHiiHandle,\r
+            Index,\r
+            mGaugeString,\r
+            mUnicodeToken,\r
+            ElapsedTime\r
+            );\r
+        }\r
+      }\r
+    }\r
+    Index++;\r
+  }\r
+}\r
+\r
+/** \r
+  Gather and print cumulative data.\r
+  \r
+  Traverse the measurement records and:<BR>\r
+  For each record with a Token listed in the CumData array:<BR>\r
+     - Update the instance count and the total, minimum, and maximum durations.\r
+  Finally, print the gathered cumulative statistics.\r
+  \r
+**/\r
+VOID\r
+ProcessCumulative(\r
+  VOID\r
+)\r
+{\r
+  UINT64                    AvgDur;         // the computed average duration\r
+  UINT64                    Dur;\r
+  UINT64                    MinDur;\r
+  UINT64                    MaxDur;\r
+  EFI_STRING                StringPtr;\r
+  UINTN                     TIndex;\r
+  EFI_STRING                StringPtrUnknown;\r
+\r
+  StringPtrUnknown = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_ALIT_UNKNOWN), NULL);  \r
+  StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_SECTION_CUMULATIVE), NULL);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_SECTION_HEADER), gDpHiiHandle,\r
+              (StringPtr == NULL) ? StringPtrUnknown: StringPtr);\r
+  FreePool (StringPtr);\r
+  FreePool (StringPtrUnknown);\r
+\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_1), gDpHiiHandle);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_SECT_2), gDpHiiHandle);\r
+  ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_DASHES), gDpHiiHandle);\r
+\r
+  for ( TIndex = 0; TIndex < NumCum; ++TIndex) {\r
+    if (CumData[TIndex].Count != 0) {\r
+      AvgDur = DivU64x32 (CumData[TIndex].Duration, CumData[TIndex].Count);\r
+      AvgDur = DurationInMicroSeconds(AvgDur);\r
+      Dur    = DurationInMicroSeconds(CumData[TIndex].Duration);\r
+      MaxDur = DurationInMicroSeconds(CumData[TIndex].MaxDur);\r
+      MinDur = DurationInMicroSeconds(CumData[TIndex].MinDur);\r
+    \r
+      ShellPrintHiiEx (-1, -1, NULL, STRING_TOKEN (STR_DP_CUMULATIVE_STATS), gDpHiiHandle,\r
+                  CumData[TIndex].Name,\r
+                  CumData[TIndex].Count,\r
+                  Dur,\r
+                  AvgDur,\r
+                  MinDur,\r
+                  MaxDur\r
+                 );\r
+    }\r
+  }\r
+}\r
diff --git a/ShellPkg/Library/UefiDpLib/DpUtilities.c b/ShellPkg/Library/UefiDpLib/DpUtilities.c
new file mode 100644 (file)
index 0000000..89c9919
--- /dev/null
@@ -0,0 +1,400 @@
+/** @file\r
+  Utility functions used by the Dp application.\r
+\r
+  Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/TimerLib.h>\r
+#include <Library/PeCoffGetEntryPointLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/DevicePathLib.h>\r
+\r
+#include <Pi/PiFirmwareFile.h>\r
+#include <Library/DxeServicesLib.h>\r
+\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/ComponentName2.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/DevicePathToText.h>\r
+\r
+#include <Guid/Performance.h>\r
+\r
+#include "Dp.h"\r
+#include "Literals.h"\r
+#include "DpInternal.h"\r
+\r
+/** \r
+  Calculate an event's duration in timer ticks.\r
+  \r
+  Given the count direction and the event's start and end timer values,\r
+  calculate the duration of the event in timer ticks.  Information for\r
+  the current measurement is pointed to by the parameter.\r
+  \r
+  If the measurement's start time is 1, it indicates that the developer\r
+  is indicating that the measurement began at the release of reset.\r
+  The start time is adjusted to the timer's starting count before performing\r
+  the elapsed time calculation.\r
+  \r
+  The calculated duration, in ticks, is the absolute difference between\r
+  the measurement's ending and starting counts.\r
+  \r
+  @param Measurement   Pointer to a MEASUREMENT_RECORD structure containing\r
+                       data for the current measurement.\r
+  \r
+  @return              The 64-bit duration of the event.\r
+**/\r
+UINT64\r
+GetDuration (\r
+  IN OUT MEASUREMENT_RECORD   *Measurement\r
+  )\r
+{\r
+  UINT64    Duration;\r
+  BOOLEAN   Error;\r
+\r
+  // PERF_START macros are called with a value of 1 to indicate\r
+  // the beginning of time.  So, adjust the start ticker value\r
+  // to the real beginning of time.\r
+  // Assumes no wraparound.  Even then, there is a very low probability\r
+  // of having a valid StartTicker value of 1.\r
+  if (Measurement->StartTimeStamp == 1) {\r
+    Measurement->StartTimeStamp = TimerInfo.StartCount;\r
+  }\r
+  if (TimerInfo.CountUp) {\r
+    Duration = Measurement->EndTimeStamp - Measurement->StartTimeStamp;\r
+    Error = (BOOLEAN)(Duration > Measurement->EndTimeStamp);\r
+  }\r
+  else {\r
+    Duration = Measurement->StartTimeStamp - Measurement->EndTimeStamp;\r
+    Error = (BOOLEAN)(Duration > Measurement->StartTimeStamp);\r
+  }\r
+\r
+  if (Error) {\r
+    DEBUG ((EFI_D_ERROR, ALit_TimerLibError));\r
+    Duration = 0;\r
+  }\r
+  return Duration;\r
+}\r
+\r
+/** \r
+  Determine whether the Measurement record is for an EFI Phase.\r
+  \r
+  The Token and Module members of the measurement record are checked.\r
+  Module must be empty and Token must be one of SEC, PEI, DXE, BDS, or SHELL.\r
+  \r
+  @param[in]  Measurement A pointer to the Measurement record to test.\r
+  \r
+  @retval     TRUE        The measurement record is for an EFI Phase.\r
+  @retval     FALSE       The measurement record is NOT for an EFI Phase.\r
+**/\r
+BOOLEAN\r
+IsPhase(\r
+  IN MEASUREMENT_RECORD        *Measurement\r
+  )\r
+{\r
+  BOOLEAN   RetVal;\r
+\r
+  RetVal = (BOOLEAN)( ( *Measurement->Module == '\0')                               &&\r
+            ((AsciiStrnCmp (Measurement->Token, ALit_SEC, PERF_TOKEN_LENGTH) == 0)    ||\r
+             (AsciiStrnCmp (Measurement->Token, ALit_PEI, PERF_TOKEN_LENGTH) == 0)    ||\r
+             (AsciiStrnCmp (Measurement->Token, ALit_DXE, PERF_TOKEN_LENGTH) == 0)    ||\r
+             (AsciiStrnCmp (Measurement->Token, ALit_BDS, PERF_TOKEN_LENGTH) == 0))\r
+            );\r
+  return RetVal;\r
+}\r
+\r
+/** \r
+  Get the file name portion of the Pdb File Name.\r
+  \r
+  The portion of the Pdb File Name between the last backslash and\r
+  either a following period or the end of the string is converted\r
+  to Unicode and copied into UnicodeBuffer.  The name is truncated,\r
+  if necessary, to ensure that UnicodeBuffer is not overrun.\r
+  \r
+  @param[in]  PdbFileName     Pdb file name.\r
+  @param[out] UnicodeBuffer   The resultant Unicode File Name.\r
+  \r
+**/\r
+VOID\r
+GetShortPdbFileName (\r
+  IN  CHAR8     *PdbFileName,\r
+  OUT CHAR16    *UnicodeBuffer\r
+  )\r
+{\r
+  UINTN IndexA;     // Current work location within an ASCII string.\r
+  UINTN IndexU;     // Current work location within a Unicode string.\r
+  UINTN StartIndex;\r
+  UINTN EndIndex;\r
+\r
+  ZeroMem (UnicodeBuffer, DXE_PERFORMANCE_STRING_LENGTH * sizeof (CHAR16));\r
+\r
+  if (PdbFileName == NULL) {\r
+    StrCpy (UnicodeBuffer, L" ");\r
+  } else {\r
+    StartIndex = 0;\r
+    for (EndIndex = 0; PdbFileName[EndIndex] != 0; EndIndex++)\r
+      ;\r
+    for (IndexA = 0; PdbFileName[IndexA] != 0; IndexA++) {\r
+      if (PdbFileName[IndexA] == '\\') {\r
+        StartIndex = IndexA + 1;\r
+      }\r
+\r
+      if (PdbFileName[IndexA] == '.') {\r
+        EndIndex = IndexA;\r
+      }\r
+    }\r
+\r
+    IndexU = 0;\r
+    for (IndexA = StartIndex; IndexA < EndIndex; IndexA++) {\r
+      UnicodeBuffer[IndexU] = (CHAR16) PdbFileName[IndexA];\r
+      IndexU++;\r
+      if (IndexU >= DXE_PERFORMANCE_STRING_LENGTH) {\r
+        UnicodeBuffer[DXE_PERFORMANCE_STRING_LENGTH] = 0;\r
+        break;\r
+      }\r
+    }\r
+  }\r
+}\r
+\r
+/** \r
+  Get a human readable name for an image handle.\r
+  The following methods will be tried orderly:\r
+    1. Image PDB\r
+    2. ComponentName2 protocol\r
+    3. FFS UI section\r
+    4. Image GUID\r
+    5. Image DevicePath\r
+    6. Unknown Driver Name\r
+\r
+  @param[in]    Handle\r
+\r
+  @post   The resulting Unicode name string is stored in the\r
+          mGaugeString global array.\r
+\r
+**/\r
+VOID\r
+GetNameFromHandle (\r
+  IN EFI_HANDLE   Handle\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  EFI_LOADED_IMAGE_PROTOCOL   *Image;\r
+  CHAR8                       *PdbFileName;\r
+  EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;\r
+  EFI_STRING                  StringPtr;\r
+  EFI_DEVICE_PATH_PROTOCOL    *LoadedImageDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL    *DevicePath;\r
+  EFI_GUID                    *NameGuid;\r
+  CHAR16                      *NameString;\r
+  UINTN                       StringSize;\r
+  CHAR8                       *PlatformLanguage;\r
+  EFI_COMPONENT_NAME2_PROTOCOL      *ComponentName2;\r
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL  *DevicePathToText;\r
+\r
+  //\r
+  // Method 1: Get the name string from image PDB\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  Handle,\r
+                  &gEfiLoadedImageProtocolGuid,\r
+                  (VOID **) &Image\r
+                  );\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    Status = gBS->OpenProtocol (\r
+                    Handle,\r
+                    &gEfiDriverBindingProtocolGuid,\r
+                    (VOID **) &DriverBinding,\r
+                    NULL,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if (!EFI_ERROR (Status)) {\r
+      Status = gBS->HandleProtocol (\r
+                      DriverBinding->ImageHandle,\r
+                      &gEfiLoadedImageProtocolGuid,\r
+                      (VOID **) &Image\r
+                      );\r
+    }\r
+  }\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    PdbFileName = PeCoffLoaderGetPdbPointer (Image->ImageBase);\r
+\r
+    if (PdbFileName != NULL) {\r
+      GetShortPdbFileName (PdbFileName, mGaugeString);\r
+      return;\r
+    }\r
+  }\r
+\r
+  //\r
+  // Method 2: Get the name string from ComponentName2 protocol\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  Handle,\r
+                  &gEfiComponentName2ProtocolGuid,\r
+                  (VOID **) &ComponentName2\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Get the current platform language setting\r
+    //\r
+    GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&PlatformLanguage, NULL);\r
+    Status = ComponentName2->GetDriverName (\r
+                               ComponentName2,\r
+                               PlatformLanguage != NULL ? PlatformLanguage : "en-US",\r
+                               &StringPtr\r
+                               );\r
+    if (!EFI_ERROR (Status)) {\r
+      SHELL_FREE_NON_NULL (PlatformLanguage);\r
+      StrnCpy (mGaugeString, StringPtr, DP_GAUGE_STRING_LENGTH);\r
+      mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
+      return;\r
+    }\r
+  }\r
+\r
+  Status = gBS->HandleProtocol (\r
+                  Handle,\r
+                  &gEfiLoadedImageDevicePathProtocolGuid,\r
+                  (VOID **) &LoadedImageDevicePath\r
+                  );\r
+  if (!EFI_ERROR (Status) && (LoadedImageDevicePath != NULL)) {\r
+    DevicePath = LoadedImageDevicePath;\r
+\r
+    //\r
+    // Try to get image GUID from LoadedImageDevicePath protocol\r
+    //\r
+    NameGuid = NULL;\r
+    while (!IsDevicePathEndType (DevicePath)) {\r
+      NameGuid = EfiGetNameGuidFromFwVolDevicePathNode ((MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *) DevicePath);\r
+      if (NameGuid != NULL) {\r
+        break;\r
+      }\r
+      DevicePath = NextDevicePathNode (DevicePath);\r
+    }\r
+\r
+    if (NameGuid != NULL) {\r
+      //\r
+      // Try to get the image's FFS UI section by image GUID\r
+      //\r
+      NameString = NULL;\r
+      StringSize = 0;\r
+      Status = GetSectionFromAnyFv (\r
+                NameGuid,\r
+                EFI_SECTION_USER_INTERFACE,\r
+                0,\r
+                (VOID **) &NameString,\r
+                &StringSize\r
+                );\r
+\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Method 3. Get the name string from FFS UI section\r
+        //\r
+        StrnCpy (mGaugeString, NameString, DP_GAUGE_STRING_LENGTH);\r
+        mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
+        FreePool (NameString);\r
+      } else {\r
+        //\r
+        // Method 4: Get the name string from image GUID\r
+        //\r
+        UnicodeSPrint (mGaugeString, sizeof (mGaugeString), L"%g", NameGuid);\r
+      }\r
+      return;\r
+    } else {\r
+      //\r
+      // Method 5: Get the name string from image DevicePath\r
+      //\r
+      Status = gBS->LocateProtocol (\r
+                      &gEfiDevicePathToTextProtocolGuid,\r
+                      NULL,\r
+                      (VOID **) &DevicePathToText\r
+                      );\r
+      if (!EFI_ERROR (Status)) {\r
+        NameString = DevicePathToText->ConvertDevicePathToText (LoadedImageDevicePath, TRUE, FALSE);\r
+        if (NameString != NULL) {\r
+          StrnCpy (mGaugeString, NameString, DP_GAUGE_STRING_LENGTH);\r
+          mGaugeString[DP_GAUGE_STRING_LENGTH] = 0;\r
+          FreePool (NameString);\r
+          return;\r
+        }\r
+      }\r
+    }\r
+  }\r
+\r
+  //\r
+  // Method 6: Unknown Driver Name\r
+  //\r
+  StringPtr = HiiGetString (gDpHiiHandle, STRING_TOKEN (STR_DP_ERROR_NAME), NULL);\r
+  ASSERT (StringPtr != NULL);\r
+  StrCpy (mGaugeString, StringPtr);\r
+  FreePool (StringPtr);\r
+}\r
+\r
+/** \r
+  Calculate the Duration in microseconds.\r
+  \r
+  Duration is multiplied by 1000, instead of Frequency being divided by 1000 or\r
+  multiplying the result by 1000, in order to maintain precision.  Since Duration is\r
+  a 64-bit value, multiplying it by 1000 is unlikely to produce an overflow.\r
+  \r
+  The time is calculated as (Duration * 1000) / Timer_Frequency.\r
+  \r
+  @param[in]  Duration   The event duration in timer ticks.\r
+  \r
+  @return     A 64-bit value which is the Elapsed time in microseconds.\r
+**/\r
+UINT64\r
+DurationInMicroSeconds (\r
+  IN UINT64 Duration\r
+  )\r
+{\r
+  UINT64 Temp;\r
+\r
+  Temp = MultU64x32 (Duration, 1000);\r
+  return DivU64x32 (Temp, TimerInfo.Frequency);\r
+}\r
+\r
+/** \r
+  Get index of Measurement Record's match in the CumData array.\r
+  \r
+  If the Measurement's Token value matches a Token in one of the CumData\r
+  records, the index of the matching record is returned.  The returned\r
+  index is a signed value so that negative values can indicate that\r
+  the Measurement didn't match any entry in the CumData array.\r
+  \r
+  @param[in]  Measurement A pointer to a Measurement Record to match against the CumData array.\r
+  \r
+  @retval     <0    Token is not in the CumData array.\r
+  @retval     >=0   Return value is the index into CumData where Token is found.\r
+**/\r
+INTN\r
+GetCumulativeItem(\r
+  IN MEASUREMENT_RECORD   *Measurement\r
+  )\r
+{\r
+  INTN    Index;\r
+\r
+  for( Index = 0; Index < (INTN)NumCum; ++Index) {\r
+    if (AsciiStrnCmp (Measurement->Token, CumData[Index].Name, PERF_TOKEN_LENGTH) == 0) {\r
+      return Index;  // Exit, we found a match\r
+    }\r
+  }\r
+  // If the for loop exits, Token was not found.\r
+  return -1;   // Indicate failure\r
+}\r
diff --git a/ShellPkg/Library/UefiDpLib/Literals.c b/ShellPkg/Library/UefiDpLib/Literals.c
new file mode 100644 (file)
index 0000000..68de0fb
--- /dev/null
@@ -0,0 +1,23 @@
+/** @file\r
+  Definitions of ASCII string literals used by DP.\r
+\r
+  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+#include <PerformanceTokens.h>\r
+\r
+// ASCII String literals which probably don't need translation\r
+CHAR8 const ALit_TimerLibError[] = "Timer library instance error!\n";\r
+CHAR8 const ALit_SEC[]    = SEC_TOK;\r
+CHAR8 const ALit_DXE[]    = DXE_TOK;\r
+CHAR8 const ALit_SHELL[]  = SHELL_TOK;\r
+CHAR8 const ALit_PEI[]    = PEI_TOK;\r
+CHAR8 const ALit_BDS[]    = BDS_TOK;\r
+CHAR8 const ALit_BdsTO[]  = "BdsTimeOut";\r
+CHAR8 const ALit_PEIM[]   = "PEIM";\r
diff --git a/ShellPkg/Library/UefiDpLib/Literals.h b/ShellPkg/Library/UefiDpLib/Literals.h
new file mode 100644 (file)
index 0000000..8aec09c
--- /dev/null
@@ -0,0 +1,26 @@
+/** @file\r
+  Declarations of ASCII string literals used by DP.\r
+\r
+  Copyright (c) 2009 - 2010, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+**/\r
+#ifndef _LITERALS_H_\r
+#define _LITERALS_H_\r
+\r
+// ASCII String literals which probably don't need translation\r
+extern CHAR8 const ALit_TimerLibError[];\r
+extern CHAR8 const ALit_SEC[];\r
+extern CHAR8 const ALit_DXE[];\r
+extern CHAR8 const ALit_SHELL[];\r
+extern CHAR8 const ALit_PEI[];\r
+extern CHAR8 const ALit_BDS[];\r
+extern CHAR8 const ALit_BdsTO[];\r
+extern CHAR8 const ALit_PEIM[];\r
+\r
+#endif  // _LITERALS_H_\r
diff --git a/ShellPkg/Library/UefiDpLib/UefiDpLib.c b/ShellPkg/Library/UefiDpLib/UefiDpLib.c
new file mode 100644 (file)
index 0000000..f3ecfea
--- /dev/null
@@ -0,0 +1,101 @@
+/** @file\r
+  Main file for NULL named library for install1 shell command functions.\r
+\r
+  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "UefiDpLib.h"\r
+\r
+STATIC CONST CHAR16 mFileName[] = L"ShellCommands";\r
+EFI_HANDLE gDpHiiHandle = NULL;\r
+\r
+#define DP_HII_GUID \\r
+  { \\r
+  0xeb832fd9, 0x9089, 0x4898, { 0x83, 0xc9, 0x41, 0x61, 0x8f, 0x5c, 0x48, 0xb9 } \\r
+  }\r
+\r
+EFI_GUID gDpHiiGuid = DP_HII_GUID;\r
+\r
+/**\r
+  Function to get the filename with help context if HII will not be used.\r
+\r
+  @return   The filename with help text in it.\r
+**/\r
+CONST CHAR16*\r
+EFIAPI\r
+UefiDpLibGetManFileName (\r
+  VOID\r
+  )\r
+{\r
+  return (mFileName);\r
+}\r
+\r
+/**\r
+  Constructor for the Shell Level 1 Commands library.\r
+\r
+  Install the handlers for level 1 UEFI Shell 2.0 commands.\r
+\r
+  @param ImageHandle    the image handle of the process\r
+  @param SystemTable    the EFI System Table pointer\r
+\r
+  @retval EFI_SUCCESS        the shell command handlers were installed sucessfully\r
+  @retval EFI_UNSUPPORTED    the shell level required was not found.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UefiDpLibConstructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  //\r
+  // check our bit of the profiles mask\r
+  //\r
+  if ((PcdGet8(PcdShellProfileMask) & BIT2) == 0) {\r
+    return (EFI_SUCCESS);\r
+  }\r
+\r
+  //\r
+  // 3rd parameter 'HII strings array' must be name of .uni strings file followed by 'Strings', e.g. mycommands.uni must be\r
+  // specified as 'mycommandsStrings' because the build Autogen process defines this as a string array for the strings in your\r
+  // .uni file.  Examine your Build folder under your package's DEBUG folder and you will find it defined in a xxxStrDefs.h file.\r
+  //\r
+  gDpHiiHandle = HiiAddPackages (&gDpHiiGuid, gImageHandle, UefiDpLibStrings, NULL);\r
+  if (gDpHiiHandle == NULL) {\r
+    return (EFI_DEVICE_ERROR);\r
+  }\r
+\r
+  //\r
+  // install our shell command handlers that are always installed\r
+  //\r
+  ShellCommandRegisterCommandName(L"dp", ShellCommandRunDp , UefiDpLibGetManFileName, 0, L"", FALSE, gDpHiiHandle, STRING_TOKEN(STR_GET_HELP_DP));\r
+\r
+  return (EFI_SUCCESS);\r
+}\r
+\r
+/**\r
+  Destructor for the library.  free any resources.\r
+\r
+  @param ImageHandle            The image handle of the process.\r
+  @param SystemTable            The EFI System Table pointer.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+UefiDpLibDestructor (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  )\r
+{\r
+  if (gDpHiiHandle != NULL) {\r
+    HiiRemovePackages(gDpHiiHandle);\r
+  }\r
+  return (EFI_SUCCESS);\r
+}\r
diff --git a/ShellPkg/Library/UefiDpLib/UefiDpLib.h b/ShellPkg/Library/UefiDpLib/UefiDpLib.h
new file mode 100644 (file)
index 0000000..2cec991
--- /dev/null
@@ -0,0 +1,60 @@
+/** @file\r
+  Main file for NULL named library for dp command functions.\r
+\r
+  Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>\r
+  This program and the accompanying materials\r
+  are licensed and made available under the terms and conditions of the BSD License\r
+  which accompanies this distribution.  The full text of the license may be found at\r
+  http://opensource.org/licenses/bsd-license.php\r
+\r
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef _UEFI_DP_LIB_H_\r
+#define _UEFI_DP_LIB_H_\r
+\r
+#include <Uefi.h>\r
+#include <ShellBase.h>\r
+\r
+extern EFI_GUID gDpHiiGuid;\r
+\r
+#include <Protocol/EfiShell.h>\r
+#include <Protocol/EfiShellParameters.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/LoadedImage.h>\r
+#include <Protocol/UnicodeCollation.h>\r
+#include <Protocol/DevicePathToText.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PcdLib.h>\r
+#include <Library/ShellCommandLib.h>\r
+#include <Library/ShellLib.h>\r
+#include <Library/SortLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/UefiRuntimeServicesTableLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/FileHandleLib.h>\r
+\r
+extern        EFI_HANDLE                        gDpHiiHandle;\r
+\r
+/**\r
+  Function for 'dp' command.\r
+\r
+  @param[in] ImageHandle  Handle to the Image (NULL if Internal).\r
+  @param[in] SystemTable  Pointer to the System Table (NULL if Internal).\r
+**/\r
+SHELL_STATUS\r
+EFIAPI\r
+ShellCommandRunDp (\r
+  IN EFI_HANDLE        ImageHandle,\r
+  IN EFI_SYSTEM_TABLE  *SystemTable\r
+  );\r
+\r
+#endif\r
+\r
diff --git a/ShellPkg/Library/UefiDpLib/UefiDpLib.inf b/ShellPkg/Library/UefiDpLib/UefiDpLib.inf
new file mode 100644 (file)
index 0000000..43de57d
--- /dev/null
@@ -0,0 +1,75 @@
+##  @file\r
+#  Display Performance Application, Module information file.\r
+#\r
+# Copyright (c) 2009 - 2013, Intel Corporation. All rights reserved.\r
+# This program and the accompanying materials\r
+# are licensed and made available under the terms and conditions of the BSD License\r
+# which accompanies this distribution.  The full text of the license may be found at\r
+# http://opensource.org/licenses/bsd-license.php\r
+#\r
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010006\r
+  BASE_NAME                      = UefiDpLib\r
+  FILE_GUID                      = 9DF262F7-CF81-4294-B5A5-B2E3CAFE5618\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = NULL|UEFI_APPLICATION UEFI_DRIVER\r
+  CONSTRUCTOR                    = UefiDpLibConstructor\r
+  DESTRUCTOR                     = UefiDpLibDestructor\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources.common]\r
+  UefiDpLib.c\r
+  UefiDpLib.h\r
+  UefiDpLib.uni\r
+  Dp.c\r
+  Dp.h\r
+  Literals.h\r
+  Literals.c\r
+  DpInternal.h\r
+  DpUtilities.c\r
+  DpTrace.c\r
+  DpProfile.c\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  ShellPkg/ShellPkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+  PerformancePkg/PerformancePkg.dec\r
+\r
+[LibraryClasses]\r
+  TimerLib\r
+  PerformanceLib\r
+  DxeServicesLib\r
+  MemoryAllocationLib\r
+  BaseLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  ShellCommandLib\r
+  ShellLib\r
+  UefiLib\r
+  UefiRuntimeServicesTableLib\r
+  UefiBootServicesTableLib\r
+  SortLib\r
+  PrintLib\r
+\r
+[Protocols]\r
+  gEfiLoadedImageProtocolGuid                             # ALWAYS_CONSUMED\r
+  gEfiDriverBindingProtocolGuid                           # SOMETIMES_CONSUMED\r
+  gEfiComponentName2ProtocolGuid                          # SOMETIMES_CONSUMED\r
+  gEfiLoadedImageDevicePathProtocolGuid                   # SOMETIMES_CONSUMED\r
+  gEfiDevicePathToTextProtocolGuid                        # SOMETIMES_CONSUMED\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize\r
+  gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask # ALWAYS_CONSUMED\r
diff --git a/ShellPkg/Library/UefiDpLib/UefiDpLib.uni b/ShellPkg/Library/UefiDpLib/UefiDpLib.uni
new file mode 100644 (file)
index 0000000..fa29f9b
Binary files /dev/null and b/ShellPkg/Library/UefiDpLib/UefiDpLib.uni differ
diff --git a/ShellPkg/Library/UefiDpLib/readme.txt b/ShellPkg/Library/UefiDpLib/readme.txt
new file mode 100644 (file)
index 0000000..849efa4
--- /dev/null
@@ -0,0 +1,2 @@
+from PerformancePkg\Dp_App\r
+SVN 13406\r
index 6b641155f2e842ff3c0d0847c461ab5fbbef9369..f22986bf4e263f0a23328ce38cbaa9546ae09d78 100644 (file)
@@ -1,7 +1,7 @@
 ##  @file\r
 # Shell Package\r
 #\r
-# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #    This program and the accompanying materials\r
 #    are licensed and made available under the terms and conditions of the BSD License\r
@@ -64,7 +64,7 @@
   gEfiMdePkgTokenSpaceGuid.PcdUefiLibMaxPrintBufferSize|16000\r
 !ifdef $(NO_SHELL_PROFILES)\r
   gEfiShellPkgTokenSpaceGuid.PcdShellProfileMask|0x00\r
-!endif\r
+!endif #$(NO_SHELL_PROFILES)\r
 \r
 [Components]\r
   ShellPkg/Library/UefiFileHandleLib/UefiFileHandleLib.inf\r
   ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf\r
   ShellPkg/Library/UefiHandleParsingLib/UefiHandleParsingLib.inf\r
 \r
+  ShellPkg/Library/UefiDpLib/UefiDpLib.inf {\r
+    <LibraryClasses>\r
+      TimerLib|MdePkg/Library/BaseTimerLibNullTemplate/BaseTimerLibNullTemplate.inf\r
+      PerformanceLib|MdePkg/Library/BasePerformanceLibNull/BasePerformanceLibNull.inf\r
+      DxeServicesLib|MdePkg/Library/DxeServicesLib/DxeServicesLib.inf\r
+  }\r
+\r
   ShellPkg/Application/Shell/Shell.inf {\r
     <LibraryClasses>\r
       NULL|ShellPkg/Library/UefiShellLevel2CommandsLib/UefiShellLevel2CommandsLib.inf\r
@@ -83,6 +90,9 @@
       NULL|ShellPkg/Library/UefiShellInstall1CommandsLib/UefiShellInstall1CommandsLib.inf\r
       NULL|ShellPkg/Library/UefiShellDebug1CommandsLib/UefiShellDebug1CommandsLib.inf\r
       NULL|ShellPkg/Library/UefiShellNetwork1CommandsLib/UefiShellNetwork1CommandsLib.inf\r
-!endif\r
+!ifdef $(INCLUDE_DP)\r
+      NULL|ShellPkg/Library/UefiDpLib/UefiDpLib.inf\r
+!endif #$(INCLUDE_DP)\r
+!endif #$(NO_SHELL_PROFILES)\r
   }\r
 \r