fdtdump.c 3.6 KB

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