diff options
-rw-r--r-- | ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c | 218 | ||||
-rw-r--r-- | ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c | 12 | ||||
-rw-r--r-- | ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf | 10 |
3 files changed, 238 insertions, 2 deletions
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 <Base.h>
+#include <Uefi.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/BdsLib.h>
+#include <Library/DebugLib.h>
+#include <Library/PcdLib.h>
+#include <Library/PrintLib.h>
+#include <Library/UefiLib.h>
+#include <Library/UefiApplicationEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiRuntimeServicesTableLib.h>
+
+#include <Protocol/DevicePathFromText.h>
+
+#include <Guid/GlobalVariable.h>
+
+#include <libfdt.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"]");
+ }
+}
+
+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.<BR>
+# Copyright (c) 2011-2012, 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
@@ -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
|