From 145292e4c861fa4e2095873dcc43dd12f9460dd9 Mon Sep 17 00:00:00 2001 From: oliviermartin Date: Fri, 28 Sep 2012 10:48:35 +0000 Subject: ArmPlatformPkg/EblCmdLib: Added the command 'dumpfdt' Signed-off-by: Olivier Martin git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@13771 6f19259b-4bc3-4df7-8a09-765794883524 --- ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c | 218 +++++++++++++++++++++++++ ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c | 12 ++ ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf | 10 +- 3 files changed, 238 insertions(+), 2 deletions(-) create mode 100644 ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c (limited to 'ArmPlatformPkg/Library/EblCmdLib') diff --git a/ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c b/ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c new file mode 100644 index 0000000000..5da71cff2b --- /dev/null +++ b/ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c @@ -0,0 +1,218 @@ +/** @file +* +* Copyright (c) 2011-2012, ARM Limited. All rights reserved. +* +* 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + +#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"]"); + } +} + +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; + + 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 + strlen(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"); + } +} + +EFI_STATUS +EblDumpFdt ( + IN UINTN Argc, + IN CHAR8 **Argv + ) +{ + EFI_STATUS Status; + EFI_DEVICE_PATH* FdtDevicePath; + EFI_PHYSICAL_ADDRESS FdtBlob; + UINTN FdtBlobSize; + UINTN Ret; + EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *EfiDevicePathFromTextProtocol; + + // If no FDT file is passed to the argument then get the one from the platform + if (Argc < 2) { + Status = GetEnvironmentVariable (L"Fdt",NULL,NULL,(VOID**)&FdtDevicePath); + if (Status == EFI_NOT_FOUND) { + // No set yet, get the Default Device Path + Status = gBS->LocateProtocol (&gEfiDevicePathFromTextProtocolGuid, NULL, (VOID **)&EfiDevicePathFromTextProtocol); + ASSERT_EFI_ERROR(Status); + FdtDevicePath = EfiDevicePathFromTextProtocol->ConvertTextToDevicePath ((CHAR16*)PcdGetPtr(PcdFdtDevicePath)); + } + } else { + return EFI_NOT_FOUND; + } + + Status = BdsLoadImage (FdtDevicePath, AllocateAnyPages, &FdtBlob, &FdtBlobSize); + if (EFI_ERROR(Status)) { + Print (L"ERROR: Did not find the Fdt Blob.\n"); + return Status; + } + + Ret = fdt_check_header((CONST VOID*)(UINTN)FdtBlob); + if (Ret != 0) { + Print (L"ERROR: Device Tree header not valid (err:%d)\n",Ret); + return Status; + } + + DumpFdt ((VOID*)(UINTN)FdtBlob); + + FreePool (FdtDevicePath); + + return EFI_SUCCESS; +} diff --git a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c index 4c298a61cf..8f7ea65e7b 100644 --- a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c +++ b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c @@ -42,6 +42,12 @@ EblDumpMmu ( IN UINTN Argc, IN CHAR8 **Argv ); + +EFI_STATUS +EblDumpFdt ( + IN UINTN Argc, + IN CHAR8 **Argv + ); /** Simple arm disassembler via a library @@ -426,6 +432,12 @@ GLOBAL_REMOVE_IF_UNREFERENCED const EBL_COMMAND_TABLE mLibCmdTemplate[] = " list all the Device Paths", NULL, EblDevicePaths + }, + { + "dumpfdt", + " dump the current fdt or the one defined in the arguments", + NULL, + EblDumpFdt } }; diff --git a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf index 0eb71a0108..9ddc9e82d1 100644 --- a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf +++ b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf @@ -1,6 +1,6 @@ #/** @file # -# Copyright (c) 2011, ARM Ltd. All rights reserved.
+# Copyright (c) 2011-2012, ARM Ltd. All rights reserved.
# 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 @@ -14,7 +14,7 @@ [Defines] INF_VERSION = 0x00010005 - BASE_NAME = ArmVeEblCmdLib + BASE_NAME = ArmPlatformEblCmdLib FILE_GUID = 6085e1ca-0d2d-4ba4-9872-c59b36ffd6ad MODULE_TYPE = UEFI_DRIVER VERSION_STRING = 1.0 @@ -30,12 +30,14 @@ [Sources.common] EblCmdLib.c EblCmdMmu.c + EblCmdFdt.c [Packages] MdePkg/MdePkg.dec MdeModulePkg/MdeModulePkg.dec EmbeddedPkg/EmbeddedPkg.dec ArmPkg/ArmPkg.dec + ArmPlatformPkg/ArmPlatformPkg.dec [LibraryClasses] BaseLib @@ -45,6 +47,7 @@ PerformanceLib TimerLib BdsLib + FdtLib [Protocols] gEfiDebugSupportProtocolGuid @@ -53,3 +56,6 @@ [Guids] gEfiDebugImageInfoTableGuid + +[Pcd] + gArmPlatformTokenSpaceGuid.PcdFdtDevicePath -- cgit v1.2.3