Revision: 17303
          http://sourceforge.net/p/edk2/code/17303
Author:   oliviermartin
Date:     2015-05-05 15:31:11 +0000 (Tue, 05 May 2015)
Log Message:
-----------
EmbeddedPkg/FdtPlatformDxe: Introduce EFI Shell command 'dumfdt'

This command dumps the Flat Device Tree currently installed
in the EFI Configuration Table.

Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Olivier Martin <[email protected]>
Reviewed-by: Ronald Cron <[email protected]>

Modified Paths:
--------------
    trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c
    trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.h
    trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf
    trunk/edk2/EmbeddedPkg/EmbeddedPkg.dec

Added Paths:
-----------
    trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/ShellDumpFdt.c

Modified: trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c
===================================================================
--- trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c 2015-05-05 
15:27:41 UTC (rev 17302)
+++ trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.c 2015-05-05 
15:31:11 UTC (rev 17303)
@@ -20,8 +20,6 @@
 
 #include <Protocol/DevicePath.h>
 
-#include <libfdt.h>
-
 //
 // Internal variables
 //
@@ -32,6 +30,12 @@
     ShellDynCmdSetFdtGetHelp  // GetHelp
 };
 
+STATIC CONST EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL mShellDynCmdProtocolDumpFdt = {
+    L"dumpfdt",                // Name of the command
+    ShellDynCmdDumpFdtHandler, // Handler
+    ShellDynCmdDumpFdtGetHelp  // GetHelp
+};
+
 STATIC CONST EFI_GUID  mFdtPlatformDxeHiiGuid = {
                          0x8afa7610, 0x62b1, 0x46aa,
                          {0xb5, 0x34, 0xc3, 0xde, 0xff, 0x39, 0x77, 0x8c}
@@ -159,6 +163,7 @@
   )
 {
   EFI_STATUS  Status;
+  EFI_HANDLE  Handle;
 
   //
   // Install the Device Tree from its expected location
@@ -168,14 +173,7 @@
     return Status;
   }
 
-  //
-  // If the development features are enabled, install the dynamic shell
-  // command "setfdt" to be able to define a device path for the FDT
-  // that has precedence over the device paths defined by
-  // "PcdFdtDevicePaths".
-  //
-
-  if (FeaturePcdGet (PcdOverridePlatformFdt)) {
+  if (FeaturePcdGet (PcdOverridePlatformFdt) || FeaturePcdGet 
(PcdDumpFdtShellCommand)) {
     //
     // Register the strings for the user interface in the HII Database.
     // This shows the way to the multi-language support, even if
@@ -192,10 +190,22 @@
                                  FdtPlatformDxeStrings,
                                  NULL
                                  );
+  }
 
+  //
+  // If the development features are enabled, install the dynamic shell
+  // command "setfdt" to be able to define a device path for the FDT
+  // that has precedence over the device paths defined by
+  // "PcdFdtDevicePaths".
+  //
+
+  if (FeaturePcdGet (PcdOverridePlatformFdt)) {
     if (mFdtPlatformDxeHiiHandle != NULL) {
+      // We install dynamic EFI command on separate handles as we cannot 
register
+      // more than one protocol of the same protocol interface on the same 
handle.
+      Handle = NULL;
       Status = gBS->InstallMultipleProtocolInterfaces (
-                      &ImageHandle,
+                      &Handle,
                       &gEfiShellDynamicCommandProtocolGuid,
                       &mShellDynCmdProtocolSetFdt,
                       NULL
@@ -215,6 +225,32 @@
     }
   }
 
+  if (FeaturePcdGet (PcdDumpFdtShellCommand)) {
+    if (mFdtPlatformDxeHiiHandle != NULL) {
+      // We install dynamic EFI command on separate handles as we cannot 
register
+      // more than one protocol of the same protocol interface on the same 
handle.
+      Handle = NULL;
+      Status = gBS->InstallMultipleProtocolInterfaces (
+                      &Handle,
+                      &gEfiShellDynamicCommandProtocolGuid,
+                      &mShellDynCmdProtocolDumpFdt,
+                      NULL
+                      );
+      if (EFI_ERROR (Status)) {
+        HiiRemovePackages (mFdtPlatformDxeHiiHandle);
+      }
+    } else {
+      Status = EFI_LOAD_ERROR;
+    }
+    if (EFI_ERROR (Status)) {
+      DEBUG ((
+        EFI_D_WARN,
+        "Unable to install \"dumpfdt\" EFI Shell command - %r \n",
+        Status
+        ));
+    }
+  }
+
   return Status;
 }
 

