fdtdump.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * fdtdump.c - Contributed by Pantelis Antoniou <pantelis.antoniou AT gmail.com>
  4. */
  5. #include <stdint.h>
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <ctype.h>
  10. #include <fdt.h>
  11. #include <libfdt_env.h>
  12. #include "util.h"
  13. #define ALIGN(x, a) (((x) + ((a) - 1)) & ~((a) - 1))
  14. #define PALIGN(p, a) ((void *)(ALIGN((unsigned long)(p), (a))))
  15. #define GET_CELL(p) (p += 4, *((const uint32_t *)(p-4)))
  16. static void print_data(const char *data, int len)
  17. {
  18. int i;
  19. const char *p = data;
  20. /* no data, don't print */
  21. if (len == 0)
  22. return;
  23. if (util_is_printable_string(data, len)) {
  24. printf(" = \"%s\"", (const char *)data);
  25. } else if ((len % 4) == 0) {
  26. printf(" = <");
  27. for (i = 0; i < len; i += 4)
  28. printf("0x%08x%s", fdt32_to_cpu(GET_CELL(p)),
  29. i < (len - 4) ? " " : "");
  30. printf(">");
  31. } else {
  32. printf(" = [");
  33. for (i = 0; i < len; i++)
  34. printf("%02x%s", *p++, i < len - 1 ? " " : "");
  35. printf("]");
  36. }
  37. }
  38. static void dump_blob(void *blob)
  39. {
  40. struct fdt_header *bph = blob;
  41. uint32_t off_mem_rsvmap = fdt32_to_cpu(bph->off_mem_rsvmap);
  42. uint32_t off_dt = fdt32_to_cpu(bph->off_dt_struct);
  43. uint32_t off_str = fdt32_to_cpu(bph->off_dt_strings);
  44. struct fdt_reserve_entry *p_rsvmap =
  45. (struct fdt_reserve_entry *)((char *)blob + off_mem_rsvmap);
  46. const char *p_struct = (const char *)blob + off_dt;
  47. const char *p_strings = (const char *)blob + off_str;
  48. uint32_t version = fdt32_to_cpu(bph->version);
  49. uint32_t totalsize = fdt32_to_cpu(bph->totalsize);
  50. uint32_t tag;
  51. const char *p, *s, *t;
  52. int depth, sz, shift;
  53. int i;
  54. uint64_t addr, size;
  55. depth = 0;
  56. shift = 4;
  57. printf("/dts-v1/;\n");
  58. printf("// magic:\t\t0x%x\n", fdt32_to_cpu(bph->magic));
  59. printf("// totalsize:\t\t0x%x (%d)\n", totalsize, totalsize);
  60. printf("// off_dt_struct:\t0x%x\n", off_dt);
  61. printf("// off_dt_strings:\t0x%x\n", off_str);
  62. printf("// off_mem_rsvmap:\t0x%x\n", off_mem_rsvmap);
  63. printf("// version:\t\t%d\n", version);
  64. printf("// last_comp_version:\t%d\n",
  65. fdt32_to_cpu(bph->last_comp_version));
  66. if (version >= 2)
  67. printf("// boot_cpuid_phys:\t0x%x\n",
  68. fdt32_to_cpu(bph->boot_cpuid_phys));
  69. if (version >= 3)
  70. printf("// size_dt_strings:\t0x%x\n",
  71. fdt32_to_cpu(bph->size_dt_strings));
  72. if (version >= 17)
  73. printf("// size_dt_struct:\t0x%x\n",
  74. fdt32_to_cpu(bph->size_dt_struct));
  75. printf("\n");
  76. for (i = 0; ; i++) {
  77. addr = fdt64_to_cpu(p_rsvmap[i].address);
  78. size = fdt64_to_cpu(p_rsvmap[i].size);
  79. if (addr == 0 && size == 0)
  80. break;
  81. printf("/memreserve/ %llx %llx;\n",
  82. (unsigned long long)addr, (unsigned long long)size);
  83. }
  84. p = p_struct;
  85. while ((tag = fdt32_to_cpu(GET_CELL(p))) != FDT_END) {
  86. /* printf("tag: 0x%08x (%d)\n", tag, p - p_struct); */
  87. if (tag == FDT_BEGIN_NODE) {
  88. s = p;
  89. p = PALIGN(p + strlen(s) + 1, 4);
  90. if (*s == '\0')
  91. s = "/";
  92. printf("%*s%s {\n", depth * shift, "", s);
  93. depth++;
  94. continue;
  95. }
  96. if (tag == FDT_END_NODE) {
  97. depth--;
  98. printf("%*s};\n", depth * shift, "");
  99. continue;
  100. }
  101. if (tag == FDT_NOP) {
  102. printf("%*s// [NOP]\n", depth * shift, "");
  103. continue;
  104. }
  105. if (tag != FDT_PROP) {
  106. fprintf(stderr, "%*s ** Unknown tag 0x%08x\n", depth * shift, "", tag);
  107. break;
  108. }
  109. sz = fdt32_to_cpu(GET_CELL(p));
  110. s = p_strings + fdt32_to_cpu(GET_CELL(p));
  111. if (version < 16 && sz >= 8)
  112. p = PALIGN(p, 8);
  113. t = p;
  114. p = PALIGN(p + sz, 4);
  115. printf("%*s%s", depth * shift, "", s);
  116. print_data(t, sz);
  117. printf(";\n");
  118. }
  119. }
  120. int main(int argc, char *argv[])
  121. {
  122. char *buf;
  123. if (argc < 2) {
  124. fprintf(stderr, "supply input filename\n");
  125. return 5;
  126. }
  127. buf = utilfdt_read(argv[1]);
  128. if (buf)
  129. dump_blob(buf);
  130. else
  131. return 10;
  132. return 0;
  133. }