mirror of https://github.com/acidanthera/audk.git
301 lines
7.3 KiB
Diff
301 lines
7.3 KiB
Diff
From 82540f3a4b280133f2d1a58cb8baba01c1f09690 Mon Sep 17 00:00:00 2001
|
|
From: Olivier Martin <olivier.martin@arm.com>
|
|
Date: Thu, 16 Feb 2012 15:56:40 +0000
|
|
Subject: [PATCH 3/3] ArmPlatformPkg/EblCmdLib: Add 'dumpfdt' EBL command
|
|
|
|
This command dumps the FDT blob pointed by the Device Path defined in the
|
|
command argument or used the Platform specifc FDT defined by its Device Path
|
|
in the UEFI Variable 'Fdt' or the PcdFdtDevicePath PCD.
|
|
---
|
|
ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c | 206 ++++++++++++++++++++++++
|
|
ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c | 12 ++
|
|
ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf | 6 +
|
|
3 files changed, 224 insertions(+), 0 deletions(-)
|
|
create mode 100755 ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c
|
|
mode change 100644 => 100755 ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c
|
|
mode change 100644 => 100755 ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
|
|
|
|
diff --git a/ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c b/ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c
|
|
new file mode 100755
|
|
index 0000000..3c5eb8e
|
|
--- /dev/null
|
|
+++ b/ArmPlatformPkg/Library/EblCmdLib/EblCmdFdt.c
|
|
@@ -0,0 +1,206 @@
|
|
+#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) {
|
|
+
|
|
+ /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
|
|
+
|
|
+ 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;
|
|
+ VOID* 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, (EFI_PHYSICAL_ADDRESS*)&FdtBlob, &FdtBlobSize);
|
|
+ if (EFI_ERROR(Status)) {
|
|
+ Print (L"ERROR: Did not find the Fdt Blob.\n");
|
|
+ return Status;
|
|
+ }
|
|
+
|
|
+ Ret = fdt_check_header(FdtBlob);
|
|
+ if (Ret != 0) {
|
|
+ Print (L"ERROR: Device Tree header not valid (err:%d)\n",Ret);
|
|
+ return Status;
|
|
+ }
|
|
+
|
|
+ DumpFdt (FdtBlob);
|
|
+
|
|
+ FreePool (FdtDevicePath);
|
|
+
|
|
+ return EFI_SUCCESS;
|
|
+}
|
|
diff --git a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.c
|
|
old mode 100644
|
|
new mode 100755
|
|
index b75dbfb..327a794
|
|
--- 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
|
|
@@ -416,6 +422,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
|
|
old mode 100644
|
|
new mode 100755
|
|
index 0eb71a0..9f84c07
|
|
--- a/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
|
|
+++ b/ArmPlatformPkg/Library/EblCmdLib/EblCmdLib.inf
|
|
@@ -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
|
|
--
|
|
1.7.0.4
|
|
|