Modified: trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.h
===================================================================
--- trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.h 2015-05-05 
15:27:41 UTC (rev 17302)
+++ trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatform.h 2015-05-05 
15:31:11 UTC (rev 17303)
@@ -127,4 +127,48 @@
   IN CONST CHAR8                         *Language
   );
 
+/**
+  This is the shell command "dumpfdt" handler function. This function handles
+  the command when it is invoked in the shell.
+
+  @param[in]  This             The instance of the
+                               EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+  @param[in]  SystemTable      The pointer to the UEFI system table.
+  @param[in]  ShellParameters  The parameters associated with the command.
+  @param[in]  Shell            The instance of the shell protocol used in the
+                               context of processing this command.
+
+  @return  SHELL_SUCCESS            The operation was successful.
+  @return  SHELL_ABORTED            Operation aborted due to internal error.
+  @return  SHELL_NOT_FOUND          Failed to locate the Device Tree into the 
EFI Configuration Table
+  @return  SHELL_OUT_OF_RESOURCES   A memory allocation failed.
+
+**/
+SHELL_STATUS
+EFIAPI
+ShellDynCmdDumpFdtHandler (
+  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,
+  IN EFI_SYSTEM_TABLE                    *SystemTable,
+  IN EFI_SHELL_PARAMETERS_PROTOCOL       *ShellParameters,
+  IN EFI_SHELL_PROTOCOL                  *Shell
+  );
+
+/**
+  This is the shell command "dumpfdt" help handler function. This
+  function returns the formatted help for the "dumpfdt" command.
+  The format matchs that in Appendix B of the revision 2.1 of the
+  UEFI Shell Specification.
+
+  @param[in]  This      The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+  @param[in]  Language  The pointer to the language string to use.
+
+  @return  CHAR16*  Pool allocated help string, must be freed by caller.
+**/
+CHAR16*
+EFIAPI
+ShellDynCmdDumpFdtGetHelp (
+  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,
+  IN CONST CHAR8                         *Language
+  );
+
 #endif /* __FDT_PLATFORM_DXE_H__ */

Modified: trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf
===================================================================
--- trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf    
2015-05-05 15:27:41 UTC (rev 17302)
+++ trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/FdtPlatformDxe.inf    
2015-05-05 15:31:11 UTC (rev 17303)
@@ -24,6 +24,7 @@
 [Sources.common]
   FdtPlatform.c
   FdtPlatformDxe.uni
+  ShellDumpFdt.c
   ShellSetFdt.c
 
 [Packages]
@@ -56,6 +57,7 @@
 
 [FeaturePcd]
   gEmbeddedTokenSpaceGuid.PcdOverridePlatformFdt
+  gEmbeddedTokenSpaceGuid.PcdDumpFdtShellCommand
 
 [Pcd]
   gEmbeddedTokenSpaceGuid.PcdFdtDevicePaths

Added: trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/ShellDumpFdt.c
===================================================================
--- trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/ShellDumpFdt.c                
                (rev 0)
+++ trunk/edk2/EmbeddedPkg/Drivers/FdtPlatformDxe/ShellDumpFdt.c        
2015-05-05 15:31:11 UTC (rev 17303)
@@ -0,0 +1,279 @@
+/** @file
+
+  Copyright (c) 2015, ARM Ltd. All rights reserved.<BR>
+
+  This program and the accompanying materials
+  are licensed and made available under the terms and conditions of the BSD 
License
+  which accompanies this distribution.  The full text of the license may be 
found at
+  http://opensource.org/licenses/bsd-license.php
+
+  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "FdtPlatform.h"
+
+#define ALIGN(x, a)     (((x) + ((a) - 1)) & ~((a) - 1))
+#define PALIGN(p, a)    ((void *)(ALIGN ((unsigned long)(p), (a))))
+#define GET_CELL(p)     (p += 4, *((const uint32_t *)(p-4)))
+
+STATIC
+UINTN
+IsPrintableString (
+  IN CONST VOID* data,
+  IN UINTN len
+  )
+{
+  CONST CHAR8 *s = data;
+  CONST CHAR8 *ss;
+
+  // Zero length is not
+  if (len == 0) {
+    return 0;
+  }
+
+  // Must terminate with zero
+  if (s[len - 1] != '\0') {
+    return 0;
+  }
+
+  ss = s;
+  while (*s/* && isprint (*s)*/) {
+    s++;
+  }
+
+  // Not zero, or not done yet
+  if (*s != '\0' || (s + 1 - ss) < len) {
+    return 0;
+  }
+
+  return 1;
+}
+
+STATIC
+VOID
+PrintData (
+  IN CONST CHAR8* data,
+  IN UINTN len
+  )
+{
+  UINTN i;
+  CONST CHAR8 *p = data;
+
+  // No data, don't print
+  if (len == 0)
+    return;
+
+  if (IsPrintableString (data, len)) {
+    Print (L" = \"%a\"", (const char *)data);
+  } else if ((len % 4) == 0) {
+    Print (L" = <");
+    for (i = 0; i < len; i += 4) {
+      Print (L"0x%08x%a", fdt32_to_cpu (GET_CELL (p)), i < (len - 4) ? " " : 
"");
+    }
+    Print (L">");
+  } else {
+    Print (L" = [");
+    for (i = 0; i < len; i++)
+      Print (L"%02x%a", *p++, i < len - 1 ? " " : "");
+    Print (L"]");
+  }
+}
+
+STATIC
+VOID
+DumpFdt (
+  IN VOID*                FdtBlob
+  )
+{
+  struct fdt_header *bph;
+  UINT32 off_dt;
+  UINT32 off_str;
+  CONST CHAR8* p_struct;
+  CONST CHAR8* p_strings;
+  CONST CHAR8* p;
+  CONST CHAR8* s;
+  CONST CHAR8* t;
+  UINT32 tag;
+  UINTN sz;
+  UINTN depth;
+  UINTN shift;
+  UINT32 version;
+
+  {
+    // Can 'memreserve' be printed by below code?
+    INTN num = fdt_num_mem_rsv (FdtBlob);
+    INTN i, err;
+    UINT64 addr = 0, size = 0;
+
+    for (i = 0; i < num; i++) {
+      err = fdt_get_mem_rsv (FdtBlob, i, &addr, &size);
+      if (err) {
+        DEBUG ((EFI_D_ERROR, "Error (%d) : Cannot get memreserve section 
(%d)\n", err, i));
+      }
+      else {
+        Print (L"/memreserve/ \t0x%lx \t0x%lx;\n", addr, size);
+      }
+    }
+  }
+
+  depth = 0;
+  shift = 4;
+
+  bph = FdtBlob;
+  off_dt = fdt32_to_cpu (bph->off_dt_struct);
+  off_str = fdt32_to_cpu (bph->off_dt_strings);
+  p_struct = (CONST CHAR8*)FdtBlob + off_dt;
+  p_strings = (CONST CHAR8*)FdtBlob + off_str;
+  version = fdt32_to_cpu (bph->version);
+
+  p = p_struct;
+  while ((tag = fdt32_to_cpu (GET_CELL (p))) != FDT_END) {
+    if (tag == FDT_BEGIN_NODE) {
+      s = p;
+      p = PALIGN (p + AsciiStrLen (s) + 1, 4);
+
+      if (*s == '\0')
+              s = "/";
+
+      Print (L"%*s%a {\n", depth * shift, L" ", s);
+
+      depth++;
+      continue;
+    }
+
+    if (tag == FDT_END_NODE) {
+      depth--;
+
+      Print (L"%*s};\n", depth * shift, L" ");
+      continue;
+    }
+
+    if (tag == FDT_NOP) {
+      Print (L"%*s// [NOP]\n", depth * shift, L" ");
+      continue;
+    }
+
+    if (tag != FDT_PROP) {
+      Print (L"%*s ** Unknown tag 0x%08x\n", depth * shift, L" ", tag);
+      break;
+    }
+    sz = fdt32_to_cpu (GET_CELL (p));
+    s = p_strings + fdt32_to_cpu (GET_CELL (p));
+    if (version < 16 && sz >= 8)
+            p = PALIGN (p, 8);
+    t = p;
+
+    p = PALIGN (p + sz, 4);
+
+    Print (L"%*s%a", depth * shift, L" ", s);
+    PrintData (t, sz);
+    Print (L";\n");
+  }
+}
+
+/**
+  This is the shell command "dumpfdt" handler function. This function handles
+  the command when it is invoked in the shell.
+
+  @param[in]  This             The instance of the
+                               EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+  @param[in]  SystemTable      The pointer to the UEFI system table.
+  @param[in]  ShellParameters  The parameters associated with the command.
+  @param[in]  Shell            The instance of the shell protocol used in the
+                               context of processing this command.
+
+  @return  SHELL_SUCCESS            The operation was successful.
+  @return  SHELL_ABORTED            Operation aborted due to internal error.
+  @return  SHELL_NOT_FOUND          Failed to locate the Device Tree into the 
EFI Configuration Table
+  @return  SHELL_OUT_OF_RESOURCES   A memory allocation failed.
+
+**/
+SHELL_STATUS
+EFIAPI
+ShellDynCmdDumpFdtHandler (
+  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,
+  IN EFI_SYSTEM_TABLE                    *SystemTable,
+  IN EFI_SHELL_PARAMETERS_PROTOCOL       *ShellParameters,
+  IN EFI_SHELL_PROTOCOL                  *Shell
+  )
+{
+  SHELL_STATUS  ShellStatus;
+  EFI_STATUS    Status;
+  VOID          *FdtBlob;
+
+  ShellStatus  = SHELL_SUCCESS;
+
+  //
+  // Install the Shell and Shell Parameters Protocols on the driver
+  // image. This is necessary for the initialisation of the Shell
+  // Library to succeed in the next step.
+  //
+  Status = gBS->InstallMultipleProtocolInterfaces (
+                  &gImageHandle,
+                  &gEfiShellProtocolGuid, Shell,
+                  &gEfiShellParametersProtocolGuid, ShellParameters,
+                  NULL
+                  );
+  if (EFI_ERROR (Status)) {
+    return SHELL_ABORTED;
+  }
+
+  //
+  // Initialise the Shell Library as we are going to use it.
+  // Assert that the return code is EFI_SUCCESS as it should.
+  // To anticipate any change is the codes returned by
+  // ShellInitialize(), leave in case of error.
+  //
+  Status = ShellInitialize ();
+  if (EFI_ERROR (Status)) {
+    ASSERT_EFI_ERROR (Status);
+    return SHELL_ABORTED;
+  }
+
+  Status = EfiGetSystemConfigurationTable (&gFdtTableGuid, &FdtBlob);
+  if (EFI_ERROR (Status)) {
+    Print (L"ERROR: Did not find the Fdt Blob.\n");
+    return EfiCodeToShellCode (Status);
+  }
+
+  DumpFdt (FdtBlob);
+
+  gBS->UninstallMultipleProtocolInterfaces (
+         gImageHandle,
+         &gEfiShellProtocolGuid, Shell,
+         &gEfiShellParametersProtocolGuid, ShellParameters,
+         NULL
+         );
+
+  return ShellStatus;
+}
+
+/**
+  This is the shell command "dumpfdt" help handler function. This
+  function returns the formatted help for the "dumpfdt" command.
+  The format matchs that in Appendix B of the revision 2.1 of the
+  UEFI Shell Specification.
+
+  @param[in]  This      The instance of the EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL.
+  @param[in]  Language  The pointer to the language string to use.
+
+  @return  CHAR16*  Pool allocated help string, must be freed by caller.
+**/
+CHAR16*
+EFIAPI
+ShellDynCmdDumpFdtGetHelp (
+  IN EFI_SHELL_DYNAMIC_COMMAND_PROTOCOL  *This,
+  IN CONST CHAR8                         *Language
+  )
+{
+  //
+  // This allocates memory. The caller has to free the allocated memory.
+  //
+  return HiiGetString (
+                mFdtPlatformDxeHiiHandle,
+                STRING_TOKEN (STR_GET_HELP_DUMPFDT),
+                Language
+                );
+}

Modified: trunk/edk2/EmbeddedPkg/EmbeddedPkg.dec
===================================================================
--- trunk/edk2/EmbeddedPkg/EmbeddedPkg.dec      2015-05-05 15:27:41 UTC (rev 
17302)
+++ trunk/edk2/EmbeddedPkg/EmbeddedPkg.dec      2015-05-05 15:31:11 UTC (rev 
17303)
@@ -82,7 +82,10 @@
   
gEmbeddedTokenSpaceGuid.PcdPrePiProduceMemoryTypeInformationHob|FALSE|BOOLEAN|0x0000001b
   gEmbeddedTokenSpaceGuid.PcdCacheEnable|FALSE|BOOLEAN|0x00000042
   gEmbeddedTokenSpaceGuid.PcdGdbSerial|FALSE|BOOLEAN|0x00000053
+  # Enable the development specific features
   gEmbeddedTokenSpaceGuid.PcdOverridePlatformFdt|TRUE|BOOLEAN|0x00000054
+  # Add 'dumpfdt' EFI Shell command
+  gEmbeddedTokenSpaceGuid.PcdDumpFdtShellCommand|TRUE|BOOLEAN|0x00000056
 
 
 [PcdsFixedAtBuild.common]


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
edk2-commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/edk2-commits

Reply via email to